From 39b73405800bd3409184a894a0d899ba28904c41 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 21 Sep 2015 15:32:18 +0200 Subject: [PATCH 01/23] added mouse button settings for 3D scene (not in use yet) --- apps/opencs/model/settings/usersettings.cpp | 35 +++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 24680ada3..3daf7f9ec 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -371,6 +371,41 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() "list go to the first/last item"); } + declareSection ("scene-input", "3D Scene Input"); + { + QString left ("Left Mouse-Button"); + QString cLeft ("Ctrl-Left Mouse-Button"); + QString right ("Right Mouse-Button"); + QString cRight ("Ctrl-Right Mouse-Button"); + QString middle ("Middle Mouse-Button"); + QString cMiddle ("Ctrl-Middle Mouse-Button"); + + QStringList values; + values << left << cLeft << right << cRight << middle << cMiddle; + + Setting *primaryNavigation = createSetting (Type_ComboBox, "p-navi", "Primary Camera Navigation Button"); + primaryNavigation->setDeclaredValues (values); + primaryNavigation->setDefaultValue (left); + + Setting *secondaryNavigation = createSetting (Type_ComboBox, "s-navi", "Secondary Camera Navigation Button"); + secondaryNavigation->setDeclaredValues (values); + secondaryNavigation->setDefaultValue (cLeft); + + Setting *primaryEditing = createSetting (Type_ComboBox, "p-edit", "Primary Editing Button"); + primaryEditing->setDeclaredValues (values); + primaryEditing->setDefaultValue (right); + + Setting *secondaryEditing = createSetting (Type_ComboBox, "s-edit", "Secondary Editing Button"); + secondaryEditing->setDeclaredValues (values); + secondaryEditing->setDefaultValue (cRight); + + values << "Context Sensitive"; + + Setting *selection = createSetting (Type_ComboBox, "select", "Selection Button"); + selection->setDeclaredValues (values); + selection->setDefaultValue (middle); + } + { /****************************************************************** * There are three types of values: From b2cb5f037447e6baa8ad6bbdeb076c388d89595a Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 24 Sep 2015 15:51:16 +0200 Subject: [PATCH 02/23] pass on user settings updates to potentially interested parties within a scene subview --- apps/opencs/view/render/editmode.cpp | 5 +++++ apps/opencs/view/render/editmode.hpp | 3 +++ apps/opencs/view/render/worldspacewidget.cpp | 5 +++++ apps/opencs/view/render/worldspacewidget.hpp | 2 ++ apps/opencs/view/widget/scenetoolmode.cpp | 5 +++++ apps/opencs/view/widget/scenetoolmode.hpp | 3 +++ apps/opencs/view/world/scenesubview.cpp | 15 ++++++++++++--- apps/opencs/view/world/scenesubview.hpp | 4 ++++ 8 files changed, 39 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/render/editmode.cpp b/apps/opencs/view/render/editmode.cpp index 8a99ba049..bf96fea3a 100644 --- a/apps/opencs/view/render/editmode.cpp +++ b/apps/opencs/view/render/editmode.cpp @@ -16,3 +16,8 @@ void CSVRender::EditMode::activate (CSVWidget::SceneToolbar *toolbar) { mWorldspaceWidget->setInteractionMask (mMask); } + +void CSVRender::EditMode::updateUserSetting (const QString& name, const QStringList& value) +{ + +} diff --git a/apps/opencs/view/render/editmode.hpp b/apps/opencs/view/render/editmode.hpp index c3192f8ea..381a6abcb 100644 --- a/apps/opencs/view/render/editmode.hpp +++ b/apps/opencs/view/render/editmode.hpp @@ -22,6 +22,9 @@ namespace CSVRender unsigned int getInteractionMask() const; virtual void activate (CSVWidget::SceneToolbar *toolbar); + + /// Default-implementation: Do nothing. + virtual void updateUserSetting (const QString& name, const QStringList& value); }; } diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index a1f0f6bf2..2eb84d0a2 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -254,6 +254,11 @@ unsigned int CSVRender::WorldspaceWidget::getInteractionMask() const return mInteractionMask & getVisibilityMask(); } +void CSVRender::WorldspaceWidget::updateUserSetting (const QString& name, const QStringList& value) +{ + +} + void CSVRender::WorldspaceWidget::addVisibilitySelectorButtons ( CSVWidget::SceneToolToggle2 *tool) { diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index fe4555820..c3796af34 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -93,6 +93,8 @@ namespace CSVRender /// marked for interaction. unsigned int getInteractionMask() const; + virtual void updateUserSetting (const QString& name, const QStringList& value); + protected: virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool); diff --git a/apps/opencs/view/widget/scenetoolmode.cpp b/apps/opencs/view/widget/scenetoolmode.cpp index 9f963873c..a93bb0556 100644 --- a/apps/opencs/view/widget/scenetoolmode.cpp +++ b/apps/opencs/view/widget/scenetoolmode.cpp @@ -71,6 +71,11 @@ void CSVWidget::SceneToolMode::addButton (ModeButton *button, const std::string& } } +CSVWidget::ModeButton *CSVWidget::SceneToolMode::getCurrent() +{ + return mCurrent; +} + void CSVWidget::SceneToolMode::selected() { std::map::const_iterator iter = diff --git a/apps/opencs/view/widget/scenetoolmode.hpp b/apps/opencs/view/widget/scenetoolmode.hpp index e6f462cf8..6828a2269 100644 --- a/apps/opencs/view/widget/scenetoolmode.hpp +++ b/apps/opencs/view/widget/scenetoolmode.hpp @@ -41,6 +41,9 @@ namespace CSVWidget /// The ownership of \a button is transferred to *this. void addButton (ModeButton *button, const std::string& id); + /// Will return a 0-pointer only if the mode does not have any buttons yet. + ModeButton *getCurrent(); + signals: void modeChanged (const std::string& id); diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index c2f3442f8..f0b18dd86 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -15,6 +15,7 @@ #include "../render/pagedworldspacewidget.hpp" #include "../render/unpagedworldspacewidget.hpp" +#include "../render/editmode.hpp" #include "../widget/scenetoolbar.hpp" #include "../widget/scenetoolmode.hpp" @@ -26,7 +27,8 @@ #include "creator.hpp" CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) -: SubView (id), mScene(NULL), mLayout(new QHBoxLayout), mDocument(document), mToolbar(NULL) +: SubView (id), mScene(NULL), mLayout(new QHBoxLayout), mDocument(document), mToolbar(NULL), + mEditMode (0) { QVBoxLayout *layout = new QVBoxLayout; @@ -121,8 +123,8 @@ CSVWidget::SceneToolbar* CSVWorld::SceneSubView::makeToolbar (CSVRender::Worldsp CSVWidget::SceneToolRun *runTool = widget->makeRunTool (toolbar); toolbar->addTool (runTool); - CSVWidget::SceneToolMode *editModeTool = widget->makeEditModeSelector (toolbar); - toolbar->addTool (editModeTool); + mEditMode = widget->makeEditModeSelector (toolbar); + toolbar->addTool (mEditMode); return toolbar; } @@ -147,6 +149,13 @@ std::string CSVWorld::SceneSubView::getTitle() const return mTitle; } +void CSVWorld::SceneSubView::updateUserSetting (const QString& name, const QStringList& value) +{ + mScene->updateUserSetting (name, value); + dynamic_cast (*mEditMode->getCurrent()).updateUserSetting (name, value); + CSVDoc::SubView::updateUserSetting (name, value); +} + void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::UniversalId& id) { setUniversalId(id); diff --git a/apps/opencs/view/world/scenesubview.hpp b/apps/opencs/view/world/scenesubview.hpp index a34d71901..29aca5ab6 100644 --- a/apps/opencs/view/world/scenesubview.hpp +++ b/apps/opencs/view/world/scenesubview.hpp @@ -27,6 +27,7 @@ namespace CSVRender namespace CSVWidget { class SceneToolbar; + class SceneToolMode; } namespace CSVWorld @@ -45,6 +46,7 @@ namespace CSVWorld CSMDoc::Document& mDocument; CSVWidget::SceneToolbar* mToolbar; std::string mTitle; + CSVWidget::SceneToolMode *mEditMode; public: @@ -58,6 +60,8 @@ namespace CSVWorld virtual std::string getTitle() const; + virtual void updateUserSetting (const QString& name, const QStringList& value); + private: void makeConnections(CSVRender::PagedWorldspaceWidget* widget); From 3ada08af90dab4440247ba4b3190b669e6b42b73 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 24 Sep 2015 16:07:17 +0200 Subject: [PATCH 03/23] store lock state and pass it on to edit mode --- apps/opencs/view/render/editmode.cpp | 5 +++++ apps/opencs/view/render/editmode.hpp | 3 +++ apps/opencs/view/world/scenesubview.cpp | 13 +++++++++++-- apps/opencs/view/world/scenesubview.hpp | 3 +++ 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/render/editmode.cpp b/apps/opencs/view/render/editmode.cpp index bf96fea3a..c3aad3f7a 100644 --- a/apps/opencs/view/render/editmode.cpp +++ b/apps/opencs/view/render/editmode.cpp @@ -21,3 +21,8 @@ void CSVRender::EditMode::updateUserSetting (const QString& name, const QStringL { } + +void CSVRender::EditMode::setEditLock (bool locked) +{ + +} diff --git a/apps/opencs/view/render/editmode.hpp b/apps/opencs/view/render/editmode.hpp index 381a6abcb..1212cd285 100644 --- a/apps/opencs/view/render/editmode.hpp +++ b/apps/opencs/view/render/editmode.hpp @@ -25,6 +25,9 @@ namespace CSVRender /// Default-implementation: Do nothing. virtual void updateUserSetting (const QString& name, const QStringList& value); + + /// Default-implementation: Ignored. + virtual void setEditLock (bool locked); }; } diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index f0b18dd86..967909969 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -28,7 +28,7 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) : SubView (id), mScene(NULL), mLayout(new QHBoxLayout), mDocument(document), mToolbar(NULL), - mEditMode (0) + mEditMode (0), mLocked (false) { QVBoxLayout *layout = new QVBoxLayout; @@ -131,7 +131,8 @@ CSVWidget::SceneToolbar* CSVWorld::SceneSubView::makeToolbar (CSVRender::Worldsp void CSVWorld::SceneSubView::setEditLock (bool locked) { - + mLocked = locked; + dynamic_cast (*mEditMode->getCurrent()).setEditLock (locked); } void CSVWorld::SceneSubView::setStatusBar (bool show) @@ -258,4 +259,12 @@ void CSVWorld::SceneSubView::replaceToolbarAndWorldspace (CSVRender::WorldspaceW mScene->selectDefaultNavigationMode(); setFocusProxy (mScene); + + connect (mEditMode, SIGNAL (modeChanged (const std::string&)), + this, SLOT (editModeChanged (const std::string&))); +} + +void CSVWorld::SceneSubView::editModeChanged (const std::string& id) +{ + dynamic_cast (*mEditMode->getCurrent()).setEditLock (mLocked); } diff --git a/apps/opencs/view/world/scenesubview.hpp b/apps/opencs/view/world/scenesubview.hpp index 29aca5ab6..f59fee37f 100644 --- a/apps/opencs/view/world/scenesubview.hpp +++ b/apps/opencs/view/world/scenesubview.hpp @@ -47,6 +47,7 @@ namespace CSVWorld CSVWidget::SceneToolbar* mToolbar; std::string mTitle; CSVWidget::SceneToolMode *mEditMode; + bool mLocked; public: @@ -85,6 +86,8 @@ namespace CSVWorld void cellSelectionChanged (const CSMWorld::UniversalId& id); void handleDrop(const std::vector& data); + + void editModeChanged (const std::string& id); }; } From d597bef2cda32eea1c12d623d0956d6e18b05976 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 25 Sep 2015 10:58:20 +0200 Subject: [PATCH 04/23] refined selection related user settings --- apps/opencs/model/settings/usersettings.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 3daf7f9ec..5cc60c318 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -399,11 +399,12 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() secondaryEditing->setDeclaredValues (values); secondaryEditing->setDefaultValue (cRight); - values << "Context Sensitive"; - Setting *selection = createSetting (Type_ComboBox, "select", "Selection Button"); selection->setDeclaredValues (values); selection->setDefaultValue (middle); + + Setting *contextSensitive = createSetting (Type_CheckBox, "context-select", "Context Sensitive Selection"); + contextSensitive->setDefaultValue ("false"); } { From 5c34a0205804dd718cc4d6efe26ee3be51b37101 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 25 Sep 2015 13:11:40 +0200 Subject: [PATCH 05/23] store mouse bindings in WorldspaceWidget --- apps/opencs/view/render/worldspacewidget.cpp | 57 +++++++++++++++++++- apps/opencs/view/render/worldspacewidget.hpp | 6 +++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 2eb84d0a2..5d866fc6c 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -18,6 +18,8 @@ #include "../../model/world/universalid.hpp" #include "../../model/world/idtable.hpp" +#include "../../model/settings/usersettings.hpp" + #include "../widget/scenetoolmode.hpp" #include "../widget/scenetooltoggle2.hpp" #include "../widget/scenetoolrun.hpp" @@ -26,6 +28,17 @@ #include "elements.hpp" #include "editmode.hpp" +namespace +{ + static const char * const sMappingSettings[] = + { + "p-navi", "s-navi", + "p-edit", "s-edit", + "select", + 0 + }; +} + CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent) : SceneWidget (document.getData().getResourceSystem(), parent), mSceneElements(0), mRun(0), mDocument(document), mInteractionMask (0) @@ -59,6 +72,13 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg this, SLOT (debugProfileDataChanged (const QModelIndex&, const QModelIndex&))); connect (debugProfiles, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), this, SLOT (debugProfileAboutToBeRemoved (const QModelIndex&, int, int))); + + for (int i=0; sMappingSettings[i]; ++i) + { + QString key ("scene-input/"); + key += sMappingSettings[i]; + storeMappingSetting (key, CSMSettings::UserSettings::instance().settingValue (key)); + } } CSVRender::WorldspaceWidget::~WorldspaceWidget () @@ -256,7 +276,8 @@ unsigned int CSVRender::WorldspaceWidget::getInteractionMask() const void CSVRender::WorldspaceWidget::updateUserSetting (const QString& name, const QStringList& value) { - + if (!value.isEmpty() && storeMappingSetting (name, value.first())) + return; } void CSVRender::WorldspaceWidget::addVisibilitySelectorButtons ( @@ -293,6 +314,40 @@ void CSVRender::WorldspaceWidget::dragMoveEvent(QDragMoveEvent *event) event->accept(); } + +bool CSVRender::WorldspaceWidget::storeMappingSetting (const QString& key, const QString& value) +{ + const QString prefix = "scene-input/"; + + if (key.startsWith (prefix)) + { + QString key2 (key.mid (prefix.length())); + + for (int i=0; sMappingSettings[i]; ++i) + if (key2==sMappingSettings[i]) + { + std::cout<<"button :"< (event->mimeData()); diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index c3796af34..23f672fbd 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -1,6 +1,8 @@ #ifndef OPENCS_VIEW_WORLDSPACEWIDGET_H #define OPENCS_VIEW_WORLDSPACEWIDGET_H +#include + #include #include "scenewidget.hpp" @@ -31,6 +33,7 @@ namespace CSVRender CSVWidget::SceneToolRun *mRun; CSMDoc::Document& mDocument; unsigned int mInteractionMask; + std::map, std::string> mButtonMapping; public: @@ -120,6 +123,9 @@ namespace CSVRender void dragMoveEvent(QDragMoveEvent *event); + /// \return Is \a key a button mapping setting? (ignored otherwise) + bool storeMappingSetting (const QString& key, const QString& value); + virtual std::string getStartupInstruction() = 0; private slots: From d46eeb04cd49d3543e3800707789fde4bdf8cadf Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 25 Sep 2015 14:16:41 +0200 Subject: [PATCH 06/23] removed a left-over debugging statement --- apps/opencs/view/render/worldspacewidget.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 5d866fc6c..834762a67 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -326,7 +326,6 @@ bool CSVRender::WorldspaceWidget::storeMappingSetting (const QString& key, const for (int i=0; sMappingSettings[i]; ++i) if (key2==sMappingSettings[i]) { - std::cout<<"button :"< Date: Sat, 26 Sep 2015 12:05:44 +0200 Subject: [PATCH 07/23] renamed ObjectHolder into ObjectTag --- apps/opencs/view/render/object.cpp | 2 +- apps/opencs/view/render/object.hpp | 4 ++-- apps/opencs/view/render/worldspacewidget.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index f05e311f9..c7485c891 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -124,7 +124,7 @@ CSVRender::Object::Object (CSMWorld::Data& data, osg::Group* parentNode, mOutline = new osgFX::Scribe; mOutline->addChild(mBaseNode); - mBaseNode->setUserData(new ObjectHolder(this)); + mBaseNode->setUserData(new ObjectTag(this)); parentNode->addChild(mBaseNode); diff --git a/apps/opencs/view/render/object.hpp b/apps/opencs/view/render/object.hpp index 9b3749069..1a1295b53 100644 --- a/apps/opencs/view/render/object.hpp +++ b/apps/opencs/view/render/object.hpp @@ -39,10 +39,10 @@ namespace CSVRender class Object; // An object to attach as user data to the osg::Node, allows us to get an Object back from a Node when we are doing a ray query - class ObjectHolder : public osg::Referenced + class ObjectTag : public osg::Referenced { public: - ObjectHolder(Object* obj) + ObjectTag (Object* obj) : mObject(obj) { } diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 834762a67..378b5bea9 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -463,7 +463,7 @@ void CSVRender::WorldspaceWidget::mousePressEvent (QMouseEvent *event) for (std::vector::iterator it = intersection.nodePath.begin(); it != intersection.nodePath.end(); ++it) { osg::Node* node = *it; - if (CSVRender::ObjectHolder* holder = dynamic_cast(node->getUserData())) + if (CSVRender::ObjectTag* holder = dynamic_cast(node->getUserData())) { // hit an Object, toggle its selection state CSVRender::Object* obj = holder->mObject; From 71247a018652cf5ac4894e1f242daccd971e41bb Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 26 Sep 2015 12:18:18 +0200 Subject: [PATCH 08/23] inserted TagBase between ObjectTag and osg::Referenced --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/view/render/object.cpp | 5 +++++ apps/opencs/view/render/object.hpp | 17 ++++++++--------- apps/opencs/view/render/tagbase.cpp | 9 +++++++++ apps/opencs/view/render/tagbase.hpp | 22 ++++++++++++++++++++++ 5 files changed, 45 insertions(+), 10 deletions(-) create mode 100644 apps/opencs/view/render/tagbase.cpp create mode 100644 apps/opencs/view/render/tagbase.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index f9a73a09f..cfa938473 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -90,7 +90,7 @@ opencs_units (view/render opencs_units_noqt (view/render lighting lightingday lightingnight - lightingbright object cell terrainstorage + lightingbright object cell terrainstorage tagbase ) opencs_hdrs_noqt (view/render diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index c7485c891..ac96cb283 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -38,6 +38,11 @@ namespace } +CSVRender::ObjectTag::ObjectTag (Object* object) +: TagBase (Element_Reference), mObject (object) +{} + + void CSVRender::Object::clear() { } diff --git a/apps/opencs/view/render/object.hpp b/apps/opencs/view/render/object.hpp index 1a1295b53..0858a2edb 100644 --- a/apps/opencs/view/render/object.hpp +++ b/apps/opencs/view/render/object.hpp @@ -8,8 +8,9 @@ #include #include -class QModelIndex; +#include "tagbase.hpp" +class QModelIndex; namespace osg { @@ -35,21 +36,19 @@ namespace CSMWorld namespace CSVRender { - class Object; // An object to attach as user data to the osg::Node, allows us to get an Object back from a Node when we are doing a ray query - class ObjectTag : public osg::Referenced + class ObjectTag : public TagBase { - public: - ObjectTag (Object* obj) - : mObject(obj) - { - } + public: - Object* mObject; + ObjectTag (Object* object); + + Object* mObject; }; + class Object { const CSMWorld::Data& mData; diff --git a/apps/opencs/view/render/tagbase.cpp b/apps/opencs/view/render/tagbase.cpp new file mode 100644 index 000000000..af9a37624 --- /dev/null +++ b/apps/opencs/view/render/tagbase.cpp @@ -0,0 +1,9 @@ + +#include "tagbase.hpp" + +CSVRender::TagBase::TagBase (Elements element) : mElement (element) {} + +CSVRender::Elements CSVRender::TagBase::getElement() const +{ + return mElement; +} diff --git a/apps/opencs/view/render/tagbase.hpp b/apps/opencs/view/render/tagbase.hpp new file mode 100644 index 000000000..874b856c6 --- /dev/null +++ b/apps/opencs/view/render/tagbase.hpp @@ -0,0 +1,22 @@ +#ifndef OPENCS_VIEW_TAGBASE_H +#define OPENCS_VIEW_TAGBASE_H + +#include + +#include "elements.hpp" + +namespace CSVRender +{ + class TagBase : public osg::Referenced + { + Elements mElement; + + public: + + TagBase (Elements element); + + Elements getElement() const; + }; +} + +#endif From 72bb33c2c479ef82eebe5c07450c0f4388848891 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 26 Sep 2015 12:24:41 +0200 Subject: [PATCH 09/23] filter mouse interaction by interaction mask --- apps/opencs/view/render/worldspacewidget.cpp | 21 ++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 378b5bea9..246f6a4bf 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -463,18 +463,27 @@ void CSVRender::WorldspaceWidget::mousePressEvent (QMouseEvent *event) for (std::vector::iterator it = intersection.nodePath.begin(); it != intersection.nodePath.end(); ++it) { osg::Node* node = *it; - if (CSVRender::ObjectTag* holder = dynamic_cast(node->getUserData())) + if (CSVRender::TagBase* tag = dynamic_cast(node->getUserData())) { - // hit an Object, toggle its selection state - CSVRender::Object* obj = holder->mObject; - obj->setSelected(!obj->getSelected()); + if (!(tag->getElement() && mInteractionMask)) + break; // not interested -> continue looking + + // hit something marked with a tag + if (CSVRender::ObjectTag *objectTag = dynamic_cast (tag)) + { + // hit an Object, toggle its selection state + CSVRender::Object* object = objectTag->mObject; + object->setSelected (!object->getSelected()); + } + return; } } +// ignoring terrain for now // must be terrain, report coordinates - std::cout << "Terrain hit at " << intersection.getWorldIntersectPoint().x() << " " << intersection.getWorldIntersectPoint().y() << std::endl; - return; +// std::cout << "Terrain hit at " << intersection.getWorldIntersectPoint().x() << " " << intersection.getWorldIntersectPoint().y() << std::endl; +// return; } } From 3844c94975d18f7b98a3cd19f7e57ec310df636c Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 26 Sep 2015 17:39:55 +0200 Subject: [PATCH 10/23] bit masking fix --- apps/opencs/view/render/worldspacewidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 246f6a4bf..42f81eea4 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -465,7 +465,7 @@ void CSVRender::WorldspaceWidget::mousePressEvent (QMouseEvent *event) osg::Node* node = *it; if (CSVRender::TagBase* tag = dynamic_cast(node->getUserData())) { - if (!(tag->getElement() && mInteractionMask)) + if (!(tag->getElement() & mInteractionMask)) break; // not interested -> continue looking // hit something marked with a tag From 501ae6372d60a6d6932f5ed72719da6196fcc665 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 26 Sep 2015 17:51:41 +0200 Subject: [PATCH 11/23] factored out mouse picking into a separate function --- apps/opencs/view/render/worldspacewidget.cpp | 97 +++++++++++--------- apps/opencs/view/render/worldspacewidget.hpp | 4 + 2 files changed, 57 insertions(+), 44 deletions(-) diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 42f81eea4..15978e0e1 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -347,6 +347,53 @@ bool CSVRender::WorldspaceWidget::storeMappingSetting (const QString& key, const return false; } +osg::ref_ptr CSVRender::WorldspaceWidget::mousePick (QMouseEvent *event) +{ + // (0,0) is considered the lower left corner of an OpenGL window + int x = event->x(); + int y = height() - event->y(); + + osg::ref_ptr intersector (new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, x, y)); + + intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::NO_LIMIT); + osgUtil::IntersectionVisitor visitor(intersector); + + visitor.setTraversalMask(getInteractionMask() << 1); + + mView->getCamera()->accept(visitor); + + for (osgUtil::LineSegmentIntersector::Intersections::iterator it = intersector->getIntersections().begin(); + it != intersector->getIntersections().end(); ++it) + { + osgUtil::LineSegmentIntersector::Intersection intersection = *it; + + // reject back-facing polygons + osg::Vec3f normal = intersection.getWorldIntersectNormal(); + normal = osg::Matrix::transform3x3(normal, mView->getCamera()->getViewMatrix()); + if (normal.z() < 0) + continue; + + for (std::vector::iterator it = intersection.nodePath.begin(); it != intersection.nodePath.end(); ++it) + { + osg::Node* node = *it; + if (osg::ref_ptr tag = dynamic_cast(node->getUserData())) + { + if (!(tag->getElement() & mInteractionMask)) + break; // not interested -> continue looking + + return tag; + } + } + +// ignoring terrain for now + // must be terrain, report coordinates +// std::cout << "Terrain hit at " << intersection.getWorldIntersectPoint().x() << " " << intersection.getWorldIntersectPoint().y() << std::endl; +// return; + } + + return osg::ref_ptr(); +} + void CSVRender::WorldspaceWidget::dropEvent (QDropEvent* event) { const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); @@ -436,54 +483,16 @@ void CSVRender::WorldspaceWidget::mousePressEvent (QMouseEvent *event) if (event->button() != Qt::RightButton) return; - // (0,0) is considered the lower left corner of an OpenGL window - int x = event->x(); - int y = height() - event->y(); + osg::ref_ptr tag = mousePick (event); - osg::ref_ptr intersector (new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, x, y)); - - intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::NO_LIMIT); - osgUtil::IntersectionVisitor visitor(intersector); - - visitor.setTraversalMask(getInteractionMask() << 1); - - mView->getCamera()->accept(visitor); - - for (osgUtil::LineSegmentIntersector::Intersections::iterator it = intersector->getIntersections().begin(); - it != intersector->getIntersections().end(); ++it) + if (tag) { - osgUtil::LineSegmentIntersector::Intersection intersection = *it; - - // reject back-facing polygons - osg::Vec3f normal = intersection.getWorldIntersectNormal(); - normal = osg::Matrix::transform3x3(normal, mView->getCamera()->getViewMatrix()); - if (normal.z() < 0) - continue; - - for (std::vector::iterator it = intersection.nodePath.begin(); it != intersection.nodePath.end(); ++it) + if (CSVRender::ObjectTag *objectTag = dynamic_cast (tag.get())) { - osg::Node* node = *it; - if (CSVRender::TagBase* tag = dynamic_cast(node->getUserData())) - { - if (!(tag->getElement() & mInteractionMask)) - break; // not interested -> continue looking - - // hit something marked with a tag - if (CSVRender::ObjectTag *objectTag = dynamic_cast (tag)) - { - // hit an Object, toggle its selection state - CSVRender::Object* object = objectTag->mObject; - object->setSelected (!object->getSelected()); - } - - return; - } + // hit an Object, toggle its selection state + CSVRender::Object* object = objectTag->mObject; + object->setSelected (!object->getSelected()); } - -// ignoring terrain for now - // must be terrain, report coordinates -// std::cout << "Terrain hit at " << intersection.getWorldIntersectPoint().x() << " " << intersection.getWorldIntersectPoint().y() << std::endl; -// return; } } diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 23f672fbd..90a85006f 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -25,6 +25,8 @@ namespace CSVWidget namespace CSVRender { + class TagBase; + class WorldspaceWidget : public SceneWidget { Q_OBJECT @@ -126,6 +128,8 @@ namespace CSVRender /// \return Is \a key a button mapping setting? (ignored otherwise) bool storeMappingSetting (const QString& key, const QString& value); + osg::ref_ptr mousePick (QMouseEvent *event); + virtual std::string getStartupInstruction() = 0; private slots: From 7bbc475bda71ea8d87ca63933c3d8c0c21dc2841 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 26 Sep 2015 18:01:49 +0200 Subject: [PATCH 12/23] apply button mapping --- apps/opencs/view/render/worldspacewidget.cpp | 39 +++++++++++++++----- apps/opencs/view/render/worldspacewidget.hpp | 2 + 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 15978e0e1..5b5219184 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -394,6 +395,20 @@ osg::ref_ptr CSVRender::WorldspaceWidget::mousePick (QMouseE return osg::ref_ptr(); } +std::string CSVRender::WorldspaceWidget::mapButton (QMouseEvent *event) +{ + std::pair phyiscal ( + event->button(), QApplication::keyboardModifiers() & Qt::ControlModifier); + + std::map, std::string>::const_iterator iter = + mButtonMapping.find (phyiscal); + + if (iter!=mButtonMapping.end()) + return iter->second; + + return ""; +} + void CSVRender::WorldspaceWidget::dropEvent (QDropEvent* event) { const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); @@ -480,18 +495,24 @@ void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event) void CSVRender::WorldspaceWidget::mousePressEvent (QMouseEvent *event) { - if (event->button() != Qt::RightButton) - return; + std::string button = mapButton (event); - osg::ref_ptr tag = mousePick (event); - - if (tag) + if (button=="p-navi" || button=="s-navi") { - if (CSVRender::ObjectTag *objectTag = dynamic_cast (tag.get())) + + } + else if (button=="p-edit" || button=="s-edit" || button=="select") + { + osg::ref_ptr tag = mousePick (event); + + if (tag) { - // hit an Object, toggle its selection state - CSVRender::Object* object = objectTag->mObject; - object->setSelected (!object->getSelected()); + if (CSVRender::ObjectTag *objectTag = dynamic_cast (tag.get())) + { + // hit an Object, toggle its selection state + CSVRender::Object* object = objectTag->mObject; + object->setSelected (!object->getSelected()); + } } } } diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 90a85006f..ed5c5bcc8 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -130,6 +130,8 @@ namespace CSVRender osg::ref_ptr mousePick (QMouseEvent *event); + std::string mapButton (QMouseEvent *event); + virtual std::string getStartupInstruction() = 0; private slots: From 5d9863aec12429aa086d54012da7638a4eb663bc Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 27 Sep 2015 11:34:14 +0200 Subject: [PATCH 13/23] removed a redundant check --- apps/opencs/view/render/worldspacewidget.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 5b5219184..70def97b9 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -378,12 +378,7 @@ osg::ref_ptr CSVRender::WorldspaceWidget::mousePick (QMouseE { osg::Node* node = *it; if (osg::ref_ptr tag = dynamic_cast(node->getUserData())) - { - if (!(tag->getElement() & mInteractionMask)) - break; // not interested -> continue looking - return tag; - } } // ignoring terrain for now From 9bf27c7e371e4b1fdf01b356210a7bb9d02d58d5 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 27 Sep 2015 14:38:12 +0200 Subject: [PATCH 14/23] moved edit mode handling from SceneSubView to WorldspaceWidget --- apps/opencs/view/render/worldspacewidget.cpp | 23 ++++++++++++++++---- apps/opencs/view/render/worldspacewidget.hpp | 5 +++++ apps/opencs/view/world/scenesubview.cpp | 18 +++------------ apps/opencs/view/world/scenesubview.hpp | 4 ---- 4 files changed, 27 insertions(+), 23 deletions(-) diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 70def97b9..be4d32bb5 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -42,7 +42,7 @@ namespace CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent) : SceneWidget (document.getData().getResourceSystem(), parent), mSceneElements(0), mRun(0), mDocument(document), - mInteractionMask (0) + mInteractionMask (0), mEditMode (0), mLocked (false) { setAcceptDrops(true); @@ -199,11 +199,14 @@ CSVWidget::SceneToolRun *CSVRender::WorldspaceWidget::makeRunTool ( CSVWidget::SceneToolMode *CSVRender::WorldspaceWidget::makeEditModeSelector ( CSVWidget::SceneToolbar *parent) { - CSVWidget::SceneToolMode *tool = new CSVWidget::SceneToolMode (parent, "Edit Mode"); + mEditMode = new CSVWidget::SceneToolMode (parent, "Edit Mode"); - addEditModeSelectorButtons (tool); + addEditModeSelectorButtons (mEditMode); - return tool; + connect (mEditMode, SIGNAL (modeChanged (const std::string&)), + this, SLOT (editModeChanged (const std::string&))); + + return mEditMode; } CSVRender::WorldspaceWidget::DropType CSVRender::WorldspaceWidget::getDropType ( @@ -279,6 +282,13 @@ void CSVRender::WorldspaceWidget::updateUserSetting (const QString& name, const { if (!value.isEmpty() && storeMappingSetting (name, value.first())) return; + + dynamic_cast (*mEditMode->getCurrent()).updateUserSetting (name, value); +} + +void CSVRender::WorldspaceWidget::setEditLock (bool locked) +{ + dynamic_cast (*mEditMode->getCurrent()).setEditLock (locked); } void CSVRender::WorldspaceWidget::addVisibilitySelectorButtons ( @@ -468,6 +478,11 @@ void CSVRender::WorldspaceWidget::debugProfileAboutToBeRemoved (const QModelInde } } +void CSVRender::WorldspaceWidget::editModeChanged (const std::string& id) +{ + dynamic_cast (*mEditMode->getCurrent()).setEditLock (mLocked); +} + void CSVRender::WorldspaceWidget::elementSelectionChanged() { setVisibilityMask (getVisibilityMask()); diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index ed5c5bcc8..272987a05 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -36,6 +36,8 @@ namespace CSVRender CSMDoc::Document& mDocument; unsigned int mInteractionMask; std::map, std::string> mButtonMapping; + CSVWidget::SceneToolMode *mEditMode; + bool mLocked; public: @@ -100,6 +102,8 @@ namespace CSVRender virtual void updateUserSetting (const QString& name, const QStringList& value); + virtual void setEditLock (bool locked); + protected: virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool); @@ -158,6 +162,7 @@ namespace CSVRender void debugProfileAboutToBeRemoved (const QModelIndex& parent, int start, int end); + void editModeChanged (const std::string& id); protected slots: diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 967909969..753d791c0 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -27,8 +27,7 @@ #include "creator.hpp" CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) -: SubView (id), mScene(NULL), mLayout(new QHBoxLayout), mDocument(document), mToolbar(NULL), - mEditMode (0), mLocked (false) +: SubView (id), mScene(NULL), mLayout(new QHBoxLayout), mDocument(document), mToolbar(NULL) { QVBoxLayout *layout = new QVBoxLayout; @@ -123,16 +122,14 @@ CSVWidget::SceneToolbar* CSVWorld::SceneSubView::makeToolbar (CSVRender::Worldsp CSVWidget::SceneToolRun *runTool = widget->makeRunTool (toolbar); toolbar->addTool (runTool); - mEditMode = widget->makeEditModeSelector (toolbar); - toolbar->addTool (mEditMode); + toolbar->addTool (widget->makeEditModeSelector (toolbar)); return toolbar; } void CSVWorld::SceneSubView::setEditLock (bool locked) { - mLocked = locked; - dynamic_cast (*mEditMode->getCurrent()).setEditLock (locked); + mScene->setEditLock (locked); } void CSVWorld::SceneSubView::setStatusBar (bool show) @@ -153,7 +150,6 @@ std::string CSVWorld::SceneSubView::getTitle() const void CSVWorld::SceneSubView::updateUserSetting (const QString& name, const QStringList& value) { mScene->updateUserSetting (name, value); - dynamic_cast (*mEditMode->getCurrent()).updateUserSetting (name, value); CSVDoc::SubView::updateUserSetting (name, value); } @@ -259,12 +255,4 @@ void CSVWorld::SceneSubView::replaceToolbarAndWorldspace (CSVRender::WorldspaceW mScene->selectDefaultNavigationMode(); setFocusProxy (mScene); - - connect (mEditMode, SIGNAL (modeChanged (const std::string&)), - this, SLOT (editModeChanged (const std::string&))); -} - -void CSVWorld::SceneSubView::editModeChanged (const std::string& id) -{ - dynamic_cast (*mEditMode->getCurrent()).setEditLock (mLocked); } diff --git a/apps/opencs/view/world/scenesubview.hpp b/apps/opencs/view/world/scenesubview.hpp index f59fee37f..2458d58f4 100644 --- a/apps/opencs/view/world/scenesubview.hpp +++ b/apps/opencs/view/world/scenesubview.hpp @@ -46,8 +46,6 @@ namespace CSVWorld CSMDoc::Document& mDocument; CSVWidget::SceneToolbar* mToolbar; std::string mTitle; - CSVWidget::SceneToolMode *mEditMode; - bool mLocked; public: @@ -86,8 +84,6 @@ namespace CSVWorld void cellSelectionChanged (const CSMWorld::UniversalId& id); void handleDrop(const std::vector& data); - - void editModeChanged (const std::string& id); }; } From 981a8a2cc2754fe5f9c9abc5e1b42b86f091dc3d Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 27 Sep 2015 16:18:22 +0200 Subject: [PATCH 15/23] delegated editing and selection functions to mode objects --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/view/render/editmode.cpp | 6 ++++ apps/opencs/view/render/editmode.hpp | 12 +++++++ apps/opencs/view/render/instancemode.cpp | 35 ++++++++++++++++++++ apps/opencs/view/render/instancemode.hpp | 24 ++++++++++++++ apps/opencs/view/render/worldspacewidget.cpp | 22 ++++++------ 6 files changed, 88 insertions(+), 13 deletions(-) create mode 100644 apps/opencs/view/render/instancemode.cpp create mode 100644 apps/opencs/view/render/instancemode.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index cfa938473..2ed55218a 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 + previewwidget editmode instancemode ) opencs_units_noqt (view/render diff --git a/apps/opencs/view/render/editmode.cpp b/apps/opencs/view/render/editmode.cpp index c3aad3f7a..2240318b6 100644 --- a/apps/opencs/view/render/editmode.cpp +++ b/apps/opencs/view/render/editmode.cpp @@ -26,3 +26,9 @@ void CSVRender::EditMode::setEditLock (bool locked) { } + +void CSVRender::EditMode::primaryEditPressed (osg::ref_ptr tag) {} + +void CSVRender::EditMode::secondaryEditPressed (osg::ref_ptr tag) {} + +void CSVRender::EditMode::selectPressed (osg::ref_ptr tag) {} diff --git a/apps/opencs/view/render/editmode.hpp b/apps/opencs/view/render/editmode.hpp index 1212cd285..c00669534 100644 --- a/apps/opencs/view/render/editmode.hpp +++ b/apps/opencs/view/render/editmode.hpp @@ -1,11 +1,14 @@ #ifndef CSV_RENDER_EDITMODE_H #define CSV_RENDER_EDITMODE_H +#include + #include "../widget/modebutton.hpp" namespace CSVRender { class WorldspaceWidget; + class TagBase; class EditMode : public CSVWidget::ModeButton { @@ -28,6 +31,15 @@ namespace CSVRender /// Default-implementation: Ignored. virtual void setEditLock (bool locked); + + /// Default-implementation: Ignored. + virtual void primaryEditPressed (osg::ref_ptr tag); + + /// Default-implementation: Ignored. + virtual void secondaryEditPressed (osg::ref_ptr tag); + + /// Default-implementation: Ignored. + virtual void selectPressed (osg::ref_ptr tag); }; } diff --git a/apps/opencs/view/render/instancemode.cpp b/apps/opencs/view/render/instancemode.cpp new file mode 100644 index 000000000..ccff8c7c5 --- /dev/null +++ b/apps/opencs/view/render/instancemode.cpp @@ -0,0 +1,35 @@ + +#include "instancemode.hpp" + +#include "elements.hpp" +#include "object.hpp" + +CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent) +: EditMode (worldspaceWidget, QIcon (":placeholder"), Element_Reference, "Instance editing", + parent) +{ + +} + +void CSVRender::InstanceMode::primaryEditPressed (osg::ref_ptr tag) +{ + +} + +void CSVRender::InstanceMode::secondaryEditPressed (osg::ref_ptr tag) +{ + +} + +void CSVRender::InstanceMode::selectPressed (osg::ref_ptr tag) +{ + if (tag) + { + if (CSVRender::ObjectTag *objectTag = dynamic_cast (tag.get())) + { + // hit an Object, toggle its selection state + CSVRender::Object* object = objectTag->mObject; + object->setSelected (!object->getSelected()); + } + } +} diff --git a/apps/opencs/view/render/instancemode.hpp b/apps/opencs/view/render/instancemode.hpp new file mode 100644 index 000000000..6071aedf0 --- /dev/null +++ b/apps/opencs/view/render/instancemode.hpp @@ -0,0 +1,24 @@ +#ifndef CSV_RENDER_INSTANCEMODE_H +#define CSV_RENDER_INSTANCEMODE_H + +#include "editmode.hpp" + +namespace CSVRender +{ + class InstanceMode : public EditMode + { + Q_OBJECT + + public: + + InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent = 0); + + virtual void primaryEditPressed (osg::ref_ptr tag); + + virtual void secondaryEditPressed (osg::ref_ptr tag); + + virtual void selectPressed (osg::ref_ptr tag); + }; +} + +#endif diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index be4d32bb5..1c1dc4d6b 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -28,6 +28,7 @@ #include "object.hpp" #include "elements.hpp" #include "editmode.hpp" +#include "instancemode.hpp" namespace { @@ -302,9 +303,7 @@ void CSVRender::WorldspaceWidget::addVisibilitySelectorButtons ( void CSVRender::WorldspaceWidget::addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool) { /// \todo replace EditMode with suitable subclasses - tool->addButton ( - new EditMode (this, QIcon (":placeholder"), Element_Reference, "Instance editing"), - "object"); + tool->addButton (new InstanceMode (this, tool), "object"); tool->addButton ( new EditMode (this, QIcon (":placeholder"), Element_Pathgrid, "Pathgrid editing"), "pathgrid"); @@ -515,15 +514,14 @@ void CSVRender::WorldspaceWidget::mousePressEvent (QMouseEvent *event) { osg::ref_ptr tag = mousePick (event); - if (tag) - { - if (CSVRender::ObjectTag *objectTag = dynamic_cast (tag.get())) - { - // hit an Object, toggle its selection state - CSVRender::Object* object = objectTag->mObject; - object->setSelected (!object->getSelected()); - } - } + EditMode& editMode = dynamic_cast (*mEditMode->getCurrent()); + + if (button=="p-edit") + editMode.primaryEditPressed (tag); + else if (button=="s-edit") + editMode.secondaryEditPressed (tag); + else if (button=="select") + editMode.selectPressed (tag); } } From 319e3f24a3d23e158adbc3e46f0f80dc55e5206f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 29 Sep 2015 13:48:04 +0200 Subject: [PATCH 16/23] on edit mode change clear selection of elements that are not affected by current edit mode (only support for instance for now since we do not have selection for other elements yet) --- apps/opencs/view/render/cell.cpp | 21 +++++++++++++++++++ apps/opencs/view/render/cell.hpp | 11 ++++++++++ apps/opencs/view/render/editmode.cpp | 1 + .../view/render/pagedworldspacewidget.cpp | 7 +++++++ .../view/render/pagedworldspacewidget.hpp | 3 +++ .../view/render/unpagedworldspacewidget.cpp | 5 +++++ .../view/render/unpagedworldspacewidget.hpp | 3 +++ apps/opencs/view/render/worldspacewidget.hpp | 10 ++++++--- 8 files changed, 58 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 28a48cfbd..c4f744510 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -211,3 +211,24 @@ bool CSVRender::Cell::referenceAdded (const QModelIndex& parent, int start, int return addObjects (start, end); } + +void CSVRender::Cell::setSelection (int elementMask, Selection mode) +{ + if (elementMask & Element_Reference) + { + for (std::map::const_iterator iter (mObjects.begin()); + iter!=mObjects.end(); ++iter) + { + bool selected = false; + + switch (mode) + { + case Selection_Clear: selected = false; break; + case Selection_All: selected = true; break; + case Selection_Invert: selected = !iter->second->getSelected(); break; + } + + iter->second->setSelected (selected); + } + } +} diff --git a/apps/opencs/view/render/cell.hpp b/apps/opencs/view/render/cell.hpp index f4272b887..d26a2d9af 100644 --- a/apps/opencs/view/render/cell.hpp +++ b/apps/opencs/view/render/cell.hpp @@ -49,6 +49,15 @@ namespace CSVRender /// \return Have any objects been added? bool addObjects (int start, int end); + public: + + enum Selection + { + Selection_Clear, + Selection_All, + Selection_Invert + }; + public: Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id); @@ -75,6 +84,8 @@ namespace CSVRender /// \return Did this call result in a modification of the visual representation of /// this cell? bool referenceAdded (const QModelIndex& parent, int start, int end); + + void setSelection (int elementMask, Selection mode); }; } diff --git a/apps/opencs/view/render/editmode.cpp b/apps/opencs/view/render/editmode.cpp index 2240318b6..e1f69a63d 100644 --- a/apps/opencs/view/render/editmode.cpp +++ b/apps/opencs/view/render/editmode.cpp @@ -15,6 +15,7 @@ unsigned int CSVRender::EditMode::getInteractionMask() const void CSVRender::EditMode::activate (CSVWidget::SceneToolbar *toolbar) { mWorldspaceWidget->setInteractionMask (mMask); + mWorldspaceWidget->clearSelection (~mMask); } void CSVRender::EditMode::updateUserSetting (const QString& name, const QStringList& value) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index b0c1e74a9..543f3788a 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -314,6 +314,13 @@ unsigned int CSVRender::PagedWorldspaceWidget::getVisibilityMask() const return WorldspaceWidget::getVisibilityMask() | mControlElements->getSelection(); } +void CSVRender::PagedWorldspaceWidget::clearSelection (int elementMask) +{ + for (std::map::iterator iter = mCells.begin(); + iter!=mCells.end(); ++iter) + iter->second->setSelection (elementMask, Cell::Selection_Clear); +} + 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 64a0bccd1..d52efd90e 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -79,6 +79,9 @@ namespace CSVRender virtual unsigned int getVisibilityMask() const; + /// \param elementMask Elements to be affected by the clear operation + virtual void clearSelection (int elementMask); + protected: virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool); diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index 3e1733c81..989c976ff 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -102,6 +102,11 @@ bool CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vectorsetSelection (elementMask, Cell::Selection_Clear); +} + 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 d01c3e766..9e6fa97f4 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.hpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.hpp @@ -43,6 +43,9 @@ namespace CSVRender virtual bool handleDrop (const std::vector& data, DropType type); + /// \param elementMask Elements to be affected by the clear operation + virtual void clearSelection (int elementMask); + private: virtual void referenceableDataChanged (const QModelIndex& topLeft, diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 272987a05..ffdcf3bc3 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -5,10 +5,11 @@ #include -#include "scenewidget.hpp" +#include "../../model/doc/document.hpp" +#include "../../model/world/tablemimedata.hpp" -#include -#include +#include "scenewidget.hpp" +#include "elements.hpp" namespace CSMWorld { @@ -104,6 +105,9 @@ namespace CSVRender virtual void setEditLock (bool locked); + /// \param elementMask Elements to be affected by the clear operation + virtual void clearSelection (int elementMask) = 0; + protected: virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool); From f28fa9fc16ec1477b1de18bf078a5d16af2b34aa Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 29 Sep 2015 13:53:47 +0200 Subject: [PATCH 17/23] clear instance selection on select click on nothing/something that isn't an instance --- apps/opencs/view/render/editmode.cpp | 5 +++++ apps/opencs/view/render/editmode.hpp | 4 ++++ apps/opencs/view/render/instancemode.cpp | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/apps/opencs/view/render/editmode.cpp b/apps/opencs/view/render/editmode.cpp index e1f69a63d..816067107 100644 --- a/apps/opencs/view/render/editmode.cpp +++ b/apps/opencs/view/render/editmode.cpp @@ -2,6 +2,11 @@ #include "worldspacewidget.hpp" +CSVRender::WorldspaceWidget& CSVRender::EditMode::getWorldspaceWidget() +{ + return *mWorldspaceWidget; +} + CSVRender::EditMode::EditMode (WorldspaceWidget *worldspaceWidget, const QIcon& icon, unsigned int mask, const QString& tooltip, QWidget *parent) : ModeButton (icon, tooltip, parent), mWorldspaceWidget (worldspaceWidget), mMask (mask) diff --git a/apps/opencs/view/render/editmode.hpp b/apps/opencs/view/render/editmode.hpp index c00669534..fa2beedd8 100644 --- a/apps/opencs/view/render/editmode.hpp +++ b/apps/opencs/view/render/editmode.hpp @@ -17,6 +17,10 @@ namespace CSVRender WorldspaceWidget *mWorldspaceWidget; unsigned int mMask; + protected: + + WorldspaceWidget& getWorldspaceWidget(); + public: EditMode (WorldspaceWidget *worldspaceWidget, const QIcon& icon, unsigned int mask, diff --git a/apps/opencs/view/render/instancemode.cpp b/apps/opencs/view/render/instancemode.cpp index ccff8c7c5..2e8f8cda2 100644 --- a/apps/opencs/view/render/instancemode.cpp +++ b/apps/opencs/view/render/instancemode.cpp @@ -3,6 +3,7 @@ #include "elements.hpp" #include "object.hpp" +#include "worldspacewidget.hpp" CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent) : EditMode (worldspaceWidget, QIcon (":placeholder"), Element_Reference, "Instance editing", @@ -30,6 +31,9 @@ void CSVRender::InstanceMode::selectPressed (osg::ref_ptr tag) // hit an Object, toggle its selection state CSVRender::Object* object = objectTag->mObject; object->setSelected (!object->getSelected()); + return; } } + + getWorldspaceWidget().clearSelection (Element_Reference); } From 2cb106f6adfe5f8f7f94079077de0d43f41f8a44 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 29 Sep 2015 16:06:55 +0200 Subject: [PATCH 18/23] added missing flagAsModified calls --- apps/opencs/view/render/pagedworldspacewidget.cpp | 2 ++ apps/opencs/view/render/unpagedworldspacewidget.cpp | 1 + 2 files changed, 3 insertions(+) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 543f3788a..7403113b3 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -319,6 +319,8 @@ void CSVRender::PagedWorldspaceWidget::clearSelection (int elementMask) for (std::map::iterator iter = mCells.begin(); iter!=mCells.end(); ++iter) iter->second->setSelection (elementMask, Cell::Selection_Clear); + + flagAsModified(); } CSVWidget::SceneToolToggle *CSVRender::PagedWorldspaceWidget::makeControlVisibilitySelector ( diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index 989c976ff..68f068dac 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -105,6 +105,7 @@ bool CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vectorsetSelection (elementMask, Cell::Selection_Clear); + flagAsModified(); } void CSVRender::UnpagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft, From 8e87b48866e66c1546c7d7f7914f9ab4f7fd015e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 29 Sep 2015 16:07:14 +0200 Subject: [PATCH 19/23] handle context-sensitive select mode in instance editing --- apps/opencs/view/render/instancemode.cpp | 23 ++++++++++++++++++++--- apps/opencs/view/render/instancemode.hpp | 6 ++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/render/instancemode.cpp b/apps/opencs/view/render/instancemode.cpp index 2e8f8cda2..333d91656 100644 --- a/apps/opencs/view/render/instancemode.cpp +++ b/apps/opencs/view/render/instancemode.cpp @@ -1,25 +1,42 @@ #include "instancemode.hpp" +#include "../../model/settings/usersettings.hpp" + #include "elements.hpp" #include "object.hpp" #include "worldspacewidget.hpp" CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent) : EditMode (worldspaceWidget, QIcon (":placeholder"), Element_Reference, "Instance editing", - parent) + parent), mContextSelect (false) { } +void CSVRender::InstanceMode::activate (CSVWidget::SceneToolbar *toolbar) +{ + EditMode::activate (toolbar); + + mContextSelect = CSMSettings::UserSettings::instance().setting ("scene-input/context-select")=="true"; +} + +void CSVRender::InstanceMode::updateUserSetting (const QString& name, const QStringList& value) +{ + if (name=="scene-input/context-select") + mContextSelect = value.at (0)=="true"; +} + void CSVRender::InstanceMode::primaryEditPressed (osg::ref_ptr tag) { - + if (mContextSelect) + selectPressed (tag); } void CSVRender::InstanceMode::secondaryEditPressed (osg::ref_ptr tag) { - + if (mContextSelect) + selectPressed (tag); } void CSVRender::InstanceMode::selectPressed (osg::ref_ptr tag) diff --git a/apps/opencs/view/render/instancemode.hpp b/apps/opencs/view/render/instancemode.hpp index 6071aedf0..cc4fd5434 100644 --- a/apps/opencs/view/render/instancemode.hpp +++ b/apps/opencs/view/render/instancemode.hpp @@ -9,10 +9,16 @@ namespace CSVRender { Q_OBJECT + bool mContextSelect; + public: InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent = 0); + virtual void activate (CSVWidget::SceneToolbar *toolbar); + + virtual void updateUserSetting (const QString& name, const QStringList& value); + virtual void primaryEditPressed (osg::ref_ptr tag); virtual void secondaryEditPressed (osg::ref_ptr tag); From 0a5bfb2107ddf46465ce74902470dc7056eb279b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 1 Oct 2015 12:46:01 +0200 Subject: [PATCH 20/23] added framework for drag operations --- apps/opencs/view/render/editmode.cpp | 21 ++++++ apps/opencs/view/render/editmode.hpp | 27 +++++++ apps/opencs/view/render/worldspacewidget.cpp | 75 +++++++++++++++++--- apps/opencs/view/render/worldspacewidget.hpp | 4 ++ 4 files changed, 116 insertions(+), 11 deletions(-) diff --git a/apps/opencs/view/render/editmode.cpp b/apps/opencs/view/render/editmode.cpp index 816067107..e1ab619cd 100644 --- a/apps/opencs/view/render/editmode.cpp +++ b/apps/opencs/view/render/editmode.cpp @@ -38,3 +38,24 @@ void CSVRender::EditMode::primaryEditPressed (osg::ref_ptr tag) {} void CSVRender::EditMode::secondaryEditPressed (osg::ref_ptr tag) {} void CSVRender::EditMode::selectPressed (osg::ref_ptr tag) {} + +bool CSVRender::EditMode::primaryEditStartDrag (osg::ref_ptr tag) +{ + return false; +} + +bool CSVRender::EditMode::secondaryEditStartDrag (osg::ref_ptr tag) +{ + return false; +} + +bool CSVRender::EditMode::selectStartDrag (osg::ref_ptr tag) +{ + return false; +} + +void CSVRender::EditMode::drag (int diffX, int diffY) {} + +void CSVRender::EditMode::dragCompleted() {} + +void CSVRender::EditMode::dragAborted() {} diff --git a/apps/opencs/view/render/editmode.hpp b/apps/opencs/view/render/editmode.hpp index fa2beedd8..361ffc5ed 100644 --- a/apps/opencs/view/render/editmode.hpp +++ b/apps/opencs/view/render/editmode.hpp @@ -44,6 +44,33 @@ namespace CSVRender /// Default-implementation: Ignored. virtual void selectPressed (osg::ref_ptr tag); + + /// Default-implementation: ignore and return false + /// + /// \return Drag accepted? + virtual bool primaryEditStartDrag (osg::ref_ptr tag); + + /// Default-implementation: ignore and return false + /// + /// \return Drag accepted? + virtual bool secondaryEditStartDrag (osg::ref_ptr tag); + + /// Default-implementation: ignore and return false + /// + /// \return Drag accepted? + virtual bool selectStartDrag (osg::ref_ptr tag); + + /// Default-implementation: ignored + virtual void drag (int diffX, int diffY); + + /// Default-implementation: ignored + virtual void dragCompleted(); + + /// Default-implementation: ignored + /// + /// \note dragAborted will not be called, if the drag is aborted via changing + /// editing mode + virtual void dragAborted(); }; } diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 1c1dc4d6b..25ee56a05 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -43,7 +43,7 @@ namespace CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent) : SceneWidget (document.getData().getResourceSystem(), parent), mSceneElements(0), mRun(0), mDocument(document), - mInteractionMask (0), mEditMode (0), mLocked (false) + mInteractionMask (0), mEditMode (0), mLocked (false), mDragging (false) { setAcceptDrops(true); @@ -480,6 +480,7 @@ void CSVRender::WorldspaceWidget::debugProfileAboutToBeRemoved (const QModelInde void CSVRender::WorldspaceWidget::editModeChanged (const std::string& id) { dynamic_cast (*mEditMode->getCurrent()).setEditLock (mLocked); + mDragging = false; } void CSVRender::WorldspaceWidget::elementSelectionChanged() @@ -495,10 +496,45 @@ void CSVRender::WorldspaceWidget::updateOverlay() void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event) { - if(event->buttons() & Qt::RightButton) + if (!mDragging) { - //mMouse->mouseMoveEvent(event); + if (mDragMode=="p-navi" || mDragMode=="s-navi") + { + + } + else if (mDragMode=="p-edit" || mDragMode=="s-edit" || mDragMode=="select") + { + osg::ref_ptr tag = mousePick (event); + + EditMode& editMode = dynamic_cast (*mEditMode->getCurrent()); + + if (mDragMode=="p-edit") + mDragging = editMode.primaryEditStartDrag (tag); + else if (mDragMode=="s-edit") + mDragging = editMode.secondaryEditStartDrag (tag); + else if (mDragMode=="select") + mDragging = editMode.selectStartDrag (tag); + + if (mDragging) + { + mDragX = event->posF().x(); + mDragY = height() - event->posF().y(); + } + } } + else + { + int diffX = event->x() - mDragX; + int diffY = (height() - event->y()) - mDragY; + + mDragX = event->x(); + mDragY = height() - event->y(); + + EditMode& editMode = dynamic_cast (*mEditMode->getCurrent()); + + editMode.drag (diffX, diffY); + } + RenderWidget::mouseMoveEvent(event); } @@ -506,6 +542,9 @@ void CSVRender::WorldspaceWidget::mousePressEvent (QMouseEvent *event) { std::string button = mapButton (event); + if (!mDragging) + mDragMode = button; + if (button=="p-navi" || button=="s-navi") { @@ -527,17 +566,25 @@ void CSVRender::WorldspaceWidget::mousePressEvent (QMouseEvent *event) void CSVRender::WorldspaceWidget::mouseReleaseEvent (QMouseEvent *event) { - if(event->button() == Qt::RightButton) + if (mDragging) { - /* - if(!getViewport()) + std::string button = mapButton (event); + + if (mDragMode=="p-navi" || mDragMode=="s-navi") { - SceneWidget::mouseReleaseEvent(event); - return; + + } + else if (mDragMode=="p-edit" || mDragMode=="s-edit" || mDragMode=="select") + { + EditMode& editMode = dynamic_cast (*mEditMode->getCurrent()); + + editMode.dragCompleted(); + mDragging = false; } - */ - //mMouse->mouseReleaseEvent(event); } + + mDragMode.clear(); + RenderWidget::mouseReleaseEvent(event); } @@ -560,7 +607,13 @@ void CSVRender::WorldspaceWidget::keyPressEvent (QKeyEvent *event) { if(event->key() == Qt::Key_Escape) { - //mMouse->cancelDrag(); + if (mDragging) + { + EditMode& editMode = dynamic_cast (*mEditMode->getCurrent()); + + editMode.dragAborted(); + mDragging = false; + } } else RenderWidget::keyPressEvent(event); diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index ffdcf3bc3..f51ce047e 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -39,6 +39,10 @@ namespace CSVRender std::map, std::string> mButtonMapping; CSVWidget::SceneToolMode *mEditMode; bool mLocked; + std::string mDragMode; + bool mDragging; + int mDragX; + int mDragY; public: From 1d4f8b2595b6f7d49d2dbc95590f5bdd2486dd68 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 1 Oct 2015 13:19:48 +0200 Subject: [PATCH 21/23] send mouse wheel input to active EditMode during drag operations --- apps/opencs/view/render/editmode.cpp | 2 ++ apps/opencs/view/render/editmode.hpp | 3 +++ apps/opencs/view/render/scenewidget.cpp | 2 ++ apps/opencs/view/render/worldspacewidget.cpp | 10 ++++++++-- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/render/editmode.cpp b/apps/opencs/view/render/editmode.cpp index e1ab619cd..cc76e3362 100644 --- a/apps/opencs/view/render/editmode.cpp +++ b/apps/opencs/view/render/editmode.cpp @@ -59,3 +59,5 @@ void CSVRender::EditMode::drag (int diffX, int diffY) {} void CSVRender::EditMode::dragCompleted() {} void CSVRender::EditMode::dragAborted() {} + +void CSVRender::EditMode::dragWheel (int diff) {} diff --git a/apps/opencs/view/render/editmode.hpp b/apps/opencs/view/render/editmode.hpp index 361ffc5ed..0a4bdf9b8 100644 --- a/apps/opencs/view/render/editmode.hpp +++ b/apps/opencs/view/render/editmode.hpp @@ -71,6 +71,9 @@ namespace CSVRender /// \note dragAborted will not be called, if the drag is aborted via changing /// editing mode virtual void dragAborted(); + + /// Default-implementation: ignored + virtual void dragWheel (int diff); }; } diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index fb3bcb3c3..76b3db348 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -110,6 +110,8 @@ bool RenderWidget::eventFilter(QObject* obj, QEvent* event) keyPressEvent(static_cast(event)); if (event->type() == QEvent::KeyRelease) keyReleaseEvent(static_cast(event)); + if (event->type() == QEvent::Wheel) + wheelEvent(static_cast(event)); // Always pass the event on to GLWidget, i.e. to OSG event queue return QObject::eventFilter(obj, event); diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 25ee56a05..3971f76fa 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -599,8 +599,14 @@ void CSVRender::WorldspaceWidget::mouseDoubleClickEvent (QMouseEvent *event) void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event) { - //if(!mMouse->wheelEvent(event)) - RenderWidget::wheelEvent(event); + if (mDragging) + { + EditMode& editMode = dynamic_cast (*mEditMode->getCurrent()); + + editMode.dragWheel (event->delta()); + } + + RenderWidget::wheelEvent(event); } void CSVRender::WorldspaceWidget::keyPressEvent (QKeyEvent *event) From 323f8bb29f04b7b48f0cbe4e5a04ac6a3f880e6e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 1 Oct 2015 13:42:21 +0200 Subject: [PATCH 22/23] sensitivity settings --- apps/opencs/model/settings/usersettings.cpp | 15 +++++++++++ apps/opencs/view/render/editmode.cpp | 4 +-- apps/opencs/view/render/editmode.hpp | 4 +-- apps/opencs/view/render/worldspacewidget.cpp | 27 +++++++++++++++++--- apps/opencs/view/render/worldspacewidget.hpp | 3 +++ 5 files changed, 46 insertions(+), 7 deletions(-) diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 5cc60c318..3e5ab24d1 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -405,6 +405,21 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() Setting *contextSensitive = createSetting (Type_CheckBox, "context-select", "Context Sensitive Selection"); contextSensitive->setDefaultValue ("false"); + + Setting *dragMouseSensitivity = createSetting (Type_DoubleSpinBox, "drag-factor", + "Mouse sensitivity during drag operations"); + dragMouseSensitivity->setDefaultValue (1.0); + dragMouseSensitivity->setRange (0.001, 100.0); + + Setting *dragWheelSensitivity = createSetting (Type_DoubleSpinBox, "drag-wheel-factor", + "Mouse wheel sensitivity during drag operations"); + dragWheelSensitivity->setDefaultValue (1.0); + dragWheelSensitivity->setRange (0.001, 100.0); + + Setting *dragShiftFactor = createSetting (Type_DoubleSpinBox, "drag-shift-factor", + "Acceleration factor during drag operations while holding down shift"); + dragShiftFactor->setDefaultValue (4.0); + dragShiftFactor->setRange (0.001, 100.0); } { diff --git a/apps/opencs/view/render/editmode.cpp b/apps/opencs/view/render/editmode.cpp index cc76e3362..c35b4f354 100644 --- a/apps/opencs/view/render/editmode.cpp +++ b/apps/opencs/view/render/editmode.cpp @@ -54,10 +54,10 @@ bool CSVRender::EditMode::selectStartDrag (osg::ref_ptr tag) return false; } -void CSVRender::EditMode::drag (int diffX, int diffY) {} +void CSVRender::EditMode::drag (int diffX, int diffY, double speedFactor) {} void CSVRender::EditMode::dragCompleted() {} void CSVRender::EditMode::dragAborted() {} -void CSVRender::EditMode::dragWheel (int diff) {} +void CSVRender::EditMode::dragWheel (int diff, double speedFactor) {} diff --git a/apps/opencs/view/render/editmode.hpp b/apps/opencs/view/render/editmode.hpp index 0a4bdf9b8..77676d6a3 100644 --- a/apps/opencs/view/render/editmode.hpp +++ b/apps/opencs/view/render/editmode.hpp @@ -61,7 +61,7 @@ namespace CSVRender virtual bool selectStartDrag (osg::ref_ptr tag); /// Default-implementation: ignored - virtual void drag (int diffX, int diffY); + virtual void drag (int diffX, int diffY, double speedFactor); /// Default-implementation: ignored virtual void dragCompleted(); @@ -73,7 +73,7 @@ namespace CSVRender virtual void dragAborted(); /// Default-implementation: ignored - virtual void dragWheel (int diff); + virtual void dragWheel (int diff, double speedFactor); }; } diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 3971f76fa..2789cd9d5 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -81,6 +81,10 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg key += sMappingSettings[i]; storeMappingSetting (key, CSMSettings::UserSettings::instance().settingValue (key)); } + + mDragFactor = CSMSettings::UserSettings::instance().settingValue ("scene-input/drag-factor").toDouble(); + mDragWheelFactor = CSMSettings::UserSettings::instance().settingValue ("scene-input/drag-wheel-factor").toDouble(); + mDragShiftFactor = CSMSettings::UserSettings::instance().settingValue ("scene-input/drag-shift-factor").toDouble(); } CSVRender::WorldspaceWidget::~WorldspaceWidget () @@ -284,7 +288,14 @@ void CSVRender::WorldspaceWidget::updateUserSetting (const QString& name, const if (!value.isEmpty() && storeMappingSetting (name, value.first())) return; - dynamic_cast (*mEditMode->getCurrent()).updateUserSetting (name, value); + if (name=="scene-input/drag-factor") + mDragFactor = value.at (0).toDouble(); + else if (name=="scene-input/drag-wheel-factor") + mDragWheelFactor = value.at (0).toDouble(); + else if (name=="scene-input/drag-shift-factor") + mDragShiftFactor = value.at (0).toDouble(); + else + dynamic_cast (*mEditMode->getCurrent()).updateUserSetting (name, value); } void CSVRender::WorldspaceWidget::setEditLock (bool locked) @@ -530,9 +541,14 @@ void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event) mDragX = event->x(); mDragY = height() - event->y(); + double factor = mDragFactor; + + if (QApplication::keyboardModifiers() & Qt::ShiftModifier) + factor *= mDragShiftFactor; + EditMode& editMode = dynamic_cast (*mEditMode->getCurrent()); - editMode.drag (diffX, diffY); + editMode.drag (diffX, diffY, factor); } RenderWidget::mouseMoveEvent(event); @@ -601,9 +617,14 @@ void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event) { if (mDragging) { + double factor = mDragWheelFactor; + + if (QApplication::keyboardModifiers() & Qt::ShiftModifier) + factor *= mDragShiftFactor; + EditMode& editMode = dynamic_cast (*mEditMode->getCurrent()); - editMode.dragWheel (event->delta()); + editMode.dragWheel (event->delta(), factor); } RenderWidget::wheelEvent(event); diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index f51ce047e..338ebcc97 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -43,6 +43,9 @@ namespace CSVRender bool mDragging; int mDragX; int mDragY; + double mDragFactor; + double mDragWheelFactor; + double mDragShiftFactor; public: From 4b0fa370e38f6791c5f48df9caf3d77719b62ad8 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 2 Oct 2015 15:06:42 +0200 Subject: [PATCH 23/23] made WorldspaceWidget::getDocument public (EditModes will need the document later) --- apps/opencs/view/render/worldspacewidget.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 338ebcc97..f5e7970b6 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -112,6 +112,8 @@ namespace CSVRender virtual void setEditLock (bool locked); + CSMDoc::Document& getDocument(); + /// \param elementMask Elements to be affected by the clear operation virtual void clearSelection (int elementMask) = 0; @@ -121,8 +123,6 @@ namespace CSVRender virtual void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool); - CSMDoc::Document& getDocument(); - virtual void updateOverlay(); virtual void mouseMoveEvent (QMouseEvent *event);