Pencil2D  ff90c0872e88be3bf81c548cd60f01983012ec49
Pencil2D is an animation software for both bitmap and vector graphics. It is free, multi-platform, and open source.
 All Classes Functions
tooloptionwidget.cpp
1 /*
2 
3 Pencil - Traditional Animation Software
4 Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon
5 Copyright (C) 2013-2017 Matt Chiawen Chang
6 
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; version 2 of the License.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15 
16 */
17 #include <QLabel>
18 #include <QToolButton>
19 #include <QCheckBox>
20 #include <QSpinBox>
21 #include <QGridLayout>
22 #include <QGroupBox>
23 #include <QRadioButton>
24 #include <QSettings>
25 #include <QDebug>
26 #include "spinslider.h"
27 #include "toolmanager.h"
28 #include "tooloptionwidget.h"
29 #include "editor.h"
30 #include "util.h"
31 #include "layer.h"
32 #include "layermanager.h"
33 
34 ToolOptionWidget::ToolOptionWidget( QWidget* parent ) : BaseDockWidget( parent )
35 {
36  setWindowTitle( tr( "Options", "Window title of tool options like pen width, feather etc.." ) );
37 }
38 
39 ToolOptionWidget::~ToolOptionWidget()
40 {
41 }
42 
43 void ToolOptionWidget::initUI()
44 {
45  createUI();
46 }
47 
48 void ToolOptionWidget::updateUI()
49 {
50  BaseTool* currentTool = editor()->tools()->currentTool();
51  Q_ASSERT( currentTool );
52 
53  disableAllOptions();
54 
55  mSizeSlider->setVisible( currentTool->isPropertyEnabled( WIDTH ) );
56  mBrushSpinBox->setVisible( currentTool->isPropertyEnabled( WIDTH) );
57  mFeatherSlider->setVisible( currentTool->isPropertyEnabled( FEATHER ) );
58  mUseFeatherBox->setVisible( currentTool->isPropertyEnabled( FEATHER ) );
59  mFeatherSpinBox->setVisible( currentTool->isPropertyEnabled( FEATHER) );
60  mUseBezierBox->setVisible( currentTool->isPropertyEnabled( BEZIER ) );
61  mUsePressureBox->setVisible( currentTool->isPropertyEnabled( PRESSURE ) );
62  mMakeInvisibleBox->setVisible( currentTool->isPropertyEnabled( INVISIBILITY ) );
63  mPreserveAlphaBox->setVisible( currentTool->isPropertyEnabled( PRESERVEALPHA ) );
64  mUseAABox->setVisible(currentTool->isPropertyEnabled( ANTI_ALIASING ) );
65  mInpolLevelsBox->setVisible(currentTool->isPropertyEnabled( INTERPOLATION ) );
66  mToleranceSlider->setVisible(currentTool->isPropertyEnabled( TOLERANCE ) );
67  mToleranceSpinBox->setVisible(currentTool->isPropertyEnabled( TOLERANCE ) );
68  mFillContour->setVisible( currentTool->isPropertyEnabled( FILLCONTOUR ) );
69 
70  visibilityOnLayer();
71 
72  const Properties& p = currentTool->properties;
73 
74  setPenWidth( p.width );
75  setPenFeather( p.feather );
76  setUseFeather( p.useFeather );
77  setPressure( p.pressure );
78  setPenInvisibility( p.invisibility );
79  setPreserveAlpha( p.preserveAlpha );
80  setVectorMergeEnabled( p.vectorMergeEnabled );
81  setAA(p.useAA);
82  setInpolLevel(p.inpolLevel);
83  setTolerance(p.tolerance);
84  setFillContour(p.useFillContour);
85 }
86 
87 void ToolOptionWidget::createUI()
88 {
89  setMinimumWidth( 115 );
90  setMaximumWidth(300);
91 
92  QFrame* optionGroup = new QFrame();
93  QGridLayout* pLayout = new QGridLayout();
94  pLayout->setMargin( 8 );
95  pLayout->setSpacing( 8 );
96 
97  QSettings settings( PENCIL2D, PENCIL2D );
98 
99  mSizeSlider = new SpinSlider( tr( "Brush" ), SpinSlider::EXPONENT, SpinSlider::INTEGER, 1, 200, this );
100  mSizeSlider->setValue( settings.value( "brushWidth" ).toDouble() );
101  mSizeSlider->setToolTip( tr( "Set Pen Width <br><b>[SHIFT]+drag</b><br>for quick adjustment" ) );
102 
103  mBrushSpinBox = new QSpinBox(this);
104  mBrushSpinBox->setRange(1,200);
105  mBrushSpinBox->setValue(settings.value( "brushWidth" ).toDouble() );
106 
107  mFeatherSlider = new SpinSlider( tr( "Feather" ), SpinSlider::LOG, SpinSlider::INTEGER, 2, 64, this );
108  mFeatherSlider->setValue( settings.value( "brushFeather" ).toDouble() );
109  mFeatherSlider->setToolTip( tr( "Set Pen Feather <br><b>[CTRL]+drag</b><br>for quick adjustment" ) );
110 
111  mFeatherSpinBox = new QSpinBox(this);
112  mFeatherSpinBox->setRange(2,64);
113  mFeatherSpinBox->setValue(settings.value( "brushFeather" ).toDouble() );
114 
115  mUseFeatherBox = new QCheckBox( tr( "Use Feather" ) );
116  mUseFeatherBox->setToolTip( tr( "Enable or disable feathering" ) );
117  mUseFeatherBox->setFont( QFont( "Helvetica", 10 ) );
118  mUseFeatherBox->setChecked( settings.value( "brushUseFeather" ).toBool() );
119 
120  mUseBezierBox = new QCheckBox( tr( "Bezier" ) );
121  mUseBezierBox->setToolTip( tr( "Bezier curve fitting" ) );
122  mUseBezierBox->setFont( QFont( "Helvetica", 10 ) );
123  mUseBezierBox->setChecked( false );
124 
125  mUsePressureBox = new QCheckBox( tr( "Pressure" ) );
126  mUsePressureBox->setToolTip( tr( "Size with pressure" ) );
127  mUsePressureBox->setFont( QFont( "Helvetica", 10 ) );
128  mUsePressureBox->setChecked( true );
129 
130  mUseAABox = new QCheckBox( tr( "Anti-Aliasing" ) );
131  mUseAABox->setToolTip( tr( "Enable Anti-Aliasing" ) );
132  mUseAABox->setFont( QFont( "Helvetica", 10 ) );
133  mUseAABox->setChecked( true );
134 
135  mFillContour = new QCheckBox( tr( "Fill Contour", "ToolOptions" ) );
136  mFillContour->setToolTip( tr( "Contour will be filled" ) );
137  mFillContour->setFont( QFont( "Helvetica", 10 ) );
138  mFillContour->setChecked( true );
139 
140  mInpolLevelsBox = new QGroupBox ( tr( "Stabilization level" ) );
141  mInpolLevelsBox->setFlat(true);
142  mInpolLevelsBox->setFont(QFont( "Helvetica", 10 ) );
143  mInpolLevelsBox->setStyleSheet(
144  "QGroupBox"
145  "{"
146  "margin-top: 1.0em"
147  "}"
148  "QGroupBox::title"
149  "{"
150  "subcontrol-origin: margin;"
151  "left: 5px;"
152  "padding: 0.7em 3px 0 3px;"
153  "}");
154 
155  mNoInpol = new QRadioButton ( tr( "" ) );
156  mNoInpol->setToolTip( tr( "No line interpolation" ) );
157  mNoInpol->setFont( QFont( "Helvetica", 10) );
158  mNoInpol->setChecked ( true );
159 
160  mSimpleInpol = new QRadioButton (tr( "" ) );
161  mSimpleInpol->setToolTip( tr( "Simple line interpolation" ) );
162  mSimpleInpol->setChecked ( false );
163 
164  mStrongInpol = new QRadioButton (tr( "" ) );
165  mStrongInpol->setToolTip( tr( "Strong line interpolation" ) );
166  mStrongInpol->setChecked ( false );
167 
168 // mExtremeInpol = new QRadioButton (tr( "" ) );
169 // mExtremeInpol->setToolTip( tr( "Extreme line interpolation" ) );
170 // mExtremeInpol->setFont( QFont( "Helvetica", 10) );
171 // mExtremeInpol->setChecked ( false );
172 
173  QGridLayout* inpolLayout = new QGridLayout();
174  inpolLayout->addWidget( mNoInpol, 16, 0, 2, 1 );
175  inpolLayout->addWidget( mSimpleInpol, 16, 1, 2, 1 );
176  inpolLayout->addWidget( mStrongInpol, 16, 2, 2, 1 );
177 // inpolLayout->addWidget( mExtremeInpol, 16, 3, 2, 1 );
178  mInpolLevelsBox->setLayout(inpolLayout);
179  inpolLayout->setSpacing(2);
180 
181  mToleranceSlider = new SpinSlider( tr( "Color Tolerance" ), SpinSlider::LINEAR, SpinSlider::INTEGER, 1, 100, this );
182  mToleranceSlider->setValue( settings.value( "Tolerance" ).toInt() );
183  mToleranceSlider->setToolTip( tr( "The extend to which the color variation will be treated as being equal" ) );
184 
185  mToleranceSpinBox = new QSpinBox(this);
186  mToleranceSpinBox->setRange(1,100);
187  mToleranceSpinBox->setValue(settings.value( "Tolerance" ).toInt() );
188 
189  mMakeInvisibleBox = new QCheckBox( tr( "Invisible" ) );
190  mMakeInvisibleBox->setToolTip( tr( "Make invisible" ) );
191  mMakeInvisibleBox->setFont( QFont( "Helvetica", 10 ) );
192  mMakeInvisibleBox->setChecked( false );
193 
194  mPreserveAlphaBox = new QCheckBox( tr( "Alpha" ) );
195  mPreserveAlphaBox->setToolTip( tr( "Preserve Alpha" ) );
196  mPreserveAlphaBox->setFont( QFont( "Helvetica", 10 ) );
197  mPreserveAlphaBox->setChecked( false );
198 
199  mVectorMergeBox = new QCheckBox( tr( "Merge" ) );
200  mVectorMergeBox->setToolTip( tr( "Merge vector lines when they are close together" ) );
201  mVectorMergeBox->setFont( QFont( "Helvetica", 10 ) );
202  mVectorMergeBox->setChecked( false );
203 
204  pLayout->addWidget( mSizeSlider, 1, 0, 1, 2 );
205  pLayout->addWidget( mBrushSpinBox, 1, 2, 1, 2);
206  pLayout->addWidget( mFeatherSlider, 2, 0, 1, 2 );
207  pLayout->addWidget( mFeatherSpinBox, 2, 2, 1, 2 );
208  pLayout->addWidget( mUseFeatherBox, 3, 0, 1, 2 );
209  pLayout->addWidget( mUseBezierBox, 4, 0, 1, 2 );
210  pLayout->addWidget( mUsePressureBox, 5, 0, 1, 2 );
211  pLayout->addWidget( mUseAABox, 6, 0, 1, 2);
212  pLayout->addWidget( mPreserveAlphaBox, 7, 0, 1, 2 );
213  pLayout->addWidget( mMakeInvisibleBox, 8, 0, 1, 2 );
214  pLayout->addWidget( mVectorMergeBox, 9, 0, 1, 2 );
215  pLayout->addWidget( mInpolLevelsBox, 10, 0, 1, 4);
216  pLayout->addWidget( mToleranceSlider, 1, 0, 1, 2);
217  pLayout->addWidget( mToleranceSpinBox, 1, 2, 1, 2);
218  pLayout->addWidget( mFillContour, 1, 0, 1, 2);
219 
220  pLayout->setRowStretch( 17, 1 );
221 
222  optionGroup->setLayout( pLayout );
223 
224  setWidget( optionGroup );
225 }
226 
227 void ToolOptionWidget::makeConnectionToEditor( Editor* editor )
228 {
229  auto toolManager = editor->tools();
230 
231  connect( mUseBezierBox, &QCheckBox::clicked, toolManager, &ToolManager::setBezier );
232  connect( mUsePressureBox, &QCheckBox::clicked, toolManager, &ToolManager::setPressure );
233  connect( mMakeInvisibleBox, &QCheckBox::clicked, toolManager, &ToolManager::setInvisibility );
234  connect( mPreserveAlphaBox, &QCheckBox::clicked, toolManager, &ToolManager::setPreserveAlpha );
235 
236  connect( mSizeSlider, &SpinSlider::valueChanged, toolManager, &ToolManager::setWidth );
237  connect( mFeatherSlider, &SpinSlider::valueChanged, toolManager, &ToolManager::setFeather );
238 
239  connect( mBrushSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), toolManager, &ToolManager::setWidth );
240  connect( mFeatherSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), toolManager, &ToolManager::setFeather );
241 
242  connect( mUseFeatherBox, &QCheckBox::clicked, toolManager, &ToolManager::setUseFeather );
243 
244  connect( mVectorMergeBox, &QCheckBox::clicked, toolManager, &ToolManager::setVectorMergeEnabled );
245  connect( mUseAABox, &QCheckBox::clicked, toolManager, &ToolManager::setAA );
246 
247  connect( mNoInpol, &QRadioButton::clicked, toolManager, &ToolManager::noInpolSelected);
248  connect( mSimpleInpol, &QRadioButton::clicked, toolManager, &ToolManager::SimplepolSelected);
249  connect( mStrongInpol, &QRadioButton::clicked, toolManager, &ToolManager::StrongpolSelected);
250  connect( mExtremeInpol, &QRadioButton::clicked, toolManager, &ToolManager::ExtremepolSelected);
251 
252  connect( mToleranceSlider, &SpinSlider::valueChanged, toolManager, &ToolManager::setTolerance);
253  connect( mToleranceSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), toolManager, &ToolManager::setTolerance);
254 
255  connect( mFillContour, &QCheckBox::clicked, toolManager, &ToolManager::setUseFillContour );
256 
257  connect( toolManager, &ToolManager::toolChanged, this, &ToolOptionWidget::onToolChanged );
258  connect( toolManager, &ToolManager::toolPropertyChanged, this, &ToolOptionWidget::onToolPropertyChanged );
259 }
260 
261 void ToolOptionWidget::onToolPropertyChanged( ToolType, ToolPropertyType ePropertyType )
262 {
263  const Properties& p = editor()->tools()->currentTool()->properties;
264 
265  switch ( ePropertyType )
266  {
267  case WIDTH:
268  setPenWidth( p.width );
269  break;
270  case FEATHER:
271  setPenFeather( p.feather );
272  break;
273  case USEFEATHER:
274  setUseFeather( p.useFeather );
275  break;
276  case PRESSURE:
277  setPressure( p.pressure );
278  break;
279  case INVISIBILITY:
280  setPenInvisibility( p.invisibility );
281  break;
282  case PRESERVEALPHA:
283  setPreserveAlpha( p.preserveAlpha );
284  break;
285  case VECTORMERGE:
286  setVectorMergeEnabled(p.vectorMergeEnabled);
287  break;
288  case ANTI_ALIASING:
289  setAA(p.useAA);
290  break;
291  case INTERPOLATION:
292  setInpolLevel(p.inpolLevel);
293  break;
294  case TOLERANCE:
295  setTolerance(p.tolerance);
296  break;
297  case FILLCONTOUR:
298  setFillContour(p.useFillContour);
299  break;
300  default:
301  break;
302  }
303 }
304 
305 void ToolOptionWidget::visibilityOnLayer()
306 {
307  auto currentLayerType = editor()->layers()->currentLayer()->type();
308  auto propertyType = editor()->tools()->currentTool()->type();
309 
310  if (currentLayerType == Layer::VECTOR)
311  {
312  switch (propertyType)
313  {
314  case PENCIL:
315  mSizeSlider->setVisible(false);
316  mBrushSpinBox->setVisible(false);
317  mUsePressureBox->setVisible(false);
318  break;
319  default:
320  mToleranceSlider->setVisible(false);
321  mToleranceSpinBox->setVisible(false);
322  mUseAABox->setVisible(false);
323  break;
324  }
325  }
326  else
327  {
328  switch (propertyType)
329  {
330  case PENCIL:
331  mFillContour->setVisible(false);
332  break;
333  default:
334  mMakeInvisibleBox->setVisible(false);
335  break;
336 
337  }
338  }
339 }
340 
341 void ToolOptionWidget::onToolChanged( ToolType )
342 {
343  updateUI();
344 }
345 
346 void ToolOptionWidget::setPenWidth( qreal width )
347 {
348  SignalBlocker b( mSizeSlider );
349  mSizeSlider->setEnabled( true );
350  mSizeSlider->setValue( width );
351 
352  SignalBlocker b2( mBrushSpinBox );
353  mBrushSpinBox->setEnabled( true );
354  mBrushSpinBox->setValue( width );
355 }
356 
357 void ToolOptionWidget::setPenFeather( qreal featherValue )
358 {
359  SignalBlocker b( mFeatherSlider );
360  mFeatherSlider->setEnabled( true );
361  mFeatherSlider->setValue( featherValue );
362 
363  SignalBlocker b2( mFeatherSpinBox );
364  mFeatherSpinBox->setEnabled( true );
365  mFeatherSpinBox->setValue( featherValue );
366 }
367 
368 void ToolOptionWidget::setUseFeather( bool useFeather)
369 {
370  SignalBlocker b( mUseFeatherBox );
371  mUseFeatherBox->setEnabled(true);
372  mUseFeatherBox->setChecked(useFeather);
373 }
374 
375 void ToolOptionWidget::setPenInvisibility( int x )
376 {
377  SignalBlocker b( mMakeInvisibleBox );
378  mMakeInvisibleBox->setEnabled( true );
379  mMakeInvisibleBox->setChecked( x > 0 );
380 }
381 
382 void ToolOptionWidget::setPressure( int x )
383 {
384  SignalBlocker b( mUsePressureBox );
385  mUsePressureBox->setEnabled( true );
386  mUsePressureBox->setChecked( x > 0 );
387 }
388 
389 void ToolOptionWidget::setPreserveAlpha( int x )
390 {
391  qDebug() << "Setting - Preserve Alpha=" << x;
392 
393  SignalBlocker b( mPreserveAlphaBox );
394  mPreserveAlphaBox->setEnabled( true );
395  mPreserveAlphaBox->setChecked( x > 0 );
396 }
397 
398 void ToolOptionWidget::setVectorMergeEnabled(int x)
399 {
400  qDebug() << "Setting - Vector Merge Enabled=" << x;
401 
402  SignalBlocker b( mVectorMergeBox );
403  mVectorMergeBox->setEnabled( true );
404  mVectorMergeBox->setChecked( x > 0 );
405 }
406 
407 void ToolOptionWidget::setAA(int x)
408 {
409  qDebug() << "Setting - Pen AA Enabled=" << x;
410 
411  SignalBlocker b( mUseAABox );
412  mUseAABox->setEnabled( true );
413  mUseAABox->setVisible( false );
414 
415  auto layerType = editor()->layers()->currentLayer()->type();
416 
417  if (layerType == Layer::BITMAP)
418  {
419  if (x == -1) {
420  mUseAABox->setEnabled(false);
421  mUseAABox->setVisible(false);
422  } else {
423  mUseAABox->setVisible(true);
424  }
425  mUseAABox->setChecked( x > 0 );
426  }
427 }
428 
429 void ToolOptionWidget::setInpolLevel(int x)
430 {
431  qDebug() << "Setting - Interpolation level:" << x;
432 
433  SignalBlocker b( mNoInpol );
434  SignalBlocker c( mSimpleInpol );
435  SignalBlocker d( mStrongInpol );
436  if (x == 0) {
437  mNoInpol->setChecked(true);
438  }
439  else if (x == 1) {
440  mSimpleInpol->setChecked(true);
441  } else if (x == 2) {
442  mStrongInpol->setChecked(true);
443  } else if (x == 3) {
444  mExtremeInpol->setChecked(true);
445  } else if (x == -1) {
446  mNoInpol->setChecked(true);
447  }
448 }
449 
450 void ToolOptionWidget::setTolerance(int tolerance)
451 {
452  SignalBlocker b( mToleranceSlider );
453  mToleranceSlider->setEnabled( true );
454  mToleranceSlider->setValue( tolerance );
455 
456  SignalBlocker b2( mToleranceSpinBox );
457  mToleranceSpinBox->setEnabled( true );
458  mToleranceSpinBox->setValue( tolerance );
459 }
460 
461 void ToolOptionWidget::setFillContour(int useFill)
462 {
463  SignalBlocker b( mFillContour );
464  mFillContour->setEnabled(true);
465  mFillContour->setChecked(useFill > 0);
466 }
467 
468 void ToolOptionWidget::disableAllOptions()
469 {
470  mSizeSlider->hide();
471  mBrushSpinBox->hide();
472  mFeatherSlider->hide();
473  mFeatherSpinBox->hide();
474  mUseFeatherBox->hide();
475  mUseBezierBox->hide();
476  mUsePressureBox->hide();
477  mMakeInvisibleBox->hide();
478  mPreserveAlphaBox->hide();
479  mVectorMergeBox->hide();
480  mUseAABox->hide();
481  mInpolLevelsBox->hide();
482  mToleranceSlider->hide();
483  mToleranceSpinBox->hide();
484  mFillContour->hide();
485 }
Definition: editor.h:45