|
1 #include <QColorDialog> |
|
2 #include <QTableView> |
|
3 #include "colorselectdialog.h" |
|
4 #include "ui_colorselectdialog.h" |
|
5 |
|
6 ColorSelectDialog::ColorSelectDialog(const ldraw::ColorTable& colorTable, QWidget *parent) : |
|
7 QDialog{parent}, |
|
8 ui{*new Ui_ColorSelectDialog}, |
|
9 colorTable{colorTable} |
|
10 { |
|
11 this->ui.setupUi(this); |
|
12 this->makeColorButtons(); |
|
13 connect(this->ui.filter, &QLineEdit::textEdited, this, &ColorSelectDialog::populateColors); |
|
14 this->updateSelectedColorTexts(); |
|
15 connect(this->ui.colorIndex, qOverload<int>(&QSpinBox::valueChanged), this, &ColorSelectDialog::spinboxEdited); |
|
16 connect(this->ui.directColorButton, &QPushButton::clicked, this, &ColorSelectDialog::chooseDirectColor); |
|
17 connect(this->ui.buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); |
|
18 connect(this->ui.buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); |
|
19 this->populateColors(); |
|
20 } |
|
21 |
|
22 ColorSelectDialog::~ColorSelectDialog() |
|
23 { |
|
24 delete &this->ui; |
|
25 } |
|
26 |
|
27 ldraw::Color colorFromButton(QAbstractButton* button) |
|
28 { |
|
29 return {button->property("_colorIndex").value<qint32>()}; |
|
30 } |
|
31 |
|
32 QString styleSheetForColor(const QColor& color) |
|
33 { |
|
34 QColor const textColor = (luma(color) < 0.4) ? Qt::white : Qt::black; |
|
35 return QString{"background-color: %1; color: %2;"} |
|
36 .arg(color.name()) |
|
37 .arg(textColor.name()); |
|
38 } |
|
39 |
|
40 void ColorSelectDialog::makeColorButtons() |
|
41 { |
|
42 this->buttons.reserve(this->colorTable.size()); |
|
43 for ( |
|
44 auto iterator = std::begin(this->colorTable); |
|
45 iterator != std::end(this->colorTable); |
|
46 ++iterator |
|
47 ) { |
|
48 const qint32 index = iterator->first; |
|
49 const ldraw::ColorTable::ColorDefinition& colordef = iterator->second; |
|
50 QPushButton* const button = new QPushButton{QString::number(index), this}; |
|
51 button->setToolTip(colordef.displayName); |
|
52 button->setStyleSheet(styleSheetForColor(colordef.faceColor)); |
|
53 button->setProperty("_colorIndex", index); |
|
54 button->setCheckable(true); |
|
55 connect(button, &QAbstractButton::clicked, this, &ColorSelectDialog::handleButtonClick); |
|
56 this->buttons.push_back(button); |
|
57 } |
|
58 std::sort( |
|
59 std::begin(this->buttons), |
|
60 std::end(this->buttons), |
|
61 [](QAbstractButton* button_1, QAbstractButton* button_2) |
|
62 { |
|
63 return colorFromButton(button_1) < colorFromButton(button_2); |
|
64 } |
|
65 ); |
|
66 } |
|
67 |
|
68 void ColorSelectDialog::populateColors() |
|
69 { |
|
70 delete this->ui.colorFrame->layout(); |
|
71 if (this->buttons.size() > 0) |
|
72 { |
|
73 QGridLayout* gridLayout = new QGridLayout{}; |
|
74 this->ui.colorFrame->setLayout(gridLayout); |
|
75 const int columnsPerRow = 8; |
|
76 int i = 0; |
|
77 for ( |
|
78 auto iterator = std::begin(this->buttons); |
|
79 iterator != std::end(this->buttons); |
|
80 ++iterator |
|
81 ) { |
|
82 QPushButton* const button = *iterator; |
|
83 const bool filtered = this->filterColor(colorFromButton(button)); |
|
84 button->setVisible(filtered); |
|
85 if (filtered) |
|
86 { |
|
87 const int row = i / columnsPerRow; |
|
88 const int column = i % columnsPerRow; |
|
89 gridLayout->addWidget(button, row, column); |
|
90 i += 1; |
|
91 } |
|
92 } |
|
93 } |
|
94 } |
|
95 |
|
96 void ColorSelectDialog::updateSelectedColorTexts() |
|
97 { |
|
98 if (ldraw::isDirectColor(this->selectedColor)) |
|
99 { |
|
100 this->ui.selectedColorName->setText(ldraw::directColorFace(this->selectedColor).name()); |
|
101 } |
|
102 else |
|
103 { |
|
104 const ldraw::ColorTable::ColorDefinition& colordef = this->colorTable[this->selectedColor]; |
|
105 this->ui.selectedColorName->setText(colordef.displayName); |
|
106 } |
|
107 this->ui.selectedColorName->setStyleSheet(styleSheetForColor(ldraw::colorFace(this->selectedColor, this->colorTable))); |
|
108 this->ui.colorIndex->setValue(this->selectedColor.index); |
|
109 for (QPushButton* button : this->buttons) |
|
110 { |
|
111 ldraw::Color buttonColor = colorFromButton(button); |
|
112 button->setChecked(buttonColor == this->selectedColor); |
|
113 } |
|
114 } |
|
115 |
|
116 void ColorSelectDialog::handleButtonClick() |
|
117 { |
|
118 QAbstractButton* button = qobject_cast<QAbstractButton*>(this->sender()); |
|
119 if (button != nullptr) |
|
120 { |
|
121 this->setCurrentColor(colorFromButton(button)); |
|
122 } |
|
123 } |
|
124 |
|
125 void ColorSelectDialog::spinboxEdited() |
|
126 { |
|
127 this->setCurrentColor(ldraw::Color{this->ui.colorIndex->value()}); |
|
128 } |
|
129 |
|
130 void ColorSelectDialog::chooseDirectColor() |
|
131 { |
|
132 QColorDialog dialog; |
|
133 dialog.setCurrentColor(ldraw::colorFace(this->selectedColor, this->colorTable)); |
|
134 if (dialog.exec()) |
|
135 { |
|
136 this->setCurrentColor(ldraw::directColor(dialog.selectedColor())); |
|
137 } |
|
138 } |
|
139 |
|
140 bool ColorSelectDialog::filterColor(ldraw::Color color) const |
|
141 { |
|
142 const QString& filterText = this->ui.filter->text(); |
|
143 if (filterText.isEmpty()) |
|
144 { |
|
145 return true; |
|
146 } |
|
147 else |
|
148 { |
|
149 const ldraw::ColorTable::ColorDefinition& colordef = this->colorTable[color]; |
|
150 return colordef.displayName.contains(filterText, Qt::CaseInsensitive); |
|
151 } |
|
152 } |
|
153 |
|
154 void ColorSelectDialog::setCurrentColor(ldraw::Color color) |
|
155 { |
|
156 this->selectedColor = color; |
|
157 this->updateSelectedColorTexts(); |
|
158 } |