]> Shamusworld >> Repos - architektonas/blob - src/mirroraction.cpp
Mirror tool now works successfully for all object types. :-D
[architektonas] / src / mirroraction.cpp
1 // mirroraction.cpp: Action class for mirroring selected objects
2 //
3 // Part of the Architektonas Project
4 // (C) 2011 Underground Software
5 // See the README and GPLv3 files for licensing and warranty information
6 //
7 // JLH = James Hammons <jlhamm@acm.org>
8 //
9 // WHO  WHEN        WHAT
10 // ---  ----------  ------------------------------------------------------------
11 // JLH  08/27/2011  Created this file
12 //
13
14 #include "mirroraction.h"
15 #include "applicationwindow.h"
16 #include "container.h"
17 #include "drawingview.h"
18 #include "line.h"
19 #include "mathconstants.h"
20 #include "painter.h"
21 //#include "vector.h"
22
23
24 //#define FIRST_POINT 0
25 //#define NEXT_POINT 1
26 enum { FIRST_POINT, NEXT_POINT };
27
28
29 MirrorAction::MirrorAction(): state(FIRST_POINT), line(NULL),
30         shiftWasPressedOnNextPoint(false), mirror(new Container(Vector()))
31 {
32 //      ApplicationWindow::drawing->document.CopySelectedContentsTo(selected);
33         ApplicationWindow::drawing->document.CopySelectedContentsTo(mirror);
34
35 //      for(std::vector<Object *>::iterator i=mirror->objects.begin(); i!=mirror->objects.end(); i++)
36 //              (*i)->Save();
37         mirror->Save();
38 }
39
40
41 MirrorAction::~MirrorAction()
42 {
43 }
44
45
46 /*virtual*/ void MirrorAction::Draw(Painter * painter)
47 {
48         painter->SetPen(QPen(Qt::red, 2.0, Qt::DotLine));
49
50         // I think stuff like crosshairs should be done in the DrawingView, tho
51         // (and it's done there now...)
52         if (state == FIRST_POINT)
53         {
54                 painter->DrawHandle(p1);
55         }
56         else
57         {
58                 Vector reflectedP2 = -(p2 - p1);
59                 Point newP2 = p1 + reflectedP2;
60                 painter->DrawLine(newP2, p2);
61                 painter->DrawHandle(p1);
62
63                 double absAngle = (Vector(p2 - p1).Angle()) * RADIANS_TO_DEGREES;
64
65                 // Keep the angle between 0 and 180 degrees
66                 if (absAngle > 180.0)
67                         absAngle -= 180.0;
68
69                 QString text = QChar(0x2221) + QObject::tr(": %1");
70                 text = text.arg(absAngle);
71 //              QString text = tr("Length: %1 in.");
72 //              text = text.arg(Vector::Magnitude(p1, p2));
73                 painter->DrawInformativeText(text);
74
75                 // Draw the mirror only if there's been a line to mirror around
76                 if (p1 != p2)
77                         mirror->Draw(painter);
78         }
79 }
80
81
82 /*virtual*/ void MirrorAction::MouseDown(Vector point)
83 {
84         // Clear our override...
85         shiftWasPressedOnNextPoint = false;
86
87         if (state == FIRST_POINT)
88                 p1 = point;
89         else
90                 p2 = point;
91 }
92
93
94 /*virtual*/ void MirrorAction::MouseMoved(Vector point)
95 {
96         if (state == FIRST_POINT)
97                 p1 = point;
98         else
99         {
100                 p2 = point;
101
102                 for(std::vector<Object *>::iterator i=mirror->objects.begin(); i!=mirror->objects.end(); i++)
103                 {
104                         (*i)->Restore();
105                         (*i)->Mirror(p1, p2);
106                 }
107         }
108 }
109
110
111 /*virtual*/ void MirrorAction::MouseReleased(void)
112 {
113         if (state == FIRST_POINT)
114         {
115                 p2 = p1;
116                 state = NEXT_POINT;
117         }
118         else if (state == NEXT_POINT)
119         {
120                 state = FIRST_POINT;
121
122                 std::vector<Object *> & objs = ApplicationWindow::drawing->document.objects;
123
124                 for(std::vector<Object *>::iterator i=objs.begin(); i!=objs.end(); i++)
125                 {
126                         if ((*i)->state == OSSelected)
127                                 (*i)->Mirror(p1, p2);
128                 }
129
130                 mirror->Clear();
131                 ApplicationWindow::drawing->document.CopySelectedContentsTo(mirror);
132                 mirror->Save();
133         }
134 }
135
136
137 /*virtual*/ bool MirrorAction::KeyDown(int key)
138 {
139         if ((key == Qt::Key_Shift) && (state == NEXT_POINT))
140         {
141                 shiftWasPressedOnNextPoint = true;
142                 p1Save = p1;
143                 p1 = p2;
144                 state = FIRST_POINT;
145                 return true;
146         }
147
148         return false;
149 }
150
151
152 /*virtual*/ bool MirrorAction::KeyReleased(int key)
153 {
154         if ((key == Qt::Key_Shift) && shiftWasPressedOnNextPoint)
155         {
156                 shiftWasPressedOnNextPoint = false;
157                 p2 = p1;
158                 p1 = p1Save;
159                 state = NEXT_POINT;
160                 return true;
161         }
162
163         return false;
164 }
165