diff --git a/Changes.md b/Changes.md index b8534ebd18f..ca7b862f389 100644 --- a/Changes.md +++ b/Changes.md @@ -1,6 +1,11 @@ 1.4.x.x (relative to 1.4.0.0b1) ======= +Features +-------- + +- GraphEditor : Added X shortcut for removing connections between nodules. Hold X then left click to remove all connections under the cursor. Hold X then left drag to draw a line, all connections that intersect with the line will be removed once the drag is ended (#788). + Improvements ------------ diff --git a/doc/source/Interface/ControlsAndShortcuts/index.md b/doc/source/Interface/ControlsAndShortcuts/index.md index b7186c38995..420ef97ed89 100644 --- a/doc/source/Interface/ControlsAndShortcuts/index.md +++ b/doc/source/Interface/ControlsAndShortcuts/index.md @@ -152,6 +152,8 @@ Disconnect plug | {{leftClick}} and drag connection to back Insert node onto connection | {{leftClick}} and drag node onto connection Auto-arrange selected nodes | {kbd}`Ctrl` + {kbd}`L` Duplicate outgoing connection | {kbd}`Shift` + {{leftClick}} and drag connection just before in plug +Disconnect connections under cursor | {kbd}`X` + {{leftClick}} +Disconnect connections under line | {kbd}`X` + {{leftClick}} and drag to draw a line, then release {{leftClick}} ### Focus Node ### diff --git a/include/GafferUI/TypeIds.h b/include/GafferUI/TypeIds.h index 397f6da201c..da3ad263b37 100644 --- a/include/GafferUI/TypeIds.h +++ b/include/GafferUI/TypeIds.h @@ -85,6 +85,7 @@ enum TypeId ToolContainerTypeId = 110291, FPSGadgetTypeId = 110292, ViewDisplayTransformTypeId = 110293, + DragEditGadgetTypeId = 110294, LastTypeId = 110450 }; diff --git a/resources/graphics.py b/resources/graphics.py index 918eb95eff7..c2ba048a6d5 100644 --- a/resources/graphics.py +++ b/resources/graphics.py @@ -34,6 +34,8 @@ "pointerRemove", "pointerRotate", "pointerPivot", + "pointerCut", + "pointerNotEditable", ] }, diff --git a/resources/graphics.svg b/resources/graphics.svg index 1a3b9cded69..26a72465dd5 100644 --- a/resources/graphics.svg +++ b/resources/graphics.svg @@ -1869,6 +1869,22 @@ x="670" y="1290" inkscape:label="pointerRotate" /> + + + + + + + + + diff --git a/src/GafferUI/DragEditGadget.cpp b/src/GafferUI/DragEditGadget.cpp new file mode 100644 index 00000000000..c2f2dac4457 --- /dev/null +++ b/src/GafferUI/DragEditGadget.cpp @@ -0,0 +1,435 @@ +////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2024, Murray Stevenson. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above +// copyright notice, this list of conditions and the following +// disclaimer. +// +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided with +// the distribution. +// +// * Neither the name of John Haddon nor the names of +// any other contributors to this software may be used to endorse or +// promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////// + +#include "DragEditGadget.h" + +#include "GafferUI/ConnectionGadget.h" +#include "GafferUI/GraphGadget.h" +#include "GafferUI/Nodule.h" +#include "GafferUI/Pointer.h" +#include "GafferUI/Style.h" +#include "GafferUI/ViewportGadget.h" + +#include "Gaffer/MetadataAlgo.h" +#include "Gaffer/ScriptNode.h" + +#include "IECore/NullObject.h" + +#include "IECoreGL/CurvesPrimitive.h" +#include "IECoreGL/Group.h" +#include "IECoreGL/ShaderLoader.h" +#include "IECoreGL/ShaderStateComponent.h" +#include "IECoreGL/TextureLoader.h" + +#include "boost/bind/bind.hpp" +#include "boost/bind/placeholders.hpp" + +using namespace GafferUI; +using namespace Gaffer; +using namespace IECore; +using namespace IECoreGL; +using namespace Imath; +using namespace boost::placeholders; +using namespace std; + +////////////////////////////////////////////////////////////////////////// +// Internal utilities +////////////////////////////////////////////////////////////////////////// + +namespace +{ + +const float g_cutLineRadius = 4.0f; +const Color4f g_cutLineColor = Color4f( 0.7f, 0.2f, 0.1f, 0.375f ); + +std::vector editableConnectionGadgetsAtLine( const ViewportGadget *viewportGadget, const LineSegment2f &line, const float radius, const bool includeEndpoint ) +{ + std::unordered_set gadgets; + + int samples = 1; + float step = 0.0f; + // Break long line segments into multiple smaller gadgetsAt tests. + // If this proves to be expensive for long drags, we could potentially + // scale the samples based on the line angle. + const float lineLength = line.length(); + if( lineLength > radius ) + { + samples = ceil( lineLength / ( radius * 2.0f ) ); + step = 1.0f / (float)samples; + samples += includeEndpoint; + } + + const V2f padding = V2f( radius ); + for( int i = 0; i < samples; ++i ) + { + const V2f p = line( i * step ); + const std::vector gadgetsAtBox = viewportGadget->gadgetsAt( Box2f( p - padding, p + padding ), GraphLayer::Connections ); + gadgets.insert( gadgetsAtBox.begin(), gadgetsAtBox.end() ); + } + + std::vector connectionGadgets; + for( const auto &gadget : gadgets ) + { + ConnectionGadget *connectionGadget = runTimeCast( gadget ); + if( !connectionGadget ) + { + connectionGadget = gadget->ancestor(); + } + if( + connectionGadget && !Gaffer::MetadataAlgo::readOnly( connectionGadget->dstNodule()->plug() ) && + ( !connectionGadget->srcNodule() || !Gaffer::MetadataAlgo::readOnly( connectionGadget->srcNodule()->plug() ) ) + ) + { + connectionGadgets.push_back( connectionGadget ); + } + } + + return connectionGadgets; +} + +const char *translucentConstantFragSource() +{ + return + "#version 120\n" + "" + "#if __VERSION__ <= 120\n" + "#define in varying\n" + "#endif\n" + "" + "in vec3 fragmentCs;" + "" + "void main()" + "{" + " gl_FragColor = vec4( fragmentCs, 0.375 );" + "}" + ; +} + +} + +////////////////////////////////////////////////////////////////////////// +// DragEditGadget +////////////////////////////////////////////////////////////////////////// + +GAFFER_GRAPHCOMPONENT_DEFINE_TYPE( DragEditGadget ); + +DragEditGadget::DragEditGadget() + : Gadget( "DragEditGadget" ), m_mode( None ), m_editable( false ), m_dragPositions( new V3fVectorData ) +{ + buttonPressSignal().connect( boost::bind( &DragEditGadget::buttonPress, this, ::_1, ::_2 ) ); + buttonReleaseSignal().connect( boost::bind( &DragEditGadget::buttonRelease, this, ::_1, ::_2 ) ); + + dragBeginSignal().connect( boost::bind( &DragEditGadget::dragBegin, this, ::_1, ::_2 ) ); + dragEnterSignal().connect( boost::bind( &DragEditGadget::dragEnter, this, ::_1, ::_2 ) ); + dragMoveSignal().connect( boost::bind( &DragEditGadget::dragMove, this, ::_1, ::_2 ) ); + dragEndSignal().connect( boost::bind( &DragEditGadget::dragEnd, this, ::_1, ::_2 ) ); + leaveSignal().connect( boost::bind( &DragEditGadget::leave, this ) ); +} + +DragEditGadget::~DragEditGadget() +{ +} + +bool DragEditGadget::acceptsParent( const GraphComponent *potentialParent ) const +{ + return runTimeCast( potentialParent ); +} + +void DragEditGadget::parentChanging( Gaffer::GraphComponent *newParent ) +{ + m_graphGadgetKeyPressConnection.disconnect(); + m_graphGadgetKeyReleaseConnection.disconnect(); + + if( auto graphGadget = runTimeCast( newParent ) ) + { + m_graphGadgetKeyPressConnection = graphGadget->keyPressSignal().connect( + boost::bind( &DragEditGadget::keyPress, this, ::_1, ::_2 ) + ); + m_graphGadgetKeyReleaseConnection = graphGadget->keyReleaseSignal().connect( + boost::bind( &DragEditGadget::keyRelease, this, ::_1, ::_2 ) + ); + } +} + +void DragEditGadget::renderLayer( Layer layer, const Style *style, RenderReason reason ) const +{ + if( layer != GraphLayer::Overlay || m_mode == None ) + { + return; + } + + if( isSelectionRender( reason ) ) + { + const ViewportGadget *viewportGadget = ancestor(); + ViewportGadget::RasterScope rasterScope( viewportGadget ); + // We render a selection overlay over the entire viewport to intercept all events. + glColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); + style->renderSolidRectangle( Box2f( V2f( 0, 0 ), viewportGadget->getViewport() ) ); + return; + } + + if( m_dragPositions->readable().size() > 1 ) + { + // Render a curve to represent the dragged cursor trail. + State::bindBaseState(); + auto glState = const_cast( State::defaultState() ); + + IECoreGL::GroupPtr group = new IECoreGL::Group(); + group->getState()->add( new IECoreGL::Primitive::DrawWireframe( false ) ); + group->getState()->add( new IECoreGL::Primitive::DrawSolid( true ) ); + group->getState()->add( new IECoreGL::CurvesPrimitive::UseGLLines( true ) ); + group->getState()->add( new IECoreGL::CurvesPrimitive::GLLineWidth( g_cutLineRadius * 2.0f ) ); + group->getState()->add( new IECoreGL::LineSmoothingStateComponent( true ) ); + group->getState()->add( new IECoreGL::Color( g_cutLineColor ) ); + group->getState()->add( + new IECoreGL::ShaderStateComponent( ShaderLoader::defaultShaderLoader(), TextureLoader::defaultTextureLoader(), "", "", translucentConstantFragSource(), new CompoundObject ) + ); + + IntVectorDataPtr vertsPerCurve = new IntVectorData(); + vertsPerCurve->writable().push_back( m_dragPositions->readable().size() ); + IECoreGL::CurvesPrimitivePtr curves = new IECoreGL::CurvesPrimitive( CubicBasisf::linear(), false, vertsPerCurve ); + curves->addPrimitiveVariable( "P", IECoreScene::PrimitiveVariable( IECoreScene::PrimitiveVariable::Vertex, m_dragPositions ) ); + group->addChild( curves ); + + group->render( glState ); + } +} + +unsigned DragEditGadget::layerMask() const +{ + return (unsigned)GraphLayer::Overlay; +} + +Imath::Box3f DragEditGadget::renderBound() const +{ + // This Gadget renders a trail anywhere the cursor is + // dragged, so we can't give it a tight render bound. + Box3f b; + b.makeInfinite(); + return b; +} + +GraphGadget *DragEditGadget::graphGadget() +{ + return parent(); +} + +const GraphGadget *DragEditGadget::graphGadget() const +{ + return parent(); +} + +bool DragEditGadget::keyPress( GadgetPtr gadget, const KeyEvent &event ) +{ + if( event.key == "X" && !event.modifiers ) + { + m_mode = Disconnect; + m_editable = !( Gaffer::MetadataAlgo::readOnly( graphGadget()->getRoot() ) || Gaffer::MetadataAlgo::getChildNodesAreReadOnly( graphGadget()->getRoot() ) ); + Pointer::setCurrent( m_editable ? "cut" : "notEditable" ); + + return true; + } + + return false; +} + +bool DragEditGadget::keyRelease( GadgetPtr gadget, const KeyEvent &event ) +{ + if( m_mode == Disconnect && event.key == "X" ) + { + m_mode = None; + Pointer::setCurrent( "" ); + m_dragPositions->writable().clear(); + dirty( DirtyType::Render ); + + return true; + } + + return false; +} + +bool DragEditGadget::buttonPress( GadgetPtr gadget, const ButtonEvent &event ) +{ + // We don't need to test `m_mode` here, as we don't get events when `m_mode` is None as + // no overlay will have been drawn in that case. + + // Accept both left and right button events. We only act on the left, but not accepting + // the right button results in the NodeMenu appearing while we have a key held. + if( event.buttons == ButtonEvent::Middle ) + { + return false; + } + + V3f i; + if( !event.line.intersect( Plane3f( V3f( 0, 0, 1 ), 0 ), i ) ) + { + return false; + } + if( event.buttons == ButtonEvent::Left && m_editable ) + { + m_dragPositions->writable().push_back( i ); + } + + return true; +} + +bool DragEditGadget::buttonRelease( GadgetPtr gadget, const ButtonEvent &event ) +{ + V3f i; + if( !event.line.intersect( Plane3f( V3f( 0, 0, 1 ), 0 ), i ) ) + { + return false; + } + if( m_mode == Disconnect && m_editable ) + { + disconnectConnectionGadgets(); + m_mergeGroupId++; + } + + m_dragPositions->writable().clear(); + dirty( DirtyType::Render ); + + return true; +} + +IECore::RunTimeTypedPtr DragEditGadget::dragBegin( GadgetPtr gadget, const DragDropEvent &event ) +{ + V3f i; + if( !event.line.intersect( Plane3f( V3f( 0, 0, 1 ), 0 ), i ) ) + { + return nullptr; + } + if( event.buttons == ButtonEvent::Left ) + { + return IECore::NullObject::defaultNullObject(); + } + + return nullptr; +} + +bool DragEditGadget::dragEnter( GadgetPtr gadget, const DragDropEvent &event ) +{ + if( event.buttons != ButtonEvent::Left ) + { + return false; + } + + return event.sourceGadget == this; +} + +bool DragEditGadget::dragMove( GadgetPtr gadget, const DragDropEvent &event ) +{ + V3f i; + if( !event.line.intersect( Plane3f( V3f( 0, 0, 1 ), 0 ), i ) ) + { + return false; + } + if( m_mode != None && m_editable ) + { + m_dragPositions->writable().push_back( i ); + dirty( DirtyType::Render ); + } + + return true; +} + +bool DragEditGadget::dragEnd( GadgetPtr gadget, const DragDropEvent &event ) +{ + if( m_mode == Disconnect && m_editable ) + { + disconnectConnectionGadgets(); + m_mergeGroupId++; + } + + m_dragPositions->writable().clear(); + dirty( DirtyType::Render ); + + return true; +} + +void DragEditGadget::leave() +{ + Pointer::setCurrent( "" ); +} + +std::string DragEditGadget::undoMergeGroup() const +{ + return fmt::format( "DragEditGadget{}{}", (void*)this, m_mergeGroupId ); +} + +void DragEditGadget::disconnectConnectionGadgets() +{ + if( m_dragPositions->readable().empty() ) + { + return; + } + + const ViewportGadget *viewportGadget = ancestor(); + std::vector rasterLines; + V3f lineStart = m_dragPositions->readable().front(); + for( const auto &lineEnd : m_dragPositions->readable() ) + { + rasterLines.emplace_back( LineSegment2f( + viewportGadget->gadgetToRasterSpace( lineStart, graphGadget() ), + viewportGadget->gadgetToRasterSpace( lineEnd, graphGadget() ) + ) ); + lineStart = lineEnd; + } + + // Overlapping gadgets will only be returned one at a time, so we + // exhaustively test and remove until no more are found. + while( true ) + { + std::unordered_set connectionsToDisconnect; + for( const auto &line : rasterLines ) + { + const auto connectionsAtLine = editableConnectionGadgetsAtLine( viewportGadget, line, g_cutLineRadius, /* includeEndpoint = */ &line == &rasterLines.back() ); + connectionsToDisconnect.insert( connectionsAtLine.begin(), connectionsAtLine.end() ); + } + + if( connectionsToDisconnect.empty() ) + { + break; + } + + ScriptNode *scriptNode = ( *connectionsToDisconnect.begin() )->dstNodule()->plug()->ancestor(); + Gaffer::UndoScope undoScope( scriptNode, Gaffer::UndoScope::Enabled, undoMergeGroup() ); + for( const auto &connection : connectionsToDisconnect ) + { + connection->dstNodule()->plug()->setInput( nullptr ); + } + } +} diff --git a/src/GafferUI/DragEditGadget.h b/src/GafferUI/DragEditGadget.h new file mode 100644 index 00000000000..0e1e658b51c --- /dev/null +++ b/src/GafferUI/DragEditGadget.h @@ -0,0 +1,108 @@ +////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2024, Murray Stevenson. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above +// copyright notice, this list of conditions and the following +// disclaimer. +// +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided with +// the distribution. +// +// * Neither the name of John Haddon nor the names of +// any other contributors to this software may be used to endorse or +// promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "GafferUI/Gadget.h" + +#include "IECore/VectorTypedData.h" + +namespace GafferUI +{ + +IE_CORE_FORWARDDECLARE( ConnectionGadget ); +IE_CORE_FORWARDDECLARE( GraphGadget ); + +class GAFFERUI_API DragEditGadget : public Gadget +{ + + public : + + ~DragEditGadget() override; + + GAFFER_GRAPHCOMPONENT_DECLARE_TYPE( GafferUI::DragEditGadget, DragEditGadgetTypeId, Gadget ); + + bool acceptsParent( const GraphComponent *potentialParent ) const override; + + protected : + + // Protected constructor and friend status so only GraphGadget can + // construct us. + DragEditGadget(); + friend class GraphGadget; + + void parentChanging( Gaffer::GraphComponent *newParent ) override; + void renderLayer( Layer layer, const Style *style, RenderReason reason ) const override; + unsigned layerMask() const override; + Imath::Box3f renderBound() const override; + + private : + + GraphGadget *graphGadget(); + const GraphGadget *graphGadget() const; + + bool keyPress( GadgetPtr gadget, const KeyEvent &event ); + bool keyRelease( GadgetPtr gadget, const KeyEvent &event ); + bool buttonPress( GadgetPtr gadget, const ButtonEvent &event ); + bool buttonRelease( GadgetPtr gadget, const ButtonEvent &event ); + + IECore::RunTimeTypedPtr dragBegin( GadgetPtr gadget, const DragDropEvent &event ); + bool dragEnter( GadgetPtr gadget, const DragDropEvent &event ); + bool dragMove( GadgetPtr gadget, const DragDropEvent &event ); + bool dragEnd( GadgetPtr gadget, const DragDropEvent &event ); + void leave(); + + std::string undoMergeGroup() const; + + void disconnectConnectionGadgets(); + + Gaffer::Signals::ScopedConnection m_graphGadgetKeyPressConnection; + Gaffer::Signals::ScopedConnection m_graphGadgetKeyReleaseConnection; + + enum Mode + { + None, + Disconnect + }; + + Mode m_mode; + bool m_editable; + int m_mergeGroupId; + IECore::V3fVectorDataPtr m_dragPositions; + +}; + +} // namespace GafferUI diff --git a/src/GafferUI/GraphGadget.cpp b/src/GafferUI/GraphGadget.cpp index 92c38ac98dc..b9933aa1971 100644 --- a/src/GafferUI/GraphGadget.cpp +++ b/src/GafferUI/GraphGadget.cpp @@ -48,6 +48,7 @@ #include "GafferUI/StandardGraphLayout.h" #include "GafferUI/Style.h" #include "GafferUI/ViewportGadget.h" +#include "DragEditGadget.h" #include "Gaffer/CompoundNumericPlug.h" #include "Gaffer/Context.h" @@ -120,6 +121,7 @@ const InternedString g_outputConnectionsMinimisedPlugName( "__uiOutputConnection const InternedString g_nodeGadgetTypeName( "nodeGadget:type" ); const InternedString g_auxiliaryConnectionsGadgetName( "__auxiliaryConnections" ); const InternedString g_annotationsGadgetName( "__annotations" ); +const InternedString g_dragEditGadgetName( "__dragEdit" ); struct CompareV2fX{ bool operator()(const Imath::V2f &a, const Imath::V2f &b) const @@ -495,6 +497,7 @@ GraphGadget::GraphGadget( Gaffer::NodePtr root, Gaffer::SetPtr filter ) setChild( g_auxiliaryConnectionsGadgetName, new AuxiliaryConnectionsGadget() ); setChild( g_annotationsGadgetName, new AnnotationsGadget() ); + setChild( g_dragEditGadgetName, new DragEditGadget() ); setRoot( root, filter ); } diff --git a/src/GafferUI/Pointer.cpp b/src/GafferUI/Pointer.cpp index fa4e977cac7..f587f050d72 100644 --- a/src/GafferUI/Pointer.cpp +++ b/src/GafferUI/Pointer.cpp @@ -71,6 +71,8 @@ static Registry ®istry() r["remove"] = new Pointer( "pointerRemove.png", Imath::V2i( 18, 11 ) ); r["rotate"] = new Pointer( "pointerRotate.png", Imath::V2i( 10 ) ); r["pivot"] = new Pointer( "pointerPivot.png", Imath::V2i( 13, 0 ) ); + r["cut"] = new Pointer( "pointerCut.png", Imath::V2i( 11, 7 ) ); + r["notEditable"] = new Pointer( "pointerNotEditable.png", Imath::V2i( 10 ) ); } return r; } diff --git a/src/GafferUI/StandardNodeGadget.cpp b/src/GafferUI/StandardNodeGadget.cpp index 7ec11db3f7f..1593e8c3c84 100644 --- a/src/GafferUI/StandardNodeGadget.cpp +++ b/src/GafferUI/StandardNodeGadget.cpp @@ -320,7 +320,7 @@ class FocusGadget : public Gadget unsigned layerMask() const override { - return (int)GraphLayer::Overlay; + return (int)GraphLayer::Highlighting; } Imath::Box3f renderBound() const override @@ -726,7 +726,7 @@ void StandardNodeGadget::renderLayer( Layer layer, const Style *style, RenderRea break; } - case GraphLayer::Overlay : + case GraphLayer::Highlighting : { const Box3f b = bound(); @@ -804,7 +804,7 @@ void StandardNodeGadget::updateTextDimming() unsigned StandardNodeGadget::layerMask() const { - return GraphLayer::Nodes | GraphLayer::Overlay | GraphLayer::OverBackdrops; + return GraphLayer::Nodes | GraphLayer::Highlighting | GraphLayer::OverBackdrops; } Imath::Box3f StandardNodeGadget::renderBound() const