From 439af4237e0b0ec7970d4027f0c74b6f00add077 Mon Sep 17 00:00:00 2001 From: Eric Mehl Date: Mon, 4 Nov 2024 08:18:35 -0500 Subject: [PATCH] StandardNodeGadget : Persistent nodule labels --- Changes.md | 1 + include/GafferUI/StandardNodeGadget.h | 2 + python/GafferUITest/StandardNodeGadgetTest.py | 42 +++++++ src/GafferUI/StandardNodeGadget.cpp | 107 ++++++++++++++++-- src/GafferUI/StandardNodule.cpp | 14 ++- 5 files changed, 154 insertions(+), 12 deletions(-) diff --git a/Changes.md b/Changes.md index 6639b2ef17c..2870141ec6b 100644 --- a/Changes.md +++ b/Changes.md @@ -9,6 +9,7 @@ Improvements - Added support for 64 bit integer ids (matching what is loaded from USD). - DeletePoints : Added modes for deleting points based on a list of ids. - Light Editor, Attribute Editor, Spreadsheet : Add original and current color swatches to color popups. +- StandardNodeGadget : Added support for `nodeGadget:inputNoduleLabelsVisible` and `nodeGadget:outputNoduleLabelsVisible` for setting nodule labels always on or off. If the metadata entry is not set, labels will be visible only when they are hovered over. Fixes ----- diff --git a/include/GafferUI/StandardNodeGadget.h b/include/GafferUI/StandardNodeGadget.h index 76be5283e40..0b8295c4eb6 100644 --- a/include/GafferUI/StandardNodeGadget.h +++ b/include/GafferUI/StandardNodeGadget.h @@ -150,6 +150,7 @@ class GAFFERUI_API StandardNodeGadget : public NodeGadget bool dragMove( GadgetPtr gadget, const DragDropEvent &event ); bool dragLeave( GadgetPtr gadget, const DragDropEvent &event ); bool drop( GadgetPtr gadget, const DragDropEvent &event ); + void noduleAdded( Nodule *nodule ); ConnectionCreator *closestDragDestination( const DragDropEvent &event ) const; @@ -163,6 +164,7 @@ class GAFFERUI_API StandardNodeGadget : public NodeGadget bool updateShape(); void updateFocusGadgetVisibility(); void updateTextDimming(); + void updatePersistentNoduleLabels(); IE_CORE_FORWARDDECLARE( ErrorGadget ); ErrorGadget *errorGadget( bool createIfMissing = true ); diff --git a/python/GafferUITest/StandardNodeGadgetTest.py b/python/GafferUITest/StandardNodeGadgetTest.py index b86ec30c173..bcea061c098 100644 --- a/python/GafferUITest/StandardNodeGadgetTest.py +++ b/python/GafferUITest/StandardNodeGadgetTest.py @@ -308,5 +308,47 @@ def assertMinWidth( gadget, minWidth ) : Gaffer.Metadata.deregisterValue( n, "nodeGadget:minWidth" ) assertMinWidth( g, 10.0 ) + def testNoduleLabelVisibility( self ) : + + n = Gaffer.Node() + n.addChild( Gaffer.FloatPlug( "fIn", direction = Gaffer.Plug.Direction.In ) ) + n.addChild( Gaffer.FloatPlug( "fOut", direction = Gaffer.Plug.Direction.Out ) ) + g = GafferUI.StandardNodeGadget( n ) + + fIn = g.nodule( n["fIn"] ) + fOut = g.nodule( n["fOut"] ) + + self.assertFalse( fIn.getLabelVisible() ) + self.assertFalse( fOut.getLabelVisible() ) + + Gaffer.Metadata.registerValue( Gaffer.Node, "nodeGadget:inputNoduleLabelsVisible", True ) + self.assertTrue( fIn.getLabelVisible() ) + self.assertFalse( fOut.getLabelVisible() ) + + Gaffer.Metadata.registerValue( Gaffer.Node, "nodeGadget:outputNoduleLabelsVisible", True ) + self.assertTrue( fIn.getLabelVisible() ) + self.assertTrue( fOut.getLabelVisible() ) + + n.addChild( Gaffer.IntPlug( "iIn", direction = Gaffer.Plug.Direction.In ) ) + n.addChild( Gaffer.IntPlug( "iOut", direction = Gaffer.Plug.Direction.Out ) ) + + iIn = g.nodule( n["iIn"] ) + iOut = g.nodule( n["iOut"] ) + + self.assertTrue( iIn.getLabelVisible() ) + self.assertTrue( iOut.getLabelVisible() ) + + Gaffer.Metadata.registerValue( Gaffer.Node, "nodeGadget:inputNoduleLabelsVisible", False ) + self.assertFalse( fIn.getLabelVisible() ) + self.assertFalse( iIn.getLabelVisible() ) + self.assertTrue( fOut.getLabelVisible() ) + self.assertTrue( iOut.getLabelVisible() ) + + Gaffer.Metadata.registerValue( Gaffer.Node, "nodeGadget:outputNoduleLabelsVisible", False ) + self.assertFalse( fIn.getLabelVisible() ) + self.assertFalse( iIn.getLabelVisible() ) + self.assertFalse( fOut.getLabelVisible() ) + self.assertFalse( iOut.getLabelVisible() ) + if __name__ == "__main__": unittest.main() diff --git a/src/GafferUI/StandardNodeGadget.cpp b/src/GafferUI/StandardNodeGadget.cpp index e07a42442b6..a7059191c8a 100644 --- a/src/GafferUI/StandardNodeGadget.cpp +++ b/src/GafferUI/StandardNodeGadget.cpp @@ -566,6 +566,8 @@ static IECore::InternedString g_paddingKey( "nodeGadget:padding" ); static IECore::InternedString g_colorKey( "nodeGadget:color" ); static IECore::InternedString g_shapeKey( "nodeGadget:shape" ); static IECore::InternedString g_focusGadgetVisibleKey( "nodeGadget:focusGadgetVisible" ); +static IECore::InternedString g_inputNoduleLabelsVisibleKey( "nodeGadget:inputNoduleLabelsVisible" ); +static IECore::InternedString g_outputNoduleLabelsVisibleKey( "nodeGadget:outputNoduleLabelsVisible" ); static IECore::InternedString g_iconKey( "icon" ); static IECore::InternedString g_iconScaleKey( "iconScale" ); static IECore::InternedString g_errorGadgetName( "__error" ); @@ -700,6 +702,7 @@ StandardNodeGadget::StandardNodeGadget( Gaffer::NodePtr node, bool auxiliary ) dragMoveSignal().connect( boost::bind( &StandardNodeGadget::dragMove, this, ::_1, ::_2 ) ); dragLeaveSignal().connect( boost::bind( &StandardNodeGadget::dragLeave, this, ::_1, ::_2 ) ); dropSignal().connect( boost::bind( &StandardNodeGadget::drop, this, ::_1, ::_2 ) ); + noduleAddedSignal().connect( boost::bind( &StandardNodeGadget::noduleAdded, this, ::_2 ) ); for( int e = FirstEdge; e <= LastEdge; e++ ) { @@ -722,6 +725,7 @@ StandardNodeGadget::StandardNodeGadget( Gaffer::NodePtr node, bool auxiliary ) updateIcon(); updateShape(); updateFocusGadgetVisibility(); + updatePersistentNoduleLabels(); } StandardNodeGadget::~StandardNodeGadget() @@ -1133,9 +1137,24 @@ void StandardNodeGadget::enter( Gadget *gadget ) { if( m_labelsVisibleOnHover ) { + IECore::ConstBoolDataPtr inputVisibleData = Gaffer::Metadata::value( node(), g_inputNoduleLabelsVisibleKey ); + IECore::ConstBoolDataPtr outputVisibleData = Gaffer::Metadata::value( node(), g_outputNoduleLabelsVisibleKey ); + for( StandardNodule::RecursiveIterator it( gadget ); !it.done(); ++it ) { - (*it)->setLabelVisible( true ); + if( + ( + (*it)->plug()->direction() == Plug::Direction::In && + ( !inputVisibleData || inputVisibleData->readable() ) + ) || + ( + (*it)->plug()->direction() == Plug::Direction::Out && + ( !outputVisibleData || outputVisibleData->readable() ) + ) + ) + { + (*it)->setLabelVisible( true ); + } } } } @@ -1144,9 +1163,24 @@ void StandardNodeGadget::leave( Gadget *gadget ) { if( m_labelsVisibleOnHover ) { + IECore::ConstBoolDataPtr inputVisibleData = Gaffer::Metadata::value( node(), g_inputNoduleLabelsVisibleKey ); + IECore::ConstBoolDataPtr outputVisibleData = Gaffer::Metadata::value( node(), g_outputNoduleLabelsVisibleKey ); + for( StandardNodule::RecursiveIterator it( gadget ); !it.done(); ++it ) { - (*it)->setLabelVisible( false ); + if( + ( + (*it)->plug()->direction() == Plug::Direction::In && + ( !inputVisibleData || !inputVisibleData->readable() ) + ) || + ( + (*it)->plug()->direction() == Plug::Direction::Out && + ( !outputVisibleData || !outputVisibleData->readable() ) + ) + ) + { + (*it)->setLabelVisible( false ); + } } } } @@ -1158,10 +1192,20 @@ bool StandardNodeGadget::dragEnter( GadgetPtr gadget, const DragDropEvent &event { // Display the labels for all the compatible nodules so the // user can see their options. + IECore::ConstBoolDataPtr inputVisibleData = Gaffer::Metadata::value( node(), g_inputNoduleLabelsVisibleKey ); + IECore::ConstBoolDataPtr outputVisibleData = Gaffer::Metadata::value( node(), g_outputNoduleLabelsVisibleKey ); + for( StandardNodule::RecursiveIterator it( this ); !it.done(); ++it ) { - (*it)->setLabelVisible( canConnect( event, it->get() ) ); + if( + ( (*it)->plug()->direction() == Plug::Direction::In && !inputVisibleData ) || + ( (*it)->plug()->direction() == Plug::Direction::Out && !outputVisibleData ) + ) + { + (*it)->setLabelVisible( canConnect( event, it->get() ) ); + } } + return true; } @@ -1202,10 +1246,7 @@ bool StandardNodeGadget::dragLeave( GadgetPtr gadget, const DragDropEvent &event if( m_dragDestination != event.destinationGadget ) { m_dragDestination->setHighlighted( false ); - for( StandardNodule::RecursiveIterator it( this ); !it.done(); ++it ) - { - (*it)->setLabelVisible( false ); - } + updatePersistentNoduleLabels(); } m_dragDestination = nullptr; @@ -1222,14 +1263,32 @@ bool StandardNodeGadget::drop( GadgetPtr gadget, const DragDropEvent &event ) connect( event, m_dragDestination ); m_dragDestination->setHighlighted( false ); - for( StandardNodule::RecursiveIterator it( this ); !it.done(); ++it ) - { - (*it)->setLabelVisible( false ); - } + updatePersistentNoduleLabels(); + m_dragDestination = nullptr; return true; } +void StandardNodeGadget::noduleAdded( Nodule *nodule ) +{ + if( auto standardNodule = IECore::runTimeCast( nodule ) ) + { + bool inputVisible = false; + bool outputVisible = false; + + if( IECore::ConstBoolDataPtr d = Gaffer::Metadata::value( node(), g_inputNoduleLabelsVisibleKey ) ) + { + inputVisible = d->readable(); + } + if( IECore::ConstBoolDataPtr d = Gaffer::Metadata::value( node(), g_outputNoduleLabelsVisibleKey ) ) + { + outputVisible = d->readable(); + } + + standardNodule->setLabelVisible( standardNodule->plug()->direction() == Plug::Direction::In ? inputVisible : outputVisible ); + } +} + ConnectionCreator *StandardNodeGadget::closestDragDestination( const DragDropEvent &event ) const { if( event.buttons != DragDropEvent::Left ) @@ -1303,6 +1362,10 @@ void StandardNodeGadget::nodeMetadataChanged( IECore::InternedString key ) { updateFocusGadgetVisibility(); } + else if( key == g_inputNoduleLabelsVisibleKey || key == g_outputNoduleLabelsVisibleKey ) + { + updatePersistentNoduleLabels(); + } } bool StandardNodeGadget::updateUserColor() @@ -1464,6 +1527,28 @@ void StandardNodeGadget::updateFocusGadgetVisibility() m_focusGadget->setVisible( !d || d->readable() ); } +void StandardNodeGadget::updatePersistentNoduleLabels() +{ + bool inputVisible = false; + if( IECore::ConstBoolDataPtr d = Gaffer::Metadata::value( node(), g_inputNoduleLabelsVisibleKey ) ) + { + inputVisible = d->readable(); + } + + bool outputVisible = false; + if( IECore::ConstBoolDataPtr d = Gaffer::Metadata::value( node(), g_outputNoduleLabelsVisibleKey ) ) + { + outputVisible = d->readable(); + } + + for( StandardNodule::RecursiveIterator it( this ); !it.done(); ++it ) + { + (*it)->setLabelVisible( + (*it)->plug()->direction() == Plug::Direction::In ? inputVisible : outputVisible + ); + } +} + StandardNodeGadget::ErrorGadget *StandardNodeGadget::errorGadget( bool createIfMissing ) { if( ErrorGadget *result = getChild( g_errorGadgetName ) ) diff --git a/src/GafferUI/StandardNodule.cpp b/src/GafferUI/StandardNodule.cpp index 016d1fef595..467fcbee2d3 100644 --- a/src/GafferUI/StandardNodule.cpp +++ b/src/GafferUI/StandardNodule.cpp @@ -67,6 +67,8 @@ Nodule::NoduleTypeDescription StandardNodule::g_noduleTypeDescri static IECore::InternedString g_colorKey( "nodule:color" ); static IECore::InternedString g_labelKey( "noduleLayout:label" ); +static IECore::InternedString g_inputNoduleLabelsVisibleKey( "nodeGadget:inputNoduleLabelsVisible" ); +static IECore::InternedString g_outputNoduleLabelsVisibleKey( "nodeGadget:outputNoduleLabelsVisible" ); StandardNodule::StandardNodule( Gaffer::PlugPtr plug ) : Nodule( plug ), m_labelVisible( false ), m_draggingConnection( false ) @@ -465,11 +467,21 @@ void StandardNodule::setCompatibleLabelsVisible( const DragDropEvent &event, boo return; } + IECore::ConstBoolDataPtr inputVisibleData = Gaffer::Metadata::value( nodeGadget->node(), g_inputNoduleLabelsVisibleKey ); + IECore::ConstBoolDataPtr outputVisibleData = Gaffer::Metadata::value( nodeGadget->node(), g_outputNoduleLabelsVisibleKey ); + for( StandardNodule::RecursiveIterator it( nodeGadget ); !it.done(); ++it ) { if( creator->canCreateConnection( it->get()->plug() ) ) { - (*it)->setLabelVisible( visible ); + if( it->get()->plug()->direction() == Plug::Direction::In ) + { + (*it)->setLabelVisible( !inputVisibleData ? visible : inputVisibleData->readable() ); + } + if( it->get()->plug()->direction() == Plug::Direction::Out ) + { + (*it)->setLabelVisible( !outputVisibleData ? visible : outputVisibleData->readable() ); + } } } }