]> Shamusworld >> Repos - architektonas/blobdiff - src/drawingview.cpp
Fixed click selection and pen functionality.
[architektonas] / src / drawingview.cpp
index 9acf00cd7e29fb1878b4c9c04a9c7d856c3fe68a..d8726fed5d91d82d86e2616877306ba2a1401cb6 100644 (file)
@@ -159,12 +159,12 @@ void DrawingView::DrawBackground(Painter * painter)
                DrawSubGrid(painter, 0xB8ECFF, 0.125, start, size);
 
        if (Global::gridSpacing <= 0.25)
-               DrawSubGrid(painter, 0xDBDBFF, 0.25, start, size);
+               DrawSubGrid(painter, 0xE6E6FF, 0.25, start, size);
 
        if (Global::gridSpacing <= 0.5)
-               DrawSubGrid(painter, 0xDBDBFF, 0.5, start, size);
+               DrawSubGrid(painter, 0xE6E6FF, 0.5, start, size);
 
-       painter->SetPen(QPen(QColor(0xD2, 0xD2, 0xFF), 2.0, Qt::SolidLine));
+       painter->SetPen(QPen(QColor(0xE0, 0xE0, 0xFF), 2.0, Qt::SolidLine));
 
        for(double i=0; i<=w; i+=spacing)
                painter->DrawVLine(leftx + i);
@@ -193,7 +193,6 @@ void DrawingView::DrawSubGrid(Painter * painter, uint32_t color, double step, Ve
 //
 void DrawingView::DeleteCurrentLayer(int layer)
 {
-//printf("DrawingView::DeleteCurrentLayer(): currentLayer = %i\n", layer);
        VPVectorIter i = document.objects.begin();
 
        while (i != document.objects.end())
@@ -230,7 +229,6 @@ void DrawingView::HandleLayerToggle(void)
 //
 void DrawingView::HandleLayerSwap(int layer1, int layer2)
 {
-//printf("DrawingView: Swapping layers %i and %i.\n", layer1, layer2);
        HandleLayerSwap(layer1, layer2, document.objects);
 }
 
@@ -253,42 +251,6 @@ void DrawingView::HandleLayerSwap(int layer1, int layer2, VPVector & v)
        }
 }
 
-void DrawingView::HandlePenWidth(float width)
-{
-       for(VPVectorIter i=select.begin(); i!=select.end(); i++)
-       {
-               Object * obj = (Object *)(*i);
-               obj->thickness = width;
-       }
-
-       supressSelected = true;
-       update();
-}
-
-void DrawingView::HandlePenStyle(int style)
-{
-       for(VPVectorIter i=select.begin(); i!=select.end(); i++)
-       {
-               Object * obj = (Object *)(*i);
-               obj->style = style;
-       }
-
-       supressSelected = true;
-       update();
-}
-
-void DrawingView::HandlePenColor(uint32_t color)
-{
-       for(VPVectorIter i=select.begin(); i!=select.end(); i++)
-       {
-               Object * obj = (Object *)(*i);
-               obj->color = color;
-       }
-
-       supressSelected = true;
-       update();
-}
-
 void DrawingView::HandlePenStamp(QAction * action)
 {
        PenWidget * pw = (PenWidget *)action->parentWidget();
@@ -340,7 +302,6 @@ QPoint DrawingView::GetAdjustedClientPosition(int x, int y)
 
 void DrawingView::focusOutEvent(QFocusEvent * /*event*/)
 {
-//     printf("DrawingView::focusOutEvent()...\n");
        // Make sure all modkeys being held are marked as released when the app
        // loses focus (N.B.: This only works because the app sets the focus policy
        // of this object to something other than Qt::NoFocus)
@@ -355,9 +316,6 @@ void DrawingView::focusInEvent(QFocusEvent * /*event*/)
                setCursor(curMarker);
        else if (Global::penDropper)
                setCursor(curDropper);
-//FocusOut already set this...
-//     else
-//             setCursor(Qt::ArrowCursor);
 }
 
 void DrawingView::paintEvent(QPaintEvent * /*event*/)
@@ -387,8 +345,12 @@ void DrawingView::paintEvent(QPaintEvent * /*event*/)
        // Do tool rendering, if any...
        if (Global::tool)
        {
-               painter.SetPen(QPen(QColor(200, 100, 0, 255), 1.0, Qt::DashLine));
-               painter.DrawCrosshair(oldPoint);
+               if (Global::toolSuppressCrosshair == false)
+               {
+                       painter.SetPen(QPen(QColor(200, 100, 0, 255), 1.0, Qt::DashLine));
+                       painter.DrawCrosshair(oldPoint);
+               }
+
                ToolDraw(&painter);
        }
 
@@ -719,16 +681,45 @@ Where is the text offset?  It looks like it's drawing in the center, but obvious
 }
 
 //
-// This toggles the selection being hovered (typically, only 1 object)
+// This toggles the selection being hovered (typically, only 1 object).  We
+// toggle because the CTRL key might be held, in which case, we want to
+// deselect a selected object.
 //
-void DrawingView::AddHoveredToSelection(void)
+void DrawingView::HandleSelectionClick(VPVector & v)
 {
-       for(VPVectorIter i=document.objects.begin(); i!=document.objects.end(); i++)
+       if (ctrlDown)
+       {
+               for(VPVectorIter i=v.begin(); i!=v.end(); i++)
+               {
+                       Object * obj = (Object *)(*i);
+
+                       if (obj->hovered)
+                               obj->selected = !obj->selected;
+               }
+
+               return;
+       }
+
+       for(VPVectorIter i=v.begin(); i!=v.end(); i++)
+               ((Object *)(*i))->selected = false;
+
+       // Check if the hover changed, and if so, reset the selection stack
+       if (oldHover.size() != v.size())
        {
-               if (((Object *)(*i))->hovered)
-//                     ((Object *)(*i))->selected = true;
-                       ((Object *)(*i))->selected = !((Object *)(*i))->selected;
+               oldHover = v;
+               currentSelect = 0;
        }
+       else
+       {
+               // Select next object in the stack under the cursor
+               currentSelect++;
+
+               if (currentSelect >= v.size())
+                       currentSelect = 0;
+       }
+
+       dragged = (Object *)v[currentSelect];
+       dragged->selected = true;
 }
 
 VPVector DrawingView::GetSelection(void)
@@ -773,6 +764,17 @@ VPVector DrawingView::GetHovered(bool exclude/*= false*/)
        return v;
 }
 
+void DrawingView::MoveSelectedToLayer(int layer)
+{
+       for(VPVectorIter i=document.objects.begin(); i!=document.objects.end(); i++)
+       {
+               Object * obj = (Object *)(*i);
+
+               if (obj->selected || obj->hovered)
+                       obj->layer = layer;
+       }
+}
+
 void DrawingView::resizeEvent(QResizeEvent * /*event*/)
 {
        Global::screenSize = Vector(size().width(), size().height());
@@ -795,6 +797,8 @@ void DrawingView::ToolHandler(int mode, Point p)
                MirrorHandler(mode, p);
        else if (Global::tool == TTDimension)
                DimensionHandler(mode, p);
+       else if (Global::tool == TTDelete)
+               DeleteHandler(mode, p);
        else if (Global::tool == TTTriangulate)
                TriangulateHandler(mode, p);
        else if (Global::tool == TTTrim)
@@ -938,7 +942,7 @@ void DrawingView::ToolDraw(Painter * painter)
                                informativeText += " (Copy)";
                }
        }
-       if (Global::tool == TTDimension)
+       else if (Global::tool == TTDimension)
        {
                if (Global::toolState == TSNone)
                {
@@ -960,6 +964,20 @@ void DrawingView::ToolDraw(Painter * painter)
                        informativeText = text.arg(absLength).arg(absAngle);
                }
        }
+       else if (Global::tool == TTTrim)
+       {
+               if (toolObj[0] != NULL)
+               {
+                       // We're assuming ATM it's just a line...
+                       painter->SetPen(0xAF0000, 3.0, LSSolid);
+                       painter->DrawLine(toolPoint[0], toolPoint[1]);
+//                     QString text = tr("Arc span: %1") + QChar(0x00B0);
+//                     informativeText = text.arg(RADIANS_TO_DEGREES * span);
+               }
+       }
+       else if (Global::tool == TTParallel)
+       {
+       }
 }
 
 void DrawingView::LineHandler(int mode, Point p)
@@ -1489,7 +1507,7 @@ void DrawingView::DimensionHandler(int mode, Point p)
                }
                else
                {
-                       Dimension * d = new Dimension(toolPoint[0], toolPoint[1], DTLinear);
+                       Dimension * d = new Dimension(toolPoint[0], toolPoint[1], DTLinear, 0, Global::penWidth);
                        d->layer = Global::activeLayer;
                        document.objects.push_back(d);
                        Global::toolState = TSNone;
@@ -1497,7 +1515,37 @@ void DrawingView::DimensionHandler(int mode, Point p)
        }
 }
 
-void DrawingView::TriangulateHandler(int mode, Point/*p*/)
+void DrawingView::DeleteHandler(int mode, Point /*p*/)
+{
+       switch (mode)
+       {
+       case ToolMouseDown:
+       {
+               VPVector hovered = GetHovered();
+
+               RemoveHoveredObjects(document.objects);
+               DeleteContents(hovered);
+       }
+               break;
+
+       case ToolMouseMove:
+               break;
+
+       case ToolMouseUp:
+               break;
+
+       case ToolKeyDown:
+               break;
+
+       case ToolKeyUp:
+               break;
+
+       case ToolCleanup:
+               break;
+       }
+}
+
+void DrawingView::TriangulateHandler(int mode, Point /*p*/)
 {
        switch (mode)
        {
@@ -1586,89 +1634,15 @@ void DrawingView::TriangulateHandler(int mode, Point/*p*/)
 
 void DrawingView::TrimHandler(int mode, Point p)
 {
-/*
-N.B.: this code is lifted straight out of the old oo code.  needs to be updated.
-      Also: trim tool should ignore snap.
-*/
        switch (mode)
        {
        case ToolMouseDown:
        {
-#if 0
-               Object * toTrim = doc->lastObjectHovered;
-
-               if (toTrim == NULL)
-                       return;
-
-               Vector v(((Line *)toTrim)->position, ((Line *)toTrim)->endpoint);
-
-               // Check to see which case we have...
-               // We're trimming point #1...
-               if (t == 0)
-               {
-                       ((Line *)toTrim)->position = ((Line *)toTrim)->position + (v * u);
-               }
-               else if (u == 1.0)
-               {
-                       ((Line *)toTrim)->endpoint = ((Line *)toTrim)->position + (v * t);
-               }
-               else
-               {
-                       Point p1 = ((Line *)toTrim)->position + (v * t);
-                       Point p2 = ((Line *)toTrim)->position + (v * u);
-                       Point p3 = ((Line *)toTrim)->endpoint;
-                       ((Line *)toTrim)->endpoint = p1;
-                       Line * line = new Line(p2, p3);
-                       emit ObjectReady(line);
-               }
-
-               doc->lastObjectHovered = NULL;
-#endif
        }
                break;
 
        case ToolMouseMove:
        {
-#if 0
-               Object * toTrim = doc->lastObjectHovered;
-               t = 0, u = 1.0;
-
-               if (toTrim == NULL)
-                       return;
-
-               if (toTrim->type != OTLine)
-                       return;
-
-               double pointHoveredT = Geometry::ParameterOfLineAndPoint(((Line *)toTrim)->position, ((Line *)toTrim)->endpoint, point);
-
-               std::vector<Object *>::iterator i;
-
-               for(i=doc->objects.begin(); i!=doc->objects.end(); i++)
-               {
-                       // Can't trim against yourself... :-P
-                       if (*i == toTrim)
-                               continue;
-
-                       Object * trimAgainst = *i;
-                       double t1;//, u1;
-
-                       if ((toTrim->type != OTLine) || (trimAgainst->type != OTLine))
-                               continue;
-
-                       int intersects = Geometry::Intersects((Line *)toTrim, (Line *)trimAgainst, &t1);//, &u1);
-
-                       if (intersects)
-                       {
-                               // Now what? We don't know which side to trim!
-                               // ... now we do, we know which side of the Line we're on!
-                               if ((t1 > t) && (t1 < pointHoveredT))
-                                       t = t1;
-
-                               if ((t1 < u) && (t1 > pointHoveredT))
-                                       u = t1;
-                       }
-               }
-#endif
                // Bail out if nothing hovered...
                if (numHovered != 1)
                {
@@ -1688,6 +1662,7 @@ N.B.: this code is lifted straight out of the old oo code.  needs to be updated.
 
                toolObj[0] = obj;
                double hoveredParam = Geometry::ParameterOfLineAndPoint(obj->p[0], obj->p[1], p);
+               double t = 0, u = 1.0;
 
                // Currently only deal with line against line trimming, can expand to
                // others as well (line/circle, circle/circle, line/arc, etc)
@@ -1705,13 +1680,70 @@ N.B.: this code is lifted straight out of the old oo code.  needs to be updated.
 
                        if (Global::numIntersectParams > 0)
                        {
+                               // Skip endpoint-endpoint intersections
+                               if ((Global::numIntersectParams == 2)
+                                       && (Global::intersectParam[0] == 0
+                                               || Global::intersectParam[0] == 1.0)
+                                       && (Global::intersectParam[1] == 0
+                                               || Global::intersectParam[1] == 1.0))
+                                       continue;
+
                                // Mark the line segment somehow (the side the mouse is on) so that it can be drawn & trimmed when we hit ToolMouseDown.
+                               if ((Global::intersectParam[0] > t) && (Global::intersectParam[0] < hoveredParam))
+                                       t = Global::intersectParam[0];
+
+                               if ((Global::intersectParam[0] < u) && (Global::intersectParam[0] > hoveredParam))
+                                       u = Global::intersectParam[0];
                        }
                }
+
+               toolParam[0] = t;
+               toolParam[1] = u;
+               toolPoint[0] = Geometry::GetPointForParameter(toolObj[0], t);
+               toolPoint[1] = Geometry::GetPointForParameter(toolObj[0], u);
        }
                break;
 
        case ToolMouseUp:
+       {
+               // Bail out if there's no object to trim
+               if (toolObj[0] == NULL)
+                       return;
+
+               Vector v(toolObj[0]->p[0], toolObj[0]->p[1]);
+
+               // Check to see which case we have.
+               if ((toolParam[0] == 0) && (toolParam[1] == 1.0))
+               {
+                       // There was no intersection, so delete the object
+                       toolObj[0]->selected = true;
+                       DeleteSelectedObjects(document.objects);
+               }
+               else if (toolParam[0] == 0)
+               {
+                       // We delete the end near point #1
+                       toolObj[0]->p[0] = toolObj[0]->p[0] + (v * toolParam[1]);
+               }
+               else if (toolParam[1] == 1.0)
+               {
+                       // We delete the end near point #2
+                       toolObj[0]->p[1] = toolObj[0]->p[0] + (v * toolParam[0]);
+               }
+               else
+               {
+                       // We delete the segment in between, and create a new line in the process
+                       Point p1 = toolObj[0]->p[0] + (v * toolParam[0]);
+                       Point p2 = toolObj[0]->p[0] + (v * toolParam[1]);
+                       Point p3 = toolObj[0]->p[1];
+                       toolObj[0]->p[1] = p1;
+                       Line * l = new Line(p2, p3, toolObj[0]->thickness, toolObj[0]->color, toolObj[0]->style);
+                       document.objects.push_back(l);
+//                     Global::toolState = TSNone;
+               }
+
+               toolObj[0]->hitObject = toolObj[0]->hitPoint[0] = toolObj[0]->hitPoint[1] = false;
+               toolObj[0] = NULL;
+       }
                break;
 
        case ToolKeyDown:
@@ -1753,7 +1785,6 @@ void DrawingView::mousePressEvent(QMouseEvent * event)
 {
        if (event->button() == Qt::LeftButton)
        {
-//printf("mousePressEvent::Qt::LeftButton numHovered=%li\n", numHovered);
                Vector point = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
 
                // Handle tool processing, if any
@@ -1766,12 +1797,6 @@ void DrawingView::mousePressEvent(QMouseEvent * event)
                        else if (Global::snapToGrid)
                                point = SnapPointToGrid(point);
 
-                       //Also, may want to figure out if hovering over a snap point on an
-                       //object, snap to grid if not.
-                       // Snap to object point if valid...
-//                     if (Global::snapPointIsValid)
-//                             point = Global::snapPoint;
-
                        ToolHandler(ToolMouseDown, point);
                        return;
                }
@@ -1779,49 +1804,41 @@ void DrawingView::mousePressEvent(QMouseEvent * event)
                // Clear the selection only if CTRL isn't being held on click
                if (!ctrlDown)
                        ClearSelected(document.objects);
-//                     ClearSelection();
 
-               // If any objects are being hovered on click, add them to the selection
-               // & return
+               // If any objects are being hovered on click, deal with 'em
                if (numHovered > 0)
                {
-                       AddHoveredToSelection();
-                       update();       // needed??
-//                     GetHovered(hover);      // prolly needed
                        VPVector hover2 = GetHovered();
                        dragged = (Object *)hover2[0];
-                       draggingObject = true;
-//printf("mousePressEvent::numHovered > 0 (hover2[0]=$%llx, type=%s)\n", dragged, objName[dragged->type]);
 
                        // Alert the pen widget
-// Maybe do this with an eyedropper tool on the pen bar?  [YES]
-//                     emit ObjectSelected(dragged);
                        if (Global::penDropper)
                        {
                                Global::penColor = dragged->color;
                                Global::penWidth = dragged->thickness;
                                Global::penStyle = dragged->style;
                                emit ObjectSelected(dragged);
-                               ClearSelected(document.objects);
                                return;
                        }
-
-                       if (Global::penStamp)
+                       else if (Global::penStamp)
                        {
                                dragged->color = Global::penColor;
                                dragged->thickness = Global::penWidth;
                                dragged->style = Global::penStyle;
                                return;
                        }
-
-                       // See if anything is using just a straight click on a handle
-                       if (HandleObjectClicked())
+                       // See if anything is using just a straight click on a custom
+                       // object handle (like Dimension objects)
+                       else if (HandleObjectClicked())
                        {
-                               draggingObject = false;
                                update();
                                return;
                        }
 
+                       draggingObject = true;
+                       HandleSelectionClick(hover2);
+                       update();       // needed??
+
                        // Needed for grab & moving objects
                        // We do it *after*... why? (doesn't seem to confer any advantage...)
                        if (hoveringIntersection)
@@ -2081,16 +2098,15 @@ void DrawingView::mouseReleaseEvent(QMouseEvent * event)
                        return;
                }
 
-//             if (Global::selectionInProgress)
-                       Global::selectionInProgress = false;
-
+               Global::selectionInProgress = false;
                informativeText.clear();
+
 // Should we be doing this automagically? Hmm...
                // Clear our vectors
 //             select.clear();
 ////           hover.clear();
 
-               // Scoop 'em up (do we need to??? Seems we do, because keyboard movement uses it.  Also, tools use it too.  But we can move it out of here)
+               // Scoop 'em up (do we need to??? Seems we do, because keyboard movement uses it.  Also, tools use it too.  But we can move it out of here [where to???])
                select = GetSelection();
 
                draggingObject = false;