Engauge Digitizer 2
Loading...
Searching...
No Matches
DlgSettingsDigitizeCurve.cpp
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 "CmdMediator.h"
8#include "CmdSettingsDigitizeCurve.h"
9#include "CursorFactory.h"
10#include "CursorSize.h"
11#include "DlgSettingsDigitizeCurve.h"
12#include "DocumentModelDigitizeCurve.h"
13#include "EngaugeAssert.h"
14#include "Logger.h"
15#include "MainWindow.h"
16#include "PointStyle.h"
17#include <QCheckBox>
18#include <QComboBox>
19#include <QGraphicsPixmapItem>
20#include <QGridLayout>
21#include <QGraphicsScene>
22#include <QGroupBox>
23#include <QLabel>
24#include <qmath.h>
25#include <QRadioButton>
26#include <QSpinBox>
27#include "Segment.h"
28#include "SegmentFactory.h"
29#include "ViewPreview.h"
30
31const int IMAGE_WIDTH = 100;
32const int IMAGE_HEIGHT = 100;
33
34const int INNER_RADIUS_MAX = 64;
35const int INNER_RADIUS_MIN = 0;
36const int LINE_LENGTH_MIN = 2; // Min length of one line in the cursor, in pixels
37const int LINE_WIDTH_MAX = 32;
38const int LINE_WIDTH_MIN = 1;
39
41 DlgSettingsAbstractBase (tr ("Digitize Curve"),
42 "DlgSettingsDigitizeCurve",
43 mainWindow),
44 m_scenePreview (0),
45 m_viewPreview (0),
46 m_modelDigitizeCurveBefore (0),
47 m_modelDigitizeCurveAfter (0)
48{
49 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::DlgSettingsDigitizeCurve";
50
51 QWidget *subPanel = createSubPanel ();
52 finishPanel (subPanel);
53}
54
55DlgSettingsDigitizeCurve::~DlgSettingsDigitizeCurve()
56{
57 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::~DlgSettingsDigitizeCurve";
58}
59
60void DlgSettingsDigitizeCurve::createControls (QGridLayout *layout,
61 int &row)
62{
63 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::createControls";
64
65 m_boxCursor = new QGroupBox (tr ("Cursor"));
66 layout->addWidget (m_boxCursor, row++, 1, 1, 2);
67
68 // Layout inside cursor group box
69 QGridLayout *layoutCursor = new QGridLayout;
70 m_boxCursor->setLayout (layoutCursor);
71 int rowCursor = 0;
72
73 QLabel *labelCursorType = new QLabel(tr ("Type:"));
74 layoutCursor->addWidget (labelCursorType, rowCursor, 0);
75
76 m_btnStandard = new QRadioButton (tr ("Standard cross"));
77 m_btnStandard->setWhatsThis (tr ("Selects the standard cross cursor"));
78 layoutCursor->addWidget (m_btnStandard, rowCursor++, 1);
79 connect (m_btnStandard, SIGNAL (toggled (bool)), this, SLOT (slotCursorStandard(bool)));
80
81 m_btnCustom = new QRadioButton (tr ("Custom cross"));
82 m_btnCustom->setWhatsThis (tr ("Selects a custom cursor based on the settings selected below"));
83 layoutCursor->addWidget (m_btnCustom, rowCursor++, 1);
84 connect (m_btnCustom, SIGNAL (toggled (bool)), this, SLOT (slotCursorCustom(bool)));
85
86 QLabel *labelSize = new QLabel(tr ("Size (pixels):"));
87 layoutCursor->addWidget (labelSize, rowCursor, 0);
88
89 m_cmbSize = new QComboBox;
90 m_cmbSize->addItem (QString::number (CursorSizeToPixels (CURSOR_SIZE_16)), QVariant (CURSOR_SIZE_16));
91 m_cmbSize->addItem (QString::number (CursorSizeToPixels (CURSOR_SIZE_32)), QVariant (CURSOR_SIZE_32));
92 m_cmbSize->addItem (QString::number (CursorSizeToPixels (CURSOR_SIZE_48)), QVariant (CURSOR_SIZE_48));
93 m_cmbSize->addItem (QString::number (CursorSizeToPixels (CURSOR_SIZE_64)), QVariant (CURSOR_SIZE_64));
94 ENGAUGE_ASSERT (m_cmbSize->count() == NUM_CURSOR_SIZES);
95 m_cmbSize->setWhatsThis (tr ("Horizontal and vertical size of the cursor in pixels"));
96 layoutCursor->addWidget (m_cmbSize, rowCursor++, 1);
97 connect (m_cmbSize, SIGNAL (currentIndexChanged (const QString &)), this, SLOT (slotCursorSize (const QString &)));
98
99 QLabel *labelInnerRadius = new QLabel(tr ("Inner radius (pixels):"));
100 layoutCursor->addWidget (labelInnerRadius, rowCursor, 0);
101
102 m_spinInnerRadius = new QSpinBox;
103 m_spinInnerRadius->setRange (INNER_RADIUS_MIN, INNER_RADIUS_MAX);
104 m_spinInnerRadius->setWhatsThis (tr ("Radius of circle at the center of the cursor that will remain empty"));
105 layoutCursor->addWidget (m_spinInnerRadius, rowCursor++, 1);
106 connect (m_spinInnerRadius, SIGNAL (valueChanged(const QString &)), this, SLOT (slotCursorInnerRadius (const QString &)));
107
108 QLabel *labelLineWidth = new QLabel(tr ("Line width (pixels):"));
109 layoutCursor->addWidget (labelLineWidth, rowCursor, 0);
110
111 m_spinLineWidth = new QSpinBox;
112 m_spinLineWidth->setRange (LINE_WIDTH_MIN, LINE_WIDTH_MAX);
113 m_spinLineWidth->setWhatsThis (tr ("Width of each arm of the cross of the cursor"));
114 layoutCursor->addWidget (m_spinLineWidth, rowCursor++, 1);
115 connect (m_spinLineWidth, SIGNAL (valueChanged(const QString &)), this, SLOT (slotCursorLineWidth (const QString &)));
116}
117
119{
120}
121
122void DlgSettingsDigitizeCurve::createPreview (QGridLayout *layout,
123 int &row)
124{
125 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::createPreview";
126
127 QLabel *labelPreview = new QLabel (tr ("Preview"));
128 layout->addWidget (labelPreview, row++, 0, 1, 4);
129
130 m_scenePreview = new QGraphicsScene (this);
131 m_scenePreview->setSceneRect(0,
132 0,
133 IMAGE_WIDTH,
134 IMAGE_HEIGHT);
135
136 m_viewPreview = new ViewPreview (m_scenePreview,
137 ViewPreview::VIEW_ASPECT_RATIO_VARIABLE,
138 this);
139 m_viewPreview->setWhatsThis (tr ("Preview window showing the currently selected cursor"));
140 m_viewPreview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
141 m_viewPreview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
142 m_viewPreview->setMinimumHeight (MINIMUM_PREVIEW_HEIGHT);
143
144 layout->addWidget (m_viewPreview, row++, 0, 1, 4);
145}
146
148{
149 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::createSubPanel";
150
151 QWidget *subPanel = new QWidget ();
152 QGridLayout *layout = new QGridLayout (subPanel);
153 subPanel->setLayout (layout);
154
155 layout->setColumnStretch (0, 1); // Empty first column
156 layout->setColumnStretch (1, 0); // Labels
157 layout->setColumnStretch (2, 0); // User controls
158 layout->setColumnStretch (3, 1); // Empty last column
159
160 int row = 0;
161 createControls(layout, row);
162 createPreview (layout, row);
163
164 return subPanel;
165}
166
168{
169 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::handleOk";
170
172 cmdMediator ().document(),
173 *m_modelDigitizeCurveBefore,
174 *m_modelDigitizeCurveAfter);
175 cmdMediator ().push (cmd);
176
177 hide ();
178}
179
181{
182 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::load";
183
185
186 // Flush old data
187 if (m_modelDigitizeCurveBefore != 0) {
188 delete m_modelDigitizeCurveBefore;
189 }
190 if (m_modelDigitizeCurveAfter != 0) {
191 delete m_modelDigitizeCurveAfter;
192 }
193
194 // Save new data
195 m_modelDigitizeCurveBefore = new DocumentModelDigitizeCurve (cmdMediator.document());
196 m_modelDigitizeCurveAfter = new DocumentModelDigitizeCurve (cmdMediator.document());
197
198 // Sanity checks. Incoming defaults must be acceptable to the local limits
199 ENGAUGE_ASSERT (INNER_RADIUS_MIN <= m_modelDigitizeCurveAfter->cursorInnerRadius ());
200 ENGAUGE_ASSERT (INNER_RADIUS_MAX >= m_modelDigitizeCurveAfter->cursorInnerRadius ());
201 ENGAUGE_ASSERT (LINE_WIDTH_MIN <= m_modelDigitizeCurveAfter->cursorLineWidth ());
202 ENGAUGE_ASSERT (LINE_WIDTH_MAX >= m_modelDigitizeCurveAfter->cursorLineWidth ());
203
204 // Populate controls
205 m_btnStandard->setChecked (m_modelDigitizeCurveAfter->cursorStandardCross());
206 m_btnCustom->setChecked (!m_modelDigitizeCurveAfter->cursorStandardCross());
207 m_spinInnerRadius->setValue (m_modelDigitizeCurveAfter->cursorInnerRadius());
208 int index = m_cmbSize->findData (QVariant (m_modelDigitizeCurveAfter->cursorSize()));
209 m_cmbSize->setCurrentIndex (index);
210 m_spinLineWidth->setValue (m_modelDigitizeCurveAfter->cursorLineWidth());
211
212 updateControls();
213 enableOk (false); // Disable Ok button since there not yet any changes
214 updatePreview();
215}
216
217void DlgSettingsDigitizeCurve::slotCursorCustom (bool)
218{
219 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::slotCursorCustom";
220
221 m_modelDigitizeCurveAfter->setCursorStandardCross(false);
222 updateControls();
223 updatePreview();
224}
225
226void DlgSettingsDigitizeCurve::slotCursorInnerRadius (const QString &)
227{
228 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::slotCursorInnerRadius";
229
230 m_modelDigitizeCurveAfter->setCursorInnerRadius (m_spinInnerRadius->value());
231 updateControls();
232 updatePreview();
233}
234
235void DlgSettingsDigitizeCurve::slotCursorLineWidth (const QString &)
236{
237 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::slotCursorLineWidth";
238
239 m_modelDigitizeCurveAfter->setCursorLineWidth (m_spinLineWidth->value());
240 updateControls();
241 updatePreview();
242}
243
244void DlgSettingsDigitizeCurve::slotCursorSize (const QString &)
245{
246 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::slotCursorSize";
247
248 m_modelDigitizeCurveAfter->setCursorSize ((CursorSize) m_cmbSize->currentData().toInt());
249 updateControls();
250 updatePreview();
251}
252
253void DlgSettingsDigitizeCurve::slotCursorStandard (bool)
254{
255 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::slotCursorStandard";
256
257 m_modelDigitizeCurveAfter->setCursorStandardCross(true);
258 updateControls();
259 updatePreview();
260}
261
262void DlgSettingsDigitizeCurve::updateControls()
263{
264 // Cursor has to fit into current extent
265 bool isGoodState = 2 * (m_modelDigitizeCurveAfter->cursorInnerRadius() + LINE_LENGTH_MIN) <=
266 CursorSizeToPixels (m_modelDigitizeCurveAfter->cursorSize());
267 enableOk (isGoodState);
268
269 m_spinInnerRadius->setEnabled (m_btnCustom->isChecked());
270 m_cmbSize->setEnabled (m_btnCustom->isChecked());
271 m_spinLineWidth->setEnabled (m_btnCustom->isChecked());
272}
273
274void DlgSettingsDigitizeCurve::updatePreview()
275{
276 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::updatePreview";
277
278 CursorFactory cursorFactory;
279 QCursor cursor = cursorFactory.generate (*m_modelDigitizeCurveAfter);
280 m_viewPreview->setCursor (cursor);
281}
Command queue stack.
Definition CmdMediator.h:24
Document & document()
Provide the Document to commands, primarily for undo/redo processing.
Command for DlgSettingsDigitizeCurve.
Create standard cross cursor, or custom cursor, according to settings.
QCursor generate(const DocumentModelDigitizeCurve &modelDigitizeCurve) const
Factory method to generate standard or custom cursor.
Abstract base class for all Settings dialogs.
void setCmdMediator(CmdMediator &cmdMediator)
Store CmdMediator for easy access by the leaf class.
CmdMediator & cmdMediator()
Provide access to Document information wrapped inside CmdMediator.
void enableOk(bool enable)
Let leaf subclass control the Ok button.
void finishPanel(QWidget *subPanel)
Add Ok and Cancel buttons to subpanel to get the whole dialog.
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.
Model for DlgSettingsDigitizeCurve and CmdSettingsDigitizeCurve.
void setCursorStandardCross(bool cursorStandardCross)
Set method for cursor type.
void setCursorLineWidth(int lineWidth)
Set method for cursor line width.
void setCursorInnerRadius(int innerRadius)
Set method for cursor inner radius.
CursorSize cursorSize() const
Get method for cursor size.
int cursorInnerRadius() const
Get method for cursor inner radius.
bool cursorStandardCross() const
Get method for cursor type.
int cursorLineWidth() const
Get method for cursor line width.
void setCursorSize(CursorSize cursorSize)
Set method for cursor size.
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Definition MainWindow.h:78
Class that modifies QGraphicsView to automatically expand/shrink the view to fit the window,...
Definition ViewPreview.h:15