1 /******************************************************************************************************
2 * (C) 2019 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 "DataKey.h"
8 #include "EngaugeAssert.h"
9 #include "EnumsToQt.h"
10 #include "GraphicsItemType.h"
11 #include "GuidelineAbstract.h"
12 #include "GuidelineAbstract.h"
13 #include "GuidelineFormat.h"
14 #include "Guidelines.h"
15 #include "GuidelineStateContext.h"
16 #include "Logger.h"
17 #include <QGraphicsLineItem>
18 #include <QGraphicsScene>
19 #include <QGraphicsSceneMouseEvent>
20 #include <QLineF>
21 #include <qmath.h>
22 #include <QMouseEvent>
23 #include <QPen>
24 #include <QTextStream>
25 #include <QWidget>
26 #include "Transformation.h"
27 #include "ZValues.h"
28
GuidelineAbstract(QGraphicsScene & scene)29 GuidelineAbstract::GuidelineAbstract(QGraphicsScene &scene) :
30 m_scene (scene),
31 m_context (nullptr),
32 m_guidelineVisible (nullptr)
33 {
34 }
35
~GuidelineAbstract()36 GuidelineAbstract::~GuidelineAbstract ()
37 {
38 delete m_context;
39 }
40
bindGuidelineVisibleToInvisible(GuidelineAbstract * guidelineVisible)41 void GuidelineAbstract::bindGuidelineVisibleToInvisible (GuidelineAbstract *guidelineVisible)
42 {
43 LOG4CPP_INFO_S ((*mainCat)) << "GuidelineAbstract::bindGuidelineVisibleToInvisible";
44
45 m_guidelineVisible = guidelineVisible;
46
47 connect (this, SIGNAL (signalHandleMoved (QPointF)),
48 guidelineVisible, SLOT (slotHandleMoved (QPointF)));
49 }
50
context()51 GuidelineStateContext *GuidelineAbstract::context ()
52 {
53 return m_context;
54 }
55
context() const56 const GuidelineStateContext *GuidelineAbstract::context () const
57 {
58 return m_context;
59 }
60
handleActiveChange(bool active)61 void GuidelineAbstract::handleActiveChange (bool active)
62 {
63 m_context->handleActiveChange (active);
64 }
65
handleGuidelineMode(bool visible,bool locked)66 void GuidelineAbstract::handleGuidelineMode (bool visible,
67 bool locked)
68 {
69 m_context->handleGuidelineMode (visible,
70 locked);
71 }
72
handleHoverEnterEvent()73 void GuidelineAbstract::handleHoverEnterEvent()
74 {
75 m_context->handleHoverEnterEvent ();
76 }
77
handleHoverLeaveEvent()78 void GuidelineAbstract::handleHoverLeaveEvent()
79 {
80 m_context->handleHoverLeaveEvent ();
81 }
82
handleMouseMoveEvent(const QPointF & posScene)83 void GuidelineAbstract::handleMouseMoveEvent (const QPointF &posScene)
84 {
85 LOG4CPP_INFO_S ((*mainCat)) << "GuidelineAbstract::handleMouseMoveEvent ("
86 << posScene.x() << ", " << posScene.y() << ")";
87
88 // Skip if there is no bound visible Guideline
89 if (m_guidelineVisible != nullptr) {
90
91 emit signalHandleMoved (posScene);
92 }
93 }
94
handleMousePressEvent(const QPointF & posScene)95 void GuidelineAbstract::handleMousePressEvent(const QPointF &posScene)
96 {
97 LOG4CPP_DEBUG_S ((*mainCat)) << "GuidelineAbstract::handleMousePressEvent";
98
99 m_context->handleMousePress(posScene);
100 }
101
handleMouseReleaseEvent(const QPointF & posScene)102 void GuidelineAbstract::handleMouseReleaseEvent (const QPointF &posScene)
103 {
104 LOG4CPP_DEBUG_S ((*mainCat)) << "GuidelineAbstract::handleMouseReleaseEvent";
105
106 m_context->handleMouseRelease (posScene);
107 }
108
sacrificeHandleAndVisibleGuidelines(const QPointF & posScene,GuidelineState guidelineStateForReplacement)109 void GuidelineAbstract::sacrificeHandleAndVisibleGuidelines (const QPointF &posScene,
110 GuidelineState guidelineStateForReplacement)
111 {
112 LOG4CPP_DEBUG_S ((*mainCat)) << "GuidelineAbstract::sacrificeHandleAndVisibleGuidelines"
113 << " keeping identifier=" << identifier().toLatin1().data()
114 << " in " << stateName ().toLatin1().data();
115
116 if (m_guidelineVisible != nullptr) {
117
118 // If scene position is off-screen then user is removing the visible Guideline
119 bool offscreen = !m_scene.sceneRect().contains (posScene);
120
121 // Remove transient Guideline, which was never registered with Guidelines
122 LOG4CPP_DEBUG_S ((*mainCat)) << "GuidelineAbstract::sacrificeHandleAndVisibleGuidelines identifierDeleting="
123 << m_guidelineVisible->identifier().toLatin1().data();
124 disconnect (this, SIGNAL (signalHandleMoved (QPointF)),
125 m_guidelineVisible, SLOT (slotHandleMoved (QPointF)));
126 m_guidelineVisible->removeFromScene (&m_scene);
127 delete m_guidelineVisible;
128 m_guidelineVisible = nullptr;
129
130 // Update Guideline value from cursor position
131 double value = context()->convertScreenPointToGraphCoordinate (posScene);
132
133 emit signalGuidelineDragged(identifier (),
134 value,
135 offscreen,
136 guidelineStateForReplacement);
137 }
138 }
139
scene()140 QGraphicsScene &GuidelineAbstract::scene ()
141 {
142 return m_scene;
143 }
144
posCursorGraph() const145 QPointF GuidelineAbstract::posCursorGraph () const
146 {
147 return m_context->posCursorGraph ();
148 }
149
setContext(GuidelineStateContext * context)150 void GuidelineAbstract::setContext (GuidelineStateContext *context)
151 {
152 m_context = context;
153 }
154
slotHandleMoved(QPointF posScreen)155 void GuidelineAbstract::slotHandleMoved (QPointF posScreen)
156 {
157 // Update geometry
158 updateGeometry (posScreen);
159 }
160
stateDump() const161 QString GuidelineAbstract::stateDump () const
162 {
163 // This is used by Guidelines::stateDump and GuidelineStateContext::stateDump
164 QString out;
165 QTextStream str (&out);
166
167 str << " " << m_context->stateName ();
168 str << " (";
169 str << (getGraphicsItemSelected() ? "selected" : "unselected") << " ";
170 str << (getGraphicsItemAcceptHover() ? "hoverable" : "unhoverable") << " ";
171 str << ((graphicsItemFlags () & QGraphicsItem::ItemIsFocusable ) != 0 ? "focusable" : "unfocusable") << " ";
172 str << ((graphicsItemFlags () & QGraphicsItem::ItemIsMovable ) != 0 ? "movable" : "unmovable") << " ";
173 str << ((graphicsItemFlags () & QGraphicsItem::ItemIsSelectable) != 0 ? "selectable" : "unselectable") << " ";
174 str << ")";
175
176 return out;
177 }
178
stateName() const179 QString GuidelineAbstract::stateName () const
180 {
181 return m_context->stateName ();
182 }
183
updateWithLatestTransformation()184 void GuidelineAbstract::updateWithLatestTransformation ()
185 {
186 m_context->updateWithLatestTransformation ();
187 }
188