Engauge Digitizer  2
DigitizeStateSelect.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 "CmdMoveBy.h"
9 #include "DataKey.h"
10 #include "DigitizeStateContext.h"
11 #include "DigitizeStateSelect.h"
12 #include "EngaugeAssert.h"
13 #include "GraphicsItemType.h"
14 #include "GraphicsScene.h"
15 #include "GraphicsView.h"
16 #include "Logger.h"
17 #include "MainWindow.h"
18 #include <QCursor>
19 #include <QGraphicsItem>
20 #include <QImage>
21 #include <QObject>
22 #include <QtToString.h>
23 
24 const QString MOVE_TEXT_DOWN (QObject::tr ("Move down"));
25 const QString MOVE_TEXT_LEFT (QObject::tr ("Move left"));
26 const QString MOVE_TEXT_RIGHT (QObject::tr ("Move right"));
27 const QString MOVE_TEXT_UP (QObject::tr ("Move up"));
28 
31 {
32 }
33 
34 DigitizeStateSelect::~DigitizeStateSelect ()
35 {
36 }
37 
39 {
41 }
42 
44  DigitizeState /* previousState */)
45 {
46  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateSelect::begin";
47 
48  setCursor(cmdMediator);
49  context().setDragMode(QGraphicsView::RubberBandDrag);
50 
51  setCursorForPoints ();
53 }
54 
55 QCursor DigitizeStateSelect::cursor(CmdMediator * /* cmdMediator */) const
56 {
57  LOG4CPP_DEBUG_S ((*mainCat)) << "DigitizeStateSelect::cursor";
58 
59  return QCursor (Qt::ArrowCursor);
60 }
61 
63 {
64  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateSelect::end";
65 
66  unsetCursorForPoints ();
67 }
68 
70 {
71  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateSelect::handleCurveChange";
72 }
73 
75  Qt::Key key,
76  bool atLeastOneSelectedItem)
77 {
78  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateSelect::handleKeyPress"
79  << " key=" << QKeySequence (key).toString ().toLatin1 ().data ();
80 
81  if (atLeastOneSelectedItem) {
82 
83  if (key == Qt::Key_Down ||
84  key == Qt::Key_Up ||
85  key == Qt::Key_Left ||
86  key == Qt::Key_Right) {
87 
88  keyPressArrow (cmdMediator,
89  key);
90 
91  }
92  }
93 }
94 
96  QPointF /* posScreen */)
97 {
98 // LOG4CPP_DEBUG_S ((*mainCat)) << "DigitizeStateSelect::handleMouseMove";
99 }
100 
102  QPointF posScreen)
103 {
104  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateSelect::handleMousePress"
105  << " posScreen=" << QPointFToString (posScreen).toLatin1 ().data ();
106 
107  // Note that GraphicsView has already called GraphicsPointAbstract::resetPositionHasChanged on all items
108 
109  m_movingStart = posScreen;
110 }
111 
113  QPointF posScreen)
114 {
115  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateSelect::handleMouseRelease"
116  << " posScreen=" << QPointFToString (posScreen).toLatin1 ().data ();
117 
118  QPointF deltaScreen = posScreen - m_movingStart;
119  QStringList positionHasChangedIdentifers = context().mainWindow().scene().positionHasChangedPointIdentifiers();
120 
121  bool positionHasChanged = (positionHasChangedIdentifers.count () > 0);
122 
123  if (positionHasChanged && (
124  deltaScreen.x () != 0 ||
125  deltaScreen.y () != 0)) {
126 
127  QString moveText = moveTextFromDeltaScreen (deltaScreen);
128 
129  // Create command to move points
130  CmdMoveBy *cmd = new CmdMoveBy (context().mainWindow(),
131  cmdMediator->document(),
132  deltaScreen,
133  moveText,
134  positionHasChangedIdentifers);
135  context().appendNewCmd (cmdMediator,
136  cmd);
137 
138  } else {
139 
140  // Selection probably changed so update the MainWindow controls (especially Cut)
142 
143  }
144 }
145 
146 void DigitizeStateSelect::keyPressArrow (CmdMediator *cmdMediator,
147  Qt::Key key)
148 {
149  QPointF deltaScreen;
150  QString moveText;
151  switch (key) {
152  case Qt::Key_Down:
153  deltaScreen = QPointF (0, zoomedToUnzoomedScreenY ());
154  moveText = MOVE_TEXT_DOWN;
155  break;
156 
157  case Qt::Key_Left:
158  deltaScreen = QPointF (-1 * zoomedToUnzoomedScreenX (), 0);
159  moveText = MOVE_TEXT_LEFT;
160  break;
161 
162  case Qt::Key_Right:
163  deltaScreen = QPointF (zoomedToUnzoomedScreenX (), 0);
164  moveText = MOVE_TEXT_RIGHT;
165  break;
166 
167  case Qt::Key_Up:
168  deltaScreen = QPointF (0, -1 * zoomedToUnzoomedScreenY ());
169  moveText = MOVE_TEXT_UP;
170  break;
171 
172  default:
173  ENGAUGE_ASSERT (false);
174  }
175 
176  // Create command to move points
177  CmdMoveBy *cmd = new CmdMoveBy (context().mainWindow(),
178  cmdMediator->document(),
179  deltaScreen,
180  moveText,
182  context().appendNewCmd (cmdMediator,
183  cmd);
184 }
185 
186 QString DigitizeStateSelect::moveTextFromDeltaScreen (const QPointF &deltaScreen)
187 {
188  QString moveText;
189 
190  // x UP x -----> +x
191  // x x |
192  // LEFT x RIGHT |
193  // x x v
194  // x DOWN x +y
195  bool downOrRight = (deltaScreen.y () > -1.0 * deltaScreen.x ());
196  bool upOrRight = (deltaScreen.y () < deltaScreen.x ());
197  if (downOrRight && upOrRight) {
198  moveText = MOVE_TEXT_RIGHT;
199  } else if (downOrRight && !upOrRight) {
200  moveText = MOVE_TEXT_DOWN;
201  } else if (!downOrRight && upOrRight) {
202  moveText = MOVE_TEXT_UP;
203  } else {
204  moveText = MOVE_TEXT_LEFT;
205  }
206 
207  return moveText;
208 }
209 
210 void DigitizeStateSelect::setCursorForPoints()
211 {
212  QCursor cursor (Qt::OpenHandCursor);
213 
214  QList<QGraphicsItem*> items = context().mainWindow().scene().items();
215  QList<QGraphicsItem*>::iterator itr;
216  for (itr = items.begin (); itr != items.end (); itr++) {
217 
218  QGraphicsItem *item = *itr;
219  if (item->data (DATA_KEY_GRAPHICS_ITEM_TYPE) == GRAPHICS_ITEM_TYPE_POINT) {
220  item->setCursor (cursor);
221  }
222  }
223 }
224 
226 {
227  return "DigitizeStateSelect";
228 }
229 
230 void DigitizeStateSelect::unsetCursorForPoints()
231 {
232  QList<QGraphicsItem*> items = context().mainWindow().scene().items();
233  QList<QGraphicsItem*>::iterator itr;
234  for (itr = items.begin (); itr != items.end (); itr++) {
235 
236  QGraphicsItem *item = *itr;
237  if (item->data (DATA_KEY_GRAPHICS_ITEM_TYPE) == GRAPHICS_ITEM_TYPE_POINT) {
238  item->unsetCursor ();
239  }
240  }
241 }
242 
244  const DocumentModelDigitizeCurve & /*modelDigitizeCurve */)
245 {
246  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateSelect::updateModelDigitizeCurve";
247 }
248 
250 {
251  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateSelect::updateModelSegments";
252 }
253 
254 double DigitizeStateSelect::zoomedToUnzoomedScreenX () const
255 {
256  double m11 = context().mainWindow ().view ().transform().m11 ();
257  return 1.0 / m11;
258 }
259 
260 double DigitizeStateSelect::zoomedToUnzoomedScreenY () const
261 {
262  double m22 = context().mainWindow ().view ().transform().m22 ();
263  return 1.0 / m22;
264 }
virtual void handleKeyPress(CmdMediator *cmdMediator, Qt::Key key, bool atLeastOneSelectedItem)
Handle a key press that was intercepted earlier.
virtual QCursor cursor(CmdMediator *cmdMediator) const
Returns the state-specific cursor shape.
void setDragMode(QGraphicsView::DragMode dragMode)
Set QGraphicsView drag mode (in m_view). Called from DigitizeStateAbstractBase subclasses.
virtual void updateModelSegments(const DocumentModelSegments &modelSegments)
Update the segments given the new settings.
void updateAfterMouseRelease()
Call MainWindow::updateControls (which is private) after the very specific case - a mouse press/relea...
QStringList selectedPointIdentifiers() const
Return a list of identifiers for the currently selected points.
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 handleMouseRelease(CmdMediator *cmdMediator, QPointF posScreen)
Handle a mouse release that was intercepted earlier.
void updateViewsOfSettings(const QString &activeCurve)
Update curve-specific view of settings. Private version gets active curve name from DigitizeStateCont...
QString selectedGraphCurve() const
Curve name that is currently selected in m_cmbCurve.
Command for moving all selected Points by a specified translation.
Definition: CmdMoveBy.h:18
virtual void handleMousePress(CmdMediator *cmdMediator, QPointF posScreen)
Handle a mouse press that was intercepted earlier.
Document & document()
Provide the Document to commands, primarily for undo/redo processing.
Definition: CmdMediator.cpp:72
DigitizeStateContext & context()
Reference to the DigitizeStateContext that contains all the DigitizeStateAbstractBase subclasses...
MainWindow & mainWindow()
Reference to the MainWindow, without const.
Model for DlgSettingsDigitizeCurve and CmdSettingsDigitizeCurve.
virtual void begin(CmdMediator *cmdMediator, DigitizeState previousState)
Method that is called at the exact moment a state is entered.
GraphicsView & view()
View for the QImage and QGraphicsItems, without const.
QStringList positionHasChangedPointIdentifiers() const
Return a list of identifiers for the points that have moved since the last call to resetPositionHasCh...
GraphicsScene & scene()
Scene container for the QImage and QGraphicsItems.
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 appendNewCmd(CmdMediator *cmdMediator, QUndoCommand *cmd)
Append just-created QUndoCommand to command stack. This is called from DigitizeStateAbstractBase subc...
virtual QString activeCurve() const
Name of the active Curve. This can include AXIS_CURVE_NAME.
virtual void end()
Method that is called at the exact moment a state is exited. Typically called just before begin for t...
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...
DigitizeStateSelect(DigitizeStateContext &context)
Single constructor.
Command queue stack.
Definition: CmdMediator.h:23
Model for DlgSettingsSegments and CmdSettingsSegments.
Base class for all digitizing states. This serves as an interface to DigitizeStateContext.
virtual QString state() const
State name for debugging.
virtual void updateModelDigitizeCurve(CmdMediator *cmdMediator, const DocumentModelDigitizeCurve &modelDigitizeCurve)
Update the digitize curve settings.