From ee5d5fae0a9d1ab190a964867b749d7154db54a9 Mon Sep 17 00:00:00 2001 From: parax0 Date: Tue, 5 Jan 2016 07:54:16 -0700 Subject: [PATCH] Added viewport context menus --- src/Editor/CBasicViewport.cpp | 15 ++-- src/Editor/CSceneViewport.cpp | 91 ++++++++++++++++++++++++- src/Editor/CSceneViewport.h | 18 +++++ src/Editor/WorldEditor/CWorldEditor.ui | 14 +++- src/Editor/WorldEditor/WInstancesTab.ui | 38 ++++++++++- src/Editor/WorldEditor/WModifyTab.ui | 8 +-- 6 files changed, 171 insertions(+), 13 deletions(-) diff --git a/src/Editor/CBasicViewport.cpp b/src/Editor/CBasicViewport.cpp index 8ded6eaa..f734f9a3 100644 --- a/src/Editor/CBasicViewport.cpp +++ b/src/Editor/CBasicViewport.cpp @@ -3,6 +3,8 @@ #include #include +#include + #include CBasicViewport::CBasicViewport(QWidget *pParent) : @@ -110,7 +112,14 @@ void CBasicViewport::mouseReleaseEvent(QMouseEvent *pEvent) // Run mouse release if we didn't just exit mouse input (or regardless on left click) if (!fromMouseInput || (pEvent->button() == Qt::LeftButton)) OnMouseRelease(pEvent); -} + + // Send context menu event to subclass if needed + if ((pEvent->button() == Qt::RightButton) && (mMoveTimer.Time() <= 0.3) && !mMouseMoved) + { + QContextMenuEvent Event(QContextMenuEvent::Mouse, QCursor::pos()); + this->ContextMenu(&Event); + } + } void CBasicViewport::mouseMoveEvent(QMouseEvent* /*pEvent*/) { @@ -161,9 +170,7 @@ void CBasicViewport::focusOutEvent(QFocusEvent*) void CBasicViewport::contextMenuEvent(QContextMenuEvent *pEvent) { - // Only allow context menu if we aren't exiting mouse input mode. - if (!mMouseMoved && (mMoveTimer.Time() < 0.5)) - ContextMenu(pEvent); + pEvent->ignore(); } void CBasicViewport::SetGameMode(bool Enabled) diff --git a/src/Editor/CSceneViewport.cpp b/src/Editor/CSceneViewport.cpp index 84f70c07..76a5bb36 100644 --- a/src/Editor/CSceneViewport.cpp +++ b/src/Editor/CSceneViewport.cpp @@ -1,6 +1,9 @@ #include "CSceneViewport.h" +#include "UICommon.h" #include "Editor/Undo/UndoCommands.h" #include +#include +#include CSceneViewport::CSceneViewport(QWidget *pParent) : CBasicViewport(pParent), @@ -9,7 +12,9 @@ CSceneViewport::CSceneViewport(QWidget *pParent) mDrawSky(true), mGizmoTransforming(false), mpHoverNode(nullptr), - mHoverPoint(CVector3f::skZero) + mHoverPoint(CVector3f::skZero), + mpContextMenu(nullptr), + mpMenuNode(nullptr) { mpRenderer = new CRenderer(); mpRenderer->SetClearColor(CColor::skBlack); @@ -17,6 +22,8 @@ CSceneViewport::CSceneViewport(QWidget *pParent) mViewInfo.pScene = mpScene; mViewInfo.pRenderer = mpRenderer; + + CreateContextMenu(); } CSceneViewport::~CSceneViewport() @@ -130,6 +137,31 @@ void CSceneViewport::keyReleaseEvent(QKeyEvent* pEvent) } } +// ************ PROTECTED ************ +void CSceneViewport::CreateContextMenu() +{ + mpContextMenu = new QMenu(this); + + mpHideNodeAction = new QAction("HideNode", this); + connect(mpHideNodeAction, SIGNAL(triggered()), this, SLOT(OnHideNode())); + + mpHideTypeAction = new QAction("HideType", this); + connect(mpHideTypeAction, SIGNAL(triggered()), this, SLOT(OnHideType())); + + mpHideLayerAction = new QAction("HideLayer", this); + connect(mpHideLayerAction, SIGNAL(triggered()), this, SLOT(OnHideLayer())); + + mpHideUnhideSeparator = new QAction(this); + mpHideUnhideSeparator->setSeparator(true); + + mpUnhideAllAction = new QAction("Unhide all", this); + connect(mpUnhideAllAction, SIGNAL(triggered()), this, SLOT(OnUnhideAll())); + + QList Actions; + Actions << mpHideNodeAction << mpHideTypeAction << mpHideLayerAction << mpHideUnhideSeparator << mpUnhideAllAction; + mpContextMenu->addActions(Actions); +} + // ************ PROTECTED SLOTS ************ void CSceneViewport::CheckUserInput() { @@ -184,8 +216,36 @@ void CSceneViewport::Paint() mpRenderer->EndFrame(); } -void CSceneViewport::ContextMenu(QContextMenuEvent* /*pEvent*/) +void CSceneViewport::ContextMenu(QContextMenuEvent* pEvent) { + // mpHoverNode is cleared during mouse input, so this call is necessary. todo: better way? + SceneRayCast(CastRay()); + + // Set up actions + TString NodeName; + bool HasHoverNode = (mpHoverNode && mpHoverNode->NodeType() != eStaticNode); + bool IsScriptNode = (mpHoverNode && mpHoverNode->NodeType() == eScriptNode); + + mpHideNodeAction->setVisible(HasHoverNode); + mpHideTypeAction->setVisible(IsScriptNode); + mpHideLayerAction->setVisible(IsScriptNode); + mpHideUnhideSeparator->setVisible(HasHoverNode); + + if (IsScriptNode) + { + CScriptNode *pScript = static_cast(mpHoverNode); + NodeName = pScript->Object()->InstanceName(); + mpHideTypeAction->setText( QString("Hide all %1 objects").arg(TO_QSTRING(pScript->Template()->TemplateName())) ); + mpHideLayerAction->setText( QString("Hide layer %1").arg(TO_QSTRING(pScript->Object()->Layer()->Name())) ); + } + else if (HasHoverNode) + NodeName = mpHoverNode->Name(); + + mpHideNodeAction->setText(QString("Hide %1").arg(TO_QSTRING(NodeName))); + + // Show menu + mpMenuNode = mpHoverNode; + mpContextMenu->exec(pEvent->pos()); } void CSceneViewport::OnResize() @@ -257,5 +317,30 @@ void CSceneViewport::OnMouseRelease(QMouseEvent *pEvent) mpEditor->UpdateSelectionUI(); } } - +} + +void CSceneViewport::OnHideNode() +{ + mpMenuNode->SetVisible(false); +} + +void CSceneViewport::OnHideType() +{ + static_cast(mpMenuNode)->Template()->SetVisible(false); +} + +void CSceneViewport::OnHideLayer() +{ + static_cast(mpMenuNode)->Object()->Layer()->SetVisible(false); +} + +void CSceneViewport::OnUnhideAll() +{ + // implement when scene iterator exists! +} + +void CSceneViewport::OnContextMenuClose() +{ + mpContextMenu = nullptr; + mpMenuNode = nullptr; } diff --git a/src/Editor/CSceneViewport.h b/src/Editor/CSceneViewport.h index e93d0fbd..ae675206 100644 --- a/src/Editor/CSceneViewport.h +++ b/src/Editor/CSceneViewport.h @@ -21,6 +21,15 @@ class CSceneViewport : public CBasicViewport CSceneNode *mpHoverNode; CVector3f mHoverPoint; + // Context Menu + QMenu *mpContextMenu; + QAction *mpHideNodeAction; + QAction *mpHideTypeAction; + QAction *mpHideLayerAction; + QAction *mpHideUnhideSeparator; + QAction *mpUnhideAllAction; + CSceneNode *mpMenuNode; + public: CSceneViewport(QWidget *pParent = 0); ~CSceneViewport(); @@ -37,6 +46,9 @@ public: void keyPressEvent(QKeyEvent* pEvent); void keyReleaseEvent(QKeyEvent* pEvent); +protected: + void CreateContextMenu(); + signals: void GizmoMoved(); void CameraOrbit(); @@ -48,6 +60,12 @@ protected slots: void OnResize(); void OnMouseClick(QMouseEvent *pEvent); void OnMouseRelease(QMouseEvent *pEvent); + + void OnHideNode(); + void OnHideType(); + void OnHideLayer(); + void OnUnhideAll(); + void OnContextMenuClose(); }; #endif // CSCENEVIEWPORT_H diff --git a/src/Editor/WorldEditor/CWorldEditor.ui b/src/Editor/WorldEditor/CWorldEditor.ui index 3d40d37c..a032e535 100644 --- a/src/Editor/WorldEditor/CWorldEditor.ui +++ b/src/Editor/WorldEditor/CWorldEditor.ui @@ -330,6 +330,18 @@ + + 0 + + + 0 + + + 0 + + + 0 + @@ -342,7 +354,7 @@ QTabWidget::Rounded - 1 + 2 diff --git a/src/Editor/WorldEditor/WInstancesTab.ui b/src/Editor/WorldEditor/WInstancesTab.ui index 7dab7b54..741c592f 100644 --- a/src/Editor/WorldEditor/WInstancesTab.ui +++ b/src/Editor/WorldEditor/WInstancesTab.ui @@ -17,21 +17,42 @@ 0 + + 0 + 0 + + 0 + - 0 + 1 Layer + + 0 + + + 0 + + + 0 + + + 0 + + + QFrame::NoFrame + QAbstractItemView::ScrollPerPixel @@ -47,11 +68,26 @@ Type + + 0 + + + 0 + + + 0 + + + 0 + + + QFrame::NoFrame + false diff --git a/src/Editor/WorldEditor/WModifyTab.ui b/src/Editor/WorldEditor/WModifyTab.ui index 606455d8..d2c8493b 100644 --- a/src/Editor/WorldEditor/WModifyTab.ui +++ b/src/Editor/WorldEditor/WModifyTab.ui @@ -18,13 +18,13 @@ 0 - 9 + 0 0 - 9 + 0 @@ -65,7 +65,7 @@ 0 0 276 - 439 + 457 @@ -137,7 +137,7 @@ 0 0 276 - 439 + 457