Skip to content

Commit ad55b47

Browse files
committed
CanvasUi: adding 1:1 zoom with hotkeys, matching Photoshop
1 parent 0ef87e6 commit ad55b47

File tree

2 files changed

+38
-6
lines changed

2 files changed

+38
-6
lines changed

include/cinder/CanvasUi.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ class CI_API CanvasUi {
144144
void zoomIn( bool disableAnimation = false );
145145
//! Zoom out by one step
146146
void zoomOut( bool disableAnimation = false );
147+
//! Set zoom to 1.0 and offset to 0.0
148+
void viewOnetoOne( bool disableAnimation = false );
147149

148150
//! Set custom viewport \a viewport rectangle in window coordinates
149151
void setCustomViewport( const Rectf& viewport );
@@ -228,9 +230,11 @@ class CI_API CanvasUi {
228230
void setHotkeysZoomIn( const std::vector<HotkeyBinding>& hotkeys );
229231
//! Set \a hotkeys for zoom out
230232
void setHotkeysZoomOut( const std::vector<HotkeyBinding>& hotkeys );
231-
//! Set \a hotkeys for reset zoom
233+
//! Set \a hotkeys for reset zoom, fitting to window for bounded and equivalent to one-to-one for unbounded
232234
void setHotkeysReset( const std::vector<HotkeyBinding>& hotkeys );
233-
235+
//! Set \a hotkeys for setting zoom and pan to 1:1
236+
void setHotkeysOneToOne( const std::vector<HotkeyBinding>& hotkeys );
237+
234238
//! Allow panning content outside viewport bounds (auto-disables constrainZoomToContent when enabled). Default is \c false.
235239
void setAllowPanOutside( bool allow );
236240
//! Check if content can be panned outside viewport bounds. Default is \c false
@@ -286,6 +290,7 @@ class CI_API CanvasUi {
286290
std::vector<HotkeyBinding> mHotkeysZoomIn;
287291
std::vector<HotkeyBinding> mHotkeysZoomOut;
288292
std::vector<HotkeyBinding> mHotkeysReset;
293+
std::vector<HotkeyBinding> mHotkeysOneToOne;
289294
std::vector<MouseButtonBinding> mPanMouseButtons;
290295

291296
// Animation state
@@ -332,4 +337,4 @@ class CI_API CanvasUi {
332337
bool matchesPanMouseButton( const app::MouseEvent& event, const std::vector<MouseButtonBinding>& buttons ) const;
333338
};
334339

335-
} // namespace cinder
340+
} // namespace cinder

src/cinder/CanvasUi.cpp

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ CanvasUi::CanvasUi()
3434
{
3535
// Set default hotkeys
3636
using namespace app;
37-
#if defined( CINDER_MSW )
37+
#if defined( CINDER_MSW ) || defined( CINDER_MAC )
3838
// On Windows, use ACCEL_DOWN (which maps to CTRL_DOWN)
3939
unsigned int modifier = KeyEvent::ACCEL_DOWN;
4040
#else
41-
// On Linux/Mac, use CTRL_DOWN directly for consistency with Windows behavior
41+
// On Linux, use CTRL_DOWN directly for consistency with Windows behavior
4242
unsigned int modifier = KeyEvent::CTRL_DOWN;
4343
#endif
4444
mHotkeysZoomIn.emplace_back( KeyEvent::KEY_PLUS, modifier );
@@ -51,6 +51,9 @@ CanvasUi::CanvasUi()
5151
mHotkeysReset.emplace_back( KeyEvent::KEY_0, modifier );
5252
mHotkeysReset.emplace_back( KeyEvent::KEY_KP0, modifier );
5353

54+
mHotkeysOneToOne.emplace_back( KeyEvent::KEY_1, modifier );
55+
mHotkeysOneToOne.emplace_back( KeyEvent::KEY_KP1, modifier );
56+
5457
// Set default pan mouse buttons: Alt+Left, Middle, or Right mouse
5558
mPanMouseButtons.emplace_back( app::MouseEvent::LEFT_DOWN, app::MouseEvent::ALT_DOWN );
5659
mPanMouseButtons.emplace_back( app::MouseEvent::MIDDLE_DOWN, 0 );
@@ -307,6 +310,20 @@ void CanvasUi::zoomOut( bool disableAnimation )
307310
}
308311
}
309312

313+
void CanvasUi::viewOnetoOne( bool disableAnimation )
314+
{
315+
vec2 centerViewport = mViewport.getSize() * 0.5f; // Center of viewport in viewport-local coordinates
316+
317+
// Calculate the zoom factor needed to reach 1.0
318+
float zoomFactor = 1.0f / mZoom;
319+
320+
if( mAnimationEnabled && ! disableAnimation ) {
321+
startZoomAnimation( zoomFactor, centerViewport );
322+
} else {
323+
zoomByStep( zoomFactor, centerViewport );
324+
}
325+
}
326+
310327
// Helper to set zoom and position with proper constraints
311328
void CanvasUi::setZoomAndPosition( float newZoom, const vec2& newPositionViewport )
312329
{
@@ -633,6 +650,12 @@ void CanvasUi::keyDown( app::KeyEvent& event )
633650
else if( matchesHotkey( event, mHotkeysReset ) ) {
634651
if( isBounded() )
635652
fitAll();
653+
else
654+
viewOnetoOne();
655+
event.setHandled();
656+
}
657+
else if( matchesHotkey( event, mHotkeysOneToOne ) ) {
658+
viewOnetoOne();
636659
event.setHandled();
637660
}
638661
}
@@ -777,6 +800,10 @@ void CanvasUi::setHotkeysReset( const std::vector<HotkeyBinding>& hotkeys )
777800
mHotkeysReset = hotkeys;
778801
}
779802

803+
void CanvasUi::setHotkeysOneToOne( const std::vector<HotkeyBinding>& hotkeys )
804+
{
805+
mHotkeysOneToOne = hotkeys;
806+
}
780807

781808
bool CanvasUi::matchesHotkey( const app::KeyEvent& event, const std::vector<HotkeyBinding>& hotkeys ) const
782809
{
@@ -908,4 +935,4 @@ void CanvasUi::setAllowPanOutside( bool allow )
908935
mConstrainZoomToContent = false;
909936
}
910937

911-
} // namespace cinder
938+
} // namespace cinder

0 commit comments

Comments
 (0)