Charlie Jiang pushed to branch gsoc-2022-chariri-3 at FreeType / FreeType Demo Programs
Commits:
-
8727ed6d
by Charlie Jiang at 2022-08-23T23:17:02+08:00
7 changed files:
- src/ftinspect/maingui.cpp
- src/ftinspect/panels/comparator.cpp
- src/ftinspect/panels/continuous.cpp
- src/ftinspect/panels/continuous.hpp
- src/ftinspect/panels/settingpanelmmgx.cpp
- src/ftinspect/panels/settingpanelmmgx.hpp
- src/ftinspect/panels/singular.cpp
Changes:
... | ... | @@ -243,13 +243,7 @@ MainGUI::createLayout() |
243 | 243 | // to change the policy we have to use a widget wrapper
|
244 | 244 | leftWidget_ = new QWidget(this);
|
245 | 245 | leftWidget_->setLayout(leftLayout_);
|
246 | - |
|
247 | - QSizePolicy leftWidgetPolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
|
|
248 | - leftWidgetPolicy.setHorizontalStretch(0);
|
|
249 | - leftWidgetPolicy.setVerticalPolicy(leftWidget_->sizePolicy().verticalPolicy());
|
|
250 | - leftWidgetPolicy.setHeightForWidth(leftWidget_->sizePolicy().hasHeightForWidth());
|
|
251 | - |
|
252 | - leftWidget_->setSizePolicy(leftWidgetPolicy);
|
|
246 | + leftWidget_->setFixedWidth(400);
|
|
253 | 247 | |
254 | 248 | // right side
|
255 | 249 | singularTab_ = new SingularTab(this, engine_);
|
... | ... | @@ -49,7 +49,10 @@ ComperatorTab::repaintGlyph() |
49 | 49 | void
|
50 | 50 | ComperatorTab::reloadFont()
|
51 | 51 | {
|
52 | - sizeSelector_->reloadFromFont(engine_);
|
|
52 | + {
|
|
53 | + QSignalBlocker blocker(sizeSelector_);
|
|
54 | + sizeSelector_->reloadFromFont(engine_);
|
|
55 | + }
|
|
53 | 56 | charMapSelector_->repopulate();
|
54 | 57 | for (auto panel : settingPanels_)
|
55 | 58 | panel->onFontChanged();
|
... | ... | @@ -47,7 +47,10 @@ void |
47 | 47 | ContinuousTab::reloadFont()
|
48 | 48 | {
|
49 | 49 | currentGlyphCount_ = engine_->currentFontNumberOfGlyphs();
|
50 | - sizeSelector_->reloadFromFont(engine_);
|
|
50 | + {
|
|
51 | + QSignalBlocker blocker(sizeSelector_);
|
|
52 | + sizeSelector_->reloadFromFont(engine_);
|
|
53 | + }
|
|
51 | 54 | setGlyphCount(qBound(0, currentGlyphCount_, INT_MAX));
|
52 | 55 | checkModeSource();
|
53 | 56 | |
... | ... | @@ -168,7 +171,13 @@ ContinuousTab::checkModeSource() |
168 | 171 | |
169 | 172 | waterfallConfigButton_->setEnabled(waterfallCheckBox_->isChecked()
|
170 | 173 | && !engine_->currentFontBitmapOnly());
|
174 | +}
|
|
175 | + |
|
171 | 176 | |
177 | +void
|
|
178 | +ContinuousTab::checkModeSourceAndRepaint()
|
|
179 | +{
|
|
180 | + checkModeSource();
|
|
172 | 181 | repaintGlyph();
|
173 | 182 | }
|
174 | 183 | |
... | ... | @@ -420,14 +429,14 @@ ContinuousTab::createConnections() |
420 | 429 | connect(indexSelector_, &GlyphIndexSelector::currentIndexChanged,
|
421 | 430 | this, &ContinuousTab::repaintGlyph);
|
422 | 431 | connect(modeSelector_, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
423 | - this, &ContinuousTab::checkModeSource);
|
|
432 | + this, &ContinuousTab::checkModeSourceAndRepaint);
|
|
424 | 433 | connect(charMapSelector_,
|
425 | 434 | QOverload<int>::of(&CharMapComboBox::currentIndexChanged),
|
426 | 435 | this, &ContinuousTab::charMapChanged);
|
427 | 436 | connect(charMapSelector_, &CharMapComboBox::forceUpdateLimitIndex,
|
428 | 437 | this, &ContinuousTab::updateLimitIndex);
|
429 | 438 | connect(sourceSelector_, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
430 | - this, &ContinuousTab::checkModeSource);
|
|
439 | + this, &ContinuousTab::checkModeSourceAndRepaint);
|
|
431 | 440 | |
432 | 441 | connect(resetPositionButton_, &QPushButton::clicked,
|
433 | 442 | canvas_, &GlyphContinuous::resetPositionDelta);
|
... | ... | @@ -453,9 +462,9 @@ ContinuousTab::createConnections() |
453 | 462 | this, &ContinuousTab::repaintGlyph);
|
454 | 463 | |
455 | 464 | connect(waterfallCheckBox_, &QCheckBox::clicked,
|
456 | - this, &ContinuousTab::checkModeSource);
|
|
465 | + this, &ContinuousTab::checkModeSourceAndRepaint);
|
|
457 | 466 | connect(verticalCheckBox_, &QCheckBox::clicked,
|
458 | - this, &ContinuousTab::checkModeSource);
|
|
467 | + this, &ContinuousTab::checkModeSourceAndRepaint);
|
|
459 | 468 | connect(kerningCheckBox_, &QCheckBox::clicked,
|
460 | 469 | this, &ContinuousTab::reloadGlyphsAndRepaint);
|
461 | 470 | connect(sourceTextEdit_, &QPlainTextEdit::textChanged,
|
... | ... | @@ -50,9 +50,10 @@ public: |
50 | 50 | |
51 | 51 | // This doesn't trigger either.
|
52 | 52 | void updateLimitIndex();
|
53 | + void checkModeSource();
|
|
53 | 54 | |
54 | 55 | // But they do
|
55 | - void checkModeSource();
|
|
56 | + void checkModeSourceAndRepaint();
|
|
56 | 57 | void charMapChanged();
|
57 | 58 | void sourceTextChanged();
|
58 | 59 | void presetStringSelected();
|
... | ... | @@ -7,6 +7,7 @@ |
7 | 7 | #include <QScrollBar>
|
8 | 8 | |
9 | 9 | #include "../engine/engine.hpp"
|
10 | +#include "../uihelper.hpp"
|
|
10 | 11 | |
11 | 12 | SettingPanelMMGX::SettingPanelMMGX(QWidget* parent,
|
12 | 13 | Engine* engine)
|
... | ... | @@ -56,10 +57,15 @@ SettingPanelMMGX::reloadFont() |
56 | 57 | w->updateInfo(currentAxes_[i]);
|
57 | 58 | listLayout_->addWidget(w);
|
58 | 59 | connect(w, &MMGXSettingItem::valueChanged,
|
59 | - this, &SettingPanelMMGX::itemChanged);
|
|
60 | + [this, index = i]
|
|
61 | + {
|
|
62 | + itemChanged(index);
|
|
63 | + });
|
|
60 | 64 | }
|
61 | 65 | }
|
62 | 66 | checkHidden();
|
67 | + retrieveValues();
|
|
68 | + syncSettings();
|
|
63 | 69 | }
|
64 | 70 | |
65 | 71 | |
... | ... | @@ -87,19 +93,20 @@ void |
87 | 93 | SettingPanelMMGX::createLayout()
|
88 | 94 | {
|
89 | 95 | showHiddenCheckBox_ = new QCheckBox(tr("Show Hidden"), this);
|
96 | + groupingCheckBox_ = new QCheckBox(tr("Grouping"), this);
|
|
90 | 97 | resetDefaultButton_ = new QPushButton(tr("Reset Default"), this);
|
91 | 98 | itemsListWidget_ = new QWidget(this);
|
92 | 99 | scrollArea_ = new UnboundScrollArea(this);
|
93 | 100 | |
94 | 101 | scrollArea_->setWidget(itemsListWidget_);
|
95 | 102 | scrollArea_->setWidgetResizable(true);
|
96 | - scrollArea_->setStyleSheet("QScrollArea {background-color:transparent;}");
|
|
97 | - itemsListWidget_->setStyleSheet("background-color:transparent;");
|
|
103 | + itemsListWidget_->setAutoFillBackground(false);
|
|
98 | 104 | |
99 | 105 | mainLayout_ = new QVBoxLayout;
|
100 | 106 | listLayout_ = new QVBoxLayout;
|
101 | 107 | listWrapperLayout_ = new QVBoxLayout;
|
102 | 108 | |
109 | + listLayout_->setSpacing(0);
|
|
103 | 110 | listLayout_->setContentsMargins(0, 0, 0, 0);
|
104 | 111 | itemsListWidget_->setContentsMargins(0, 0, 0, 0);
|
105 | 112 | |
... | ... | @@ -109,6 +116,7 @@ SettingPanelMMGX::createLayout() |
109 | 116 | listWrapperLayout_->addStretch(1);
|
110 | 117 | |
111 | 118 | mainLayout_->addWidget(showHiddenCheckBox_);
|
119 | + mainLayout_->addWidget(groupingCheckBox_);
|
|
112 | 120 | mainLayout_->addWidget(resetDefaultButton_);
|
113 | 121 | mainLayout_->addWidget(scrollArea_, 1);
|
114 | 122 | |
... | ... | @@ -123,16 +131,34 @@ SettingPanelMMGX::createConnections() |
123 | 131 | this, &SettingPanelMMGX::checkHidden);
|
124 | 132 | connect(resetDefaultButton_, &QCheckBox::clicked,
|
125 | 133 | this, &SettingPanelMMGX::resetDefaultClicked);
|
134 | + connect(groupingCheckBox_, &QCheckBox::clicked,
|
|
135 | + this, &SettingPanelMMGX::checkGrouping);
|
|
126 | 136 | }
|
127 | 137 | |
128 | 138 | |
129 | 139 | void
|
130 | -SettingPanelMMGX::itemChanged()
|
|
140 | +SettingPanelMMGX::retrieveValues()
|
|
131 | 141 | {
|
132 | 142 | currentValues_.resize(currentAxes_.size());
|
133 | 143 | for (unsigned i = 0; i < currentAxes_.size(); ++i)
|
134 | 144 | currentValues_[i] = itemWidgets_[i]->value();
|
145 | +}
|
|
146 | + |
|
147 | + |
|
148 | +void
|
|
149 | +SettingPanelMMGX::itemChanged(size_t index)
|
|
150 | +{
|
|
151 | + if (groupingCheckBox_->isChecked()
|
|
152 | + && index < currentAxes_.size() && index < itemWidgets_.size())
|
|
153 | + {
|
|
154 | + auto tag = currentAxes_[index].tag;
|
|
155 | + auto value = itemWidgets_[index]->value();
|
|
156 | + for (size_t i = 0; i < itemWidgets_.size(); ++i)
|
|
157 | + if (i != index && currentAxes_[i].tag == tag)
|
|
158 | + itemWidgets_[i]->setValue(value);
|
|
159 | + }
|
|
135 | 160 | |
161 | + retrieveValues();
|
|
136 | 162 | emit mmgxCoordsChanged();
|
137 | 163 | }
|
138 | 164 | |
... | ... | @@ -142,7 +168,35 @@ SettingPanelMMGX::resetDefaultClicked() |
142 | 168 | {
|
143 | 169 | for (auto w : itemWidgets_)
|
144 | 170 | w->resetDefault();
|
145 | - itemChanged();
|
|
171 | + |
|
172 | + retrieveValues();
|
|
173 | + emit mmgxCoordsChanged();
|
|
174 | +}
|
|
175 | + |
|
176 | + |
|
177 | +void
|
|
178 | +SettingPanelMMGX::checkGrouping()
|
|
179 | +{
|
|
180 | + if (!groupingCheckBox_->isChecked())
|
|
181 | + return;
|
|
182 | + auto maxIndex = std::max(itemWidgets_.size(), currentAxes_.size());
|
|
183 | + for (size_t i = maxIndex - 1; ; --i)
|
|
184 | + {
|
|
185 | + if (!currentAxes_[i].hidden)
|
|
186 | + {
|
|
187 | + auto tag = currentAxes_[i].tag;
|
|
188 | + auto value = itemWidgets_[i]->value();
|
|
189 | + for (size_t j = 0; j < maxIndex; ++j)
|
|
190 | + if (j != i && currentAxes_[j].tag == tag)
|
|
191 | + itemWidgets_[j]->setValue(value);
|
|
192 | + }
|
|
193 | + |
|
194 | + if (i == 0)
|
|
195 | + break;
|
|
196 | + }
|
|
197 | + |
|
198 | + retrieveValues();
|
|
199 | + emit mmgxCoordsChanged();
|
|
146 | 200 | }
|
147 | 201 | |
148 | 202 | |
... | ... | @@ -158,6 +212,8 @@ void |
158 | 212 | MMGXSettingItem::updateInfo(MMGXAxisInfo& info)
|
159 | 213 | {
|
160 | 214 | axisInfo_ = info;
|
215 | + valueValidator_->setRange(info.minimum, info.maximum, 10);
|
|
216 | + |
|
161 | 217 | if (info.hidden)
|
162 | 218 | nameLabel_->setText("<i>" + info.name + "</i>");
|
163 | 219 | else
|
... | ... | @@ -174,13 +230,19 @@ MMGXSettingItem::updateInfo(MMGXAxisInfo& info) |
174 | 230 | }
|
175 | 231 | |
176 | 232 | |
233 | +void
|
|
234 | +MMGXSettingItem::setValue(FT_Fixed value)
|
|
235 | +{
|
|
236 | + actualValue_ = value;
|
|
237 | + updateSlider();
|
|
238 | + updateLineEdit();
|
|
239 | +}
|
|
240 | + |
|
241 | + |
|
177 | 242 | void
|
178 | 243 | MMGXSettingItem::resetDefault()
|
179 | 244 | {
|
180 | - QSignalBlocker blocker(this);
|
|
181 | - slider_->setValue(static_cast<int>((axisInfo_.def - axisInfo_.minimum)
|
|
182 | - / (axisInfo_.maximum - axisInfo_.minimum)
|
|
183 | - * 1024));
|
|
245 | + setValue(static_cast<FT_Fixed>(axisInfo_.def * 65536.0));
|
|
184 | 246 | }
|
185 | 247 | |
186 | 248 | |
... | ... | @@ -188,18 +250,31 @@ void |
188 | 250 | MMGXSettingItem::createLayout()
|
189 | 251 | {
|
190 | 252 | nameLabel_ = new QLabel(this);
|
191 | - valueLabel_ = new QLabel(this);
|
|
253 | + |
|
254 | + // 1/1024 = 0.0009765625
|
|
255 | + valueValidator_ = new QDoubleValidator(0, 0, 10, this);
|
|
256 | + valueValidator_->setNotation(QDoubleValidator::StandardNotation);
|
|
257 | + |
|
258 | + valueLineEdit_ = new QLineEdit("0", this);
|
|
259 | + valueLineEdit_->setValidator(valueValidator_);
|
|
260 | + |
|
192 | 261 | slider_ = new QSlider(this);
|
193 | 262 | slider_->setOrientation(Qt::Horizontal);
|
194 | 263 | |
264 | + resetDefaultButton_ = new QPushButton(this);
|
|
265 | + resetDefaultButton_->setText(tr("Def"));
|
|
266 | + setButtonNarrowest(resetDefaultButton_);
|
|
267 | + |
|
195 | 268 | mainLayout_ = new QGridLayout();
|
196 | 269 | |
197 | - mainLayout_->addWidget(nameLabel_, 0, 0);
|
|
198 | - mainLayout_->addWidget(valueLabel_, 0, 1, 1, 1, Qt::AlignRight);
|
|
270 | + mainLayout_->addWidget(nameLabel_, 0, 0, 1, 2);
|
|
199 | 271 | mainLayout_->addWidget(slider_, 1, 0, 1, 2);
|
272 | + mainLayout_->addWidget(valueLineEdit_, 2, 0, 1, 1, Qt::AlignVCenter);
|
|
273 | + mainLayout_->addWidget(resetDefaultButton_, 2, 1, 1, 1, Qt::AlignVCenter);
|
|
200 | 274 | |
275 | + mainLayout_->setSpacing(4);
|
|
201 | 276 | mainLayout_->setContentsMargins(4, 4, 4, 4);
|
202 | - setContentsMargins(4, 4, 4, 4);
|
|
277 | + setContentsMargins(0, 0, 0, 0);
|
|
203 | 278 | setLayout(mainLayout_);
|
204 | 279 | setFrameShape(StyledPanel);
|
205 | 280 | }
|
... | ... | @@ -210,6 +285,10 @@ MMGXSettingItem::createConnections() |
210 | 285 | {
|
211 | 286 | connect(slider_, &QSlider::valueChanged,
|
212 | 287 | this, &MMGXSettingItem::sliderValueChanged);
|
288 | + connect(valueLineEdit_, &QLineEdit::editingFinished,
|
|
289 | + this, &MMGXSettingItem::lineEditChanged);
|
|
290 | + connect(resetDefaultButton_, &QToolButton::clicked,
|
|
291 | + this, &MMGXSettingItem::resetDefaultSingle);
|
|
213 | 292 | }
|
214 | 293 | |
215 | 294 | |
... | ... | @@ -223,19 +302,53 @@ MMGXSettingItem::sliderValueChanged() |
223 | 302 | |
224 | 303 | if (axisInfo_.isMM)
|
225 | 304 | actualValue_ = FT_RoundFix(actualValue_);
|
226 | - else
|
|
227 | - {
|
|
228 | - double x = actualValue_ / 65536.0 * 100.0;
|
|
229 | - x += x < 0.0 ? -0.5 : 0.5;
|
|
230 | - x = static_cast<int>(x);
|
|
231 | - x = x / 100.0 * 65536.0;
|
|
232 | - x += x < 0.0 ? -0.5 : 0.5;
|
|
233 | 305 | |
234 | - actualValue_ = static_cast<FT_Fixed>(x);
|
|
306 | + updateLineEdit();
|
|
307 | + emit valueChanged();
|
|
308 | +}
|
|
309 | + |
|
310 | + |
|
311 | +void
|
|
312 | +MMGXSettingItem::lineEditChanged()
|
|
313 | +{
|
|
314 | + bool succ = false;
|
|
315 | + auto newValue = valueLineEdit_->text().toDouble(&succ);
|
|
316 | + if (!succ || newValue > axisInfo_.maximum || newValue < axisInfo_.minimum)
|
|
317 | + {
|
|
318 | + updateLineEdit();
|
|
319 | + return;
|
|
235 | 320 | }
|
236 | 321 | |
237 | - valueLabel_->setText(QString::number(actualValue_ / 65536.0));
|
|
322 | + actualValue_ = static_cast<FT_Fixed>(newValue / 65536.0);
|
|
323 | + |
|
324 | + updateSlider();
|
|
325 | + emit valueChanged();
|
|
326 | +}
|
|
238 | 327 | |
328 | + |
|
329 | +void
|
|
330 | +MMGXSettingItem::updateLineEdit()
|
|
331 | +{
|
|
332 | + QSignalBlocker blocker(valueLineEdit_);
|
|
333 | + valueLineEdit_->setText(QString::number(actualValue_ / 65536.0));
|
|
334 | +}
|
|
335 | + |
|
336 | + |
|
337 | +void
|
|
338 | +MMGXSettingItem::updateSlider()
|
|
339 | +{
|
|
340 | + QSignalBlocker blocker(slider_);
|
|
341 | + slider_->setValue(
|
|
342 | + static_cast<int>((actualValue_ / 65536.0 - axisInfo_.minimum)
|
|
343 | + / (axisInfo_.maximum - axisInfo_.minimum)
|
|
344 | + * 1024));
|
|
345 | +}
|
|
346 | + |
|
347 | + |
|
348 | +void
|
|
349 | +MMGXSettingItem::resetDefaultSingle()
|
|
350 | +{
|
|
351 | + resetDefault();
|
|
239 | 352 | emit valueChanged();
|
240 | 353 | }
|
241 | 354 |
... | ... | @@ -12,9 +12,13 @@ |
12 | 12 | #include <QBoxLayout>
|
13 | 13 | #include <QCheckBox>
|
14 | 14 | #include <QScrollArea>
|
15 | +#include <QLineEdit>
|
|
15 | 16 | #include <QSlider>
|
16 | 17 | #include <QFrame>
|
18 | +#include <QPushButton>
|
|
19 | +#include <QToolButton>
|
|
17 | 20 | #include <QLabel>
|
21 | +#include <QDoubleValidator>
|
|
18 | 22 | |
19 | 23 | #include <freetype/fttypes.h>
|
20 | 24 | |
... | ... | @@ -41,6 +45,7 @@ private: |
41 | 45 | Engine* engine_;
|
42 | 46 | |
43 | 47 | QCheckBox* showHiddenCheckBox_;
|
48 | + QCheckBox* groupingCheckBox_;
|
|
44 | 49 | QPushButton* resetDefaultButton_;
|
45 | 50 | QWidget* itemsListWidget_;
|
46 | 51 | UnboundScrollArea* scrollArea_;
|
... | ... | @@ -56,8 +61,10 @@ private: |
56 | 61 | void createLayout();
|
57 | 62 | void createConnections();
|
58 | 63 | |
59 | - void itemChanged();
|
|
64 | + void retrieveValues();
|
|
65 | + void itemChanged(size_t index);
|
|
60 | 66 | void resetDefaultClicked();
|
67 | + void checkGrouping();
|
|
61 | 68 | };
|
62 | 69 | |
63 | 70 | |
... | ... | @@ -71,6 +78,7 @@ public: |
71 | 78 | |
72 | 79 | void updateInfo(MMGXAxisInfo& info);
|
73 | 80 | FT_Fixed value() { return actualValue_; }
|
81 | + void setValue(FT_Fixed value);
|
|
74 | 82 | void resetDefault();
|
75 | 83 | |
76 | 84 | signals:
|
... | ... | @@ -78,8 +86,10 @@ signals: |
78 | 86 | |
79 | 87 | private:
|
80 | 88 | QLabel* nameLabel_;
|
81 | - QLabel* valueLabel_;
|
|
82 | 89 | QSlider* slider_;
|
90 | + QPushButton* resetDefaultButton_;
|
|
91 | + QLineEdit* valueLineEdit_;
|
|
92 | + QDoubleValidator* valueValidator_;
|
|
83 | 93 | |
84 | 94 | QGridLayout* mainLayout_;
|
85 | 95 | |
... | ... | @@ -89,6 +99,10 @@ private: |
89 | 99 | void createLayout();
|
90 | 100 | void createConnections();
|
91 | 101 | void sliderValueChanged();
|
102 | + void lineEditChanged();
|
|
103 | + void updateLineEdit();
|
|
104 | + void updateSlider();
|
|
105 | + void resetDefaultSingle();
|
|
92 | 106 | };
|
93 | 107 | |
94 | 108 |
... | ... | @@ -409,7 +409,10 @@ SingularTab::reloadFont() |
409 | 409 | {
|
410 | 410 | currentGlyphCount_ = engine_->currentFontNumberOfGlyphs();
|
411 | 411 | indexSelector_->setMinMax(0, currentGlyphCount_);
|
412 | - sizeSelector_->reloadFromFont(engine_);
|
|
412 | + {
|
|
413 | + QSignalBlocker blocker(sizeSelector_);
|
|
414 | + sizeSelector_->reloadFromFont(engine_);
|
|
415 | + }
|
|
413 | 416 | drawGlyph();
|
414 | 417 | }
|
415 | 418 |