From 6b0721a7bf04c0a74cded9b494569f56783a019b Mon Sep 17 00:00:00 2001 From: Eric Mehl Date: Fri, 8 Dec 2023 13:10:17 -0500 Subject: [PATCH] LightPositionTool : Drag to place targets --- include/GafferSceneUI/LightPositionTool.h | 9 +++ src/GafferSceneUI/LightPositionTool.cpp | 68 ++++++++++++++++++++--- 2 files changed, 70 insertions(+), 7 deletions(-) diff --git a/include/GafferSceneUI/LightPositionTool.h b/include/GafferSceneUI/LightPositionTool.h index 57d11fcf92d..7db67dd3acb 100644 --- a/include/GafferSceneUI/LightPositionTool.h +++ b/include/GafferSceneUI/LightPositionTool.h @@ -96,6 +96,11 @@ class GAFFERSCENEUI_API LightPositionTool : public GafferSceneUI::TransformTool bool handleDragMove( GafferUI::Gadget *gadget, const GafferUI::DragDropEvent &event ); bool handleDragEnd(); + IECore::RunTimeTypedPtr sceneGadgetDragBegin( GafferUI::Gadget *gadget, const GafferUI::DragDropEvent &event ); + bool sceneGadgetDragEnter( GafferUI::Gadget *gadget, const GafferUI::DragDropEvent &event ); + bool sceneGadgetDragMove( const GafferUI::DragDropEvent &event ); + bool sceneGadgetDragEnd(); + bool keyPress( const GafferUI::KeyEvent &event ); bool keyRelease( const GafferUI::KeyEvent &event ); void viewportGadgetLeave( const GafferUI::ButtonEvent &event ); @@ -105,6 +110,8 @@ class GAFFERSCENEUI_API LightPositionTool : public GafferSceneUI::TransformTool bool buttonPress( const GafferUI::ButtonEvent &event ); + bool placeTarget( const IECore::LineSegment3f &eventLine ); + enum class TargetMode { None, @@ -138,6 +145,8 @@ class GAFFERSCENEUI_API LightPositionTool : public GafferSceneUI::TransformTool IECore::MurmurHash m_key; + bool m_draggingTarget; + static ToolDescription g_toolDescription; static size_t g_firstPlugIndex; diff --git a/src/GafferSceneUI/LightPositionTool.cpp b/src/GafferSceneUI/LightPositionTool.cpp index 24ec195d6f8..c143ba402b1 100644 --- a/src/GafferSceneUI/LightPositionTool.cpp +++ b/src/GafferSceneUI/LightPositionTool.cpp @@ -533,7 +533,8 @@ size_t LightPositionTool::g_firstPlugIndex = 0; LightPositionTool::LightPositionTool( SceneView *view, const std::string &name ) : TransformTool( view, name ), - m_targetMode( TargetMode::None ) + m_targetMode( TargetMode::None ), + m_draggingTarget( false ) { m_shadowHandle = new ShadowHandle(); m_shadowHandle->setRasterScale( 0 ); @@ -554,6 +555,11 @@ LightPositionTool::LightPositionTool( SceneView *view, const std::string &name ) // We have to insert this before the underlying SelectionTool connections or it starts an object drag. sg->buttonPressSignal().connectFront( boost::bind( &LightPositionTool::buttonPress, this, ::_2 ) ); + sg->dragBeginSignal().connectFront( boost::bind( &LightPositionTool::sceneGadgetDragBegin, this, ::_1, ::_2 ) ); + sg->dragEnterSignal().connectFront( boost::bind( &LightPositionTool::sceneGadgetDragEnter, this, ::_1, ::_2 ) ); + sg->dragMoveSignal().connectFront( boost::bind( &LightPositionTool::sceneGadgetDragMove, this, ::_2 ) ); + sg->dragEndSignal().connectFront( boost::bind( &LightPositionTool::sceneGadgetDragEnd, this ) ); + // We need to track the tool state/view visibility so we don't leave a lingering target cursor sg->visibilityChangedSignal().connect( boost::bind( &LightPositionTool::visibilityChanged, this, ::_1 ) ); @@ -730,6 +736,49 @@ bool LightPositionTool::handleDragEnd() return false; } +RunTimeTypedPtr LightPositionTool::sceneGadgetDragBegin( Gadget *gadget, const DragDropEvent &event ) +{ + if( !activePlug()->getValue() || getTargetMode() == TargetMode::None ) + { + return nullptr; + } + m_draggingTarget = true; + + TransformTool::dragBegin(); + return gadget; +} + +bool LightPositionTool::sceneGadgetDragEnter( Gadget *gadget, const DragDropEvent &event ) +{ + return m_draggingTarget && event.sourceGadget == gadget && event.data == gadget; +} + +bool LightPositionTool::sceneGadgetDragMove( const DragDropEvent &event ) +{ + if( !m_draggingTarget ) + { + return false; + } + + // We always return true to prevent the SelectTool defaults. + if( !selectionEditable() || !m_shadowHandle->enabled() ) + { + return true; + } + + UndoScope undoScope( selection().back().editTarget()->ancestor(), UndoScope::Enabled, undoMergeGroup() ); + + placeTarget( event.line ); + return true; +} + +bool LightPositionTool::sceneGadgetDragEnd() +{ + m_draggingTarget = false; + TransformTool::dragEnd(); + return false; +} + bool LightPositionTool::keyPress( const KeyEvent &event ) { // We track this regardless of whether we're active or not in case the tool @@ -809,27 +858,32 @@ bool LightPositionTool::buttonPress( const ButtonEvent &event ) } // We always return true to prevent the SelectTool defaults. - if( !selectionEditable() || !m_shadowHandle->enabled() ) { return true; } + UndoScope undoScope( selection().back().editTarget()->ancestor() ); + + placeTarget( event.line ); + return true; +} + +bool LightPositionTool::placeTarget( const LineSegment3f &eventLine ) +{ ScenePlug::ScenePath scenePath; V3f targetPos; const SceneGadget *sceneGadget = runTimeCast( view()->viewportGadget()->getPrimaryChild() ); - if( !sceneGadget->objectAt( event.line, scenePath, targetPos ) ) + if( !sceneGadget->objectAt( eventLine, scenePath, targetPos ) ) { - return true; + return false; } const auto shadowHandle = static_cast( m_shadowHandle.get() ); Selection s = selection().back(); ScriptNodePtr scriptNode = s.editTarget()->ancestor(); - UndoScope undoScope( scriptNode ); - if( getTargetMode() == TargetMode::ShadowPivot ) { const V3f newPivot = targetPos * sceneGadget->fullTransform(); @@ -848,7 +902,7 @@ bool LightPositionTool::buttonPress( const ButtonEvent &event ) if( !shadowHandle->getShadowPivot() || !shadowHandle->getShadowTarget() ) { - return true; + return false; } position( shadowHandle->getShadowPivot().value(), shadowHandle->getShadowTarget().value(), shadowHandle->getPivotDistance().value() );