diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 0d621c83e6..dde5310512 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/cell.cpp b/apps/opencs/view/render/cell.cpp index 40981164de..bd85c8a142 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) - { - removeObject (iter->first); - modified = true; - } - + bool deleted = iter2->second; ids.erase (iter2); + + if (deleted) + { + iter = removeObject (iter); + modified = true; + continue; + } } + + ++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; @@ -249,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) @@ -276,3 +312,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 59f4cafee4..85b9bf21b4 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; @@ -47,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? @@ -93,12 +99,18 @@ 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. CSMWorld::CellCoordinates getCoordinates() const; bool isDeleted() const; + + std::vector > getSelection (unsigned int elementMask) const; }; } diff --git a/apps/opencs/view/render/instancemode.cpp b/apps/opencs/view/render/instancemode.cpp index 4725a993fc..4b6b2e41f8 100644 --- a/apps/opencs/view/render/instancemode.cpp +++ b/apps/opencs/view/render/instancemode.cpp @@ -9,16 +9,73 @@ #include "../../model/world/idtree.hpp" #include "../../model/world/commands.hpp" +#include "../widget/scenetoolbar.hpp" +#include "../widget/scenetoolmode.hpp" + #include "mask.hpp" + #include "object.hpp" #include "worldspacewidget.hpp" #include "pagedworldspacewidget.hpp" +#include "instanceselectionmode.hpp" CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent) : EditMode (worldspaceWidget, QIcon (":placeholder"), Mask_Reference, "Instance editing", - parent) + parent), mSubMode (0), mSelectionMode (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" + "
  • Use primary edit to move instances around freely
  • " + "
  • Use secondary edit to move instances around within the grid
  • " + "
" + "Not implemented yet"); + mSubMode->addButton (":placeholder", "rotate", + "Rotate selected instances" + "
  • Use primary edit to rotate instances freely
  • " + "
  • Use secondary edit to rotate instances within the grid
  • " + "
" + "Not implemented yet"); + mSubMode->addButton (":placeholder", "scale", + "Scale selected instances" + "
  • Use primary edit to scale instances freely
  • " + "
  • Use secondary edit to scale instances along the grid
  • " + "
" + "Not implemented yet"); + } + + if (!mSelectionMode) + mSelectionMode = new InstanceSelectionMode (toolbar, getWorldspaceWidget()); + + EditMode::activate (toolbar); + + toolbar->addTool (mSubMode); + toolbar->addTool (mSelectionMode); +} + +void CSVRender::InstanceMode::deactivate (CSVWidget::SceneToolbar *toolbar) +{ + if (mSelectionMode) + { + toolbar->removeTool (mSelectionMode); + delete mSelectionMode; + mSelectionMode = 0; + } + + if (mSubMode) + { + 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 7649c241ca..78836878a4 100644 --- a/apps/opencs/view/render/instancemode.hpp +++ b/apps/opencs/view/render/instancemode.hpp @@ -3,16 +3,29 @@ #include "editmode.hpp" +namespace CSVWidget +{ + class SceneToolMode; +} + namespace CSVRender { + class InstanceSelectionMode; + class InstanceMode : public EditMode { Q_OBJECT + CSVWidget::SceneToolMode *mSubMode; + InstanceSelectionMode *mSelectionMode; 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/render/instanceselectionmode.cpp b/apps/opencs/view/render/instanceselectionmode.cpp new file mode 100644 index 0000000000..5c3aaa8d16 --- /dev/null +++ b/apps/opencs/view/render/instanceselectionmode.cpp @@ -0,0 +1,93 @@ + +#include "instanceselectionmode.hpp" + +#include +#include + +#include "../../model/world/idtable.hpp" +#include "../../model/world/commands.hpp" + +#include "worldspacewidget.hpp" +#include "object.hpp" + +bool CSVRender::InstanceSelectionMode::createContextMenu (QMenu *menu) +{ + if (menu) + { + menu->addAction (mSelectAll); + menu->addAction (mDeselectAll); + menu->addAction (mSelectSame); + menu->addAction (mDeleteSelection); + } + + return true; +} + +CSVRender::InstanceSelectionMode::InstanceSelectionMode (CSVWidget::SceneToolbar *parent, + WorldspaceWidget& worldspaceWidget) +: CSVWidget::SceneToolMode (parent, "Selection Mode"), mWorldspaceWidget (worldspaceWidget) +{ + 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 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() +{ + mWorldspaceWidget.selectAll (Mask_Reference); +} + +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); + } +} + +void CSVRender::InstanceSelectionMode::selectSame() +{ + mWorldspaceWidget.selectAllWithSameParentId (Mask_Reference); +} diff --git a/apps/opencs/view/render/instanceselectionmode.hpp b/apps/opencs/view/render/instanceselectionmode.hpp new file mode 100644 index 0000000000..cac2ca8c20 --- /dev/null +++ b/apps/opencs/view/render/instanceselectionmode.hpp @@ -0,0 +1,46 @@ +#ifndef CSV_RENDER_INSTANCE_SELECTION_MODE_H +#define CSV_RENDER_INSTANCE_SELECTION_MODE_H + +#include "../widget/scenetoolmode.hpp" + +class QAction; + +namespace CSVRender +{ + class WorldspaceWidget; + + class InstanceSelectionMode : public CSVWidget::SceneToolMode + { + Q_OBJECT + + WorldspaceWidget& mWorldspaceWidget; + QAction *mSelectAll; + QAction *mDeselectAll; + QAction *mDeleteSelection; + QAction *mSelectSame; + + /// 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, WorldspaceWidget& worldspaceWidget); + + private slots: + + void selectAll(); + + void clearSelection(); + + void deleteSelection(); + + void selectSame(); + }; +} + +#endif diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index 1821da059e..b980b658a4 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) @@ -284,3 +285,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 e7638e7a99..4a89fe201f 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 1880beab8b..d71446d0b3 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -509,6 +509,24 @@ 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(); +} + +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; @@ -520,6 +538,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 647341d1f4..419a2a46a2 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -98,8 +98,20 @@ 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); + + // 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) + 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 dad37c946b..8d65c36948 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -108,11 +108,29 @@ void CSVRender::UnpagedWorldspaceWidget::clearSelection (int elementMask) flagAsModified(); } +void CSVRender::UnpagedWorldspaceWidget::selectAll (int elementMask) +{ + mCell->setSelection (elementMask, Cell::Selection_All); + flagAsModified(); +} + +void CSVRender::UnpagedWorldspaceWidget::selectAllWithSameParentId (int elementMask) +{ + mCell->selectAllWithSameParentId (elementMask); + flagAsModified(); +} + std::string CSVRender::UnpagedWorldspaceWidget::getCellId (const osg::Vec3f& point) const { 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 70a20c216d..a4c517948d 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.hpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.hpp @@ -46,8 +46,20 @@ 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); + + // 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) + 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 7a77edad42..ac6426b42e 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -127,6 +127,15 @@ 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; + + // 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 @@ -140,6 +149,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 diff --git a/apps/opencs/view/widget/modebutton.cpp b/apps/opencs/view/widget/modebutton.cpp index 7c62f6bb16..88f0502479 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 ac14afc952..1615ff298a 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 a93bb05567..125f4ac79a 100644 --- a/apps/opencs/view/widget/scenetoolmode.cpp +++ b/apps/opencs/view/widget/scenetoolmode.cpp @@ -3,10 +3,27 @@ #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) +{ + if (mCurrent) + return mCurrent->createContextMenu (menu); + + return false; +} + void CSVWidget::SceneToolMode::adjustToolTip (const ModeButton *activeMode) { QString toolTip = mToolTip; @@ -15,6 +32,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 6828a22691..3aa8e6799a 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,17 @@ namespace CSVWidget void adjustToolTip (const ModeButton *activeMode); + virtual void contextMenuEvent (QContextMenuEvent *event); + + /// 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 + /// + /// \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); diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 44fe94d840..7014b14864 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; }