From bb8d0671717bac2c5350e34024273381be1d8175 Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Tue, 13 Aug 2013 20:15:59 -0500 Subject: [PATCH] Various fixes to Container/Group handling, added DrawArcAction. Also, fixed snap to grid to work as it should. If it's on, it's on; if it's off it's off. Seems simple in concept and, as it turns out, it was simple in implementation. Dunno why it took so long to finally fix it. :-P --- TODO | 15 +++++-- architektonas.pro | 2 + src/applicationwindow.cpp | 1 + src/container.cpp | 4 +- src/drawarcaction.cpp | 88 +++++++++++++++++++++++++++++++++++++++ src/drawarcaction.h | 25 +++++++++++ src/drawingview.cpp | 53 +++++++++++++++++++---- src/drawingview.h | 2 + src/object.cpp | 3 +- src/object.h | 1 + src/painter.cpp | 17 ++++++++ src/painter.h | 1 + 12 files changed, 198 insertions(+), 14 deletions(-) create mode 100644 src/drawarcaction.cpp create mode 100644 src/drawarcaction.h diff --git a/TODO b/TODO index 540d541..9bbbe20 100644 --- a/TODO +++ b/TODO @@ -3,11 +3,13 @@ Stuff To Be Implemented/Fixed - Add Arc - Add Polygon + - Add Ellipse + - Add Spline + - Add Text - Manipulate Dimension - Object connections - Group selection (kind done, needs more work though) - Take movement code out of Objects and put it into top level Container - - Fix snap to grid to honor both states (right now, it's a weird mix of states) - Add OSD routines so they don't have to be implemented in Objects - Add OSD to Object creation - Add layers @@ -17,7 +19,12 @@ Stuff To Be Implemented/Fixed - Add fill/hatch to Objects - Fix zooming to be more intuitive - Add other Dimension types, like radial, diametric, leader - - Add Ellipse - - Add Spline - - Add Text + - Mirror tool + - Restrict movement horizontal/vertical tool + - Trim tool + +Stuff That's Done +----------------- + + - Fix snap to grid to honor both states (right now, it's a weird mix of states) diff --git a/architektonas.pro b/architektonas.pro index 108fba7..668392e 100644 --- a/architektonas.pro +++ b/architektonas.pro @@ -52,6 +52,7 @@ HEADERS = \ src/container.h \ src/dimension.h \ src/drawingview.h \ + src/drawarcaction.h \ src/drawcircleaction.h \ src/drawdimensionaction.h \ src/drawlineaction.h \ @@ -82,6 +83,7 @@ SOURCES = \ src/container.cpp \ src/dimension.cpp \ src/drawingview.cpp \ + src/drawarcaction.cpp \ src/drawcircleaction.cpp \ src/drawdimensionaction.cpp \ src/drawlineaction.cpp \ diff --git a/src/applicationwindow.cpp b/src/applicationwindow.cpp index daae37c..b812e4d 100644 --- a/src/applicationwindow.cpp +++ b/src/applicationwindow.cpp @@ -386,6 +386,7 @@ void ApplicationWindow::SetInternalToolStates(void) drawing->SetAddLineToolActive(addLineAct->isChecked()); drawing->SetAddCircleToolActive(addCircleAct->isChecked()); + drawing->SetAddArcToolActive(addArcAct->isChecked()); drawing->SetAddDimensionToolActive(addDimensionAct->isChecked()); } diff --git a/src/container.cpp b/src/container.cpp index 757828a..da491f6 100644 --- a/src/container.cpp +++ b/src/container.cpp @@ -25,6 +25,7 @@ Container::Container(Vector p1, Object * p/*= NULL*/): Object(p1, p), dragging(false), draggingHandle1(false), draggingHandle2(false)//, needUpdate(false) { type = OTContainer; + state = OSInactive; } @@ -34,6 +35,7 @@ Container::Container(const Container & copy): Object(copy.position, copy.parent) // Use overloaded assignment operator *this = copy; type = OTContainer; + state = OSInactive; } @@ -85,7 +87,7 @@ Container & Container::operator=(const Container & from) painter->SetPen(QPen(Qt::blue, 2.0, Qt::DashLine)); painter->SetBrush(QBrush(Qt::NoBrush)); - painter->DrawRect(boundary); + painter->DrawPaddedRect(boundary); } } diff --git a/src/drawarcaction.cpp b/src/drawarcaction.cpp new file mode 100644 index 0000000..96db309 --- /dev/null +++ b/src/drawarcaction.cpp @@ -0,0 +1,88 @@ +// drawarcaction.cpp: Draw arc object +// +// Part of the Architektonas Project +// (C) 2011 Underground Software +// See the README and GPLv3 files for licensing and warranty information +// +// JLH = James Hammons +// +// WHO WHEN WHAT +// --- ---------- ------------------------------------------------------------ +// JLH 08/13/2013 Created this file +// + +#include "drawarcaction.h" +#include "painter.h" +#include "arc.h" +//#include "vector.h" + + +enum { FIRST_POINT, SECOND_POINT, THIRD_POINT }; +//#define FIRST_POINT 0 +//#define SECOND_POINT 1 +#define NEXT_POINT 2 + + +DrawArcAction::DrawArcAction(): state(FIRST_POINT), arc(NULL) +{ +} + + +DrawArcAction::~DrawArcAction() +{ +} + + +/*virtual*/ void DrawArcAction::Draw(Painter * painter) +{ + painter->SetPen(QPen(Qt::red, 2.0, Qt::DotLine)); + + // I think stuff like crosshairs should be done in the DrawingView, tho + if (state == FIRST_POINT) + { + painter->DrawHandle(p1); + } + else + { +// painter->DrawLine(p1, p2); +// painter->DrawHandle(p2); + } +} + + +/*virtual*/ void DrawArcAction::MouseDown(Vector point) +{ + if (state == FIRST_POINT) + p1 = point; +// else +// p2 = point; +} + + +/*virtual*/ void DrawArcAction::MouseMoved(Vector point) +{ + if (state == FIRST_POINT) + p1 = point; +// else +// p2 = point; +} + + +/*virtual*/ void DrawArcAction::MouseReleased(void) +{ + if (state == FIRST_POINT) + { +// p2 = p1; + state = NEXT_POINT; + } + else if (state == NEXT_POINT) + { + // We create the new object here, and then pass it off to the + // DrawingView which stuffs it into the document. +// text = new Text(p1, p2); +// arc = new Arc(...); + // We don't need no stinkin' sentinels, when we have signals & slots! + emit ObjectReady(arc); + } +} + diff --git a/src/drawarcaction.h b/src/drawarcaction.h new file mode 100644 index 0000000..afb9f91 --- /dev/null +++ b/src/drawarcaction.h @@ -0,0 +1,25 @@ +#ifndef __DRAWARCACTION_H__ +#define __DRAWARCACTION_H__ + +#include "action.h" + +class Arc; + +class DrawArcAction: public Action +{ + public: + DrawArcAction(); + ~DrawArcAction(); + + virtual void Draw(Painter *); + virtual void MouseDown(Vector); + virtual void MouseMoved(Vector); + virtual void MouseReleased(void); + + private: + int state; + Arc * arc; + Vector p1, p2; +}; + +#endif // __DRAWARCACTION_H__ diff --git a/src/drawingview.cpp b/src/drawingview.cpp index 8f689a8..31aeaf0 100644 --- a/src/drawingview.cpp +++ b/src/drawingview.cpp @@ -34,6 +34,7 @@ #include "arc.h" #include "circle.h" #include "dimension.h" +#include "drawarcaction.h" #include "drawcircleaction.h" #include "drawdimensionaction.h" #include "drawlineaction.h" @@ -124,7 +125,8 @@ Painter::zoom *and* size. Same with the dimension text; it's drawn at 10pt and scaled the same way as the arrowheads. Need a way to scale line widths as well. :-/ Shouldn't be too difficult, just -need a thickness parameter similar to the "size" param for dimensions. +need a thickness parameter similar to the "size" param for dimensions. (And now +we do! :-) */ #if 0 @@ -180,6 +182,19 @@ void DrawingView::SetAddCircleToolActive(bool state/*= true*/) } +void DrawingView::SetAddArcToolActive(bool state/*= true*/) +{ + if (state) + { + toolAction = new DrawArcAction(); + connect(toolAction, SIGNAL(ObjectReady(Object *)), this, + SLOT(AddNewObjectToDocument(Object *))); + } + + update(); +} + + void DrawingView::SetAddDimensionToolActive(bool state/*= true*/) { if (state) @@ -328,6 +343,26 @@ QPoint DrawingView::GetAdjustedClientPosition(int x, int y) } +// +// This looks strange, but it's really quite simple: We want a point that's +// more than half-way to the next grid point to snap there while conversely we +// want a point that's less than half-way to to the next grid point then snap +// to the one before it. So we add half of the grid spacing to the point, then +// divide by it so that we can remove the fractional part, then multiply it +// back to get back to the correct answer. +// +Vector DrawingView::SnapPointToGrid(Vector point) +{ + point += gridSpacing / 2.0; // *This* adds to Z!!! + point /= gridSpacing; + point.x = floor(point.x);//need to fix this for negative numbers... + point.y = floor(point.y); + point.z = 0; // Make *sure* Z doesn't go anywhere!!! + point *= gridSpacing; + return point; +} + + void DrawingView::paintEvent(QPaintEvent * /*event*/) { QPainter qtPainter(this); @@ -388,6 +423,10 @@ void DrawingView::mousePressEvent(QMouseEvent * event) if (event->button() == Qt::LeftButton) { Vector point = Painter::QtToCartesianCoords(Vector(event->x(), event->y())); + + if (Object::snapToGrid) + point = SnapPointToGrid(point); + collided = document.Collided(point); if (collided) @@ -437,14 +476,9 @@ void DrawingView::mouseMoveEvent(QMouseEvent * event) // Grid processing... #if 1 - // This looks strange, but it's really quite simple: We want a point that's - // more than half-way to the next grid point to snap there while conversely - // we want a point that's less than half-way to to the next grid point then - // snap to the one before it. So we add half of the grid spacing to the - // point, then divide by it so that we can remove the fractional part, then - // multiply it back to get back to the correct answer. - if (event->buttons() & Qt::LeftButton) + if ((event->buttons() & Qt::LeftButton) && Object::snapToGrid) { +#if 0 point += gridSpacing / 2.0; // *This* adds to Z!!! point /= gridSpacing; //200% is ok, gridSpacing = 6 in this case... @@ -455,6 +489,9 @@ void DrawingView::mouseMoveEvent(QMouseEvent * event) point.y = floor(point.y); point.z = 0; // Make *sure* Z doesn't go anywhere!!! point *= gridSpacing; +#else + point = SnapPointToGrid(point); +#endif } #endif //we should keep track of the last point here and only pass this down *if* the point diff --git a/src/drawingview.h b/src/drawingview.h index 888737e..b296f28 100644 --- a/src/drawingview.h +++ b/src/drawingview.h @@ -17,6 +17,7 @@ class DrawingView: public QWidget void SetRotateToolActive(bool state = true); void SetAddLineToolActive(bool state = true); void SetAddCircleToolActive(bool state = true); + void SetAddArcToolActive(bool state = true); void SetAddDimensionToolActive(bool state = true); void SetGridSize(uint32_t); void UpdateGridBackground(void); @@ -34,6 +35,7 @@ class DrawingView: public QWidget private: QPoint GetAdjustedMousePosition(QMouseEvent * event); QPoint GetAdjustedClientPosition(int x, int y); + Vector SnapPointToGrid(Vector); public: bool useAntialiasing; diff --git a/src/object.cpp b/src/object.cpp index 523601d..fc8d834 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -189,8 +189,9 @@ printf("Object: Destroyed!\n"); #endif -/*virtual*/ void Object::Translate(Vector) +/*virtual*/ void Object::Translate(Vector amount) { + position += amount; } diff --git a/src/object.h b/src/object.h index 513b677..72aaad6 100644 --- a/src/object.h +++ b/src/object.h @@ -79,6 +79,7 @@ class Object static int viewportHeight; static bool deleteActive; static bool dimensionActive; + public: static bool snapToGrid; static bool ignoreClicks; static bool dontMove; diff --git a/src/painter.cpp b/src/painter.cpp index 6cfd91f..308cab6 100644 --- a/src/painter.cpp +++ b/src/painter.cpp @@ -208,6 +208,7 @@ void Painter::DrawPoint(int x, int y) } +// This is drawn in Qt coordinates... void Painter::DrawRoundedRect(QRectF rect, double radiusX, double radiusY) { if (!painter) @@ -217,6 +218,22 @@ void Painter::DrawRoundedRect(QRectF rect, double radiusX, double radiusY) } +// This is drawn partially in Cartesian coordinates, and partially in Qt +// coordinates. The rect itself is in Cartesian but we want to pad it by a set +// number of pixels. +void Painter::DrawPaddedRect(QRectF rect) +{ + if (!painter) + return; + + Vector v1 = CartesianToQtCoords(Vector(rect.x(), rect.y())); + Vector v2 = CartesianToQtCoords(Vector(rect.right(), rect.bottom())); + QRectF screenRect(QPointF(v1.x, v1.y), QPointF(v2.x, v2.y)); + screenRect.adjust(-8, 8, 8, -8); // Left/top, right/bottom + painter->drawRect(screenRect); +} + + void Painter::DrawRect(QRectF rect) { if (!painter) diff --git a/src/painter.h b/src/painter.h index 219547c..84e3e14 100644 --- a/src/painter.h +++ b/src/painter.h @@ -26,6 +26,7 @@ class Painter void DrawLine(Vector, Vector); void DrawPoint(int, int); void DrawRoundedRect(QRectF, double, double); + void DrawPaddedRect(QRectF); void DrawRect(QRectF); void DrawText(QRectF, int, QString); void DrawArrowhead(Vector, Vector, double); -- 2.37.2