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 #ifndef GUIDELINES_H
8 #define GUIDELINES_H
9 
10 #include "ColorPalette.h"
11 #include "CoordsType.h"
12 #include "GuidelineState.h"
13 #include <QList>
14 #include <QString>
15 #include "Transformation.h"
16 
17 class DocumentModelGuidelines;
18 class GraphicsScene;
19 class GuidelineAbstract;
20 class GuidelineFactory;
21 class MainWindow;
22 class QGraphicsScene;
23 
24 typedef QList<GuidelineAbstract*> GuidelineContainerPrivate;
25 
26 /// This class contains all Guideline objects
27 class Guidelines
28 {
29   /// For unit testing
30   friend class TestGuidelines;
31 
32 public:
33   /// Single constructor.
34   Guidelines(MainWindow &mainWindow);
35   ~Guidelines();
36 
37   /// Remove guidelines since the current Document is about to be closed
38   void clear ();
39 
40   /// Color to be used for guidelines
41   ColorPalette color () const;
42 
43   /// Return cartesian or polar
44   CoordsType coordsType () const;
45 
46   /// Factory method for creating a new Guideline
47   GuidelineAbstract *createGuideline (const QString &identifier,
48                                       GuidelineState stateInitial);
49 
50   /// Factory method for creating a new GUIDELINE_STATE_DEPLOYED_CONSTANT_R_ACTIVE
51   void createGuidelineR (const QString &identifier,
52                          double r);
53 
54   /// Factory method for creating a new GUIDELINE_STATE_DEPLOYED_CONSTANT_R_ACTIVE
55   void createGuidelineR (const QString &identifier,
56                          const QPointF &posScreen);
57 
58   /// Factory method for creating a new GUIDELINE_STATE_DEPLOYED_CONSTANT_T_ACTIVE
59   void createGuidelineT (const QString &identifier,
60                          double t);
61 
62   /// Factory method for creating a new GUIDELINE_STATE_DEPLOYED_CONSTANT_T_ACTIVE
63   void createGuidelineT (const QString &identifier,
64                          const QPointF &posScreen);
65 
66   /// Factory method for creating a new GUIDELINE_STATE_DEPLOYED_CONSTANT_X_ACTIVE
67   void createGuidelineX (const QString &identifier,
68                          double x);
69 
70   /// Factory method for creating a new GUIDELINE_STATE_DEPLOYED_CONSTANT_X_ACTIVE
71   void createGuidelineX (const QString &identifier,
72                          const QPointF &posScreen);
73 
74   /// Factory method for creating a new GUIDELINE_STATE_DEPLOYED_CONSTANT_Y_ACTIVE
75   void createGuidelineY (const QString &identifier,
76                          double y);
77 
78   /// Factory method for creating a new GUIDELINE_STATE_DEPLOYED_CONSTANT_Y_ACTIVE
79   void createGuidelineY (const QString &identifier,
80                          const QPointF &posScreen);
81 
82   /// Factory method for creating a new replacement Guideline, which replaces one
83   /// handle and one visible Guideline after a drag
84   void createReplacementGuideline (const QString &identifierReplaced,
85                                    double newValue,
86                                    GuidelineState guidelineStateForReplacement);
87 
88   /// DigitizeState change so active status may (or may not) be toggled
89   void handleActiveChange (bool active);
90 
91   /// User toggled guideline mode
92   void handleGuidelineMode (bool visible,
93                             bool locked);
94 
95   /// Initialize Guideline factory
96   void initialize (GraphicsScene &scene);
97 
98   /// Return complete set of guidelines information for Document
99   DocumentModelGuidelines modelGuidelines () const;
100 
101   /// Move an X/T guideline from one value to another. Closest value wins
102   void moveGuidelineXT (const QString &identifier,
103                         double valueAfter);
104 
105   /// Move an Y/R guideline from one value to another. Closest value wins
106   void moveGuidelineYR (const QString &identifier,
107                         double valueAfter);
108 
109   /// Remove an X/T or Y/R guideline. Since Guideline identifiers are unique this
110   /// method is not implemented with separate X/T and Y/R versions
111   void removeGuideline (const QString &identifier);
112 
113   /// Load Guidelines from Document
114   void setModelGuidelines (CoordsType coordsType,
115                            const DocumentModelGuidelines &modelGuidelines);
116 
117   /// States listed as a string for debugging only
118   QString stateDump () const;
119 
120   /// Return copy of transformation owned by MainWindow
121   Transformation transformation () const;
122 
123   /// Force a color update
124   void updateColor ();
125 
126   /// Update transformation. This is called after a command has been executed
127   void updateWithLatestTransformation ();
128 
129 private:
130   Guidelines();
131 
132   GuidelineContainerPrivate::iterator findIdentifierXT (const QString &identifier);
133   GuidelineContainerPrivate::iterator findIdentifierYR (const QString &identifier);
134 
135   /// Return read-only reference to X/T and Y/R containers for testing only
136   const GuidelineContainerPrivate &guidelineContainerPrivateXT () const;
137   const GuidelineContainerPrivate &guidelineContainerPrivateYR () const;
138 
139   /// Add a new Guideline to the global list maintained by this class
140   void registerGuidelineXT (GuidelineAbstract *guideline);
141   void registerGuidelineYR (GuidelineAbstract *guideline);
142 
143   GuidelineAbstract *unregisterGuideline (const QString &identifier);
144 
145   // Save for easy removal later
146   GuidelineContainerPrivate m_guidelineContainerXT;
147   GuidelineContainerPrivate m_guidelineContainerYR;
148 
149   MainWindow &m_mainWindow;
150 
151   GuidelineFactory *m_guidelineFactory;
152 };
153 
154 #endif // GUIDELINES_H
155