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