Engauge Digitizer 2
Loading...
Searching...
No Matches
DigitizeStateScale.cpp
Go to the documentation of this file.
1/******************************************************************************************************
2 * (C) 2017 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 "CmdAddScale.h"
8#include "CmdMediator.h"
9#include "CursorFactory.h"
10#include "DigitizeStateScale.h"
12#include "DlgEditScale.h"
13#include "Document.h"
14#include "EngaugeAssert.h"
15#include "GraphicsPoint.h"
16#include "GraphicsScene.h"
17#include "GraphicsView.h"
18#include "Logger.h"
19#include "MainWindow.h"
20#include "PointStyle.h"
21#include <QCursor>
22#include <QGraphicsLineItem>
23#include <QMessageBox>
24#include "QtToString.h"
25#include "ZValues.h"
26
29 m_temporaryPoint0 (nullptr),
30 m_temporaryPoint1 (nullptr),
31 m_line (nullptr)
32{
33}
34
38
40{
41 return AXIS_CURVE_NAME;
42}
43
45 DigitizeState /* previousState */)
46{
47 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateScale::begin";
48
49 setCursor(cmdMediator);
50 context().setDragMode(QGraphicsView::NoDrag);
53}
54
55bool DigitizeStateScale::canPaste (const Transformation & /* transformation */,
56 const QSize & /* viewSize */) const
57{
58 return false;
59}
60
61QCursor DigitizeStateScale::cursor(CmdMediator *cmdMediator) const
62{
63 LOG4CPP_DEBUG_S ((*mainCat)) << "DigitizeStateScale::cursor";
64
65 CursorFactory cursorFactory;
66 QCursor cursor = cursorFactory.generate (cmdMediator->document().modelDigitizeCurve());
67
68 return cursor;
69}
70
72{
73 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateScale::end";
74}
75
77{
78 return false;
79}
80
82 const QString &pointIdentifier)
83{
84 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateScale::handleContextMenuEventAxis "
85 << " point=" << pointIdentifier.toLatin1 ().data ();
86}
87
89 const QStringList &pointIdentifiers)
90{
91 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateScale::handleContextMenuEventGraph "
92 << "points=" << pointIdentifiers.join(",").toLatin1 ().data ();
93}
94
96{
97 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateScale::handleCurveChange";
98}
99
101 Qt::Key key,
102 bool /* atLeastOneSelectedItem */)
103{
104 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateScale::handleKeyPress"
105 << " key=" << QKeySequence (key).toString ().toLatin1 ().data ();
106}
107
109 QPointF posScreen)
110{
111 if (m_temporaryPoint1 != nullptr) {
112
113 LOG4CPP_DEBUG_S ((*mainCat)) << "DigitizeStateScale::handleMouseMove"
114 << " oldPos=" << QPointFToString (m_temporaryPoint1->pos ()).toLatin1().data()
115 << " newPos=" << QPointFToString (posScreen).toLatin1().data();
116
117 m_temporaryPoint1->setPos (posScreen);
118
119 updateLineGeometry();
120 }
121}
122
124 QPointF posScreen)
125{
126 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateScale::handleMousePress";
127
128 GeometryWindow *NULL_GEOMETRY_WINDOW = nullptr;
129
130 // Create the scale bar to give the user immediate feedback that something was created
131 const Curve &curveAxes = cmdMediator->curveAxes();
132 PointStyle pointStyleAxes = curveAxes.curveStyle().pointStyle();
133 m_pointIdentifier0 = Point::temporaryPointIdentifier();
134 m_pointIdentifier1 = m_pointIdentifier0 + "b";
135 m_temporaryPoint0 = context().mainWindow().scene().createPoint(m_pointIdentifier0,
136 pointStyleAxes,
137 posScreen,
138 NULL_GEOMETRY_WINDOW);
139 m_temporaryPoint1 = context().mainWindow().scene().createPoint(m_pointIdentifier1,
140 pointStyleAxes,
141 posScreen,
142 NULL_GEOMETRY_WINDOW);
143
144 // Subtle stuff happening here. GraphicsPoints by default can receive focus for clicking/dragging,
145 // but for some reason that was causing the dragged second endpoint to jump to the origin the Nth
146 // time that a scale bar was created, for every N>1. So we make the endpoint passive and update
147 // its position manually in handleMouseMove
148 m_temporaryPoint0->setPassive ();
149 m_temporaryPoint1->setPassive ();
150
151 context().mainWindow().scene().addTemporaryScaleBar (m_temporaryPoint0,
152 m_temporaryPoint1,
153 m_pointIdentifier0,
154 m_pointIdentifier1);
155
156 m_line = new QGraphicsLineItem;
157 context().mainWindow().scene().addItem (m_line);
158 m_line->setPen (QColor (Qt::red));
159 m_line->setZValue (Z_VALUE_CURVE);
160 m_line->setVisible (true);
161
162 updateLineGeometry ();
163
164 // Attempts to select an endpoint right here, or after an super short timer interval
165 // failed. That would have been nice for having the click create the scale bar and, while
166 // the mouse was still pressed, selecting an endpoint thus allowing a single click-and-drag to
167 // create the scale bar. We fall back to the less elegant solution (which the user will never
168 // notice) of capturing mouse move events and using those to move an endpoint
169}
170
172 QPointF /* posScreen */)
173{
174 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateScale::handleMouseRelease";
175
176 if (context().mainWindow().transformIsDefined()) {
177
178 QMessageBox::warning (nullptr,
179 QObject::tr ("Engauge Digitizer"),
180 QObject::tr ("The scale bar has been defined, and another is not needed or allowed."));
181
182 removeTemporaryPointsAndLine ();
183
184 } else {
185
186 // Ask user for coordinates
187 DlgEditScale *dlg = new DlgEditScale (context ().mainWindow (),
188 cmdMediator->document().modelCoords(),
189 cmdMediator->document().modelGeneral(),
190 context().mainWindow().modelMainWindow());
191 int rtn = dlg->exec ();
192
193 double scaleLength = dlg->scaleLength ();
194 QPointF posScreen0 = m_temporaryPoint0->pos ();
195 QPointF posScreen1 = m_temporaryPoint1->pos ();
196 delete dlg;
197
198 removeTemporaryPointsAndLine ();
199
200 if (rtn == QDialog::Accepted) {
201
202 // User wants to add this scale point. There are no additional sanity checks to run
203
204 int nextOrdinal0 = cmdMediator->document().nextOrdinalForCurve(AXIS_CURVE_NAME);
205 int nextOrdinal1 = nextOrdinal0 + 1;
206
207 // Create command to add point
208 Document &document = cmdMediator->document ();
209 QUndoCommand *cmd = new CmdAddScale (context ().mainWindow(),
210 document,
211 posScreen0,
212 posScreen1,
213 scaleLength,
214 nextOrdinal0,
215 nextOrdinal1);
216 context().appendNewCmd(cmdMediator,
217 cmd);
218 }
219 }
220}
221
222void DigitizeStateScale::removeTemporaryPointsAndLine ()
223{
224 context().mainWindow().scene().removePoint (m_pointIdentifier0); // Deallocates GraphicsPoint automatically
225 context().mainWindow().scene().removePoint (m_pointIdentifier1); // Deallocates GraphicsPoint automaticall
226 context().mainWindow().scene().removeItem (m_line);
227 delete m_line;
228 m_temporaryPoint0 = nullptr;
229 m_temporaryPoint1 = nullptr;
230 m_line = nullptr;
231}
232
234{
235 return "DigitizeStateScale";
236}
237
239{
240 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateScale::updateAfterPointAddition";
241}
242
243void DigitizeStateScale::updateLineGeometry ()
244{
245 m_line->setLine (m_temporaryPoint0->pos ().x (),
246 m_temporaryPoint0->pos ().y (),
247 m_temporaryPoint1->pos ().x (),
248 m_temporaryPoint1->pos ().y ());
249}
250
252 const DocumentModelDigitizeCurve & /*modelDigitizeCurve */)
253{
254 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateScale::updateModelDigitizeCurve";
255
256 setCursor(cmdMediator);
257}
258
260{
261 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateScale::updateModelSegments";
262}
const QString AXIS_CURVE_NAME
DigitizeState
Set of possible states of Digitize toolbar.
log4cpp::Category * mainCat
Definition Logger.cpp:14
QString QPointFToString(const QPointF &pos)
const int Z_VALUE_CURVE
Definition ZValues.cpp:10
Command for adding one scale point.
Definition CmdAddScale.h:17
Command queue stack.
Definition CmdMediator.h:24
const Curve & curveAxes() const
See Document::curveAxes.
Document & document()
Provide the Document to commands, primarily for undo/redo processing.
Create standard cross cursor, or custom cursor, according to settings.
QCursor generate(const DocumentModelDigitizeCurve &modelDigitizeCurve) const
Factory method to generate standard or custom cursor.
PointStyle pointStyle() const
Get method for PointStyle.
Container for one set of digitized Points.
Definition Curve.h:34
CurveStyle curveStyle() const
Return the curve style.
Definition Curve.cpp:149
DigitizeStateAbstractBase(DigitizeStateContext &context)
Single constructor.
DigitizeStateContext & context()
Reference to the DigitizeStateContext that contains all the DigitizeStateAbstractBase subclasses,...
void setCursor(CmdMediator *cmdMediator)
Update the cursor according to the current state.
Container for all DigitizeStateAbstractBase subclasses. This functions as the context class in a stan...
void setDragMode(QGraphicsView::DragMode dragMode)
Set QGraphicsView drag mode (in m_view). Called from DigitizeStateAbstractBase subclasses.
void appendNewCmd(CmdMediator *cmdMediator, QUndoCommand *cmd)
Append just-created QUndoCommand to command stack. This is called from DigitizeStateAbstractBase subc...
MainWindow & mainWindow()
Reference to the MainWindow, without const.
virtual bool guidelinesAreSelectable() const
Enable/disable guidelines according to state.
virtual void handleCurveChange(CmdMediator *cmdMediator)
Handle the selection of a new curve. At a minimum, DigitizeStateSegment will generate a new set of Se...
virtual void handleContextMenuEventAxis(CmdMediator *cmdMediator, const QString &pointIdentifier)
Handle a right click, on an axis point, that was intercepted earlier.
virtual void begin(CmdMediator *cmdMediator, DigitizeState previousState)
Method that is called at the exact moment a state is entered.
virtual void end()
Method that is called at the exact moment a state is exited. Typically called just before begin for t...
virtual void handleContextMenuEventGraph(CmdMediator *cmdMediator, const QStringList &pointIdentifiers)
Handle a right click, on a graph point, that was intercepted earlier.
virtual QString activeCurve() const
Name of the active Curve. This can include AXIS_CURVE_NAME.
virtual void handleMouseRelease(CmdMediator *cmdMediator, QPointF posScreen)
Handle a mouse release that was intercepted earlier.
virtual void updateAfterPointAddition()
Update graphics attributes after possible new points. This is useful for highlight opacity.
virtual bool canPaste(const Transformation &transformation, const QSize &viewSize) const
Return true if there is good data in the clipboard for pasting, and that is compatible with the curre...
virtual void updateModelSegments(const DocumentModelSegments &modelSegments)
Update the segments given the new settings.
virtual void handleMouseMove(CmdMediator *cmdMediator, QPointF posScreen)
Handle a mouse move. This is part of an experiment to see if augmenting the cursor in Point Match mod...
virtual void updateModelDigitizeCurve(CmdMediator *cmdMediator, const DocumentModelDigitizeCurve &modelDigitizeCurve)
Update the digitize curve settings.
virtual QCursor cursor(CmdMediator *cmdMediator) const
Returns the state-specific cursor shape.
DigitizeStateScale(DigitizeStateContext &context)
Single constructor.
virtual void handleMousePress(CmdMediator *cmdMediator, QPointF posScreen)
Handle a mouse press that was intercepted earlier.
virtual void handleKeyPress(CmdMediator *cmdMediator, Qt::Key key, bool atLeastOneSelectedItem)
Handle a key press that was intercepted earlier.
virtual QString state() const
State name for debugging.
Dialog box for editing the information of the map scale.
double scaleLength() const
Return the scale bar length specified by the user. Only applies if dialog was accepted.
Model for DlgSettingsDigitizeCurve and CmdSettingsDigitizeCurve.
Model for DlgSettingsSegments and CmdSettingsSegments.
Storage of one imported image and the data attached to that image.
Definition Document.h:44
DocumentModelGeneral modelGeneral() const
Get method for DocumentModelGeneral.
Definition Document.cpp:735
DocumentModelDigitizeCurve modelDigitizeCurve() const
Get method for DocumentModelDigitizeCurve.
Definition Document.cpp:721
int nextOrdinalForCurve(const QString &curveName) const
Default next ordinal value for specified curve.
Definition Document.cpp:791
DocumentModelCoords modelCoords() const
Get method for DocumentModelCoords.
Definition Document.cpp:707
Window that displays the geometry information, as a table, for the current curve.
QPointF pos() const
Proxy method for QGraphicsItem::pos.
void setPassive()
Prevent automatic focus on point (=make it passive) for scale bar so drags can be made to work proper...
GraphicsPoint * createPoint(const QString &identifier, const PointStyle &pointStyle, const QPointF &posScreen, GeometryWindow *geometryWindow)
Create one QGraphicsItem-based object that represents one Point. It is NOT added to m_graphicsLinesFo...
void addTemporaryScaleBar(GraphicsPoint *point0, GraphicsPoint *point1, const QString &pointIdentifier0, const QString &pointIdentifier1)
Add temporary scale bar to scene.
void removePoint(const QString &identifier)
Remove specified point. This aborts if the point does not exist.
void updateViewsOfSettings(const QString &activeCurve)
Update curve-specific view of settings. Private version gets active curve name from DigitizeStateCont...
void handleGuidelinesActiveChange(bool active)
Handle Guidelines active status toggle.
GraphicsScene & scene()
Scene container for the QImage and QGraphicsItems.
Details for a specific Point.
Definition PointStyle.h:21
static QString temporaryPointIdentifier()
Point identifier for temporary point that is used by DigitzeStateAxis.
Definition Point.cpp:519
Affine transformation between screen and graph coordinates, based on digitized axis points.
#define LOG4CPP_INFO_S(logger)
Definition convenience.h:18
#define LOG4CPP_DEBUG_S(logger)
Definition convenience.h:20