Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crop Window Toggle #5518

Merged
merged 2 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Changes.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
1.x.x.x (relative to 1.3.x.x)
=======

Improvements
------------

- Toolbars : Changed hotkey behavior to toogle any tool on and off. Exclusive tools such as the Translate and Crop Window tools activate the first tool (currently Selection Tool) when they are toggled off.
- CropWindowTool : Added <kbd>`Alt` + <kbd>`C` for toggling both the crop window tool and the relevant crop window `enabled` plug.

Breaking Changes
----------------

Expand Down
1 change: 1 addition & 0 deletions doc/source/Interface/ControlsAndShortcuts/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ Cycle Transform Tool Orientation | {kbd}`O`
Scale Tool | {kbd}`R`
Camera Tool | {kbd}`T`
Crop Window Tool | {kbd}`C`
Crop Window Tool and crop enabled | {kbd}`Alt` + {kbd}`C`
Pin to numeric bookmark | {kbd}`1` … {kbd}`9`

### 3D scenes ###
Expand Down
2 changes: 2 additions & 0 deletions include/GafferSceneUI/CropWindowTool.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ class GAFFERSCENEUI_API CropWindowTool : public GafferUI::Tool

Imath::Box2f resolutionGate() const;

bool keyPress( const GafferUI::KeyEvent &event );

Gaffer::Signals::ScopedConnection m_overlayRectangleChangedConnection;

std::string m_overlayMessage;
Expand Down
7 changes: 5 additions & 2 deletions include/GafferUI/View.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,11 @@ class GAFFERUI_API View : public Gaffer::Node

private :

void toolsChildAdded( Gaffer::GraphComponent *child ) const;
void toolPlugSet( Gaffer::Plug *plug ) const;
void toolsChildAdded( Gaffer::GraphComponent *child );
void toolPlugSet( Gaffer::Plug *plug );

using ToolPlugSetMap = std::unordered_map<Tool *, Gaffer::Signals::ScopedConnection>;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the last push, I changed this to be keyed to Tool * instead of the name of the tool. Though we don't expect the tool name to change, it is possible. Keying on Tool * is more reliable.

ToolPlugSetMap m_toolPlugSetConnections;

ViewportGadgetPtr m_viewportGadget;
Gaffer::ContextPtr m_context;
Expand Down
9 changes: 2 additions & 7 deletions python/GafferUI/Viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,13 +225,8 @@ def __keyPress( self, widget, event ) :

for t in self.__toolChooser.tools() :
if Gaffer.Metadata.value( t, "viewer:shortCut" ) == event.key :
if not t["active"].getValue():
t["active"].setValue( True )
else:
# If it's already active, and it's a non-exclusive tool, then pressing the key
# again should deactivate it
if Gaffer.Metadata.value( t, "tool:exclusive" ) == False:
t["active"].setValue( False )
t["active"].setValue( not t["active"].getValue() )

return True

# \todo The Viewer should not need to know about `TransformTool` and orientations.
Expand Down
21 changes: 21 additions & 0 deletions src/GafferSceneUI/CropWindowTool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,8 @@ CropWindowTool::CropWindowTool( View *view, const std::string &name )

Metadata::plugValueChangedSignal().connect( boost::bind( &CropWindowTool::metadataChanged, this, ::_3 ) );
Metadata::nodeValueChangedSignal().connect( boost::bind( &CropWindowTool::metadataChanged, this, ::_2 ) );

view->viewportGadget()->keyPressSignal().connect( boost::bind( &CropWindowTool::keyPress, this, ::_2 ) );
}

CropWindowTool::~CropWindowTool()
Expand Down Expand Up @@ -1018,3 +1020,22 @@ Box2f CropWindowTool::resolutionGate() const
}
return resolutionGate;
}

bool CropWindowTool::keyPress( const KeyEvent &event )
{
if( const auto hotkey = Gaffer::Metadata::value<StringData>( this, "viewer:shortCut" ) )
{
if( event.key == hotkey->readable() && event.modifiers == KeyEvent::Modifiers::Alt )
{
const bool newState = !activePlug()->getValue();

activePlug()->setValue( newState );
if( m_cropWindowEnabledPlug )
{
UndoScope undoScope( m_cropWindowPlug->ancestor<ScriptNode>() );
m_cropWindowEnabledPlug->setValue( newState );
johnhaddon marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
return false;
}
33 changes: 26 additions & 7 deletions src/GafferUI/View.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,30 +254,49 @@ void View::registerView( const IECore::TypeId nodeType, const std::string &plugP
namedCreators()[nodeType].push_back( RegexAndCreator( boost::regex( plugPath ), creator ) );
}

void View::toolsChildAdded( Gaffer::GraphComponent *child ) const
void View::toolsChildAdded( Gaffer::GraphComponent *child )
{
auto tool = static_cast<Tool *>( child ); // Type guaranteed by `ToolContainer::acceptsChild()`
tool->plugSetSignal().connect( boost::bind( &View::toolPlugSet, this, ::_1 ) );
m_toolPlugSetConnections[tool] = tool->plugSetSignal().connect( boost::bind( &View::toolPlugSet, this, ::_1 ) );
}

void View::toolPlugSet( Gaffer::Plug *plug ) const
void View::toolPlugSet( Gaffer::Plug *plug )
{
auto tool = plug->ancestor<Tool>();
if( plug != tool->activePlug() )
{
return;
}

if( !tool->activePlug()->getValue() || !exclusive( tool ) )
if( !exclusive( tool ) )
{
return;
}

for( auto &t : Tool::Range( *tools() ) )
if( tool->activePlug()->getValue() )
{
if( t != tool && exclusive( t.get() ) )
for( auto &t : Tool::Range( *tools() ) )
{
t->activePlug()->setValue( false );
if( t != tool && exclusive( t.get() ) )
{
// Prevent re-entering `toolPlugSet()` when disabling other exclusive tools
Signals::BlockedConnection toolPlugSetBlocker( m_toolPlugSetConnections[t.get()] );
t->activePlug()->setValue( false );
}
}
}
else
{
for( auto &t : Tool::Range( *tools() ) )
{
auto order = Metadata::value<IntData>( t.get(), "order" );
if( order && order->readable() == 0 )
{
// Prevent re-entering `toolPlugSet()` when enabling the default tool
Signals::BlockedConnection toolPlugSetBlocker( m_toolPlugSetConnections[t.get()] );
t->activePlug()->setValue( true );
break;
}
johnhaddon marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
Expand Down
Loading