src/rotateaction.h \
src/settingsdialog.h \
src/text.h \
+ src/trimaction.h \
src/vector.h
SOURCES = \
src/rotateaction.cpp \
src/settingsdialog.cpp \
src/text.cpp \
+ src/trimaction.cpp \
src/vector.cpp
<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>
#include "painter.h"
#include "rotateaction.h"
#include "settingsdialog.h"
+#include "trimaction.h"
// Class variables
}
+void ApplicationWindow::TrimTool(void)
+{
+ ClearUIToolStatesExcept(trimAct);
+ SetInternalToolStates();
+}
+
+
void ApplicationWindow::AddLineTool(void)
{
ClearUIToolStatesExcept(addLineAct);
if (exception != mirrorAct)
mirrorAct->setChecked(false);
+
+ if (exception != trimAct)
+ trimAct->setChecked(false);
}
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;
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.
menu->addAction(fixLengthAct);
menu->addAction(rotateAct);
menu->addAction(mirrorAct);
+ menu->addAction(trimAct);
menu->addAction(connectAct);
menu->addAction(disconnectAct);
menu->addSeparator();
toolbar->addAction(fixLengthAct);
toolbar->addAction(rotateAct);
toolbar->addAction(mirrorAct);
+ toolbar->addAction(trimAct);
toolbar->addAction(deleteAct);
toolbar->addAction(connectAct);
toolbar->addAction(disconnectAct);
void DimensionTool(void);
void RotateTool(void);
void MirrorTool(void);
+ void TrimTool(void);
void AddLineTool(void);
void AddCircleTool(void);
void AddArcTool(void);
QAction * connectAct;
QAction * disconnectAct;
QAction * mirrorAct;
+ QAction * trimAct;
// Class variables
public:
/*virtual*/ void Circle::Mirror(Point p1, Point p2)
{
Point c1 = Geometry::MirrorPointAroundLine(position, p1, p2);
-// return new Circle(c1, radius);
position = c1;
}
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
// 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%...
{
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;
#ifndef __DIMENSION_H__
#define __DIMENSION_H__
-#include "connection.h"
#include "object.h"
class Line;
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;
{
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);
p1Save = p1;
p1 = p2;
state = FIRST_POINT;
- emit(NeedRefresh());
+ emit NeedRefresh();
}
}
}
-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);
--- /dev/null
+// 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();
+ }
+}
+
--- /dev/null
+#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__
+