All Classes Namespaces Functions Variables Enumerations Properties Pages
displayoptionwidget.cpp
1 /*
2 
3 Pencil2D - Traditional Animation Software
4 Copyright (C) 2012-2020 Matthew Chiawen Chang
5 
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; version 2 of the License.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 */
16 
17 #include "displayoptionwidget.h"
18 #include "ui_displayoption.h"
19 
20 #include <QToolButton>
21 #include <QGridLayout>
22 #include <QSettings>
23 
24 #include "preferencemanager.h"
25 #include "viewmanager.h"
26 #include "overlaymanager.h"
27 #include "layermanager.h"
28 #include "scribblearea.h"
29 #include "editor.h"
30 #include "util.h"
31 #include "movemode.h"
32 
33 #include "flowlayout.h"
34 
35 
36 DisplayOptionWidget::DisplayOptionWidget(QWidget *parent) :
37  BaseDockWidget(parent),
38  ui(new Ui::DisplayOption)
39 {
40  ui->setupUi(this);
41 }
42 
43 DisplayOptionWidget::~DisplayOptionWidget()
44 {
45  delete ui;
46 }
47 
48 void DisplayOptionWidget::initUI()
49 {
50  updateUI();
51  anglePreferences();
52  makeConnections();
53 
55  layout->addWidget(ui->mirrorButton);
56  layout->addWidget(ui->mirrorVButton);
57  layout->addWidget(ui->thinLinesButton);
58  layout->addWidget(ui->outLinesButton);
59  layout->addWidget(ui->overlayCenterButton);
60  layout->addWidget(ui->overlayThirdsButton);
61  layout->addWidget(ui->overlayGoldenRatioButton);
62  layout->addWidget(ui->overlaySafeAreaButton);
63  layout->addWidget(ui->overlayPerspective1Button);
64  layout->addWidget(ui->overlayPerspective2Button);
65  layout->addWidget(ui->overlayPerspective3Button);
66  layout->addWidget(ui->overlayChooseAngle);
67 
68  delete ui->scrollAreaWidgetContents->layout();
69  ui->scrollAreaWidgetContents->setLayout(layout);
70 
71  prepareOverlayManager();
72 
73 #ifdef __APPLE__
74  // Mac only style. ToolButtons are naturally borderless on Win/Linux.
75  QString stylesheet =
76  "QToolButton { border: 0px; } "
77  "QToolButton:pressed{ border: 1px solid #FFADAD; border-radius: 2px; background-color: #D5D5D5; }"
78  "QToolButton:checked{ border: 1px solid #ADADAD; border-radius: 2px; background-color: #D5D5D5; }";
79 
80  ui->mirrorButton->setStyleSheet(stylesheet);
81  ui->mirrorVButton->setStyleSheet(stylesheet);
82  ui->thinLinesButton->setStyleSheet(stylesheet);
83  ui->outLinesButton->setStyleSheet(stylesheet);
84  ui->overlayCenterButton->setStyleSheet(stylesheet);
85  ui->overlayThirdsButton->setStyleSheet(stylesheet);
86  ui->overlayGoldenRatioButton->setStyleSheet(stylesheet);
87  ui->overlaySafeAreaButton->setStyleSheet(stylesheet);
88  ui->overlayPerspective1Button->setStyleSheet(stylesheet);
89  ui->overlayPerspective2Button->setStyleSheet(stylesheet);
90  ui->overlayPerspective3Button->setStyleSheet(stylesheet);
91  ui->overlayChooseAngle->setStyleSheet(stylesheet);
92 #endif
93 }
94 
95 void DisplayOptionWidget::makeConnections()
96 {
97  connect(ui->mirrorButton, &QToolButton::clicked, this, &DisplayOptionWidget::toggleMirror);
98  connect(ui->mirrorVButton, &QToolButton::clicked, this, &DisplayOptionWidget::toggleMirrorV);
99  connect(ui->overlayCenterButton, &QToolButton::clicked, this, &DisplayOptionWidget::toggleOverlayCenter);
100  connect(ui->overlayThirdsButton, &QToolButton::clicked, this, &DisplayOptionWidget::toggleOverlayThirds);
101  connect(ui->overlayGoldenRatioButton, &QToolButton::clicked, this, &DisplayOptionWidget::toggleOverlayGoldenRatio);
102  connect(ui->overlaySafeAreaButton, &QToolButton::clicked, this, &DisplayOptionWidget::toggleOverlaySafeAreas);
103  connect(ui->overlayPerspective1Button, &QToolButton::clicked, this, &DisplayOptionWidget::toggleOverlayPerspective1);
104  connect(ui->overlayPerspective2Button, &QToolButton::clicked, this, &DisplayOptionWidget::toggleOverlayPerspective2);
105  connect(ui->overlayPerspective3Button, &QToolButton::clicked, this, &DisplayOptionWidget::toggleOverlayPerspective3);
106 
107  PreferenceManager* prefs = editor()->preference();
108  ScribbleArea* pScriArea = editor()->getScribbleArea();
109 
110  connect(ui->thinLinesButton, &QToolButton::clicked, pScriArea, &ScribbleArea::toggleThinLines);
111  connect(ui->outLinesButton, &QToolButton::clicked, pScriArea, &ScribbleArea::toggleOutlines);
112  connect(prefs, &PreferenceManager::optionChanged, this, &DisplayOptionWidget::updateUI);
113 
114  ViewManager* view = editor()->view();
115  connect(view, &ViewManager::viewFlipped, this, &DisplayOptionWidget::updateUI);
116 }
117 
118 void DisplayOptionWidget::prepareOverlayManager()
119 {
120  editor()->overlays()->initPerspOverlay();
121  editor()->getScribbleArea()->prepOverlays();
122 
123  if (ui->overlayPerspective1Button->isChecked())
124  {
125  editor()->overlays()->setOverlayPerspective1(true);
126  editor()->overlays()->updatePerspOverlay(1);
127  editor()->overlays()->setMoveMode(MoveMode::PERSP_SINGLE);
128  }
129  if (ui->overlayPerspective2Button->isChecked())
130  {
131  editor()->overlays()->setOverlayPerspective2(true);
132  editor()->overlays()->updatePerspOverlay(2);
133  editor()->overlays()->setMoveMode(MoveMode::PERSP_LEFT);
134  }
135  if (ui->overlayPerspective3Button->isChecked())
136  {
137  editor()->overlays()->setOverlayPerspective3(true);
138  editor()->overlays()->updatePerspOverlay(3);
139  editor()->overlays()->setMoveMode(MoveMode::PERSP_LEFT);
140  }
141  editor()->overlays()->updatePerspOverlayActiveList();
142 }
143 
144 void DisplayOptionWidget::clearPreviousAngle(int angle)
145 {
146  switch (angle)
147  {
148  case 2: ui->action2_degrees->setChecked(false); break;
149  case 3: ui->action3_degrees->setChecked(false); break;
150  case 5: ui->action5_degrees->setChecked(false); break;
151  case 7: ui->action7_5_degrees->setChecked(false); break;
152  case 10: ui->action10_degrees->setChecked(false); break;
153  case 15: ui->action15_degrees->setChecked(false); break;
154  case 20: ui->action20_degrees->setChecked(false); break;
155  case 30: ui->action30_degrees->setChecked(false); break;
156  default: ui->action15_degrees->setChecked(false);
157  }
158 }
159 
160 void DisplayOptionWidget::changeAngle(int angle)
161 {
162  clearPreviousAngle(mOverlayAngle);
163  mOverlayAngle = angle;
164  QSettings settings(PENCIL2D, PENCIL2D);
165  settings.setValue("OverlayAngle", angle);
166  emit editor()->view()->viewChanged();
167 }
168 
169 void DisplayOptionWidget::updateUI()
170 {
171  PreferenceManager* prefs = editor()->preference();
172 
173  bool canEnableVectorButtons = editor()->layers()->currentLayer()->type() == Layer::VECTOR;
174  ui->thinLinesButton->setEnabled(canEnableVectorButtons);
175  ui->outLinesButton->setEnabled(canEnableVectorButtons);
176 
177  QSignalBlocker b1(ui->thinLinesButton);
178  ui->thinLinesButton->setChecked(prefs->isOn(SETTING::INVISIBLE_LINES));
179 
180  QSignalBlocker b2(ui->outLinesButton);
181  ui->outLinesButton->setChecked(prefs->isOn(SETTING::OUTLINES));
182 
183  QSignalBlocker b9(ui->overlayCenterButton);
184  ui->overlayCenterButton->setChecked(prefs->isOn(SETTING::OVERLAY_CENTER));
185 
186  QSignalBlocker b10(ui->overlayThirdsButton);
187  ui->overlayThirdsButton->setChecked(prefs->isOn(SETTING::OVERLAY_THIRDS));
188 
189  QSignalBlocker b11(ui->overlayGoldenRatioButton);
190  ui->overlayGoldenRatioButton->setChecked(prefs->isOn(SETTING::OVERLAY_GOLDEN));
191 
192  QSignalBlocker b12(ui->overlaySafeAreaButton);
193  ui->overlaySafeAreaButton->setChecked(prefs->isOn(SETTING::OVERLAY_SAFE));
194 
195  QSignalBlocker b13(ui->overlayPerspective1Button);
196  ui->overlayPerspective1Button->setChecked(prefs->isOn(SETTING::OVERLAY_PERSPECTIVE1));
197 
198  QSignalBlocker b14(ui->overlayPerspective2Button);
199  ui->overlayPerspective2Button->setChecked(prefs->isOn(SETTING::OVERLAY_PERSPECTIVE2));
200 
201  QSignalBlocker b15(ui->overlayPerspective3Button);
202  ui->overlayPerspective3Button->setChecked(prefs->isOn(SETTING::OVERLAY_PERSPECTIVE3));
203 
204  bool enableSafeArea = (prefs->isOn(SETTING::ACTION_SAFE_ON) || prefs->isOn(SETTING::TITLE_SAFE_ON));
205  ui->overlaySafeAreaButton->setEnabled(enableSafeArea);
206 
207  const ViewManager* view = editor()->view();
208 
209  QSignalBlocker b3(ui->mirrorButton);
210  ui->mirrorButton->setChecked(view->isFlipHorizontal());
211 
212  QSignalBlocker b4(ui->mirrorVButton);
213  ui->mirrorVButton->setChecked(view->isFlipVertical());
214 }
215 
216 int DisplayOptionWidget::getMinHeightForWidth(int width)
217 {
218  return ui->innerWidget->layout()->heightForWidth(width);
219 }
220 
221 void DisplayOptionWidget::toggleMirror(bool isOn)
222 {
223  editor()->view()->flipHorizontal(isOn);
224 }
225 
226 void DisplayOptionWidget::toggleMirrorV(bool isOn)
227 {
228  editor()->view()->flipVertical(isOn);
229 }
230 
231 void DisplayOptionWidget::toggleOverlayCenter(bool isOn)
232 {
233  editor()->overlays()->setOverlayCenter(isOn);
234  editor()->preference()->set(SETTING::OVERLAY_CENTER, isOn);
235  emit editor()->view()->viewChanged();
236 }
237 
238 void DisplayOptionWidget::toggleOverlayThirds(bool isOn)
239 {
240  editor()->overlays()->setOverlayThirds(isOn);
241  editor()->preference()->set(SETTING::OVERLAY_THIRDS, isOn);
242  emit editor()->view()->viewChanged();
243 }
244 
245 void DisplayOptionWidget::toggleOverlayGoldenRatio(bool isOn)
246 {
247  editor()->overlays()->setOverlayGoldenRatio(isOn);
248  editor()->preference()->set(SETTING::OVERLAY_GOLDEN, isOn);
249  emit editor()->view()->viewChanged();
250 }
251 
252 void DisplayOptionWidget::toggleOverlaySafeAreas(bool isOn)
253 {
254  editor()->overlays()->setOverlaySafeAreas(isOn);
255  editor()->preference()->set(SETTING::OVERLAY_SAFE, isOn);
256  emit editor()->view()->viewChanged();
257 }
258 
259 void DisplayOptionWidget::toggleOverlayPerspective1(bool isOn)
260 {
261  editor()->overlays()->setOverlayPerspective1(isOn);
262  editor()->preference()->set(SETTING::OVERLAY_PERSPECTIVE1, isOn);
263  emit editor()->view()->viewChanged();
264 }
265 
266 void DisplayOptionWidget::toggleOverlayPerspective2(bool isOn)
267 {
268  editor()->overlays()->setOverlayPerspective2(isOn);
269  editor()->preference()->set(SETTING::OVERLAY_PERSPECTIVE2, isOn);
270  emit editor()->view()->viewChanged();
271 }
272 
273 void DisplayOptionWidget::toggleOverlayPerspective3(bool isOn)
274 {
275  editor()->overlays()->setOverlayPerspective3(isOn);
276  editor()->preference()->set(SETTING::OVERLAY_PERSPECTIVE3, isOn);
277  emit editor()->view()->viewChanged();
278 }
279 
280 void DisplayOptionWidget::anglePreferences()
281 {
282  buttonStylesheet = "::menu-indicator{ image: none; }"
283  "QToolButton { border: 0px; }"
284  "QToolButton:pressed { border: 1px solid #ADADAD; border-radius: 2px; background-color: #D5D5D5; }"
285  "QToolButton:checked { border: 1px solid #ADADAD; border-radius: 2px; background-color: #D5D5D5; }";
286 
287  ui->overlayChooseAngle->setArrowType(Qt::ArrowType::NoArrow);
288  ui->overlayChooseAngle->setStyleSheet(buttonStylesheet);
289 
290  ui->overlayChooseAngle->addAction(ui->action2_degrees);
291  ui->overlayChooseAngle->addAction(ui->action3_degrees);
292  ui->overlayChooseAngle->addAction(ui->action5_degrees);
293  ui->overlayChooseAngle->addAction(ui->action7_5_degrees);
294  ui->overlayChooseAngle->addAction(ui->action10_degrees);
295  ui->overlayChooseAngle->addAction(ui->action15_degrees);
296  ui->overlayChooseAngle->addAction(ui->action20_degrees);
297  ui->overlayChooseAngle->addAction(ui->action30_degrees);
298 
299  QSettings settings(PENCIL2D, PENCIL2D);
300  mOverlayAngle = settings.value("OverlayAngle").toInt();
301 
302  switch (mOverlayAngle)
303  {
304  case 2: ui->action2_degrees->setChecked(true); break;
305  case 3: ui->action3_degrees->setChecked(true); break;
306  case 5: ui->action5_degrees->setChecked(true); break;
307  case 7: ui->action7_5_degrees->setChecked(true); break;
308  case 10: ui->action10_degrees->setChecked(true); break;
309  case 15: ui->action15_degrees->setChecked(true); break;
310  case 20: ui->action20_degrees->setChecked(true); break;
311  case 30: ui->action30_degrees->setChecked(true); break;
312  default: ui->action15_degrees->setChecked(true);
313  }
314 
315  connect( ui->action2_degrees, &QAction::triggered, this, &DisplayOptionWidget::angle2degrees);
316  connect( ui->action3_degrees, &QAction::triggered, this, &DisplayOptionWidget::angle3degrees);
317  connect( ui->action5_degrees, &QAction::triggered, this, &DisplayOptionWidget::angle5degrees);
318  connect( ui->action7_5_degrees, &QAction::triggered, this, &DisplayOptionWidget::angle7_5degrees);
319  connect(ui->action10_degrees, &QAction::triggered, this, &DisplayOptionWidget::angle10degrees);
320  connect(ui->action15_degrees, &QAction::triggered, this, &DisplayOptionWidget::angle15degrees);
321  connect(ui->action20_degrees, &QAction::triggered, this, &DisplayOptionWidget::angle20degrees);
322  connect(ui->action30_degrees, &QAction::triggered, this, &DisplayOptionWidget::angle30degrees);
323 }
324 
325 void DisplayOptionWidget::angle2degrees(bool)
326 {
327  changeAngle(2);
328 }
329 
330 void DisplayOptionWidget::angle3degrees(bool)
331 {
332  changeAngle(3);
333 }
334 
335 void DisplayOptionWidget::angle5degrees(bool)
336 {
337  changeAngle(5);
338 }
339 
340 void DisplayOptionWidget::angle7_5degrees(bool)
341 {
342  changeAngle(7);
343 }
344 
345 void DisplayOptionWidget::angle10degrees(bool)
346 {
347  changeAngle(10);
348 }
349 
350 void DisplayOptionWidget::angle15degrees(bool)
351 {
352  changeAngle(15);
353 }
354 
355 void DisplayOptionWidget::angle20degrees(bool)
356 {
357  changeAngle(20);
358 }
359 
360 void DisplayOptionWidget::angle30degrees(bool)
361 {
362  changeAngle(30);
363 }
QLayout * layout() const const
void triggered(bool checked)
void setupUi(QWidget *widget)
void clicked(bool checked)
void addWidget(QWidget *w)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)