Skip to content

Commit

Permalink
PathColumnBinding : Allow MenuItems to retain PathListingWidget
Browse files Browse the repository at this point in the history
  • Loading branch information
johnhaddon committed Aug 9, 2024
1 parent 8ffd4c5 commit 5ea05f7
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 13 deletions.
7 changes: 6 additions & 1 deletion include/GafferUI/PathColumn.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ class GAFFERUI_API PathColumn : public IECore::RefCounted, public Gaffer::Signal
ButtonSignal &buttonDoubleClickSignal();

using ContextMenuSignal = Gaffer::Signals::Signal<void ( PathColumn &column, PathListingWidget &widget, MenuDefinition &menuDefinition ), Gaffer::Signals::CatchingCombiner<void>>;
/// To retain `widget` for use in MenuItem commands, use `PathListingWidgetPtr( &widget )`.
ContextMenuSignal &contextMenuSignal();

/// Creation
Expand Down Expand Up @@ -272,11 +273,13 @@ IE_CORE_DECLAREPTR( FileIconPathColumn )
/// C++ interface for the `GafferUI.PathListingWidget` Python class. Provided for
/// use in PathColumn event signals, so that event handling may be implemented
/// from C++ if desired.
class PathListingWidget
class PathListingWidget : public IECore::RefCounted
{

public :

IE_CORE_DECLAREMEMBERPTR( PathListingWidget )

using Columns = std::vector<PathColumnPtr>;
virtual void setColumns( const Columns &columns ) = 0;
virtual Columns getColumns() const = 0;
Expand All @@ -287,6 +290,8 @@ class PathListingWidget

};

IE_CORE_DECLAREPTR( PathListingWidget )

/// C++ interface for the `IECore.MenuDefinition` Python class. Provided for use
/// in `PathColumn::contextMenuSignal()`, so that event handling may be
/// implemented from C++ if desired.
Expand Down
28 changes: 16 additions & 12 deletions src/GafferUIModule/PathColumnBinding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,15 @@ class PathListingWidgetAccessor : public GafferUI::PathListingWidget
public :

PathListingWidgetAccessor( object widget )
: m_widget( widget )
: m_widget(
boost::python::handle<>( PyWeakref_NewRef( widget.ptr(), nullptr ) )
)
{
}

object widget()
object widget() const
{
return m_widget;
return m_widget();
}

void setColumns( const Columns &columns ) override
Expand All @@ -88,13 +90,13 @@ class PathListingWidgetAccessor : public GafferUI::PathListingWidget
{
pythonColumns.append( c );
}
m_widget.attr( "setColumns" )( pythonColumns );
widget().attr( "setColumns" )( pythonColumns );
}

Columns getColumns() const override
{
IECorePython::ScopedGILLock gilLock;
object pythonColumns = m_widget.attr( "getColumns" )();
object pythonColumns = widget().attr( "getColumns" )();
Columns columns;
boost::python::container_utils::extend_container( columns, pythonColumns );
return columns;
Expand All @@ -119,13 +121,13 @@ class PathListingWidgetAccessor : public GafferUI::PathListingWidget
pythonSelection = pythonList;
}

m_widget.attr( "setSelection" )( pythonSelection );
widget().attr( "setSelection" )( pythonSelection );
}

Selection getSelection() const override
{
IECorePython::ScopedGILLock gilLock;
object pythonSelection = m_widget.attr( "getSelection" )();
object pythonSelection = widget().attr( "getSelection" )();
extract<IECore::PathMatcher> e( pythonSelection );
if( e.check() )
{
Expand All @@ -141,7 +143,9 @@ class PathListingWidgetAccessor : public GafferUI::PathListingWidget

private :

// The Python PathListingWidget object.
// A `weakref` for the Python PathListingWidget object. We use a
// weak reference to avoid `PathListingWidget->Menu->MenuDefinition->PathListingWidget`
// reference cycles when a C++ MenuItem stores a PathListingWidgetPtr.
object m_widget;

};
Expand Down Expand Up @@ -385,9 +389,9 @@ struct ButtonSignalCaller
{
// C++-based slots are passed a PathListingWidgetAccessor which gives them limited
// access to the functionality of the Python PathListingWidget.
PathListingWidgetAccessor accessor( widget );
PathListingWidget::Ptr accessor = new PathListingWidgetAccessor( widget );
IECorePython::ScopedGILRelease gilRelease;
return s( path, accessor, event );
return s( path, *accessor, event );
}
};

Expand All @@ -412,10 +416,10 @@ struct ContextMenuSignalCaller
{
static void call( PathColumn::ContextMenuSignal &s, PathColumn &column, object pathListingWidget, object menuDefinition )
{
PathListingWidgetAccessor pathListingWidgetAccessor( pathListingWidget );
PathListingWidget::Ptr pathListingWidgetAccessor = new PathListingWidgetAccessor( pathListingWidget );
MenuDefinitionAccessor menuDefinitionAccessor( menuDefinition );
IECorePython::ScopedGILRelease gilRelease;
s( column, pathListingWidgetAccessor, menuDefinitionAccessor );
s( column, *pathListingWidgetAccessor, menuDefinitionAccessor );
}
};

Expand Down

0 comments on commit 5ea05f7

Please sign in to comment.