From e8e915bcdecaf2c35389d92f57ce2867372b0a2e Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Wed, 18 May 2016 10:46:25 -0400 Subject: [PATCH] Share selection functionality with instance editing mode. --- apps/opencs/CMakeLists.txt | 2 +- .../view/render/instanceselectionmode.cpp | 102 ++++++------------ .../view/render/instanceselectionmode.hpp | 30 ++---- apps/opencs/view/render/pathgridmode.cpp | 82 ++------------ apps/opencs/view/render/pathgridmode.hpp | 18 +--- .../view/render/pathgridselectionmode.cpp | 71 ++++++++++++ .../view/render/pathgridselectionmode.hpp | 38 +++++++ apps/opencs/view/render/selectionmode.cpp | 77 +++++++++++++ apps/opencs/view/render/selectionmode.hpp | 51 +++++++++ 9 files changed, 293 insertions(+), 178 deletions(-) create mode 100644 apps/opencs/view/render/pathgridselectionmode.cpp create mode 100644 apps/opencs/view/render/pathgridselectionmode.hpp create mode 100644 apps/opencs/view/render/selectionmode.cpp create mode 100644 apps/opencs/view/render/selectionmode.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index b33dc1508..f8cf1e2d8 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -86,7 +86,7 @@ opencs_units (view/widget opencs_units (view/render scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget previewwidget editmode instancemode instanceselectionmode instancemovemode - orbitcameramode pathgridmode + orbitcameramode pathgridmode selectionmode pathgridselectionmode ) opencs_units_noqt (view/render diff --git a/apps/opencs/view/render/instanceselectionmode.cpp b/apps/opencs/view/render/instanceselectionmode.cpp index 5c3aaa8d1..bf8ede0eb 100644 --- a/apps/opencs/view/render/instanceselectionmode.cpp +++ b/apps/opencs/view/render/instanceselectionmode.cpp @@ -1,4 +1,3 @@ - #include "instanceselectionmode.hpp" #include @@ -10,84 +9,49 @@ #include "worldspacewidget.hpp" #include "object.hpp" -bool CSVRender::InstanceSelectionMode::createContextMenu (QMenu *menu) +namespace CSVRender { - if (menu) + InstanceSelectionMode::InstanceSelectionMode(CSVWidget::SceneToolbar* parent, WorldspaceWidget& worldspaceWidget) + : SelectionMode(parent, worldspaceWidget, Mask_Reference) { - menu->addAction (mSelectAll); - menu->addAction (mDeselectAll); - menu->addAction (mSelectSame); - menu->addAction (mDeleteSelection); - } + mSelectSame = new QAction("Extend selection to instances with same object ID", this); + mDeleteSelection = new QAction("Delete selected instances", this); - return true; -} + connect(mSelectSame, SIGNAL(triggered()), this, SLOT(selectSame())); + connect(mDeleteSelection, SIGNAL(triggered()), this, SLOT(deleteSelection())); + } -CSVRender::InstanceSelectionMode::InstanceSelectionMode (CSVWidget::SceneToolbar *parent, - WorldspaceWidget& worldspaceWidget) -: CSVWidget::SceneToolMode (parent, "Selection Mode"), mWorldspaceWidget (worldspaceWidget) -{ - addButton (":placeholder", "cube-centre", - "Centred cube" - "" - "Not implemented yet"); - addButton (":placeholder", "cube-corner", - "Cube corner to corner" - "" - "Not implemented yet"); - addButton (":placeholder", "sphere", - "Centred sphere" - "" - "Not implemented yet"); + bool InstanceSelectionMode::createContextMenu(QMenu* menu) + { + if (menu) + { + SelectionMode::createContextMenu(menu); - mSelectAll = new QAction ("Select all instances", this); - mDeselectAll = new QAction ("Clear selection", this); - mDeleteSelection = new QAction ("Delete selected instances", this); - mSelectSame = new QAction ("Extend selection to instances with same object ID", this); - connect (mSelectAll, SIGNAL (triggered ()), this, SLOT (selectAll())); - connect (mDeselectAll, SIGNAL (triggered ()), this, SLOT (clearSelection())); - connect (mDeleteSelection, SIGNAL (triggered ()), this, SLOT (deleteSelection())); - connect (mSelectSame, SIGNAL (triggered ()), this, SLOT (selectSame())); -} + menu->addAction(mSelectSame); + menu->addAction(mDeleteSelection); + } -void CSVRender::InstanceSelectionMode::selectAll() -{ - mWorldspaceWidget.selectAll (Mask_Reference); -} + return true; + } -void CSVRender::InstanceSelectionMode::clearSelection() -{ - mWorldspaceWidget.clearSelection (Mask_Reference); -} + void InstanceSelectionMode::selectSame() + { + getWorldspaceWidget().selectAllWithSameParentId(Mask_Reference); + } -void CSVRender::InstanceSelectionMode::deleteSelection() -{ - std::vector > selection = - mWorldspaceWidget.getSelection (Mask_Reference); + void InstanceSelectionMode::deleteSelection() + { + std::vector > selection = getWorldspaceWidget().getSelection(Mask_Reference); - CSMWorld::IdTable& referencesTable = - dynamic_cast (*mWorldspaceWidget.getDocument().getData(). - getTableModel (CSMWorld::UniversalId::Type_References)); + CSMWorld::IdTable& referencesTable = dynamic_cast( + *getWorldspaceWidget().getDocument().getData().getTableModel(CSMWorld::UniversalId::Type_References)); - for (std::vector >::iterator iter (selection.begin()); - iter!=selection.end(); ++iter) - { - CSMWorld::DeleteCommand *command = new CSMWorld::DeleteCommand (referencesTable, - static_cast (iter->get())->mObject->getReferenceId()); + for (std::vector >::iterator iter = selection.begin(); iter != selection.end(); ++iter) + { + CSMWorld::DeleteCommand* command = new CSMWorld::DeleteCommand(referencesTable, + static_cast(iter->get())->mObject->getReferenceId()); - mWorldspaceWidget.getDocument().getUndoStack().push (command); + getWorldspaceWidget().getDocument().getUndoStack().push(command); + } } } - -void CSVRender::InstanceSelectionMode::selectSame() -{ - mWorldspaceWidget.selectAllWithSameParentId (Mask_Reference); -} diff --git a/apps/opencs/view/render/instanceselectionmode.hpp b/apps/opencs/view/render/instanceselectionmode.hpp index cac2ca8c2..a590240d9 100644 --- a/apps/opencs/view/render/instanceselectionmode.hpp +++ b/apps/opencs/view/render/instanceselectionmode.hpp @@ -1,23 +1,19 @@ #ifndef CSV_RENDER_INSTANCE_SELECTION_MODE_H #define CSV_RENDER_INSTANCE_SELECTION_MODE_H -#include "../widget/scenetoolmode.hpp" - -class QAction; +#include "selectionmode.hpp" namespace CSVRender { - class WorldspaceWidget; - - class InstanceSelectionMode : public CSVWidget::SceneToolMode + class InstanceSelectionMode : public SelectionMode { Q_OBJECT - WorldspaceWidget& mWorldspaceWidget; - QAction *mSelectAll; - QAction *mDeselectAll; - QAction *mDeleteSelection; - QAction *mSelectSame; + public: + + InstanceSelectionMode(CSVWidget::SceneToolbar* parent, WorldspaceWidget& worldspaceWidget); + + protected: /// Add context menu items to \a menu. /// @@ -25,20 +21,16 @@ namespace CSVRender /// /// \return Have there been any menu items to be added (if menu is 0 and there /// items to be added, the function must return true anyway. - virtual bool createContextMenu (QMenu *menu); + bool createContextMenu(QMenu* menu); - public: + private: - InstanceSelectionMode (CSVWidget::SceneToolbar *parent, WorldspaceWidget& worldspaceWidget); + QAction* mDeleteSelection; + QAction* mSelectSame; private slots: - void selectAll(); - - void clearSelection(); - void deleteSelection(); - void selectSame(); }; } diff --git a/apps/opencs/view/render/pathgridmode.cpp b/apps/opencs/view/render/pathgridmode.cpp index 3a2cc600a..0dd458346 100644 --- a/apps/opencs/view/render/pathgridmode.cpp +++ b/apps/opencs/view/render/pathgridmode.cpp @@ -10,9 +10,12 @@ #include "../../model/world/idtable.hpp" #include "../../model/world/idtree.hpp" +#include "../widget/scenetoolbar.hpp" + #include "cell.hpp" #include "mask.hpp" #include "pathgrid.hpp" +#include "pathgridselectionmode.hpp" #include "worldspacewidget.hpp" namespace CSVRender @@ -22,6 +25,7 @@ namespace CSVRender getTooltip(), parent) , mDragMode(DragMode_None) , mFromNode(0) + , mSelectionMode(0) { } @@ -39,33 +43,13 @@ namespace CSVRender void PathgridMode::activate(CSVWidget::SceneToolbar* toolbar) { - mSelectAll = new QAction("Select all other nodes in cell", this); - mInvertSelection = new QAction("Invert selection", this); - mClearSelection = new QAction("Clear selection", this); - mRemoveSelected = new QAction("Remove selected nodes", this); - mRemoveSelectedEdges = new QAction("Remove edges between selected nodes", this); - - connect(mSelectAll, SIGNAL(triggered()), this, SLOT(selectAll())); - connect(mInvertSelection, SIGNAL(triggered()), this, SLOT(invertSelection())); - connect(mClearSelection, SIGNAL(triggered()), this, SLOT(clearSelection())); - connect(mRemoveSelected, SIGNAL(triggered()), this, SLOT(removeSelected())); - connect(mRemoveSelectedEdges, SIGNAL(triggered()), this, SLOT(removeSelectedEdges())); - - EditMode::activate(toolbar); - } - - bool PathgridMode::createContextMenu(QMenu* menu) - { - if (menu) + if (!mSelectionMode) { - menu->addAction(mSelectAll); - menu->addAction(mInvertSelection); - menu->addAction(mClearSelection); - menu->addAction(mRemoveSelected); - menu->addAction(mRemoveSelectedEdges); + mSelectionMode = new PathgridSelectionMode(toolbar, getWorldspaceWidget()); } - return true; + EditMode::activate(toolbar); + toolbar->addTool(mSelectionMode); } void PathgridMode::primaryEditPressed(const WorldspaceHitResult& hitResult) @@ -245,54 +229,4 @@ namespace CSVRender { getWorldspaceWidget().reset(Mask_Pathgrid); } - - void PathgridMode::selectAll() - { - // Select rest of nodes in selected cell - getWorldspaceWidget().selectAll(Mask_Pathgrid); - } - - void PathgridMode::invertSelection() - { - getWorldspaceWidget().invertSelection(Mask_Pathgrid); - } - - void PathgridMode::clearSelection() - { - getWorldspaceWidget().clearSelection(Mask_Pathgrid); - } - - void PathgridMode::removeSelected() - { - std::vector > selection = getWorldspaceWidget().getSelection (Mask_Pathgrid); - - for (std::vector >::iterator it = selection.begin(); it != selection.end(); ++it) - { - if (PathgridTag* tag = dynamic_cast(it->get())) - { - QUndoStack& undoStack = getWorldspaceWidget().getDocument().getUndoStack(); - QString description = "Remove selected nodes"; - - CSMWorld::CommandMacro macro(undoStack, description); - tag->getPathgrid()->applyRemoveNodes(macro); - } - } - } - - void PathgridMode::removeSelectedEdges() - { - std::vector > selection = getWorldspaceWidget().getSelection (Mask_Pathgrid); - - for (std::vector >::iterator it = selection.begin(); it != selection.end(); ++it) - { - if (PathgridTag* tag = dynamic_cast(it->get())) - { - QUndoStack& undoStack = getWorldspaceWidget().getDocument().getUndoStack(); - QString description = "Remove edges between selected nodes"; - - CSMWorld::CommandMacro macro(undoStack, description); - tag->getPathgrid()->applyRemoveEdges(macro); - } - } - } } diff --git a/apps/opencs/view/render/pathgridmode.hpp b/apps/opencs/view/render/pathgridmode.hpp index b6933cb8e..908eefa5b 100644 --- a/apps/opencs/view/render/pathgridmode.hpp +++ b/apps/opencs/view/render/pathgridmode.hpp @@ -7,6 +7,8 @@ namespace CSVRender { + class PathgridSelectionMode; + class PathgridMode : public EditMode { Q_OBJECT @@ -17,8 +19,6 @@ namespace CSVRender virtual void activate(CSVWidget::SceneToolbar* toolbar); - virtual bool createContextMenu(QMenu* menu); - virtual void primaryEditPressed(const WorldspaceHitResult& hit); virtual void secondaryEditPressed(const WorldspaceHitResult& hit); @@ -52,21 +52,9 @@ namespace CSVRender std::string mLastId, mEdgeId; unsigned short mFromNode; - QAction* mSelectAll; - QAction* mInvertSelection; - QAction* mClearSelection; - QAction* mRemoveSelected; - QAction* mRemoveSelectedEdges; + PathgridSelectionMode* mSelectionMode; QString getTooltip(); - - private slots: - - void selectAll(); - void invertSelection(); - void clearSelection(); - void removeSelected(); - void removeSelectedEdges(); }; } diff --git a/apps/opencs/view/render/pathgridselectionmode.cpp b/apps/opencs/view/render/pathgridselectionmode.cpp new file mode 100644 index 000000000..db41faf50 --- /dev/null +++ b/apps/opencs/view/render/pathgridselectionmode.cpp @@ -0,0 +1,71 @@ +#include "pathgridselectionmode.hpp" + +#include +#include + +#include "../../model/world/idtable.hpp" +#include "../../model/world/commands.hpp" +#include "../../model/world/commandmacro.hpp" + +#include "worldspacewidget.hpp" +#include "pathgrid.hpp" + +namespace CSVRender +{ + PathgridSelectionMode::PathgridSelectionMode(CSVWidget::SceneToolbar* parent, WorldspaceWidget& worldspaceWidget) + : SelectionMode(parent, worldspaceWidget, Mask_Pathgrid) + { + mRemoveSelectedNodes = new QAction("Remove selected nodes", this); + mRemoveSelectedEdges = new QAction("Remove edges between selected nodes", this); + + connect(mRemoveSelectedNodes, SIGNAL(triggered()), this, SLOT(removeSelectedNodes())); + connect(mRemoveSelectedEdges, SIGNAL(triggered()), this, SLOT(removeSelectedEdges())); + } + + bool PathgridSelectionMode::createContextMenu(QMenu* menu) + { + if (menu) + { + SelectionMode::createContextMenu(menu); + + menu->addAction(mRemoveSelectedNodes); + menu->addAction(mRemoveSelectedEdges); + } + + return true; + } + + void PathgridSelectionMode::removeSelectedNodes() + { + std::vector > selection = getWorldspaceWidget().getSelection (Mask_Pathgrid); + + for (std::vector >::iterator it = selection.begin(); it != selection.end(); ++it) + { + if (PathgridTag* tag = dynamic_cast(it->get())) + { + QUndoStack& undoStack = getWorldspaceWidget().getDocument().getUndoStack(); + QString description = "Remove selected nodes"; + + CSMWorld::CommandMacro macro(undoStack, description); + tag->getPathgrid()->applyRemoveNodes(macro); + } + } + } + + void PathgridSelectionMode::removeSelectedEdges() + { + std::vector > selection = getWorldspaceWidget().getSelection (Mask_Pathgrid); + + for (std::vector >::iterator it = selection.begin(); it != selection.end(); ++it) + { + if (PathgridTag* tag = dynamic_cast(it->get())) + { + QUndoStack& undoStack = getWorldspaceWidget().getDocument().getUndoStack(); + QString description = "Remove edges between selected nodes"; + + CSMWorld::CommandMacro macro(undoStack, description); + tag->getPathgrid()->applyRemoveEdges(macro); + } + } + } +} diff --git a/apps/opencs/view/render/pathgridselectionmode.hpp b/apps/opencs/view/render/pathgridselectionmode.hpp new file mode 100644 index 000000000..e4cb1e044 --- /dev/null +++ b/apps/opencs/view/render/pathgridselectionmode.hpp @@ -0,0 +1,38 @@ +#ifndef CSV_RENDER_PATHGRID_SELECTION_MODE_H +#define CSV_RENDER_PATHGRID_SELECTION_MODE_H + +#include "selectionmode.hpp" + +namespace CSVRender +{ + class PathgridSelectionMode : public SelectionMode + { + Q_OBJECT + + public: + + PathgridSelectionMode(CSVWidget::SceneToolbar* parent, WorldspaceWidget& worldspaceWidget); + + protected: + + /// Add context menu items to \a menu. + /// + /// \attention menu can be a 0-pointer + /// + /// \return Have there been any menu items to be added (if menu is 0 and there + /// items to be added, the function must return true anyway. + bool createContextMenu(QMenu* menu); + + private: + + QAction* mRemoveSelectedNodes; + QAction* mRemoveSelectedEdges; + + private slots: + + void removeSelectedNodes(); + void removeSelectedEdges(); + }; +} + +#endif diff --git a/apps/opencs/view/render/selectionmode.cpp b/apps/opencs/view/render/selectionmode.cpp new file mode 100644 index 000000000..82a3c49e4 --- /dev/null +++ b/apps/opencs/view/render/selectionmode.cpp @@ -0,0 +1,77 @@ +#include "selectionmode.hpp" + +#include +#include + +#include "worldspacewidget.hpp" + +namespace CSVRender +{ + SelectionMode::SelectionMode(CSVWidget::SceneToolbar* parent, WorldspaceWidget& worldspaceWidget, + unsigned int interactionMask) + : SceneToolMode(parent, "Selection mode") + , mWorldspaceWidget(worldspaceWidget) + , mInteractionMask(interactionMask) + { + addButton(":placeholder", "cube-centre", + "Centred cube" + "
  • Drag with primary (make instances the selection) or secondary (invert selection state) select button from the centre of the selection cube outwards
  • " + "
  • The selection cube is aligned to the word space axis
  • " + "
  • If context selection mode is enabled, a drag with primary/secondary edit not starting on an instance will have the same effect
  • " + "
" + "Not implemented yet"); + addButton(":placeholder", "cube-corner", + "Cube corner to corner" + "
  • Drag with primary (make instances the selection) or secondary (invert selection state) select button from one corner of the selection cube to the opposite corner
  • " + "
  • The selection cube is aligned to the word space axis
  • " + "
  • If context selection mode is enabled, a drag with primary/secondary edit not starting on an instance will have the same effect
  • " + "
" + "Not implemented yet"); + addButton(":placeholder", "sphere", + "Centred sphere" + "
  • Drag with primary (make instances the selection) or secondary (invert selection state) select button from the centre of the selection sphere outwards
  • " + "
  • If context selection mode is enabled, a drag with primary/secondary edit not starting on an instance will have the same effect
  • " + "
" + "Not implemented yet"); + + mSelectAll = new QAction("Select all", this); + mDeselectAll = new QAction("Clear selection", this); + mInvertSelection = new QAction("Invert selection", this); + + connect(mSelectAll, SIGNAL(triggered()), this, SLOT(selectAll())); + connect(mDeselectAll, SIGNAL(triggered()), this, SLOT(clearSelection())); + connect(mInvertSelection, SIGNAL(triggered()), this, SLOT(invertSelection())); + } + + WorldspaceWidget& SelectionMode::getWorldspaceWidget() + { + return mWorldspaceWidget; + } + + bool SelectionMode::createContextMenu (QMenu* menu) + { + if (menu) + { + menu->addAction(mSelectAll); + menu->addAction(mDeselectAll); + menu->addAction(mInvertSelection); + } + + return true; + } + + void SelectionMode::selectAll() + { + getWorldspaceWidget().selectAll(mInteractionMask); + } + + void SelectionMode::clearSelection() + { + getWorldspaceWidget().clearSelection(mInteractionMask); + } + + void SelectionMode::invertSelection() + { + getWorldspaceWidget().invertSelection(mInteractionMask); + } +} diff --git a/apps/opencs/view/render/selectionmode.hpp b/apps/opencs/view/render/selectionmode.hpp new file mode 100644 index 000000000..f28888bfd --- /dev/null +++ b/apps/opencs/view/render/selectionmode.hpp @@ -0,0 +1,51 @@ +#ifndef CSV_RENDER_SELECTION_MODE_H +#define CSV_RENDER_SELECTION_MODE_H + +#include "../widget/scenetoolmode.hpp" + +#include "mask.hpp" + +class QAction; + +namespace CSVRender +{ + class WorldspaceWidget; + + class SelectionMode : public CSVWidget::SceneToolMode + { + Q_OBJECT + + public: + + SelectionMode(CSVWidget::SceneToolbar* parent, WorldspaceWidget& worldspaceWidget, + unsigned int interactionMask); + + protected: + + WorldspaceWidget& getWorldspaceWidget(); + + /// Add context menu items to \a menu. + /// + /// \attention menu can be a 0-pointer + /// + /// \return Have there been any menu items to be added (if menu is 0 and there + /// items to be added, the function must return true anyway. + virtual bool createContextMenu (QMenu* menu); + + private: + + WorldspaceWidget& mWorldspaceWidget; + unsigned int mInteractionMask; + QAction* mSelectAll; + QAction* mDeselectAll; + QAction* mInvertSelection; + + protected slots: + + virtual void selectAll(); + virtual void clearSelection(); + virtual void invertSelection(); + }; +} + +#endif