]> Shamusworld >> Repos - architektonas/commitdiff
Added new icons, beginning of selection rectangle functionality.
authorShamus Hammons <jlhamm@acm.org>
Sun, 7 Jul 2013 20:55:33 +0000 (15:55 -0500)
committerShamus Hammons <jlhamm@acm.org>
Sun, 7 Jul 2013 20:55:33 +0000 (15:55 -0500)
res/architektonas.qrc
res/group-tool.png [new file with mode: 0644]
res/snap-to-grid-tool.png [new file with mode: 0644]
src/applicationwindow.cpp
src/container.cpp
src/container.h
src/drawingview.cpp
src/drawingview.h

index 0ff0eceb1b9b5c3ffe3d930402fdb6ff48a5a707..f32a316eb4977a4b9f5fd6952f638973f004eadf 100644 (file)
                <file>dimension-tool.png</file>
                <file>fix-angle.png</file>
                <file>fix-length.png</file>
+               <file>group-tool.png</file>
                <file>generic-tool.png</file>
                <file>rotate-tool.png</file>
+               <file>snap-to-grid-tool.png</file>
                <file>splash.png</file>
                <file>quit.png</file>
                <file>zoom-in.png</file>
diff --git a/res/group-tool.png b/res/group-tool.png
new file mode 100644 (file)
index 0000000..18d260b
Binary files /dev/null and b/res/group-tool.png differ
diff --git a/res/snap-to-grid-tool.png b/res/snap-to-grid-tool.png
new file mode 100644 (file)
index 0000000..33a7403
Binary files /dev/null and b/res/snap-to-grid-tool.png differ
index 77767f0610ae2a32b9d2df941a48f1db2e97f5b1..4aac209c35e3764bc7f59e1a8a74fad758469549 100644 (file)
@@ -398,8 +398,10 @@ void ApplicationWindow::Settings(void)
 //
 void ApplicationWindow::HandleGrouping(void)
 {
+       int itemsSelected = drawing->document.ItemsSelected();
+
        // If nothing selected, do nothing
-       if (drawing->document.ItemsSelected() == 0)
+       if (itemsSelected == 0)
        {
                statusBar()->showMessage(tr("No objects selected to make a group from."));
                return;
@@ -407,7 +409,7 @@ void ApplicationWindow::HandleGrouping(void)
 
        // If it's a group that's selected, ungroup it and leave the objects in a
        // selected state
-       if (drawing->document.ItemsSelected() == 1)
+       if (itemsSelected == 1)
        {
                Object * object = drawing->document.SelectedItem(0);
 
@@ -431,16 +433,18 @@ else
                ((Container *)object)->SelectAll();
                ((Container *)object)->MoveContentsTo(&(drawing->document));
                drawing->document.Delete(object);
+               statusBar()->showMessage(tr("Objects ungrouped."));
        }
        // Otherwise, if it's a group of 2 or more objects (which can be groups too)
        // group them and select the group
-       else if (drawing->document.ItemsSelected() > 1)
+       else if (itemsSelected > 1)
        {
                Container * container = new Container(Vector(), &(drawing->document));
                drawing->document.MoveSelectedContentsTo(container);
                drawing->document.Add(container);
                container->DeselectAll();
                container->state = OSSelected;
+               statusBar()->showMessage(QString(tr("Grouped %1 objects.")).arg(itemsSelected));
        }
 
        drawing->update();
@@ -453,7 +457,7 @@ void ApplicationWindow::CreateActions(void)
                QIcon(":/res/quit.png"), QKeySequence(tr("Ctrl+q")));
        connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
 
-       snapToGridAct = CreateAction(tr("Snap To &Grid"), tr("Snap To Grid"), tr("Snaps mouse cursor to the visible grid when moving/creating objects."), QIcon(":/res/generic-tool.png"), QKeySequence(tr("S")), true);
+       snapToGridAct = CreateAction(tr("Snap To &Grid"), tr("Snap To Grid"), tr("Snaps mouse cursor to the visible grid when moving/creating objects."), QIcon(":/res/snap-to-grid-tool.png"), QKeySequence(tr("S")), true);
        connect(snapToGridAct, SIGNAL(triggered()), this, SLOT(SnapToGridTool()));
 
        fixAngleAct = CreateAction(tr("Fix &Angle"), tr("Fix Angle"), tr("Fixes the angle of an object."),
@@ -511,7 +515,7 @@ void ApplicationWindow::CreateActions(void)
        settingsAct = CreateAction(tr("&Settings"), tr("Settings"), tr("Change certain defaults for Architektonas."), QIcon(":/res/generic-tool.png"), QKeySequence());
        connect(settingsAct, SIGNAL(triggered()), this, SLOT(Settings()));
 
-       groupAct = CreateAction(tr("&Group"), tr("Group"), tr("Group/ungroup selected objects."), QIcon(":/res/generic-tool.png"), QKeySequence("g"));
+       groupAct = CreateAction(tr("&Group"), tr("Group"), tr("Group/ungroup selected objects."), QIcon(":/res/group-tool.png"), QKeySequence("g"));
        connect(groupAct, SIGNAL(triggered()), this, SLOT(HandleGrouping()));
 
 //Hm. I think we'll have to have separate logic to do the "Radio Group Toolbar" thing...
index cd9b4f5ef5880772601dcff6606cc7728e76eb1b..bd37b7738610a1e4c54586699b2932cf57cec417 100644 (file)
@@ -21,6 +21,7 @@
 
 
 Container::Container(Vector p1, Object * p/*= NULL*/): Object(p1, p),
+       isTopLevelContainer(false),
        dragging(false), draggingHandle1(false), draggingHandle2(false)//, needUpdate(false)
 {
        type = OTContainer;
@@ -111,6 +112,14 @@ Also: should put the snap logic into the Object base class (as a static method).
 */
 
 
+// Need to add checking here for clicking on a member of a group (Container),
+// and checking for if it's a top level container (the DrawingView's document).
+/*
+One approach is to check for the parent of the container: If it's NULL, then it's
+the DrawingView's document. It might be better, though, to set a boolean like
+isTopLevelContainer so that we can do things like edit members of a group without
+having to ungroup them first (like Inkscape).
+*/
 /*virtual*/ bool Container::Collided(Vector point)
 {
        objectWasDragged = false;
@@ -144,8 +153,19 @@ printf("Container::Collided: Deleting object ($%X)\n", *i);
                }
        }
 
-       // Do we decouple the state of the generic container from the objects inside??? Mebbe.
-       state = OSInactive;
+       // We check to see if the container we're trying to access is the
+       // DrawingView's document. If so, we ignore the state of the container.
+       // Otherwise, we care about the state of the container. :-)
+       if (isTopLevelContainer)
+               state = OSInactive;
+       else
+       {
+               state = (collision ? OSSelected : OSInactive);
+
+               if (state == OSSelected)
+                       DeselectAll();
+       }
+
        return collision;
 }
 
@@ -162,10 +182,12 @@ printf("Container::Collided: Deleting object ($%X)\n", *i);
 //     objectWasDragged = true;
 //printf("CONTAINER: PointerMoved()\n");
 
-       for(int i=0; i<(int)objects.size(); i++)
+       for(std::vector<Object *>::iterator i=objects.begin(); i!=objects.end(); i++)
+//     for(int i=0; i<(int)objects.size(); i++)
        {
-//             if (objects[i]->GetState() == OSSelected)
-                       objects[i]->PointerMoved(point);
+////           if (objects[i]->GetState() == OSSelected)
+//                     objects[i]->PointerMoved(point);
+               (*i)->PointerMoved(point);
        }
 
        // Generic container doesn't need this???
@@ -196,15 +218,15 @@ about keeping track of old states...
 
 /*virtual*/ bool Container::NeedsUpdate(void)
 {
-       needUpdate = false;
-
-       for(uint i=0; i<objects.size(); i++)
+       // Search through objects for one that needs an update; if one is found,
+       // return immediately.
+       for(std::vector<Object *>::iterator i=objects.begin(); i!=objects.end(); i++)
        {
-               if (objects[i]->NeedsUpdate())
-                       needUpdate = true;
+               if ((*i)->NeedsUpdate())
+                       return true;
        }
 
-       return needUpdate;
+       return false;
 }
 
 
@@ -215,14 +237,6 @@ printf("Container: Added object (=$%X). size = %li\n", object, objects.size());
 }
 
 
-#if 0
-/*virtual*/ ObjectType Container::Type(void)
-{
-       return OTContainer;
-}
-#endif
-
-
 void Container::Delete(Object * objectToDelete)
 {
        std::vector<Object *>::iterator i = objects.begin();
@@ -260,15 +274,6 @@ void Container::DeleteSelectedItems(void)
 
 void Container::Clear(void)
 {
-#if 0
-       // No memory leaks!
-       while (objects.size() > 0)
-       {
-printf("Container: Deleting object ($%X)...\n", objects[0]);
-               delete objects[0];
-               objects.erase(objects.begin());
-       }
-#else
        std::vector<Object *>::iterator i = objects.begin();
 
        while (i != objects.end())
@@ -277,7 +282,6 @@ printf("Container: Deleting object ($%X)...\n", *i);
                delete (*i);
                objects.erase(i);
        }
-#endif
 }
 
 
index 8744f64d47a21c60642c7668014d9ab73868a00e..7e6a14d1b0647feaad94caf94ff9356ec3639668 100644 (file)
@@ -21,16 +21,13 @@ class Container: public Object
                virtual bool NeedsUpdate(void);
                virtual void Add(Object *);
                virtual void Enumerate(FILE *);
-//             virtual ObjectType Type(void);
                void Delete(Object *);
                void DeleteSelectedItems(void);
                void Clear(void);
                void SelectAll(void);
                void DeselectAll(void);
                int ItemsSelected(void);
-//             ObjectType SelectedItemType(unsigned int);
                Object * SelectedItem(unsigned int);
-//             void ReparentContentsTo(Object *);
                void MoveContentsTo(Container *);
                void MoveSelectedContentsTo(Container *);
 
@@ -39,11 +36,11 @@ class Container: public Object
 
        public:
                std::vector<Object *> objects;
+               bool isTopLevelContainer;
        private:
                bool dragging;
                bool draggingHandle1;
                bool draggingHandle2;
-//             bool needUpdate;
                bool objectWasDragged;
 };
 
index 330f73377540c8e96c9cd2388f0888344534dfde..1c095f4a73b41a3a5b070e880c81f4cb8372c04e 100644 (file)
@@ -50,8 +50,11 @@ DrawingView::DrawingView(QWidget * parent/*= NULL*/): QWidget(parent),
 //     gridSpacing(32.0), collided(false), rotateTool(false), rx(150.0), ry(150.0),
        gridSpacing(12.0), collided(false), rotateTool(false), rx(150.0), ry(150.0),
        scrollDrag(false), addLineTool(false), addCircleTool(false),
-       addDimensionTool(false), toolAction(NULL)
+       addDimensionTool(false),
+       selectionInProgress(false),
+       toolAction(NULL)
 {
+       document.isTopLevelContainer = true;
        setBackgroundRole(QPalette::Base);
        setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
 
@@ -280,6 +283,15 @@ void DrawingView::paintEvent(QPaintEvent * /*event*/)
 
        if (toolAction)
                toolAction->Draw(&painter);
+
+       if (selectionInProgress)
+       {
+//             painter.SetPen(QPen(Qt::green, 1.0, Qt::SolidLine));
+               painter.SetPen(QPen(QColor(255, 127, 0, 255)));
+//             painter.SetBrush(QBrush(Qt::NoBrush));
+               painter.SetBrush(QBrush(QColor(255, 127, 0, 100)));
+               painter.DrawRect(selection);
+       }
 }
 
 
@@ -295,6 +307,14 @@ void DrawingView::mousePressEvent(QMouseEvent * event)
 
                if (toolAction)
                        toolAction->MouseDown(point);
+
+               // Didn't hit any object and not using a tool, so do a selection rectangle
+               if (!(collided || toolAction))
+               {
+                       selectionInProgress = true;
+                       selection.setTopLeft(QPointF(point.x, point.y));
+                       selection.setBottomRight(QPointF(point.x, point.y));
+               }
        }
        else if (event->button() == Qt::MiddleButton)
        {
@@ -309,6 +329,7 @@ void DrawingView::mousePressEvent(QMouseEvent * event)
 void DrawingView::mouseMoveEvent(QMouseEvent * event)
 {
        Vector point = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+       selection.setBottomRight(QPointF(point.x, point.y));
 
        if (event->buttons() & Qt::MiddleButton)
        {
@@ -352,7 +373,7 @@ void DrawingView::mouseMoveEvent(QMouseEvent * event)
 //changed...
        document.PointerMoved(point);
 
-       if (document.NeedsUpdate())
+       if (document.NeedsUpdate() || selectionInProgress)
                update();
 
        if (toolAction)
@@ -378,6 +399,12 @@ void DrawingView::mouseReleaseEvent(QMouseEvent * event)
 
                if (toolAction)
                        toolAction->MouseReleased();
+
+               if (selectionInProgress)
+               {
+                       // Select all the stuff inside of selection
+                       selectionInProgress = false;
+               }
        }
        else if (event->button() == Qt::MiddleButton)
        {
index ac7170d026bd63c44a65a23caa4a4c83005a4a94..eaf8826f564e4d6ab747ed78bd61bb6044de6c8a 100644 (file)
@@ -54,6 +54,8 @@ class DrawingView: public QWidget
                bool addLineTool;
                bool addCircleTool;
                bool addDimensionTool;
+               bool selectionInProgress;
+               QRectF selection;
 
        public:
                Action * toolAction;