Add 'View > Zoom to Selected' action (#1047)

* implements pan/zoom to the selected layer(s) on Period

Relates to #989

* adds layer menu support: Layer -> Center View on Selection

* relocate Center View on Selection to View -> Zoom to selected

* use the proper menu title
This commit is contained in:
Adam Jahn 2023-02-20 20:00:07 -05:00 committed by Keavon Chambers
parent 37775eb9e9
commit 4797aed05b
5 changed files with 29 additions and 4 deletions

View File

@ -280,6 +280,7 @@ pub fn default_mapping() -> Mapping {
entry!(KeyDown(PageDown); modifiers=[Shift], action_dispatch=NavigationMessage::TranslateCanvasByViewportFraction { delta: DVec2::new(-1., 0.) }), entry!(KeyDown(PageDown); modifiers=[Shift], action_dispatch=NavigationMessage::TranslateCanvasByViewportFraction { delta: DVec2::new(-1., 0.) }),
entry!(KeyDown(PageUp); action_dispatch=NavigationMessage::TranslateCanvasByViewportFraction { delta: DVec2::new(0., 1.) }), entry!(KeyDown(PageUp); action_dispatch=NavigationMessage::TranslateCanvasByViewportFraction { delta: DVec2::new(0., 1.) }),
entry!(KeyDown(PageDown); action_dispatch=NavigationMessage::TranslateCanvasByViewportFraction { delta: DVec2::new(0., -1.) }), entry!(KeyDown(PageDown); action_dispatch=NavigationMessage::TranslateCanvasByViewportFraction { delta: DVec2::new(0., -1.) }),
entry!(KeyDown(Period); action_dispatch=NavigationMessage::FitViewportToSelection),
// //
// PortfolioMessage // PortfolioMessage
entry!(KeyDown(KeyO); modifiers=[Accel], action_dispatch=PortfolioMessage::OpenDocument), entry!(KeyDown(KeyO); modifiers=[Accel], action_dispatch=PortfolioMessage::OpenDocument),

View File

@ -186,7 +186,8 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
} }
#[remain::unsorted] #[remain::unsorted]
Navigation(message) => { Navigation(message) => {
self.navigation_handler.process_message(message, responses, (&self.document_legacy, ipp)); self.navigation_handler
.process_message(message, responses, (&self.document_legacy, ipp, self.selected_visible_layers_bounding_box(&render_data)));
} }
#[remain::unsorted] #[remain::unsorted]
Overlays(message) => { Overlays(message) => {

View File

@ -17,6 +17,7 @@ pub enum NavigationMessage {
padding_scale_factor: Option<f32>, padding_scale_factor: Option<f32>,
prevent_zoom_past_100: bool, prevent_zoom_past_100: bool,
}, },
FitViewportToSelection,
IncreaseCanvasZoom { IncreaseCanvasZoom {
center_on_mouse: bool, center_on_mouse: bool,
}, },

View File

@ -1,4 +1,7 @@
use crate::consts::{VIEWPORT_ROTATE_SNAP_INTERVAL, VIEWPORT_SCROLL_RATE, VIEWPORT_ZOOM_LEVELS, VIEWPORT_ZOOM_MOUSE_RATE, VIEWPORT_ZOOM_SCALE_MAX, VIEWPORT_ZOOM_SCALE_MIN, VIEWPORT_ZOOM_WHEEL_RATE}; use crate::consts::{
VIEWPORT_ROTATE_SNAP_INTERVAL, VIEWPORT_SCROLL_RATE, VIEWPORT_ZOOM_LEVELS, VIEWPORT_ZOOM_MOUSE_RATE, VIEWPORT_ZOOM_SCALE_MAX, VIEWPORT_ZOOM_SCALE_MIN, VIEWPORT_ZOOM_TO_FIT_PADDING_SCALE_FACTOR,
VIEWPORT_ZOOM_WHEEL_RATE,
};
use crate::messages::frontend::utility_types::MouseCursorIcon; use crate::messages::frontend::utility_types::MouseCursorIcon;
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, KeysGroup}; use crate::messages::input_mapper::utility_types::input_keyboard::{Key, KeysGroup};
use crate::messages::input_mapper::utility_types::input_mouse::{ViewportBounds, ViewportPosition}; use crate::messages::input_mapper::utility_types::input_mouse::{ViewportBounds, ViewportPosition};
@ -48,9 +51,9 @@ impl Default for NavigationMessageHandler {
} }
} }
impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHandler)> for NavigationMessageHandler { impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHandler, Option<[DVec2; 2]>)> for NavigationMessageHandler {
#[remain::check] #[remain::check]
fn process_message(&mut self, message: NavigationMessage, responses: &mut VecDeque<Message>, (document, ipp): (&Document, &InputPreprocessorMessageHandler)) { fn process_message(&mut self, message: NavigationMessage, responses: &mut VecDeque<Message>, (document, ipp, selection_bounds): (&Document, &InputPreprocessorMessageHandler, Option<[DVec2; 2]>)) {
use NavigationMessage::*; use NavigationMessage::*;
#[remain::sorted] #[remain::sorted]
@ -91,6 +94,18 @@ impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHand
responses.push_back(PortfolioMessage::UpdateDocumentWidgets.into()); responses.push_back(PortfolioMessage::UpdateDocumentWidgets.into());
self.create_document_transform(&ipp.viewport_bounds, responses); self.create_document_transform(&ipp.viewport_bounds, responses);
} }
FitViewportToSelection => {
if let Some(bounds) = selection_bounds {
responses.push_back(
FitViewportToBounds {
bounds,
padding_scale_factor: Some(VIEWPORT_ZOOM_TO_FIT_PADDING_SCALE_FACTOR),
prevent_zoom_past_100: false,
}
.into(),
)
}
}
IncreaseCanvasZoom { center_on_mouse } => { IncreaseCanvasZoom { center_on_mouse } => {
let new_scale = *VIEWPORT_ZOOM_LEVELS.iter().find(|scale| **scale > self.zoom).unwrap_or(&self.zoom); let new_scale = *VIEWPORT_ZOOM_LEVELS.iter().find(|scale| **scale > self.zoom).unwrap_or(&self.zoom);
if center_on_mouse { if center_on_mouse {
@ -272,6 +287,7 @@ impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHand
WheelCanvasTranslate, WheelCanvasTranslate,
TranslateCanvas, TranslateCanvas,
TranslateCanvasByViewportFraction, TranslateCanvasByViewportFraction,
FitViewportToSelection,
); );
if self.panning || self.tilting || self.zooming { if self.panning || self.tilting || self.zooming {

View File

@ -222,6 +222,12 @@ impl PropertyHolder for MenuBarMessageHandler {
MenuBarEntry::new_root( MenuBarEntry::new_root(
"View".into(), "View".into(),
MenuBarEntryChildren(vec![vec![ MenuBarEntryChildren(vec![vec![
MenuBarEntry {
label: "Zoom to Selected".into(),
shortcut: action_keys!(NavigationMessageDiscriminant::FitViewportToSelection),
action: MenuBarEntry::create_action(|_| NavigationMessage::FitViewportToSelection.into()),
..MenuBarEntry::default()
},
MenuBarEntry { MenuBarEntry {
label: "Zoom to Fit".into(), label: "Zoom to Fit".into(),
shortcut: action_keys!(DocumentMessageDiscriminant::ZoomCanvasToFitAll), shortcut: action_keys!(DocumentMessageDiscriminant::ZoomCanvasToFitAll),