]> Shamusworld >> Repos - architektonas/commitdiff
Fix object selection to work while in snap mode.
authorShamus Hammons <jlhamm@acm.org>
Sun, 18 Aug 2013 19:24:25 +0000 (14:24 -0500)
committerShamus Hammons <jlhamm@acm.org>
Sun, 18 Aug 2013 19:24:25 +0000 (14:24 -0500)
Turns out that unless the point on the object you were trying to select
fell on a grid point, you couldn't select it in snap mode. So moving the
grid snap code into the objects is what solved that, though
ungraciously. Will have to see if there's a better way to do it. :-P

src/applicationwindow.cpp
src/arc.cpp
src/circle.cpp
src/drawingview.cpp
src/drawingview.h
src/line.cpp
src/object.cpp
src/object.h

index c51000044ba82085b214772d0c2740d521b5349d..f9362ca5967071d34a0202608d9759249c32b759 100644 (file)
@@ -299,13 +299,16 @@ when zooming in, new origin will be (xCenter - origin.x) / 2, (yCenter - origin.
        // This just zooms leaving origin intact... should zoom in at the current center! [DONE]
        // This should actually be calculated by drawing->gridPixels / grid size.
        Painter::zoom *= zoomFactor;
        // This just zooms leaving origin intact... should zoom in at the current center! [DONE]
        // This should actually be calculated by drawing->gridPixels / grid size.
        Painter::zoom *= zoomFactor;
-       drawing->gridSpacing = drawing->gridPixels / Painter::zoom;
+//     drawing->gridSpacing = drawing->gridPixels / Painter::zoom;
+       Object::gridSpacing = drawing->gridPixels / Painter::zoom;
 //     zoomIndicator->setText(QString("Grid: %2\" Zoom: %1%").arg(Painter::zoom * 100.0 * SCREEN_ZOOM).arg(drawing->gridSpacing));
 //     zoomIndicator->setText(QString("Grid: %2\" Zoom: %1%").arg(Painter::zoom * 100.0 * SCREEN_ZOOM).arg(drawing->gridSpacing));
-       zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(drawing->gridSpacing));
+//     zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(drawing->gridSpacing));
+       zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(Object::gridSpacing));
        drawing->UpdateGridBackground();
        drawing->update();
 
        drawing->UpdateGridBackground();
        drawing->update();
 
-       baseUnitInput->setText(QString("%1").arg(drawing->gridSpacing));
+//     baseUnitInput->setText(QString("%1").arg(drawing->gridSpacing));
+       baseUnitInput->setText(QString("%1").arg(Object::gridSpacing));
 }
 
 
 }
 
 
@@ -338,13 +341,16 @@ x 2 = (-426, -301)
 //printf("Zoom out...\n");
        // This just zooms leaving origin intact... should zoom out at the current center! [DONE]
        Painter::zoom /= zoomFactor;
 //printf("Zoom out...\n");
        // This just zooms leaving origin intact... should zoom out at the current center! [DONE]
        Painter::zoom /= zoomFactor;
-       drawing->gridSpacing = drawing->gridPixels / Painter::zoom;
+//     drawing->gridSpacing = drawing->gridPixels / Painter::zoom;
+       Object::gridSpacing = drawing->gridPixels / Painter::zoom;
 //     zoomIndicator->setText(QString("Grid: %2\" Zoom: %1%").arg(Painter::zoom * 100.0 * SCREEN_ZOOM).arg(drawing->gridSpacing));
 //     zoomIndicator->setText(QString("Grid: %2\" Zoom: %1%").arg(Painter::zoom * 100.0 * SCREEN_ZOOM).arg(drawing->gridSpacing));
-       zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(drawing->gridSpacing));
+//     zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(drawing->gridSpacing));
+       zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(Object::gridSpacing));
        drawing->UpdateGridBackground();
        drawing->update();
 
        drawing->UpdateGridBackground();
        drawing->update();
 
-       baseUnitInput->setText(QString("%1").arg(drawing->gridSpacing));
+//     baseUnitInput->setText(QString("%1").arg(drawing->gridSpacing));
+       baseUnitInput->setText(QString("%1").arg(Object::gridSpacing));
 }
 
 
 }
 
 
@@ -500,8 +506,10 @@ void ApplicationWindow::HandleGridSizeInBaseUnits(QString text)
        if (!ok || value == 0)
                return;
 
        if (!ok || value == 0)
                return;
 
-       drawing->gridSpacing = value;
-       Painter::zoom = drawing->gridPixels / drawing->gridSpacing;
+//     drawing->gridSpacing = value;
+//     Painter::zoom = drawing->gridPixels / drawing->gridSpacing;
+       Object::gridSpacing = value;
+       Painter::zoom = drawing->gridPixels / Object::gridSpacing;
        drawing->UpdateGridBackground();
        drawing->update();
 }
        drawing->UpdateGridBackground();
        drawing->update();
 }
index ad08a572979dc651c6a13592a8126a3001b06d9b..030e293a70a20697f9575d893585894a71643e72 100644 (file)
@@ -71,7 +71,8 @@ Arc::~Arc()
                        Vector oldLine = (p3 * (radius * 1.25)) + position;
                        pen = QPen(QColor(0x80, 0x80, 0x80), 1.0, Qt::DashLine);
                        painter->SetPen(pen);
                        Vector oldLine = (p3 * (radius * 1.25)) + position;
                        pen = QPen(QColor(0x80, 0x80, 0x80), 1.0, Qt::DashLine);
                        painter->SetPen(pen);
-                       painter->DrawLine((int)position.x, (int)position.y, (int)oldLine.x, (int)oldLine.y);
+//                     painter->DrawLine((int)position.x, (int)position.y, (int)oldLine.x, (int)oldLine.y);
+                       painter->DrawLine(position, oldLine);
                }
 
                // In rotating and setting the span, we draw a line showing where
                }
 
                // In rotating and setting the span, we draw a line showing where
@@ -147,52 +148,16 @@ Also: should put the snap logic into the Object base class (as a static method).
 /*virtual*/ bool Arc::Collided(Vector point)
 {
        objectWasDragged = false;
 /*virtual*/ bool Arc::Collided(Vector point)
 {
        objectWasDragged = false;
-//     Vector v1 = point - position;                   // Head minus tail (vector points at "point")
-
-#if 1
        bool hitSomething = HitTest(point);
        draggingCenter = hitCenter;
        draggingEdge   = hitArc;
        draggingRotate = hitRotate;
        draggingSpan   = hitSpan;
        bool hitSomething = HitTest(point);
        draggingCenter = hitCenter;
        draggingEdge   = hitArc;
        draggingRotate = hitRotate;
        draggingSpan   = hitSpan;
-#else
-       // Check for collision with various things...
-       hitHandle1 = false;     // Moving
-       hitHandle2 = false;     // Rotation
-       hitHandle3 = false;     // Setting span of the arc
-       hitHandle4 = false;     // Resizing
-/*
-What we have:
-the center of the arc
-the starting angle
-the span of the arc
-The point on a unit circle given an angle a is x = cos(a), y = sin(a)
-This vector is already unitized, so all we need to do to get our point is to multiply it by
-radius (to get the length correct) and add it to the center point (to get the correct position).
-*/
-       Vector v1 = point - position;                   // Head minus tail (vector points at "point")
-       Point p1(cos(startAngle), sin(startAngle));
-       Point p2(cos(startAngle + angleSpan), sin(startAngle + angleSpan));
-       Vector handle2 = (p1 * radius) + position;
-       Vector handle3 = (p2 * radius) + position;
-       double pointerAngle = v1.Angle();
 
 
-#if 1
-       // Center handle
-       if (v1.Magnitude() < 10.0)
-               hitHandle1 = true;
-       // Span handle
-       else if (Vector(handle3 - point).Magnitude() < 10.0)
-               hitHandle3 = true;
-       // Rotate handle
-       else if (Vector(handle2 - point).Magnitude() < 10.0)
-               hitHandle2 = true;
-       // Resize handle (the arc itself)
-       else if ((v1.Magnitude() < radius + 3.0) && (v1.Magnitude() > radius - 3.0)
-               && AngleInArcSpan(pointerAngle))
-               hitHandle4 = true;
-#endif
-#endif
+       // Now that we've done our hit testing on the non-snapped point, snap it if
+       // necessary...
+       if (snapToGrid)
+               point = SnapPointToGrid(point);
 
 /*
 State Management:
 
 /*
 State Management:
@@ -226,7 +191,6 @@ Selected|  |  |  |
 
 so let's do like this:
 */
 
 so let's do like this:
 */
-//     if (hitCenter || hitArc || hitRotate || hitSpan)
        if (hitSomething)
        {
                oldState = state;
        if (hitSomething)
        {
                oldState = state;
index 909d30416bac3676beaf8d6d8cbe905184f04eb7..9111c04ec1e8c36289703979a9848d0797664707 100644 (file)
@@ -87,6 +87,11 @@ Circle::~Circle()
        objectWasDragged = false;
        HitTest(point);
 
        objectWasDragged = false;
        HitTest(point);
 
+       // Now that we've done our hit testing on the non-snapped point, snap it if
+       // necessary...
+       if (snapToGrid)
+               point = SnapPointToGrid(point);
+
        draggingCenter = hitCenter;
        draggingEdge = hitCircle;
 
        draggingCenter = hitCenter;
        draggingEdge = hitCircle;
 
index 5bbcddf62ffeb0396b5f5edc5924e46ceaea9a5e..bdc3540b0442fc51b243e6096da6a94b362d2632 100644 (file)
@@ -47,7 +47,7 @@ DrawingView::DrawingView(QWidget * parent/*= NULL*/): QWidget(parent),
        gridBackground(BACKGROUND_MAX_SIZE, BACKGROUND_MAX_SIZE),
        scale(1.0), offsetX(-10), offsetY(-10),
        document(Vector(0, 0)),
        gridBackground(BACKGROUND_MAX_SIZE, BACKGROUND_MAX_SIZE),
        scale(1.0), offsetX(-10), offsetY(-10),
        document(Vector(0, 0)),
-       gridSpacing(12.0), gridPixels(0), collided(false), rotateTool(false),
+       /*gridSpacing(12.0),*/ gridPixels(0), collided(false), rotateTool(false),
        rx(150.0), ry(150.0),
        scrollDrag(false), addLineTool(false), addCircleTool(false),
        addDimensionTool(false),
        rx(150.0), ry(150.0),
        scrollDrag(false), addLineTool(false), addCircleTool(false),
        addDimensionTool(false),
@@ -57,6 +57,7 @@ DrawingView::DrawingView(QWidget * parent/*= NULL*/): QWidget(parent),
        setBackgroundRole(QPalette::Base);
        setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
 
        setBackgroundRole(QPalette::Base);
        setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
 
+       Object::gridSpacing = 12.0;
 //     toolPalette = new ToolWindow();
 //     CreateCursors();
 //     setCursor(cur[TOOLSelect]);
 //     toolPalette = new ToolWindow();
 //     CreateCursors();
 //     setCursor(cur[TOOLSelect]);
@@ -168,7 +169,8 @@ void DrawingView::SetGridSize(uint32_t size)
        pmp.end();
 
        // Set up new BG brush & zoom level (pixels per base unit)
        pmp.end();
 
        // Set up new BG brush & zoom level (pixels per base unit)
-       Painter::zoom = gridPixels / gridSpacing;
+//     Painter::zoom = gridPixels / gridSpacing;
+       Painter::zoom = gridPixels / Object::gridSpacing;
        UpdateGridBackground();
 }
 
        UpdateGridBackground();
 }
 
@@ -282,6 +284,7 @@ QPoint DrawingView::GetAdjustedClientPosition(int x, int y)
 }
 
 
 }
 
 
+#if 0
 //
 // 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
 //
 // 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
@@ -300,6 +303,7 @@ Vector DrawingView::SnapPointToGrid(Vector point)
        point *= gridSpacing;
        return point;
 }
        point *= gridSpacing;
        return point;
 }
+#endif
 
 
 void DrawingView::paintEvent(QPaintEvent * /*event*/)
 
 
 void DrawingView::paintEvent(QPaintEvent * /*event*/)
@@ -375,9 +379,13 @@ So, how to fix this? Have the Object check itself?
 Maybe we can fix this by having the initial point not be snapped, but when there's
 a drag, we substitute the snapped point 'oldPoint' which the Object keeps track of
 internally to know how far it was dragged...
 Maybe we can fix this by having the initial point not be snapped, but when there's
 a drag, we substitute the snapped point 'oldPoint' which the Object keeps track of
 internally to know how far it was dragged...
+
+Now we do... :-/
 */
 */
+#if 0
                if (Object::snapToGrid)
                if (Object::snapToGrid)
-                       point = SnapPointToGrid(point);
+                       point = Object::SnapPointToGrid(point);
+#endif
 
                collided = document.Collided(point);
 
 
                collided = document.Collided(point);
 
@@ -427,25 +435,11 @@ void DrawingView::mouseMoveEvent(QMouseEvent * event)
        }
 
        // Grid processing...
        }
 
        // Grid processing...
-#if 1
        if ((event->buttons() & Qt::LeftButton) && Object::snapToGrid)
        {
        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...
-//won't run into problems until gridSpacing = 1.5 (zoom = 800%)
-//run into problems with this approach: when zoom level is 200% this truncates to
-//integers, which is *not* what's wanted here...
-               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;
-#else
-               point = SnapPointToGrid(point);
-#endif
+               point = Object::SnapPointToGrid(point);
        }
        }
-#endif
+
        oldPoint = point;
 //we should keep track of the last point here and only pass this down *if* the point
 //changed...
        oldPoint = point;
 //we should keep track of the last point here and only pass this down *if* the point
 //changed...
@@ -458,7 +452,7 @@ void DrawingView::mouseMoveEvent(QMouseEvent * event)
        {
                if (Object::snapToGrid)
                {
        {
                if (Object::snapToGrid)
                {
-                       point = SnapPointToGrid(point);
+                       point = Object::SnapPointToGrid(point);
                        oldPoint = point;
                }
 
                        oldPoint = point;
                }
 
index 44420e9e08216fe2f325201d008e4e4139f21843..819ab78d226c3a92a26fb0d7a49a22880e4bd7b7 100644 (file)
@@ -39,7 +39,7 @@ class DrawingView: public QWidget
        private:
                QPoint GetAdjustedMousePosition(QMouseEvent * event);
                QPoint GetAdjustedClientPosition(int x, int y);
        private:
                QPoint GetAdjustedMousePosition(QMouseEvent * event);
                QPoint GetAdjustedClientPosition(int x, int y);
-               Vector SnapPointToGrid(Vector);
+//             Vector SnapPointToGrid(Vector);
 
        public:
                bool useAntialiasing;
 
        public:
                bool useAntialiasing;
@@ -51,12 +51,13 @@ class DrawingView: public QWidget
                int32_t offsetX, offsetY;                               // Window offsets
        public:
                Container document;
                int32_t offsetX, offsetY;                               // Window offsets
        public:
                Container document;
-               double gridSpacing;                                             // Grid spacing in base units
+//             double gridSpacing;                                             // Grid spacing in base units
                uint32_t gridPixels;                                    // Grid size in pixels
 //             double gridBaseUnits;                                   // Grid size in base units
        private:
                bool collided;
 //Should this go into Object's class variables???
                uint32_t gridPixels;                                    // Grid size in pixels
 //             double gridBaseUnits;                                   // Grid size in base units
        private:
                bool collided;
 //Should this go into Object's class variables???
+//maybe, maybe not... :-P
                bool rotateTool;
                double rx, ry;
                bool scrollDrag;
                bool rotateTool;
                double rx, ry;
                bool scrollDrag;
@@ -64,8 +65,6 @@ class DrawingView: public QWidget
                bool addLineTool;
                bool addCircleTool;
                bool addDimensionTool;
                bool addLineTool;
                bool addCircleTool;
                bool addDimensionTool;
-//             bool selectionInProgress;
-//             QRectF selection;
 
        public:
                Action * toolAction;
 
        public:
                Action * toolAction;
index e80e988797c28004cd84d45c7ba76411bbad1049..37b43c8865cb86740da00abda5767ad562a512d7 100644 (file)
@@ -123,11 +123,15 @@ Line::~Line()
 {
        // We can assume this, since this is a mouse down event here.
        objectWasDragged = false;
 {
        // We can assume this, since this is a mouse down event here.
        objectWasDragged = false;
-//     SaveHitState();
        HitTest(point);
        HitTest(point);
-//     return HitStateChanged();
+
+       // Now that we've done our hit testing on the non-snapped point, snap it if
+       // necessary...
+       if (snapToGrid)
+               point = SnapPointToGrid(point);
 
 // this is shite. this should be checked for in the Container, not here!
 
 // this is shite. this should be checked for in the Container, not here!
+#warning "!!! This should be checked for in Container, not here !!!"
        // If we're part of a non-top-level container, send this signal to it
        if (parent->type == OTContainer && !((Container *)parent)->isTopLevelContainer
                && (hitLine || hitPoint1 || hitPoint2))
        // If we're part of a non-top-level container, send this signal to it
        if (parent->type == OTContainer && !((Container *)parent)->isTopLevelContainer
                && (hitLine || hitPoint1 || hitPoint2))
@@ -209,28 +213,26 @@ a dimension only) Draw() function... :-/
                }
        }
 
                }
        }
 
-
        if (state == OSInactive)
        {
        if (state == OSInactive)
        {
-//printf("Line: pp = %lf, length = %lf, distance = %lf\n", parameterizedPoint, lineSegment.Magnitude(), distance);
-//printf("      v1.Magnitude = %lf, v2.Magnitude = %lf\n", v1.Magnitude(), v2.Magnitude());
-//printf("      point = %lf,%lf,%lf; p1 = %lf,%lf,%lf; p2 = %lf,%lf,%lf\n", point.x, point.y, point.z, position.x, position.y, position.z, endpoint.x, endpoint.y, endpoint.z);
-//printf("      \n", );
 //How to translate this into pixels from Document space???
 //How to translate this into pixels from Document space???
-//Maybe we need to pass a scaling factor in here from the caller? That would make sense, as
-//the caller knows about the zoom factor and all that good kinda crap
-//I think what's needed is an Object class variable/method that can be changed by the TLC and
-//called in derived classes to properly scale the location to the current zoom level. That *should* work.
-
-// ALSO: Need to code a global (read: Object class) variable that tells use whether a modifier
-//       key was pressed in addition to the mouse click, so we can do stuff like, say, hold
-//       down CTRL and be able to do multiple selecting of objects (in that case, we would
-//       keep the Object state from changing).
+//Maybe we need to pass a scaling factor in here from the caller? That would
+//make sense, as the caller knows about the zoom factor and all that good kinda
+//crap
+//I think what's needed is an Object class variable/method that can be changed
+//by the TLC and called in derived classes to properly scale the location to
+//the current zoom level. That *should* work.
+
+// ALSO: Need to code a global (read: Object class) variable that tells use
+//       whether a modifier key was pressed in addition to the mouse click, so
+//       we can do stuff like, say, hold down CTRL and be able to do multiple
+//       selecting of objects (in that case, we would keep the Object state
+//       from changing).
                if (hitPoint1)
                {
                        oldState = state;
                        state = OSSelected;
                if (hitPoint1)
                {
                        oldState = state;
                        state = OSSelected;
-                       oldPoint = position; //maybe "position"?
+                       oldPoint = position;
                        draggingHandle1 = true;
                        return true;
                }
                        draggingHandle1 = true;
                        return true;
                }
@@ -238,7 +240,7 @@ a dimension only) Draw() function... :-/
                {
                        oldState = state;
                        state = OSSelected;
                {
                        oldState = state;
                        state = OSSelected;
-                       oldPoint = endpoint; //maybe "position"?
+                       oldPoint = endpoint;
                        draggingHandle2 = true;
                        return true;
                }
                        draggingHandle2 = true;
                        return true;
                }
@@ -253,12 +255,6 @@ a dimension only) Draw() function... :-/
        }
        else if (state == OSSelected)
        {
        }
        else if (state == OSSelected)
        {
-               // Here we test for collision with handles as well! (SOON!) [I think it works...NOPE]
-/*
-Like so:
-               if (v1.Magnitude() < 2.0) // Handle #1
-               else if (v2.Magnitude() < 2.0) // Handle #2
-*/
                if (hitLine)
                {
                        oldState = state;
                if (hitLine)
                {
                        oldState = state;
index 404d30576113a97ad9516b04677d087f81ad4346..93af822b8476008c2f60e6158955078cdaf38c0d 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "object.h"
 #include <stdlib.h>
 
 #include "object.h"
 #include <stdlib.h>
+#include <math.h>
 
 // Initialize static variables
 bool Object::fixedAngle = false;
 
 // Initialize static variables
 bool Object::fixedAngle = false;
@@ -31,6 +32,7 @@ bool Object::ignoreClicks = false;
 bool Object::dontMove = false;
 bool Object::selectionInProgress = false;
 QRectF Object::selection;
 bool Object::dontMove = false;
 bool Object::selectionInProgress = false;
 QRectF Object::selection;
+double Object::gridSpacing;
 
 
 Object::Object(): position(Vector(0, 0)), parent(0), type(OTObject),
 
 
 Object::Object(): position(Vector(0, 0)), parent(0), type(OTObject),
@@ -291,3 +293,25 @@ void Object::SetSnapMode(bool state/*= true*/)
 {
        snapToGrid = state;
 }
 {
        snapToGrid = state;
 }
+
+
+//
+// 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 Object::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;
+}
+
+
index 72aaad644f29a79d96dba2d08a59e83118529509..39dbb9e4137633bf0483e7711ecb6df8fc3d8d81 100644 (file)
@@ -57,6 +57,7 @@ class Object
                static void SetDeleteActive(bool state = true);
                static void SetDimensionActive(bool state = true);
                static void SetSnapMode(bool state = true);
                static void SetDeleteActive(bool state = true);
                static void SetDimensionActive(bool state = true);
                static void SetSnapMode(bool state = true);
+               static Vector SnapPointToGrid(Vector);
 
        protected:
                Vector position;                                        // All objects have a position (doubles as reference point)
 
        protected:
                Vector position;                                        // All objects have a position (doubles as reference point)
@@ -86,6 +87,7 @@ class Object
        public:
                static bool selectionInProgress;
                static QRectF selection;
        public:
                static bool selectionInProgress;
                static QRectF selection;
+               static double gridSpacing;                      // Grid spacing in base units
 };
 
 #endif // __OBJECT_H__
 };
 
 #endif // __OBJECT_H__