]> Shamusworld >> Repos - architektonas/commitdiff
Added preliminary (i.e., non-functional) trim tool. Also:
authorShamus Hammons <jlhamm@acm.org>
Fri, 14 Feb 2014 19:38:28 +0000 (13:38 -0600)
committerShamus Hammons <jlhamm@acm.org>
Fri, 14 Feb 2014 19:38:28 +0000 (13:38 -0600)
- Bugfix for incorrect mirrored point in Geomtry::Mirror()
- Added miscellaneous missing icons
- Added auto-connect to add lines tool
- Fixed Dimension object to respond to where the dimension line actually is

18 files changed:
architektonas.pro
res/architektonas.qrc
res/block-import.png [new file with mode: 0644]
res/layer-add.png [new file with mode: 0644]
res/layer-delete.png [new file with mode: 0644]
res/layer-down.png [new file with mode: 0644]
res/layer-edit.png [new file with mode: 0644]
res/layer-up.png [new file with mode: 0644]
res/trim-tool.png [new file with mode: 0644]
src/applicationwindow.cpp
src/applicationwindow.h
src/circle.cpp
src/dimension.cpp
src/dimension.h
src/drawlineaction.cpp
src/geometry.cpp
src/trimaction.cpp [new file with mode: 0644]
src/trimaction.h [new file with mode: 0644]

index edea5ee62184d50c40be368896cf63305a98265f..eea6798fbcaa90ced5f0b118a11c9803d86dffb4 100644 (file)
@@ -78,6 +78,7 @@ HEADERS = \
        src/rotateaction.h \
        src/settingsdialog.h \
        src/text.h \
+       src/trimaction.h \
        src/vector.h
 
 SOURCES = \
@@ -112,5 +113,6 @@ SOURCES = \
        src/rotateaction.cpp \
        src/settingsdialog.cpp \
        src/text.cpp \
+       src/trimaction.cpp \
        src/vector.cpp
 
index cf1593b60acce920faa58ab729e3a2f9b42e59e1..602ddae4d8e7bdcce916516cedf101c4f396c359 100644 (file)
@@ -15,6 +15,7 @@
                <file>rotate-tool.png</file>
                <file>snap-to-grid-tool.png</file>
                <file>splash.png</file>
+               <file>trim-tool.png</file>
                <file>quit.png</file>
                <file>zoom-in.png</file>
                <file>zoom-out.png</file>
diff --git a/res/block-import.png b/res/block-import.png
new file mode 100644 (file)
index 0000000..8648f4f
Binary files /dev/null and b/res/block-import.png differ
diff --git a/res/layer-add.png b/res/layer-add.png
new file mode 100644 (file)
index 0000000..40745b5
Binary files /dev/null and b/res/layer-add.png differ
diff --git a/res/layer-delete.png b/res/layer-delete.png
new file mode 100644 (file)
index 0000000..43369c2
Binary files /dev/null and b/res/layer-delete.png differ
diff --git a/res/layer-down.png b/res/layer-down.png
new file mode 100644 (file)
index 0000000..04d9219
Binary files /dev/null and b/res/layer-down.png differ
diff --git a/res/layer-edit.png b/res/layer-edit.png
new file mode 100644 (file)
index 0000000..105cb5d
Binary files /dev/null and b/res/layer-edit.png differ
diff --git a/res/layer-up.png b/res/layer-up.png
new file mode 100644 (file)
index 0000000..1891222
Binary files /dev/null and b/res/layer-up.png differ
diff --git a/res/trim-tool.png b/res/trim-tool.png
new file mode 100644 (file)
index 0000000..4f80fbd
Binary files /dev/null and b/res/trim-tool.png differ
index 5261dd11a2488037d601f1b0e44e836edb51f16f..4f1be35d14a453acfdf3d6b082cf6b0360873d65 100644 (file)
@@ -45,6 +45,7 @@
 #include "painter.h"
 #include "rotateaction.h"
 #include "settingsdialog.h"
+#include "trimaction.h"
 
 
 // Class variables
@@ -267,6 +268,13 @@ void ApplicationWindow::MirrorTool(void)
 }
 
 
+void ApplicationWindow::TrimTool(void)
+{
+       ClearUIToolStatesExcept(trimAct);
+       SetInternalToolStates();
+}
+
+
 void ApplicationWindow::AddLineTool(void)
 {
        ClearUIToolStatesExcept(addLineAct);
@@ -397,6 +405,9 @@ void ApplicationWindow::ClearUIToolStatesExcept(QAction * exception)
 
        if (exception != mirrorAct)
                mirrorAct->setChecked(false);
+
+       if (exception != trimAct)
+               trimAct->setChecked(false);
 }
 
 
@@ -421,6 +432,7 @@ void ApplicationWindow::SetInternalToolStates(void)
        drawing->SetToolActive(addDimensionAct->isChecked() ? new DrawDimensionAction() : NULL);
        drawing->SetToolActive(mirrorAct->isChecked() ? new MirrorAction() : NULL);
        drawing->SetToolActive(rotateAct->isChecked() ? new RotateAction() : NULL);
+       drawing->SetToolActive(trimAct->isChecked() ? new TrimAction() : NULL);
 
        if (drawing->toolAction)
                Object::ignoreClicks = true;
@@ -700,6 +712,9 @@ void ApplicationWindow::CreateActions(void)
        mirrorAct = CreateAction(tr("&Mirror"), tr("Mirror"), tr("Mirror selected objects around a line."), QIcon(":/res/mirror-tool.png"), QKeySequence("m,i"), true);
        connect(mirrorAct, SIGNAL(triggered()), this, SLOT(MirrorTool()));
 
+       trimAct = CreateAction(tr("&Trim"), tr("Trim"), tr("Trim extraneous lines from selected objects."), QIcon(":/res/trim-tool.png"), QKeySequence("t,r"), true);
+       connect(trimAct, SIGNAL(triggered()), this, SLOT(TrimTool()));
+
 
 //Hm. I think we'll have to have separate logic to do the "Radio Group Toolbar" thing...
 // Yup, in order to turn them off, we'd have to have an "OFF" toolbar button. Ick.
@@ -770,6 +785,7 @@ void ApplicationWindow::CreateMenus(void)
        menu->addAction(fixLengthAct);
        menu->addAction(rotateAct);
        menu->addAction(mirrorAct);
+       menu->addAction(trimAct);
        menu->addAction(connectAct);
        menu->addAction(disconnectAct);
        menu->addSeparator();
@@ -818,6 +834,7 @@ void ApplicationWindow::CreateToolbars(void)
        toolbar->addAction(fixLengthAct);
        toolbar->addAction(rotateAct);
        toolbar->addAction(mirrorAct);
+       toolbar->addAction(trimAct);
        toolbar->addAction(deleteAct);
        toolbar->addAction(connectAct);
        toolbar->addAction(disconnectAct);
index cf252477f01286072ed7928d2464844d522eaf60..089ab8f28010983f7174b5fbaa134c50dd0b488f 100644 (file)
@@ -34,6 +34,7 @@ class ApplicationWindow: public QMainWindow
                void DimensionTool(void);
                void RotateTool(void);
                void MirrorTool(void);
+               void TrimTool(void);
                void AddLineTool(void);
                void AddCircleTool(void);
                void AddArcTool(void);
@@ -94,6 +95,7 @@ class ApplicationWindow: public QMainWindow
                QAction * connectAct;
                QAction * disconnectAct;
                QAction * mirrorAct;
+               QAction * trimAct;
 
        // Class variables
        public:
index d8a2e5d61bda7faa31c349546a7b94c79d0771c1..88cdaa714684be3272265a3ffaae7c08f1d6dc70 100644 (file)
@@ -253,7 +253,6 @@ same reference number.
 /*virtual*/ void Circle::Mirror(Point p1, Point p2)
 {
        Point c1 = Geometry::MirrorPointAroundLine(position, p1, p2);
-//     return new Circle(c1, radius);
        position = c1;
 }
 
index 7c4488d05bacbf27c4825b21d28a132a116846c0..01d7ec3d9d1e601f6312b8172b977ba92539bc3e 100644 (file)
@@ -73,33 +73,33 @@ all objects move as a unified whole.
        double angle = v.Angle();
        Vector orthogonal = Vector::Normal(position, endpoint);
        Vector unit = v.Unit();
+       linePt1 = position, linePt2 = endpoint;
 
 // Horizontally aligned display
 #if 1
-       Vector pos = position, endp = endpoint, ortho;
-       double y1, y2;
+       Vector /*pos = position, endp = endpoint,*/ ortho;
+       double y1;
 
        if ((angle < PI_OVER_2) || (angle > PI3_OVER_2))
        {
-               y1 = (pos.y > endp.y ? pos.y : endp.y);
-               y2 = (pos.y > endp.y ? endp.y : pos.y);
+               y1 = (position.y > endpoint.y ? position.y : endpoint.y);
                ortho = Vector(0, 1.0);
                angle = 0;
        }
        else
        {
-               y1 = (pos.y > endp.y ? endp.y : pos.y);
-               y2 = (pos.y > endp.y ? pos.y : endp.y);
+               y1 = (position.y > endpoint.y ? endpoint.y : position.y);
                ortho = Vector(0, -1.0);
                angle = PI;
        }
 
-       pos.y = endp.y = y1;
-       unit = Vector(pos, endp).Unit();
-       Point p1 = pos + (ortho * 10.0 * size);
-       Point p2 = endp + (ortho * 10.0 * size);
-       Point p3 = pos + (ortho * 16.0 * size);
-       Point p4 = endp + (ortho * 16.0 * size);
+//     pos.y = endp.y = y1;
+       linePt1.y = linePt2.y = y1;
+       unit = Vector(linePt1, linePt2).Unit();
+       Point p1 = linePt1 + (ortho * 10.0 * size);
+       Point p2 = linePt2 + (ortho * 10.0 * size);
+       Point p3 = linePt1 + (ortho * 16.0 * size);
+       Point p4 = linePt2 + (ortho * 16.0 * size);
        Point p5 = position + (ortho * 4.0 * size);
        Point p6 = endpoint + (ortho * 4.0 * size);
 #endif
@@ -124,7 +124,8 @@ I believe they are pixels.
        // Calculate whether or not the arrowheads are too crowded to put inside
        // the extension lines. 9.0 is the length of the arrowhead.
 //     double t = Geometry::ParameterOfLineAndPoint(position, endpoint, endpoint - (unit * 9.0 * size));
-       double t = Geometry::ParameterOfLineAndPoint(pos, endp, endp - (unit * 9.0 * size));
+//     double t = Geometry::ParameterOfLineAndPoint(pos, endp, endp - (unit * 9.0 * size));
+       double t = Geometry::ParameterOfLineAndPoint(linePt1, linePt2, linePt2 - (unit * 9.0 * size));
 //printf("Dimension::Draw(): t = %lf\n", t);
 
 // On the screen, it's acting like this is actually 58%...
@@ -326,8 +327,13 @@ about keeping track of old states...
 {
        Vector orthogonal = Vector::Normal(position, endpoint);
        // Get our line parallel to our points
+#if 0
        Point p1 = position + (orthogonal * 10.0 * size);
        Point p2 = endpoint + (orthogonal * 10.0 * size);
+#else
+       Point p1 = linePt1 + (orthogonal * 10.0 * size);
+       Point p2 = linePt2 + (orthogonal * 10.0 * size);
+#endif
        Point p3(p1, point);
 
        hitPoint1 = hitPoint2 = hitLine = hitFlipSwitch = false;
index c3709b61bbaf24da3fa23aa78a273ba3a399ec7f..9a9b3d48c024e4e4f35666304f281a4e19492f74 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef __DIMENSION_H__
 #define __DIMENSION_H__
 
-#include "connection.h"
 #include "object.h"
 
 class Line;
@@ -38,6 +37,7 @@ class Dimension: public Object
                Vector endpoint;                                        // Starting point is Object::position
                Vector oldPoint;                                        // Used for dragging
                Point oldEndpoint;
+               Point linePt1, linePt2;                         // Used for testing dimension line hits
 
        private:
                bool dragging;
index 27b9513c04574e395ca22a7273c3b3ed126b003d..5490e9829bcc553fc71fbd8213c402a4b66a74b8 100644 (file)
@@ -80,12 +80,22 @@ DrawLineAction::~DrawLineAction()
        {
                p2 = p1;
                state = NEXT_POINT;
+               line = NULL;
        }
        else if (state == NEXT_POINT)
        {
+               Line * oldLine = line;
                // We create the new object here, and then pass it off to the
                // DrawingView which stuffs it into the document.
                line = new Line(p1, p2);
+
+               // Connect Lines by default
+               if (oldLine)
+               {
+                       oldLine->Connect(line, 0);
+                       line->Connect(oldLine, 1.0);
+               }
+
                // We don't need no stinkin' sentinels, when we have signals & slots!
                emit ObjectReady(line);
 
@@ -103,7 +113,7 @@ DrawLineAction::~DrawLineAction()
                p1Save = p1;
                p1 = p2;
                state = FIRST_POINT;
-               emit(NeedRefresh());
+               emit NeedRefresh();
        }
 }
 
index cfb051101c94498c1e026bacc7a2a58379d7f0ec..41928aa629b7b253798ad19a1a0b73c3b56c19e5 100644 (file)
@@ -62,15 +62,15 @@ double Geometry::ParameterOfLineAndPoint(Point tail, Point head, Point point)
 }
 
 
-Point Geometry::MirrorPointAroundLine(Point point, Point p1, Point p2)
+Point Geometry::MirrorPointAroundLine(Point point, Point tail, Point head)
 {
        // Get the vector of the intersection of the line and the normal on the
        // line to the point in question.
-       double t = ParameterOfLineAndPoint(p1, p2, point);
-       Vector v = Vector(p1, p2) * t;
+       double t = ParameterOfLineAndPoint(tail, head, point);
+       Vector v = Vector(tail, head) * t;
 
-       // Get the point normal to point to the line passed in (p2 is the tail)
-       Point normalOnLine = p2 + v;
+       // Get the point normal to point to the line passed in
+       Point normalOnLine = tail + v;
 
        // Make our mirrored vector (head - tail)
        Vector mirror = -(point - normalOnLine);
diff --git a/src/trimaction.cpp b/src/trimaction.cpp
new file mode 100644 (file)
index 0000000..ea8e9eb
--- /dev/null
@@ -0,0 +1,161 @@
+// TrimAction.cpp: Action class for mirroring selected objects
+//
+// Part of the Architektonas Project
+// (C) 2011 Underground Software
+// See the README and GPLv3 files for licensing and warranty information
+//
+// JLH = James Hammons <jlhamm@acm.org>
+//
+// WHO  WHEN        WHAT
+// ---  ----------  ------------------------------------------------------------
+// JLH  08/27/2011  Created this file
+//
+
+#include "trimaction.h"
+#include "applicationwindow.h"
+#include "container.h"
+#include "drawingview.h"
+#include "line.h"
+#include "mathconstants.h"
+#include "painter.h"
+
+
+enum { FIRST_POINT, NEXT_POINT };
+
+
+TrimAction::TrimAction(): state(FIRST_POINT), line(NULL),
+       shiftWasPressedOnNextPoint(false), ctrlWasPressed(false),
+       mirror(new Container(Vector()))
+{
+       ApplicationWindow::drawing->document.CopySelectedContentsTo(mirror);
+       mirror->Save();
+}
+
+
+TrimAction::~TrimAction()
+{
+}
+
+
+/*virtual*/ void TrimAction::Draw(Painter * painter)
+{
+       painter->SetPen(QPen(Qt::red, 2.0, Qt::DotLine));
+
+       if (state == FIRST_POINT)
+       {
+               painter->DrawHandle(p1);
+       }
+       else
+       {
+               Vector reflectedP2 = -(p2 - p1);
+               Point newP2 = p1 + reflectedP2;
+               painter->DrawLine(newP2, p2);
+               painter->DrawHandle(p1);
+
+               double absAngle = (Vector(p2 - p1).Angle()) * RADIANS_TO_DEGREES;
+
+               // Keep the angle between 0 and 180 degrees
+               if (absAngle > 180.0)
+                       absAngle -= 180.0;
+
+               QString text = QChar(0x2221) + QObject::tr(": %1");
+               text = text.arg(absAngle);
+
+               if (ctrlWasPressed)
+                       text += " (Copy)";
+
+               painter->DrawInformativeText(text);
+
+               // Draw the mirror only if there's been a line to mirror around
+               if (p1 != p2)
+                       mirror->Draw(painter);
+       }
+}
+
+
+/*virtual*/ void TrimAction::MouseDown(Vector point)
+{
+       // Clear our override...
+       shiftWasPressedOnNextPoint = false;
+
+       if (state == FIRST_POINT)
+               p1 = point;
+       else
+               p2 = point;
+}
+
+
+/*virtual*/ void TrimAction::MouseMoved(Vector point)
+{
+       if (state == FIRST_POINT)
+               p1 = point;
+       else
+       {
+               p2 = point;
+               mirror->Restore();
+               mirror->Mirror(p1, p2);
+       }
+}
+
+
+/*virtual*/ void TrimAction::MouseReleased(void)
+{
+       if (state == FIRST_POINT)
+       {
+               p2 = p1;
+               state = NEXT_POINT;
+       }
+       else if (state == NEXT_POINT)
+       {
+               if (!ctrlWasPressed)
+               {
+                       state = FIRST_POINT;
+                       ApplicationWindow::drawing->document.MirrorSelected(p1, p2);
+
+                       mirror->Clear();
+                       ApplicationWindow::drawing->document.CopySelectedContentsTo(mirror);
+                       mirror->Save();
+               }
+               else
+               {
+                       mirror->CopyContentsTo(&(ApplicationWindow::drawing->document));
+               }
+       }
+}
+
+
+/*virtual*/ void TrimAction::KeyDown(int key)
+{
+       if ((key == Qt::Key_Shift) && (state == NEXT_POINT))
+       {
+               shiftWasPressedOnNextPoint = true;
+               p1Save = p1;
+               p1 = p2;
+               state = FIRST_POINT;
+               emit NeedRefresh();
+       }
+       else if (key == Qt::Key_Control)
+       {
+               ctrlWasPressed = true;
+               emit NeedRefresh();
+       }
+}
+
+
+/*virtual*/ void TrimAction::KeyReleased(int key)
+{
+       if ((key == Qt::Key_Shift) && shiftWasPressedOnNextPoint)
+       {
+               shiftWasPressedOnNextPoint = false;
+               p2 = p1;
+               p1 = p1Save;
+               state = NEXT_POINT;
+               emit NeedRefresh();
+       }
+       else if (key == Qt::Key_Control)
+       {
+               ctrlWasPressed = false;
+               emit NeedRefresh();
+       }
+}
+
diff --git a/src/trimaction.h b/src/trimaction.h
new file mode 100644 (file)
index 0000000..02720de
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef __TRIMACTION_H__
+#define __TRIMACTION_H__
+
+#include "action.h"
+
+class Container;
+class Line;
+
+class TrimAction: public Action
+{
+       public:
+               TrimAction();
+               ~TrimAction();
+
+               virtual void Draw(Painter *);
+               virtual void MouseDown(Vector);
+               virtual void MouseMoved(Vector);
+               virtual void MouseReleased(void);
+               virtual void KeyDown(int);
+               virtual void KeyReleased(int);
+
+       private:
+               int state;
+               Line * line;
+               Vector p1, p2, p1Save;
+               bool shiftWasPressedOnNextPoint;
+               bool ctrlWasPressed;
+               Container * mirror;
+};
+
+#endif // __TRIMACTION_H__
+