From c1901069be63ecd09b6c5d34d3e56807c3c05bb2 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 15 Jan 2016 12:07:25 +0100 Subject: [PATCH 01/10] added instance mode sub-modes --- apps/opencs/view/render/instancemode.cpp | 43 +++++++++++++++++++++++- apps/opencs/view/render/instancemode.hpp | 10 ++++++ apps/opencs/view/world/scenesubview.cpp | 2 +- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/render/instancemode.cpp b/apps/opencs/view/render/instancemode.cpp index b6430036b..449d9d7a6 100644 --- a/apps/opencs/view/render/instancemode.cpp +++ b/apps/opencs/view/render/instancemode.cpp @@ -9,6 +9,9 @@ #include "../../model/world/idtree.hpp" #include "../../model/world/commands.hpp" +#include "../widget/scenetoolbar.hpp" +#include "../widget/scenetoolmode.hpp" + #include "elements.hpp" #include "object.hpp" #include "worldspacewidget.hpp" @@ -16,9 +19,47 @@ CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent) : EditMode (worldspaceWidget, QIcon (":placeholder"), Element_Reference, "Instance editing", - parent) + parent), mSubMode (0) +{ +} + +void CSVRender::InstanceMode::activate (CSVWidget::SceneToolbar *toolbar) +{ + if (!mSubMode) + { + mSubMode = new CSVWidget::SceneToolMode (toolbar, "Edit Sub-Mode"); + mSubMode->addButton (":placeholder", "move", + "Move selected instances" + "" + "Not implemented yet"); + mSubMode->addButton (":placeholder", "rotate", + "Rotate selected instances" + "" + "Not implemented yet"); + mSubMode->addButton (":placeholder", "scale", + "Scale selected instances" + "" + "Not implemented yet"); + } + + EditMode::activate (toolbar); + + toolbar->addTool (mSubMode); +} + +void CSVRender::InstanceMode::deactivate (CSVWidget::SceneToolbar *toolbar) { + toolbar->removeTool (mSubMode); + delete mSubMode; + mSubMode = 0; + EditMode::deactivate (toolbar); } void CSVRender::InstanceMode::primaryEditPressed (osg::ref_ptr tag) diff --git a/apps/opencs/view/render/instancemode.hpp b/apps/opencs/view/render/instancemode.hpp index 7649c241c..1eec62874 100644 --- a/apps/opencs/view/render/instancemode.hpp +++ b/apps/opencs/view/render/instancemode.hpp @@ -3,16 +3,26 @@ #include "editmode.hpp" +namespace CSVWidget +{ + class SceneToolMode; +} + namespace CSVRender { class InstanceMode : public EditMode { Q_OBJECT + CSVWidget::SceneToolMode *mSubMode; public: InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent = 0); + virtual void activate (CSVWidget::SceneToolbar *toolbar); + + virtual void deactivate (CSVWidget::SceneToolbar *toolbar); + virtual void primaryEditPressed (osg::ref_ptr tag); virtual void secondaryEditPressed (osg::ref_ptr tag); diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 44fe94d84..7014b1486 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -122,7 +122,7 @@ CSVWidget::SceneToolbar* CSVWorld::SceneSubView::makeToolbar (CSVRender::Worldsp CSVWidget::SceneToolRun *runTool = widget->makeRunTool (toolbar); toolbar->addTool (runTool); - toolbar->addTool (widget->makeEditModeSelector (toolbar)); + toolbar->addTool (widget->makeEditModeSelector (toolbar), runTool); return toolbar; } From 0305ae369327ad39a354a5b7f91abaed424b0287 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 19 Jan 2016 12:17:13 +0100 Subject: [PATCH 02/10] added selection mode UI --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/view/render/instancemode.cpp | 23 +++++++++++++--- apps/opencs/view/render/instancemode.hpp | 3 +++ .../view/render/instanceselectionmode.cpp | 27 +++++++++++++++++++ .../view/render/instanceselectionmode.hpp | 19 +++++++++++++ 5 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 apps/opencs/view/render/instanceselectionmode.cpp create mode 100644 apps/opencs/view/render/instanceselectionmode.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 0e9a49432..ae4bbd66c 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -85,7 +85,7 @@ opencs_units (view/widget opencs_units (view/render scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget - previewwidget editmode instancemode + previewwidget editmode instancemode instanceselectionmode ) opencs_units_noqt (view/render diff --git a/apps/opencs/view/render/instancemode.cpp b/apps/opencs/view/render/instancemode.cpp index 449d9d7a6..53ebc7052 100644 --- a/apps/opencs/view/render/instancemode.cpp +++ b/apps/opencs/view/render/instancemode.cpp @@ -16,10 +16,11 @@ #include "object.hpp" #include "worldspacewidget.hpp" #include "pagedworldspacewidget.hpp" +#include "instanceselectionmode.hpp" CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent) : EditMode (worldspaceWidget, QIcon (":placeholder"), Element_Reference, "Instance editing", - parent), mSubMode (0) + parent), mSubMode (0), mSelectionMode (0) { } @@ -48,16 +49,30 @@ void CSVRender::InstanceMode::activate (CSVWidget::SceneToolbar *toolbar) "Not implemented yet"); } + if (!mSelectionMode) + mSelectionMode = new InstanceSelectionMode (toolbar); + EditMode::activate (toolbar); toolbar->addTool (mSubMode); + toolbar->addTool (mSelectionMode); } void CSVRender::InstanceMode::deactivate (CSVWidget::SceneToolbar *toolbar) { - toolbar->removeTool (mSubMode); - delete mSubMode; - mSubMode = 0; + if (mSelectionMode) + { + toolbar->removeTool (mSelectionMode); + delete mSelectionMode; + mSelectionMode = 0; + } + + if (mSubMode) + { + toolbar->removeTool (mSubMode); + delete mSubMode; + mSubMode = 0; + } EditMode::deactivate (toolbar); } diff --git a/apps/opencs/view/render/instancemode.hpp b/apps/opencs/view/render/instancemode.hpp index 1eec62874..78836878a 100644 --- a/apps/opencs/view/render/instancemode.hpp +++ b/apps/opencs/view/render/instancemode.hpp @@ -10,10 +10,13 @@ namespace CSVWidget namespace CSVRender { + class InstanceSelectionMode; + class InstanceMode : public EditMode { Q_OBJECT CSVWidget::SceneToolMode *mSubMode; + InstanceSelectionMode *mSelectionMode; public: diff --git a/apps/opencs/view/render/instanceselectionmode.cpp b/apps/opencs/view/render/instanceselectionmode.cpp new file mode 100644 index 000000000..9fd825999 --- /dev/null +++ b/apps/opencs/view/render/instanceselectionmode.cpp @@ -0,0 +1,27 @@ + +#include "instanceselectionmode.hpp" + +CSVRender::InstanceSelectionMode::InstanceSelectionMode (CSVWidget::SceneToolbar *parent) +: CSVWidget::SceneToolMode (parent, "Selection Mode") +{ + 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"); +} diff --git a/apps/opencs/view/render/instanceselectionmode.hpp b/apps/opencs/view/render/instanceselectionmode.hpp new file mode 100644 index 000000000..e823de213 --- /dev/null +++ b/apps/opencs/view/render/instanceselectionmode.hpp @@ -0,0 +1,19 @@ +#ifndef CSV_RENDER_INSTANCE_SELECTION_MODE_H +#define CSV_RENDER_INSTANCE_SELECTION_MODE_H + +#include "../widget/scenetoolmode.hpp" + +namespace CSVRender +{ + class InstanceSelectionMode : public CSVWidget::SceneToolMode + { + Q_OBJECT + + public: + + InstanceSelectionMode (CSVWidget::SceneToolbar *parent); + + }; +} + +#endif From eee972a1a4414a065e55153fe88413f7e6229cfc Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 19 Jan 2016 12:47:11 +0100 Subject: [PATCH 03/10] added scene tool mode context menu feature --- apps/opencs/view/widget/scenetoolmode.cpp | 17 +++++++++++++++++ apps/opencs/view/widget/scenetoolmode.hpp | 11 +++++++++++ 2 files changed, 28 insertions(+) diff --git a/apps/opencs/view/widget/scenetoolmode.cpp b/apps/opencs/view/widget/scenetoolmode.cpp index a93bb0556..efb508f9d 100644 --- a/apps/opencs/view/widget/scenetoolmode.cpp +++ b/apps/opencs/view/widget/scenetoolmode.cpp @@ -3,10 +3,24 @@ #include #include #include +#include +#include #include "scenetoolbar.hpp" #include "modebutton.hpp" +void CSVWidget::SceneToolMode::contextMenuEvent (QContextMenuEvent *event) +{ + QMenu menu (this); + if (createContextMenu (&menu)) + menu.exec (event->globalPos()); +} + +bool CSVWidget::SceneToolMode::createContextMenu (QMenu *menu) +{ + return false; +} + void CSVWidget::SceneToolMode::adjustToolTip (const ModeButton *activeMode) { QString toolTip = mToolTip; @@ -15,6 +29,9 @@ void CSVWidget::SceneToolMode::adjustToolTip (const ModeButton *activeMode) toolTip += "

(left click to change mode)"; + if (createContextMenu (0)) + toolTip += "
(right click to access context menu)"; + setToolTip (toolTip); } diff --git a/apps/opencs/view/widget/scenetoolmode.hpp b/apps/opencs/view/widget/scenetoolmode.hpp index 6828a2269..43cd4a7d7 100644 --- a/apps/opencs/view/widget/scenetoolmode.hpp +++ b/apps/opencs/view/widget/scenetoolmode.hpp @@ -6,6 +6,7 @@ #include class QHBoxLayout; +class QMenu; namespace CSVWidget { @@ -29,6 +30,16 @@ namespace CSVWidget void adjustToolTip (const ModeButton *activeMode); + virtual void contextMenuEvent (QContextMenuEvent *event); + + /// Add context menu items to \a menu. Default-implementation: return false + /// + /// \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); + public: SceneToolMode (SceneToolbar *parent, const QString& toolTip); From ecbcd6b1717718d1ccaa3e18d7ad930eb2244f61 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 19 Jan 2016 12:52:30 +0100 Subject: [PATCH 04/10] allow mode buttons to setup the context menu --- apps/opencs/view/widget/modebutton.cpp | 5 +++++ apps/opencs/view/widget/modebutton.hpp | 10 ++++++++++ apps/opencs/view/widget/scenetoolmode.cpp | 3 +++ apps/opencs/view/widget/scenetoolmode.hpp | 3 ++- 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/widget/modebutton.cpp b/apps/opencs/view/widget/modebutton.cpp index 7c62f6bb1..88f050247 100644 --- a/apps/opencs/view/widget/modebutton.cpp +++ b/apps/opencs/view/widget/modebutton.cpp @@ -7,3 +7,8 @@ CSVWidget::ModeButton::ModeButton (const QIcon& icon, const QString& tooltip, QW void CSVWidget::ModeButton::activate (SceneToolbar *toolbar) {} void CSVWidget::ModeButton::deactivate (SceneToolbar *toolbar) {} + +bool CSVWidget::ModeButton::createContextMenu (QMenu *menu) +{ + return false; +} diff --git a/apps/opencs/view/widget/modebutton.hpp b/apps/opencs/view/widget/modebutton.hpp index ac14afc95..1615ff298 100644 --- a/apps/opencs/view/widget/modebutton.hpp +++ b/apps/opencs/view/widget/modebutton.hpp @@ -3,6 +3,8 @@ #include "pushbutton.hpp" +class QMenu; + namespace CSVWidget { class SceneToolbar; @@ -22,6 +24,14 @@ namespace CSVWidget /// Default-Implementation: do nothing virtual void deactivate (SceneToolbar *toolbar); + + /// Add context menu items to \a menu. Default-implementation: return false + /// + /// \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); }; } diff --git a/apps/opencs/view/widget/scenetoolmode.cpp b/apps/opencs/view/widget/scenetoolmode.cpp index efb508f9d..125f4ac79 100644 --- a/apps/opencs/view/widget/scenetoolmode.cpp +++ b/apps/opencs/view/widget/scenetoolmode.cpp @@ -18,6 +18,9 @@ void CSVWidget::SceneToolMode::contextMenuEvent (QContextMenuEvent *event) bool CSVWidget::SceneToolMode::createContextMenu (QMenu *menu) { + if (mCurrent) + return mCurrent->createContextMenu (menu); + return false; } diff --git a/apps/opencs/view/widget/scenetoolmode.hpp b/apps/opencs/view/widget/scenetoolmode.hpp index 43cd4a7d7..3aa8e6799 100644 --- a/apps/opencs/view/widget/scenetoolmode.hpp +++ b/apps/opencs/view/widget/scenetoolmode.hpp @@ -32,7 +32,8 @@ namespace CSVWidget virtual void contextMenuEvent (QContextMenuEvent *event); - /// Add context menu items to \a menu. Default-implementation: return false + /// Add context menu items to \a menu. Default-implementation: Pass on request to + /// current mode button or return false, if there is no current mode button. /// /// \attention menu can be a 0-pointer /// From 45e6974266f6df4c9185bf2b225309d19d969078 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 19 Jan 2016 14:25:20 +0100 Subject: [PATCH 05/10] added select all and clear selection features --- apps/opencs/view/render/instancemode.cpp | 3 +- .../view/render/instanceselectionmode.cpp | 37 ++++++++++++++++++- .../view/render/instanceselectionmode.hpp | 23 +++++++++++- .../view/render/pagedworldspacewidget.cpp | 9 +++++ .../view/render/pagedworldspacewidget.hpp | 3 ++ .../view/render/unpagedworldspacewidget.cpp | 6 +++ .../view/render/unpagedworldspacewidget.hpp | 3 ++ apps/opencs/view/render/worldspacewidget.hpp | 3 ++ 8 files changed, 82 insertions(+), 5 deletions(-) diff --git a/apps/opencs/view/render/instancemode.cpp b/apps/opencs/view/render/instancemode.cpp index ff49e0286..4b6b2e41f 100644 --- a/apps/opencs/view/render/instancemode.cpp +++ b/apps/opencs/view/render/instancemode.cpp @@ -9,7 +9,6 @@ #include "../../model/world/idtree.hpp" #include "../../model/world/commands.hpp" - #include "../widget/scenetoolbar.hpp" #include "../widget/scenetoolmode.hpp" @@ -52,7 +51,7 @@ void CSVRender::InstanceMode::activate (CSVWidget::SceneToolbar *toolbar) } if (!mSelectionMode) - mSelectionMode = new InstanceSelectionMode (toolbar); + mSelectionMode = new InstanceSelectionMode (toolbar, getWorldspaceWidget()); EditMode::activate (toolbar); diff --git a/apps/opencs/view/render/instanceselectionmode.cpp b/apps/opencs/view/render/instanceselectionmode.cpp index 9fd825999..794a150d2 100644 --- a/apps/opencs/view/render/instanceselectionmode.cpp +++ b/apps/opencs/view/render/instanceselectionmode.cpp @@ -1,8 +1,25 @@ #include "instanceselectionmode.hpp" -CSVRender::InstanceSelectionMode::InstanceSelectionMode (CSVWidget::SceneToolbar *parent) -: CSVWidget::SceneToolMode (parent, "Selection Mode") +#include +#include + +#include "worldspacewidget.hpp" + +bool CSVRender::InstanceSelectionMode::createContextMenu (QMenu *menu) +{ + if (menu) + { + menu->addAction (mSelectAll); + menu->addAction (mDeselectAll); + } + + return true; +} + +CSVRender::InstanceSelectionMode::InstanceSelectionMode (CSVWidget::SceneToolbar *parent, + WorldspaceWidget& worldspaceWidget) +: CSVWidget::SceneToolMode (parent, "Selection Mode"), mWorldspaceWidget (worldspaceWidget) { addButton (":placeholder", "cube-centre", "Centred cube" @@ -24,4 +41,20 @@ CSVRender::InstanceSelectionMode::InstanceSelectionMode (CSVWidget::SceneToolbar "

  • 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 Instances", this); + mDeselectAll = new QAction ("Clear selection", this); + + connect (mSelectAll, SIGNAL (triggered ()), this, SLOT (selectAll())); + connect (mDeselectAll, SIGNAL (triggered ()), this, SLOT (clearSelection())); +} + +void CSVRender::InstanceSelectionMode::selectAll() +{ + mWorldspaceWidget.selectAll (Mask_Reference); +} + +void CSVRender::InstanceSelectionMode::clearSelection() +{ + mWorldspaceWidget.clearSelection (Mask_Reference); } diff --git a/apps/opencs/view/render/instanceselectionmode.hpp b/apps/opencs/view/render/instanceselectionmode.hpp index e823de213..6b3a4e37d 100644 --- a/apps/opencs/view/render/instanceselectionmode.hpp +++ b/apps/opencs/view/render/instanceselectionmode.hpp @@ -3,16 +3,37 @@ #include "../widget/scenetoolmode.hpp" +class QAction; + namespace CSVRender { + class WorldspaceWidget; + class InstanceSelectionMode : public CSVWidget::SceneToolMode { Q_OBJECT + WorldspaceWidget& mWorldspaceWidget; + QAction *mSelectAll; + QAction *mDeselectAll; + + /// 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); + public: - InstanceSelectionMode (CSVWidget::SceneToolbar *parent); + InstanceSelectionMode (CSVWidget::SceneToolbar *parent, WorldspaceWidget& worldspaceWidget); + + private slots: + + void selectAll(); + void clearSelection(); }; } diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 1880beab8..ccb3efb1d 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -509,6 +509,15 @@ void CSVRender::PagedWorldspaceWidget::clearSelection (int elementMask) flagAsModified(); } +void CSVRender::PagedWorldspaceWidget::selectAll (int elementMask) +{ + for (std::map::iterator iter = mCells.begin(); + iter!=mCells.end(); ++iter) + iter->second->setSelection (elementMask, Cell::Selection_All); + + flagAsModified(); +} + std::string CSVRender::PagedWorldspaceWidget::getCellId (const osg::Vec3f& point) const { const int cellSize = 8192; diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index 647341d1f..3f9e605af 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -98,6 +98,9 @@ namespace CSVRender /// \param elementMask Elements to be affected by the clear operation virtual void clearSelection (int elementMask); + /// \param elementMask Elements to be affected by the select operation + virtual void selectAll (int elementMask); + virtual std::string getCellId (const osg::Vec3f& point) const; protected: diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index dad37c946..48180f866 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -108,6 +108,12 @@ void CSVRender::UnpagedWorldspaceWidget::clearSelection (int elementMask) flagAsModified(); } +void CSVRender::UnpagedWorldspaceWidget::selectAll (int elementMask) +{ + mCell->setSelection (elementMask, Cell::Selection_All); + flagAsModified(); +} + std::string CSVRender::UnpagedWorldspaceWidget::getCellId (const osg::Vec3f& point) const { return mCellId; diff --git a/apps/opencs/view/render/unpagedworldspacewidget.hpp b/apps/opencs/view/render/unpagedworldspacewidget.hpp index 70a20c216..8971f22a8 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.hpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.hpp @@ -46,6 +46,9 @@ namespace CSVRender /// \param elementMask Elements to be affected by the clear operation virtual void clearSelection (int elementMask); + /// \param elementMask Elements to be affected by the select operation + virtual void selectAll (int elementMask); + virtual std::string getCellId (const osg::Vec3f& point) const; private: diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 7a77edad4..13e66b7f0 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -127,6 +127,9 @@ namespace CSVRender /// \param elementMask Elements to be affected by the clear operation virtual void clearSelection (int elementMask) = 0; + /// \param elementMask Elements to be affected by the select operation + virtual void selectAll (int elementMask) = 0; + /// Return the next intersection point with scene elements matched by /// \a interactionMask based on \a localPos and the camera vector. /// If there is no such point, instead a point "in front" of \a localPos will be From c1f0aa7260059007262aa1f4d21555fb1827c10b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 25 Jan 2016 14:55:02 +0100 Subject: [PATCH 06/10] added delete selection item to selection mode button menu --- apps/opencs/view/render/cell.cpp | 13 ++++++++++ apps/opencs/view/render/cell.hpp | 4 +++ .../view/render/instanceselectionmode.cpp | 26 +++++++++++++++++++ .../view/render/instanceselectionmode.hpp | 3 +++ apps/opencs/view/render/object.cpp | 5 ++++ apps/opencs/view/render/object.hpp | 2 ++ .../view/render/pagedworldspacewidget.cpp | 17 ++++++++++++ .../view/render/pagedworldspacewidget.hpp | 3 +++ .../view/render/unpagedworldspacewidget.cpp | 6 +++++ .../view/render/unpagedworldspacewidget.hpp | 3 +++ apps/opencs/view/render/worldspacewidget.hpp | 3 +++ 11 files changed, 85 insertions(+) diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 40981164d..4372018fb 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -276,3 +276,16 @@ bool CSVRender::Cell::isDeleted() const { return mDeleted; } + +std::vector > CSVRender::Cell::getSelection (unsigned int elementMask) const +{ + std::vector > result; + + if (elementMask & Mask_Reference) + for (std::map::const_iterator iter (mObjects.begin()); + iter!=mObjects.end(); ++iter) + if (iter->second->getSelected()) + result.push_back (iter->second->getTag()); + + return result; +} diff --git a/apps/opencs/view/render/cell.hpp b/apps/opencs/view/render/cell.hpp index 59f4cafee..3e51bb334 100644 --- a/apps/opencs/view/render/cell.hpp +++ b/apps/opencs/view/render/cell.hpp @@ -31,6 +31,8 @@ namespace CSMWorld namespace CSVRender { + class TagBase; + class Cell { CSMWorld::Data& mData; @@ -99,6 +101,8 @@ namespace CSVRender CSMWorld::CellCoordinates getCoordinates() const; bool isDeleted() const; + + std::vector > getSelection (unsigned int elementMask) const; }; } diff --git a/apps/opencs/view/render/instanceselectionmode.cpp b/apps/opencs/view/render/instanceselectionmode.cpp index 794a150d2..754123d2d 100644 --- a/apps/opencs/view/render/instanceselectionmode.cpp +++ b/apps/opencs/view/render/instanceselectionmode.cpp @@ -4,7 +4,11 @@ #include #include +#include "../../model/world/idtable.hpp" +#include "../../model/world/commands.hpp" + #include "worldspacewidget.hpp" +#include "object.hpp" bool CSVRender::InstanceSelectionMode::createContextMenu (QMenu *menu) { @@ -12,6 +16,7 @@ bool CSVRender::InstanceSelectionMode::createContextMenu (QMenu *menu) { menu->addAction (mSelectAll); menu->addAction (mDeselectAll); + menu->addAction (mDeleteSelection); } return true; @@ -44,9 +49,11 @@ CSVRender::InstanceSelectionMode::InstanceSelectionMode (CSVWidget::SceneToolbar mSelectAll = new QAction ("Select all Instances", this); mDeselectAll = new QAction ("Clear selection", this); + mDeleteSelection = new QAction ("Delete selection", this); connect (mSelectAll, SIGNAL (triggered ()), this, SLOT (selectAll())); connect (mDeselectAll, SIGNAL (triggered ()), this, SLOT (clearSelection())); + connect (mDeleteSelection, SIGNAL (triggered ()), this, SLOT (deleteSelection())); } void CSVRender::InstanceSelectionMode::selectAll() @@ -58,3 +65,22 @@ void CSVRender::InstanceSelectionMode::clearSelection() { mWorldspaceWidget.clearSelection (Mask_Reference); } + +void CSVRender::InstanceSelectionMode::deleteSelection() +{ + std::vector > selection = + mWorldspaceWidget.getSelection (Mask_Reference); + + CSMWorld::IdTable& referencesTable = + dynamic_cast (*mWorldspaceWidget.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()); + + mWorldspaceWidget.getDocument().getUndoStack().push (command); + } +} diff --git a/apps/opencs/view/render/instanceselectionmode.hpp b/apps/opencs/view/render/instanceselectionmode.hpp index 6b3a4e37d..07b774543 100644 --- a/apps/opencs/view/render/instanceselectionmode.hpp +++ b/apps/opencs/view/render/instanceselectionmode.hpp @@ -16,6 +16,7 @@ namespace CSVRender WorldspaceWidget& mWorldspaceWidget; QAction *mSelectAll; QAction *mDeselectAll; + QAction *mDeleteSelection; /// Add context menu items to \a menu. /// @@ -34,6 +35,8 @@ namespace CSVRender void selectAll(); void clearSelection(); + + void deleteSelection(); }; } diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index 1821da059..dcf217a36 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -284,3 +284,8 @@ std::string CSVRender::Object::getReferenceableId() const { return mReferenceableId; } + +osg::ref_ptr CSVRender::Object::getTag() const +{ + return static_cast (mBaseNode->getUserData()); +} diff --git a/apps/opencs/view/render/object.hpp b/apps/opencs/view/render/object.hpp index e7638e7a9..4a89fe201 100644 --- a/apps/opencs/view/render/object.hpp +++ b/apps/opencs/view/render/object.hpp @@ -114,6 +114,8 @@ namespace CSVRender std::string getReferenceId() const; std::string getReferenceableId() const; + + osg::ref_ptr getTag() const; }; } diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index ccb3efb1d..ef5c4e868 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -529,6 +529,23 @@ std::string CSVRender::PagedWorldspaceWidget::getCellId (const osg::Vec3f& point return cellCoordinates.getId (mWorldspace); } +std::vector > CSVRender::PagedWorldspaceWidget::getSelection ( + unsigned int elementMask) const +{ + std::vector > result; + + for (std::map::const_iterator iter = mCells.begin(); + iter!=mCells.end(); ++iter) + { + std::vector > cellResult = + iter->second->getSelection (elementMask); + + result.insert (result.end(), cellResult.begin(), cellResult.end()); + } + + return result; +} + CSVWidget::SceneToolToggle *CSVRender::PagedWorldspaceWidget::makeControlVisibilitySelector ( CSVWidget::SceneToolbar *parent) { diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index 3f9e605af..bd4233a64 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -103,6 +103,9 @@ namespace CSVRender virtual std::string getCellId (const osg::Vec3f& point) const; + virtual std::vector > getSelection (unsigned int elementMask) + const; + protected: virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool); diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index 48180f866..a026a2473 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -119,6 +119,12 @@ std::string CSVRender::UnpagedWorldspaceWidget::getCellId (const osg::Vec3f& poi return mCellId; } +std::vector > CSVRender::UnpagedWorldspaceWidget::getSelection ( + unsigned int elementMask) const +{ + return mCell->getSelection (elementMask); +} + void CSVRender::UnpagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) { diff --git a/apps/opencs/view/render/unpagedworldspacewidget.hpp b/apps/opencs/view/render/unpagedworldspacewidget.hpp index 8971f22a8..3aea8dee4 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.hpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.hpp @@ -51,6 +51,9 @@ namespace CSVRender virtual std::string getCellId (const osg::Vec3f& point) const; + virtual std::vector > getSelection (unsigned int elementMask) + const; + private: virtual void referenceableDataChanged (const QModelIndex& topLeft, diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 13e66b7f0..cd031fcba 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -143,6 +143,9 @@ namespace CSVRender virtual std::string getCellId (const osg::Vec3f& point) const = 0; + virtual std::vector > getSelection (unsigned int elementMask) + const = 0; + protected: /// Visual elements in a scene From 790367b980ef6980b62abb30b61890100c7aca60 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 25 Jan 2016 16:12:20 +0100 Subject: [PATCH 07/10] fixed object removal via setting state to delete --- apps/opencs/view/render/cell.cpp | 36 ++++++++++++++++++++++---------- apps/opencs/view/render/cell.hpp | 4 ++++ 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 4372018fb..758498de1 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -22,11 +22,18 @@ bool CSVRender::Cell::removeObject (const std::string& id) if (iter==mObjects.end()) return false; - delete iter->second; - mObjects.erase (iter); + removeObject (iter); return true; } +std::map::iterator CSVRender::Cell::removeObject ( + std::map::iterator iter) +{ + delete iter->second; + mObjects.erase (iter++); + return iter; +} + bool CSVRender::Cell::addObjects (int start, int end) { bool modified = false; @@ -161,8 +168,8 @@ bool CSVRender::Cell::referenceDataChanged (const QModelIndex& topLeft, // perform update and remove where needed bool modified = false; - for (std::map::iterator iter (mObjects.begin()); - iter!=mObjects.end(); ++iter) + std::map::iterator iter = mObjects.begin(); + while (iter!=mObjects.end()) { if (iter->second->referenceDataChanged (topLeft, bottomRight)) modified = true; @@ -171,23 +178,30 @@ bool CSVRender::Cell::referenceDataChanged (const QModelIndex& topLeft, if (iter2!=ids.end()) { - if (iter2->second) + bool deleted = iter2->second; + ids.erase (iter2); + + if (deleted) { - removeObject (iter->first); + iter = removeObject (iter); modified = true; + continue; } - - ids.erase (iter2); } + + ++iter; } // add new objects for (std::map::iterator iter (ids.begin()); iter!=ids.end(); ++iter) { - mObjects.insert (std::make_pair ( - iter->first, new Object (mData, mCellNode, iter->first, false))); + if (!iter->second) + { + mObjects.insert (std::make_pair ( + iter->first, new Object (mData, mCellNode, iter->first, false))); - modified = true; + modified = true; + } } return modified; diff --git a/apps/opencs/view/render/cell.hpp b/apps/opencs/view/render/cell.hpp index 3e51bb334..9f062b439 100644 --- a/apps/opencs/view/render/cell.hpp +++ b/apps/opencs/view/render/cell.hpp @@ -49,6 +49,10 @@ namespace CSVRender /// \return Was the object deleted? bool removeObject (const std::string& id); + // Remove object and return iterator to next object. + std::map::iterator removeObject ( + std::map::iterator iter); + /// Add objects from reference table that are within this cell. /// /// \return Have any objects been added? From 39e1b06101ab6947fec43470fa0225060a9cc80b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 25 Jan 2016 16:18:55 +0100 Subject: [PATCH 08/10] fixed deletion of objects that are selected (was leaving a node behind) --- apps/opencs/view/render/object.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index dcf217a36..b980b658a 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -187,6 +187,7 @@ CSVRender::Object::~Object() clear(); mParentNode->removeChild(mBaseNode); + mParentNode->removeChild(mOutline); } void CSVRender::Object::setSelected(bool selected) From d5ef40aeb7738b2c5be6207e4d03a91782760903 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 26 Jan 2016 10:51:47 +0100 Subject: [PATCH 09/10] minor improvements to wording of instance selection menu items --- apps/opencs/view/render/instanceselectionmode.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/render/instanceselectionmode.cpp b/apps/opencs/view/render/instanceselectionmode.cpp index 754123d2d..2fd91c8e2 100644 --- a/apps/opencs/view/render/instanceselectionmode.cpp +++ b/apps/opencs/view/render/instanceselectionmode.cpp @@ -47,9 +47,9 @@ CSVRender::InstanceSelectionMode::InstanceSelectionMode (CSVWidget::SceneToolbar "" "Not implemented yet"); - mSelectAll = new QAction ("Select all Instances", this); + mSelectAll = new QAction ("Select all instances", this); mDeselectAll = new QAction ("Clear selection", this); - mDeleteSelection = new QAction ("Delete selection", this); + mDeleteSelection = new QAction ("Delete selected instances", this); connect (mSelectAll, SIGNAL (triggered ()), this, SLOT (selectAll())); connect (mDeselectAll, SIGNAL (triggered ()), this, SLOT (clearSelection())); From 1d0ef97bf6bc566fa817e51179467a854c925365 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 26 Jan 2016 11:31:37 +0100 Subject: [PATCH 10/10] added select all of same ID item to selection mode button menu --- apps/opencs/view/render/cell.cpp | 22 +++++++++++++++++++ apps/opencs/view/render/cell.hpp | 4 ++++ .../view/render/instanceselectionmode.cpp | 9 +++++++- .../view/render/instanceselectionmode.hpp | 3 +++ .../view/render/pagedworldspacewidget.cpp | 9 ++++++++ .../view/render/pagedworldspacewidget.hpp | 6 +++++ .../view/render/unpagedworldspacewidget.cpp | 6 +++++ .../view/render/unpagedworldspacewidget.hpp | 6 +++++ apps/opencs/view/render/worldspacewidget.hpp | 6 +++++ 9 files changed, 70 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 758498de1..bd85c8a14 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -263,6 +263,28 @@ void CSVRender::Cell::setSelection (int elementMask, Selection mode) } } +void CSVRender::Cell::selectAllWithSameParentId (int elementMask) +{ + std::set ids; + + for (std::map::const_iterator iter (mObjects.begin()); + iter!=mObjects.end(); ++iter) + { + if (iter->second->getSelected()) + ids.insert (iter->second->getReferenceableId()); + } + + for (std::map::const_iterator iter (mObjects.begin()); + iter!=mObjects.end(); ++iter) + { + if (!iter->second->getSelected() && + ids.find (iter->second->getReferenceableId())!=ids.end()) + { + iter->second->setSelected (true); + } + } +} + void CSVRender::Cell::setCellArrows (int mask) { for (int i=0; i<4; ++i) diff --git a/apps/opencs/view/render/cell.hpp b/apps/opencs/view/render/cell.hpp index 9f062b439..85b9bf21b 100644 --- a/apps/opencs/view/render/cell.hpp +++ b/apps/opencs/view/render/cell.hpp @@ -99,6 +99,10 @@ namespace CSVRender void setSelection (int elementMask, Selection mode); + // Select everything that references the same ID as at least one of the elements + // already selected + void selectAllWithSameParentId (int elementMask); + void setCellArrows (int mask); /// Returns 0, 0 in case of an unpaged cell. diff --git a/apps/opencs/view/render/instanceselectionmode.cpp b/apps/opencs/view/render/instanceselectionmode.cpp index 2fd91c8e2..5c3aaa8d1 100644 --- a/apps/opencs/view/render/instanceselectionmode.cpp +++ b/apps/opencs/view/render/instanceselectionmode.cpp @@ -16,6 +16,7 @@ bool CSVRender::InstanceSelectionMode::createContextMenu (QMenu *menu) { menu->addAction (mSelectAll); menu->addAction (mDeselectAll); + menu->addAction (mSelectSame); menu->addAction (mDeleteSelection); } @@ -50,10 +51,11 @@ CSVRender::InstanceSelectionMode::InstanceSelectionMode (CSVWidget::SceneToolbar 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())); } void CSVRender::InstanceSelectionMode::selectAll() @@ -84,3 +86,8 @@ void CSVRender::InstanceSelectionMode::deleteSelection() mWorldspaceWidget.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 07b774543..cac2ca8c2 100644 --- a/apps/opencs/view/render/instanceselectionmode.hpp +++ b/apps/opencs/view/render/instanceselectionmode.hpp @@ -17,6 +17,7 @@ namespace CSVRender QAction *mSelectAll; QAction *mDeselectAll; QAction *mDeleteSelection; + QAction *mSelectSame; /// Add context menu items to \a menu. /// @@ -37,6 +38,8 @@ namespace CSVRender void clearSelection(); void deleteSelection(); + + void selectSame(); }; } diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index ef5c4e868..d71446d0b 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -518,6 +518,15 @@ void CSVRender::PagedWorldspaceWidget::selectAll (int elementMask) flagAsModified(); } +void CSVRender::PagedWorldspaceWidget::selectAllWithSameParentId (int elementMask) +{ + for (std::map::iterator iter = mCells.begin(); + iter!=mCells.end(); ++iter) + iter->second->selectAllWithSameParentId (elementMask); + + flagAsModified(); +} + std::string CSVRender::PagedWorldspaceWidget::getCellId (const osg::Vec3f& point) const { const int cellSize = 8192; diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index bd4233a64..419a2a46a 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -101,6 +101,12 @@ namespace CSVRender /// \param elementMask Elements to be affected by the select operation virtual void selectAll (int elementMask); + // Select everything that references the same ID as at least one of the elements + // already selected + // + /// \param elementMask Elements to be affected by the select operation + virtual void selectAllWithSameParentId (int elementMask); + virtual std::string getCellId (const osg::Vec3f& point) const; virtual std::vector > getSelection (unsigned int elementMask) diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index a026a2473..8d65c3694 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -114,6 +114,12 @@ void CSVRender::UnpagedWorldspaceWidget::selectAll (int elementMask) flagAsModified(); } +void CSVRender::UnpagedWorldspaceWidget::selectAllWithSameParentId (int elementMask) +{ + mCell->selectAllWithSameParentId (elementMask); + flagAsModified(); +} + std::string CSVRender::UnpagedWorldspaceWidget::getCellId (const osg::Vec3f& point) const { return mCellId; diff --git a/apps/opencs/view/render/unpagedworldspacewidget.hpp b/apps/opencs/view/render/unpagedworldspacewidget.hpp index 3aea8dee4..a4c517948 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.hpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.hpp @@ -49,6 +49,12 @@ namespace CSVRender /// \param elementMask Elements to be affected by the select operation virtual void selectAll (int elementMask); + // Select everything that references the same ID as at least one of the elements + // already selected + // + /// \param elementMask Elements to be affected by the select operation + virtual void selectAllWithSameParentId (int elementMask); + virtual std::string getCellId (const osg::Vec3f& point) const; virtual std::vector > getSelection (unsigned int elementMask) diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index cd031fcba..ac6426b42 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -130,6 +130,12 @@ namespace CSVRender /// \param elementMask Elements to be affected by the select operation virtual void selectAll (int elementMask) = 0; + // Select everything that references the same ID as at least one of the elements + // already selected + // + /// \param elementMask Elements to be affected by the select operation + virtual void selectAllWithSameParentId (int elementMask) = 0; + /// Return the next intersection point with scene elements matched by /// \a interactionMask based on \a localPos and the camera vector. /// If there is no such point, instead a point "in front" of \a localPos will be