Engauge Digitizer 2
Loading...
Searching...
No Matches
DlgSettingsDigitizeCurve.cpp
Go to the documentation of this file.
1/******************************************************************************************************
2 * (C) 2014 markummitchell@github.com. This file is part of Engauge Digitizer, which is released *
3 * under GNU General Public License version 2 (GPLv2) or (at your option) any later version. See file *
4 * LICENSE or go to gnu.org/licenses for details. Distribution requires prior written permission. *
5 ******************************************************************************************************/
6
7#include "ButtonWhatsThis.h"
8#include "ButtonWhatsThis.h"
9#include "CmdMediator.h"
11#include "CursorFactory.h"
12#include "CursorSize.h"
15#include "EngaugeAssert.h"
16#include "Logger.h"
17#include "MainWindow.h"
18#include "PointStyle.h"
19#include <QCheckBox>
20#include <QComboBox>
21#include <QGraphicsPixmapItem>
22#include <QGridLayout>
23#include <QGraphicsScene>
24#include <QGroupBox>
25#include <QLabel>
26#include <qmath.h>
27#include <QRadioButton>
28#include <QSpinBox>
29#include <QWhatsThis>
30#include "Segment.h"
31#include "SegmentFactory.h"
32#include "ViewPreview.h"
33
34const int IMAGE_WIDTH = 100;
35const int IMAGE_HEIGHT = 100;
36const int MINIMUM_HEIGHT = 450;
37const int INNER_RADIUS_MAX = 64;
38const int INNER_RADIUS_MIN = 0;
39const int LINE_LENGTH_MIN = 2; // Min length of one line in the cursor, in pixels
40const int LINE_WIDTH_MAX = 32;
41const int LINE_WIDTH_MIN = 1;
42
44 DlgSettingsAbstractBase (tr ("Digitize Curve"),
45 "DlgSettingsDigitizeCurve",
47 m_scenePreview (nullptr),
48 m_viewPreview (nullptr),
49 m_modelDigitizeCurveBefore (nullptr),
50 m_modelDigitizeCurveAfter (nullptr)
51{
52 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::DlgSettingsDigitizeCurve";
53
54 QWidget *subPanel = createSubPanel ();
55 finishPanel (subPanel);
56}
57
59{
60 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::~DlgSettingsDigitizeCurve";
61}
62
63void DlgSettingsDigitizeCurve::createControls (QGridLayout *layout,
64 int &row)
65{
66 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::createControls";
67
68 m_boxCursor = new QGroupBox (tr ("Cursor"));
69 layout->addWidget (m_boxCursor, row, 1, 1, 2);
70
71 createWhatsThis (layout,
72 m_btnWhatsThis,
73 row++,
74 3);
75
76 // Layout inside cursor group box
77 QGridLayout *layoutCursor = new QGridLayout;
78 m_boxCursor->setLayout (layoutCursor);
79 int rowCursor = 0;
80
81 QLabel *labelCursorType = new QLabel(QString ("%1:").arg (tr ("Type")));
82 layoutCursor->addWidget (labelCursorType, rowCursor, 0);
83
84 m_btnStandard = new QRadioButton (tr ("Standard cross"));
85 m_btnStandard->setWhatsThis (tr ("Selects the standard cross cursor"));
86 layoutCursor->addWidget (m_btnStandard, rowCursor++, 1);
87 connect (m_btnStandard, SIGNAL (toggled (bool)), this, SLOT (slotCursorStandard(bool)));
88
89 m_btnCustom = new QRadioButton (tr ("Custom cross"));
90 m_btnCustom->setWhatsThis (tr ("Selects a custom cursor based on the settings selected below"));
91 layoutCursor->addWidget (m_btnCustom, rowCursor++, 1);
92 connect (m_btnCustom, SIGNAL (toggled (bool)), this, SLOT (slotCursorCustom(bool)));
93
94 QLabel *labelSize = new QLabel(QString ("%1:").arg (tr ("Size (pixels)")));
95 layoutCursor->addWidget (labelSize, rowCursor, 0);
96
97 m_cmbSize = new QComboBox;
98 m_cmbSize->addItem (QString::number (CursorSizeToPixels (CURSOR_SIZE_16)), QVariant (CURSOR_SIZE_16));
99 m_cmbSize->addItem (QString::number (CursorSizeToPixels (CURSOR_SIZE_32)), QVariant (CURSOR_SIZE_32));
100 m_cmbSize->addItem (QString::number (CursorSizeToPixels (CURSOR_SIZE_48)), QVariant (CURSOR_SIZE_48));
101 m_cmbSize->addItem (QString::number (CursorSizeToPixels (CURSOR_SIZE_64)), QVariant (CURSOR_SIZE_64));
102 ENGAUGE_ASSERT (m_cmbSize->count() == NUM_CURSOR_SIZES);
103 m_cmbSize->setWhatsThis (tr ("Horizontal and vertical size of the cursor in pixels"));
104 layoutCursor->addWidget (m_cmbSize, rowCursor++, 1);
105 connect (m_cmbSize, SIGNAL (currentIndexChanged (const QString &)), this, SLOT (slotCursorSize (const QString &)));
106
107 QLabel *labelInnerRadius = new QLabel(QString ("%1:").arg (tr ("Inner radius (pixels)")));
108 layoutCursor->addWidget (labelInnerRadius, rowCursor, 0);
109
110 m_spinInnerRadius = new QSpinBox;
111 m_spinInnerRadius->setRange (INNER_RADIUS_MIN, INNER_RADIUS_MAX);
112 m_spinInnerRadius->setWhatsThis (tr ("Radius of circle at the center of the cursor that will remain empty"));
113 layoutCursor->addWidget (m_spinInnerRadius, rowCursor++, 1);
114 connect (m_spinInnerRadius, SIGNAL (valueChanged(const QString &)), this, SLOT (slotCursorInnerRadius (const QString &)));
115
116 QLabel *labelLineWidth = new QLabel(QString ("%1:").arg (tr ("Line width (pixels)")));
117 layoutCursor->addWidget (labelLineWidth, rowCursor, 0);
118
119 m_spinLineWidth = new QSpinBox;
120 m_spinLineWidth->setRange (LINE_WIDTH_MIN, LINE_WIDTH_MAX);
121 m_spinLineWidth->setWhatsThis (tr ("Width of each arm of the cross of the cursor"));
122 layoutCursor->addWidget (m_spinLineWidth, rowCursor++, 1);
123 connect (m_spinLineWidth, SIGNAL (valueChanged(const QString &)), this, SLOT (slotCursorLineWidth (const QString &)));
124}
125
127{
128}
129
130void DlgSettingsDigitizeCurve::createPreview (QGridLayout *layout,
131 int &row)
132{
133 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::createPreview";
134
135 QLabel *labelPreview = new QLabel (tr ("Preview"));
136 layout->addWidget (labelPreview, row++, 0, 1, 4);
137
138 m_scenePreview = new QGraphicsScene (this);
139 m_scenePreview->setSceneRect(0,
140 0,
143
144 m_viewPreview = new ViewPreview (m_scenePreview,
146 this);
147 m_viewPreview->setWhatsThis (tr ("Preview window showing the currently selected cursor.\n\n"
148 "Drag the cursor over this area to see the effects of the current settings on the cursor shape."));
149 m_viewPreview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
150 m_viewPreview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
151 m_viewPreview->setMinimumHeight (MINIMUM_PREVIEW_HEIGHT);
152
153 layout->addWidget (m_viewPreview, row++, 0, 1, 4);
154}
155
157{
158 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::createSubPanel";
159
160 QWidget *subPanel = new QWidget ();
161 QGridLayout *layout = new QGridLayout (subPanel);
162 subPanel->setLayout (layout);
163
164 layout->setColumnStretch (0, 1); // Empty first column
165 layout->setColumnStretch (1, 0); // Labels
166 layout->setColumnStretch (2, 0); // User controls
167 layout->setColumnStretch (3, 1); // Empty last column
168
169 int row = 0;
170 createControls(layout, row);
171 createPreview (layout, row);
172
173 return subPanel;
174}
175
177{
178 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::handleOk";
179
181 cmdMediator ().document(),
182 *m_modelDigitizeCurveBefore,
183 *m_modelDigitizeCurveAfter);
184 cmdMediator ().push (cmd);
185
186 hide ();
187}
188
190{
191 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::load";
192
194
195 // Flush old data
196 delete m_modelDigitizeCurveBefore;
197 delete m_modelDigitizeCurveAfter;
198
199 // Save new data
200 m_modelDigitizeCurveBefore = new DocumentModelDigitizeCurve (cmdMediator.document());
201 m_modelDigitizeCurveAfter = new DocumentModelDigitizeCurve (cmdMediator.document());
202
203 // Sanity checks. Incoming defaults must be acceptable to the local limits
205 ENGAUGE_ASSERT (INNER_RADIUS_MAX >= m_modelDigitizeCurveAfter->cursorInnerRadius ());
207 ENGAUGE_ASSERT (LINE_WIDTH_MAX >= m_modelDigitizeCurveAfter->cursorLineWidth ());
208
209 // Populate controls
210 m_btnStandard->setChecked (m_modelDigitizeCurveAfter->cursorStandardCross());
211 m_btnCustom->setChecked (!m_modelDigitizeCurveAfter->cursorStandardCross());
212 m_spinInnerRadius->setValue (m_modelDigitizeCurveAfter->cursorInnerRadius());
213 int index = m_cmbSize->findData (QVariant (m_modelDigitizeCurveAfter->cursorSize()));
214 m_cmbSize->setCurrentIndex (index);
215 m_spinLineWidth->setValue (m_modelDigitizeCurveAfter->cursorLineWidth());
216
217 updateControls();
218 enableOk (false); // Disable Ok button since there not yet any changes
219 updatePreview();
220}
221
223{
224 if (!smallDialogs) {
225 setMinimumHeight (MINIMUM_HEIGHT);
226 }
227}
228
229void DlgSettingsDigitizeCurve::slotCursorCustom (bool)
230{
231 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::slotCursorCustom";
232
233 m_modelDigitizeCurveAfter->setCursorStandardCross(false);
234 updateControls();
235 updatePreview();
236}
237
238void DlgSettingsDigitizeCurve::slotCursorInnerRadius (const QString &)
239{
240 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::slotCursorInnerRadius";
241
242 m_modelDigitizeCurveAfter->setCursorInnerRadius (m_spinInnerRadius->value());
243 updateControls();
244 updatePreview();
245}
246
247void DlgSettingsDigitizeCurve::slotCursorLineWidth (const QString &)
248{
249 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::slotCursorLineWidth";
250
251 m_modelDigitizeCurveAfter->setCursorLineWidth (m_spinLineWidth->value());
252 updateControls();
253 updatePreview();
254}
255
256void DlgSettingsDigitizeCurve::slotCursorSize (const QString &)
257{
258 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::slotCursorSize";
259
260 m_modelDigitizeCurveAfter->setCursorSize (static_cast<CursorSize> (m_cmbSize->currentData().toInt()));
261 updateControls();
262 updatePreview();
263}
264
265void DlgSettingsDigitizeCurve::slotCursorStandard (bool)
266{
267 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::slotCursorStandard";
268
269 m_modelDigitizeCurveAfter->setCursorStandardCross(true);
270 updateControls();
271 updatePreview();
272}
273
274void DlgSettingsDigitizeCurve::slotWhatsThis ()
275{
276 QWhatsThis::enterWhatsThisMode();
277}
278
279void DlgSettingsDigitizeCurve::updateControls()
280{
281 // Cursor has to fit into current extent
282 bool isGoodState = 2 * (m_modelDigitizeCurveAfter->cursorInnerRadius() + LINE_LENGTH_MIN) <=
283 CursorSizeToPixels (m_modelDigitizeCurveAfter->cursorSize());
284 enableOk (isGoodState);
285
286 m_spinInnerRadius->setEnabled (m_btnCustom->isChecked());
287 m_cmbSize->setEnabled (m_btnCustom->isChecked());
288 m_spinLineWidth->setEnabled (m_btnCustom->isChecked());
289}
290
291void DlgSettingsDigitizeCurve::updatePreview()
292{
293 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::updatePreview";
294
295 CursorFactory cursorFactory;
296 QCursor cursor = cursorFactory.generate (*m_modelDigitizeCurveAfter);
297 m_viewPreview->setCursor (cursor);
298}
int CursorSizeToPixels(CursorSize cursorSize)
CursorSize
Custom cursor sizes supported on all platforms for the most part, according to QCursor documentation.
Definition CursorSize.h:11
@ CURSOR_SIZE_48
Definition CursorSize.h:14
@ CURSOR_SIZE_32
Definition CursorSize.h:13
@ CURSOR_SIZE_16
Definition CursorSize.h:12
@ CURSOR_SIZE_64
Definition CursorSize.h:15
@ NUM_CURSOR_SIZES
Definition CursorSize.h:16
const int MINIMUM_HEIGHT
const int INNER_RADIUS_MIN
const int LINE_WIDTH_MAX
const int LINE_LENGTH_MIN
const int IMAGE_WIDTH
const int INNER_RADIUS_MAX
const int IMAGE_HEIGHT
const int LINE_WIDTH_MIN
#define ENGAUGE_ASSERT(cond)
Drop in replacement for Q_ASSERT.
log4cpp::Category * mainCat
Definition Logger.cpp:14
Command queue stack.
Definition CmdMediator.h:24
Command for DlgSettingsDigitizeCurve.
QCursor generate(const DocumentModelDigitizeCurve &modelDigitizeCurve) const
Factory method to generate standard or custom cursor.
DlgSettingsAbstractBase(const QString &title, const QString &dialogName, MainWindow &mainWindow)
Single constructor.
void setCmdMediator(CmdMediator &cmdMediator)
Store CmdMediator for easy access by the leaf class.
void finishPanel(QWidget *subPanel, int minimumWidth=MINIMUM_DIALOG_WIDTH, int minimumHeightOrZero=0)
Add Ok and Cancel buttons to subpanel to get the whole dialog.
CmdMediator & cmdMediator()
Provide access to Document information wrapped inside CmdMediator.
void createWhatsThis(QGridLayout *layout, ButtonWhatsThis *button, int row, int column)
Create a WhatsThis button in a grid layout.
void enableOk(bool enable)
Let leaf subclass control the Ok button.
static int MINIMUM_PREVIEW_HEIGHT
Dialog layout constant that guarantees preview has sufficent room.
MainWindow & mainWindow()
Get method for MainWindow.
DlgSettingsDigitizeCurve(MainWindow &mainWindow)
Single constructor.
virtual void handleOk()
Process slotOk.
virtual void createOptionalSaveDefault(QHBoxLayout *layout)
Let subclass define an optional Save As Default button.
virtual QWidget * createSubPanel()
Create dialog-specific panel to which base class will add Ok and Cancel buttons.
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
virtual void setSmallDialogs(bool smallDialogs)
If false then dialogs have a minimum size so all controls are visible.
Model for DlgSettingsDigitizeCurve and CmdSettingsDigitizeCurve.
void setCursorStandardCross(bool cursorStandardCross)
Set method for cursor type.
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Definition MainWindow.h:95
Class that modifies QGraphicsView to automatically expand/shrink the view to fit the window,...
Definition ViewPreview.h:15
@ VIEW_ASPECT_RATIO_VARIABLE
Definition ViewPreview.h:22
#define LOG4CPP_INFO_S(logger)
Definition convenience.h:18