Engauge Digitizer 2
Loading...
Searching...
No Matches
DlgSettingsAxesChecker.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 "Checker.h"
8#include "CmdMediator.h"
10#include "CoordScale.h"
12#include "EngaugeAssert.h"
13#include "Logger.h"
14#include "MainWindow.h"
15#include <QButtonGroup>
16#include <QComboBox>
17#include <QGraphicsRectItem>
18#include <QGraphicsScene>
19#include <QGridLayout>
20#include <QGroupBox>
21#include <QLabel>
22#include <QLineEdit>
23#include <qmath.h>
24#include <QRadioButton>
25#include "ViewPreview.h"
26
27const int AXIS_WIDTH = 4;
28const int MINIMUM_HEIGHT = 500;
29const int RECT_WIDTH = 640;
30const int RECT_HEIGHT = 480;
31const int X_LEFT = RECT_WIDTH / 8;
32const int X_RIGHT = RECT_WIDTH * 7 / 8;
33const int Y_TOP = RECT_HEIGHT / 8;
34const int Y_BOTTOM = RECT_HEIGHT * 7 / 8;
35const int TICKS_PER_AXIS = 6;
36const int TICK_MARK_LENGTH = 8;
37
39 DlgSettingsAbstractBase (tr ("Axes Checker"),
40 "DlgSettingsAxesChecker",
41 mainWindow),
42 m_checker (nullptr),
43 m_modelAxesCheckerBefore (nullptr),
44 m_modelAxesCheckerAfter (nullptr),
45 m_modelCoords (nullptr)
46{
47 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsAxesChecker::DlgSettingsAxesChecker";
48
49 QWidget *subPanel = createSubPanel ();
50 finishPanel (subPanel);
51}
52
54{
55 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsAxesChecker::~DlgSettingsAxesChecker";
56
57 delete m_checker;
58}
59
60void DlgSettingsAxesChecker::createControls (QGridLayout *layout,
61 int &row)
62{
63 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsAxesChecker::createControls";
64
65 QGroupBox *groupBox = new QGroupBox (tr ("Axes Checker Lifetime"));
66 layout->addWidget (groupBox, row++, 1, 1, 2);
67
68 QGridLayout *layoutLifetime = new QGridLayout;
69 groupBox->setLayout (layoutLifetime);
70
71 int rowLifetime = 0;
72 m_btnNever = new QRadioButton (tr ("Do not show"), groupBox);
73 m_btnNever->setWhatsThis (tr ("Never show axes checker."));
74 layoutLifetime->addWidget (m_btnNever, rowLifetime++, 0, 1, 2);
75
76 m_btnNSeconds = new QRadioButton (tr ("Show for a number of seconds"), groupBox);
77 m_btnNSeconds->setWhatsThis (tr ("Show axes checker for a number of seconds after changing axes points."));
78 layoutLifetime->addWidget (m_btnNSeconds, rowLifetime, 0, 1, 1);
79
80 m_cmbSeconds = new QComboBox;
81 for (int seconds = 1; seconds <= 10; seconds++) {
82 m_cmbSeconds->addItem (QString::number (seconds), QVariant (seconds));
83 }
84 layoutLifetime->addWidget (m_cmbSeconds, rowLifetime++, 1);
85 connect (m_cmbSeconds, SIGNAL (activated (const QString &)), this, SLOT (slotSeconds (const QString &))); // activated() ignores code changes
86
87 m_btnForever = new QRadioButton (tr ("Show always"), groupBox);
88 m_btnForever->setWhatsThis (tr ("Always show axes checker."));
89 layoutLifetime->addWidget (m_btnForever, rowLifetime++, 0, 1, 2);
90
91 m_groupMode = new QButtonGroup;
92 m_groupMode->addButton (m_btnNever);
93 m_groupMode->addButton (m_btnNSeconds);
94 m_groupMode->addButton (m_btnForever);
95 connect (m_groupMode, SIGNAL (buttonReleased (QAbstractButton*)), this, SLOT (slotGroupMode (QAbstractButton*)));
96
97 QLabel *labelLineColor = new QLabel (QString ("%1:").arg (tr ("Line color")));
98 layout->addWidget (labelLineColor, row, 1);
99
100 m_cmbLineColor = new QComboBox;
101 m_cmbLineColor->setWhatsThis (tr ("Select a color for the highlight lines drawn at each axis point"));
102 populateColorComboWithoutTransparent (*m_cmbLineColor);
103 connect (m_cmbLineColor, SIGNAL (activated (const QString &)), this, SLOT (slotLineColor (const QString &))); // activated() ignores code changes
104 layout->addWidget (m_cmbLineColor, row++, 2);
105}
106
108{
109}
110
111void DlgSettingsAxesChecker::createPoints ()
112{
113 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsAxesChecker::createPoints";
114
115 QBrush AXES_BRUSH (Qt::gray);
116
117 m_checker = new Checker (*m_scenePreview);
118
119 // Create an invisible rectangular item that will guarantee a margin all around the outside, since otherwise QGraphicsView
120 // will zoom in on the points
121 QGraphicsRectItem *itemRect = new QGraphicsRectItem (0,
122 0,
125 itemRect->setPen (Qt::NoPen);
126 m_scenePreview->addItem (itemRect);
127
128 // For a realistic background, draw a rectangle underneath (lower z value), and some tick marks
129 QGraphicsRectItem *frameBox = new QGraphicsRectItem (X_LEFT,
130 Y_BOTTOM,
131 X_RIGHT - X_LEFT,
132 Y_TOP - Y_BOTTOM);
133 frameBox->setPen (QPen (AXES_BRUSH, AXIS_WIDTH));
134 frameBox->setZValue (-1);
135 m_scenePreview->addItem (frameBox);
136 for (int x = X_LEFT; x < X_RIGHT; x += (X_RIGHT - X_LEFT) / TICKS_PER_AXIS) {
137 QGraphicsLineItem *tick = new QGraphicsLineItem (x, Y_BOTTOM, x, Y_BOTTOM + TICK_MARK_LENGTH);
138 tick->setPen (QPen (AXES_BRUSH, AXIS_WIDTH));
139 tick->setZValue (-1);
140 m_scenePreview->addItem (tick);
141 }
142 for (int y = Y_TOP; y < Y_BOTTOM; y += (Y_BOTTOM - Y_TOP) / TICKS_PER_AXIS) {
143 QGraphicsLineItem *tick = new QGraphicsLineItem (X_LEFT, y, X_LEFT + TICK_MARK_LENGTH, y);
144 tick->setPen (QPen (AXES_BRUSH, AXIS_WIDTH));
145 tick->setZValue (-1);
146 m_scenePreview->addItem (tick);
147 }
148}
149
150void DlgSettingsAxesChecker::createPreview (QGridLayout *layout,
151 int &row)
152{
153 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsAxesChecker::createPreview";
154
155 QLabel *labelPreview = new QLabel (tr ("Preview"));
156 layout->addWidget (labelPreview, row++, 0, 1, 4);
157
158 m_scenePreview = new QGraphicsScene (this);
159 m_viewPreview = new ViewPreview (m_scenePreview,
161 this);
162 m_viewPreview->setWhatsThis (tr ("Preview window that shows how current settings affect the displayed axes checker"));
163 m_viewPreview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
164 m_viewPreview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
165 m_viewPreview->setMinimumHeight (MINIMUM_PREVIEW_HEIGHT);
166
167 layout->addWidget (m_viewPreview, row++, 0, 1, 4);
168}
169
171{
172 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsAxesChecker::createSubPanel";
173
174 QWidget *subPanel = new QWidget ();
175 QGridLayout *layout = new QGridLayout (subPanel);
176 subPanel->setLayout (layout);
177
178 layout->setColumnStretch(0, 1); // Empty first column
179 layout->setColumnStretch(1, 0); // X
180 layout->setColumnStretch(2, 0); // Y
181 layout->setColumnStretch(3, 1); // Empty first column
182
183 int row = 0;
184 createControls (layout, row);
185 createPreview (layout, row);
186
187 createPoints ();
188
189 return subPanel;
190}
191
193{
194 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsAxesChecker::handleOk";
195
197 cmdMediator ().document(),
198 *m_modelAxesCheckerBefore,
199 *m_modelAxesCheckerAfter);
200 cmdMediator ().push (cmd);
201
202 hide ();
203}
204
206{
207 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsAxesChecker::load";
208
210
211 // Flush old data
212 delete m_modelAxesCheckerBefore;
213 delete m_modelAxesCheckerAfter;
214 delete m_modelCoords;
215
216 // Save new data
217 m_modelAxesCheckerBefore = new DocumentModelAxesChecker (cmdMediator.document());
218 m_modelAxesCheckerAfter = new DocumentModelAxesChecker (cmdMediator.document());
219 m_modelCoords = new DocumentModelCoords (cmdMediator.document());
220
221 // Populate controls
222 CheckerMode checkerMode = m_modelAxesCheckerAfter->checkerMode();
223 m_btnNever->setChecked (checkerMode == CHECKER_MODE_NEVER);
224 m_btnNSeconds->setChecked (checkerMode == CHECKER_MODE_N_SECONDS);
225 m_btnForever->setChecked (checkerMode == CHECKER_MODE_FOREVER);
226 int indexSeconds = m_cmbSeconds->findData (QVariant (m_modelAxesCheckerAfter->checkerSeconds()));
227 ENGAUGE_ASSERT (indexSeconds >= 0);
228 m_cmbSeconds->setCurrentIndex(indexSeconds);
229
230 int indexLineColor = m_cmbLineColor->findData (QVariant (m_modelAxesCheckerAfter->lineColor()));
231 ENGAUGE_ASSERT (indexLineColor >= 0);
232 m_cmbLineColor->setCurrentIndex (indexLineColor);
233
234 updateControls ();
235 enableOk (false); // Disable Ok button since there not yet any changes
236 updatePreview();
237}
238
240{
241 if (!smallDialogs) {
242 setMinimumHeight (MINIMUM_HEIGHT);
243 }
244}
245
246void DlgSettingsAxesChecker::slotGroupMode (QAbstractButton*)
247{
248 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsAxesChecker::slotGroupMode";
249
250 if (m_btnNever->isChecked ()) {
251 m_modelAxesCheckerAfter->setCheckerMode(CHECKER_MODE_NEVER);
252 } else if (m_btnNSeconds->isChecked ()) {
253 m_modelAxesCheckerAfter->setCheckerMode(CHECKER_MODE_N_SECONDS);
254 } else {
255 m_modelAxesCheckerAfter->setCheckerMode(CHECKER_MODE_FOREVER);
256 }
257
258 updateControls ();
259 updatePreview();
260}
261
262void DlgSettingsAxesChecker::slotLineColor(const QString &)
263{
264 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsAxesChecker::slotLineColor";
265
266 m_modelAxesCheckerAfter->setLineColor (static_cast<ColorPalette> (m_cmbLineColor->currentData().toInt()));
267 updateControls();
268 updatePreview();
269}
270
271void DlgSettingsAxesChecker::slotSeconds (const QString &)
272{
273 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsAxesChecker::slotLineColor";
274
275 m_modelAxesCheckerAfter->setCheckerSeconds(m_cmbSeconds->currentData().toInt());
276 updateControls();
277}
278
279void DlgSettingsAxesChecker::updateControls ()
280{
281 enableOk (true);
282
283 m_cmbSeconds->setEnabled (m_btnNSeconds->isChecked ());
284}
285
286void DlgSettingsAxesChecker::updatePreview()
287{
288 const int ZERO_RADIUS_SINCE_NO_POINTS = 0;
289
290 QVector<QPointF> points;
291 points.push_back (QPointF (X_LEFT, Y_TOP));
292 points.push_back (QPointF (X_LEFT, Y_BOTTOM));
293 points.push_back (QPointF (X_RIGHT, Y_BOTTOM));
294
295 QPolygonF polygon (points);
296
297 ENGAUGE_CHECK_PTR (m_checker);
298 m_checker->prepareForDisplay (polygon,
299 ZERO_RADIUS_SINCE_NO_POINTS,
300 *m_modelAxesCheckerAfter,
301 *m_modelCoords,
302 mainWindow().cmdMediator()->document().documentAxesPointsRequired());
303}
CheckerMode
Options for axes checker mode. Specifically, how long the checker is displayed after a change.
Definition CheckerMode.h:14
@ CHECKER_MODE_NEVER
Definition CheckerMode.h:15
@ CHECKER_MODE_N_SECONDS
Definition CheckerMode.h:16
@ CHECKER_MODE_FOREVER
Definition CheckerMode.h:17
ColorPalette
const int RECT_HEIGHT
const int X_LEFT
const int X_RIGHT
const int RECT_WIDTH
const int AXIS_WIDTH
const int TICKS_PER_AXIS
const int TICK_MARK_LENGTH
const int Y_BOTTOM
const int Y_TOP
const int MINIMUM_HEIGHT
#define ENGAUGE_ASSERT(cond)
Drop in replacement for Q_ASSERT if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS) define ENGAUGE...
#define ENGAUGE_CHECK_PTR(ptr)
#endif
log4cpp::Category * mainCat
Definition Logger.cpp:14
Box shape that is drawn through the three axis points, to temporarily (usually) or permanently (rarel...
Definition Checker.h:34
void prepareForDisplay(const QPolygonF &polygon, int pointRadius, const DocumentModelAxesChecker &modelAxesChecker, const DocumentModelCoords &modelCoords, DocumentAxesPointsRequired documentAxesPointsRequired)
Create the polygon from current information, including pixel coordinates, just prior to display.
Definition Checker.cpp:135
Command queue stack.
Definition CmdMediator.h:24
Document & document()
Provide the Document to commands, primarily for undo/redo processing.
Command for DlgSettingsAxesChecker.
Abstract base class for all Settings dialogs.
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 populateColorComboWithoutTransparent(QComboBox &combo)
Add colors in color palette to combobox, without transparent entry at end.
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.
virtual void handleOk()
Process slotOk.
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
virtual void createOptionalSaveDefault(QHBoxLayout *layout)
Let subclass define an optional Save As Default button.
DlgSettingsAxesChecker(MainWindow &mainWindow)
Single constructor.
virtual void setSmallDialogs(bool smallDialogs)
If false then dialogs have a minimum size so all controls are visible.
virtual QWidget * createSubPanel()
Create dialog-specific panel to which base class will add Ok and Cancel buttons.
Model for DlgSettingsAxesChecker and CmdSettingsAxesChecker.
void setLineColor(ColorPalette lineColor)
Set method for line color.
ColorPalette lineColor() const
Get method for line color.
int checkerSeconds() const
Get method for checker lifetime in seconds.
void setCheckerSeconds(int seconds)
Set method for checker lifetime in seconds.
CheckerMode checkerMode() const
Get method for checker lifetime mode.
void setCheckerMode(CheckerMode checkerMode)
Set method for checker mode.
Model for DlgSettingsCoords and CmdSettingsCoords.
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Definition MainWindow.h:92
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