Rework navigation tool hints and navigation shortcuts (#1419)

* Added Pan,Tilt,Zoom to View menu + Tilt shortcut changes

* formating

* fixed menus, added action for when dispatch happens from menu

* set key mappings to spec

* fix labels for navigation tool

* fix some spacing

* add action that locks spacebar for navigation when using it as a modifier so the node overlay does not toggle

* escape from the node-graph-overlay, set toggle to ctrl+space, fix demo art

* move all transform state into an enum

* rename confusing flag

* fix demo art and tests

---------

Co-authored-by: Ezbaze <rybitwamateusz3@gmail.com>
This commit is contained in:
mobile-bungalow
2023-09-10 15:42:27 -07:00
committed by GitHub
parent ad9ccaa800
commit b29acbd784
10 changed files with 249 additions and 133 deletions

File diff suppressed because one or more lines are too long

View File

@@ -79,7 +79,7 @@ pub const DEFAULT_FONT_FAMILY: &str = "Merriweather";
pub const DEFAULT_FONT_STYLE: &str = "Normal (400)";
// Document
pub const GRAPHITE_DOCUMENT_VERSION: &str = "0.0.17"; // Remember to update the demo artwork in /demos with both this version number and the contents so it remains editable
pub const GRAPHITE_DOCUMENT_VERSION: &str = "0.0.18"; // Remember to update the demo artwork in /demos with both this version number and the contents so it remains editable
pub const DEFAULT_DOCUMENT_NAME: &str = "Untitled Document";
pub const FILE_SAVE_SUFFIX: &str = ".graphite";
pub const MAX_UNDO_HISTORY_LEN: usize = 100; // TODO: Add this to user preferences

View File

@@ -37,6 +37,9 @@ pub fn default_mapping() -> Mapping {
refresh_keys=[Control],
action_dispatch=NavigationMessage::PointerMove { snap_angle: Control, wait_for_snap_angle_release: true, snap_zoom: Control, zoom_from_viewport: None },
),
entry!(KeyDown(Lmb); action_dispatch=NavigationMessage::TransformFromMenuEnd { commit_key: Key::Lmb }),
entry!(KeyDown(Mmb); action_dispatch=NavigationMessage::TransformFromMenuEnd { commit_key: Key::Mmb }),
entry!(KeyDown(Rmb); action_dispatch=NavigationMessage::TransformFromMenuEnd { commit_key: Key::Rmb }),
// NORMAL PRIORITY:
//
// NodeGraphMessage
@@ -106,8 +109,7 @@ pub fn default_mapping() -> Mapping {
entry!(KeyUp(Lmb); modifiers=[Shift], action_dispatch=NavigateToolMessage::ClickZoom { zoom_in: false }),
entry!(KeyUp(Lmb); action_dispatch=NavigateToolMessage::ClickZoom { zoom_in: true }),
entry!(PointerMove; refresh_keys=[Control], action_dispatch=NavigateToolMessage::PointerMove { snap_angle: Control, snap_zoom: Control }),
entry!(KeyDown(Mmb); action_dispatch=NavigateToolMessage::TranslateCanvasBegin),
entry!(KeyDown(Rmb); action_dispatch=NavigateToolMessage::RotateCanvasBegin),
entry!(KeyDown(Lmb); modifiers=[Alt], action_dispatch=NavigateToolMessage::RotateCanvasBegin),
entry!(KeyDown(Lmb); action_dispatch=NavigateToolMessage::ZoomCanvasBegin),
entry!(KeyUp(Rmb); action_dispatch=NavigateToolMessage::TransformCanvasEnd),
entry!(KeyUp(Lmb); action_dispatch=NavigateToolMessage::TransformCanvasEnd),
@@ -315,12 +317,15 @@ pub fn default_mapping() -> Mapping {
entry!(KeyDown(KeyS); action_dispatch=TransformLayerMessage::BeginScale),
//
// NavigationMessage
entry!(KeyDown(Mmb); modifiers=[Control], action_dispatch=NavigationMessage::RotateCanvasBegin),
entry!(KeyDown(Lmb); modifiers=[Alt], action_dispatch=NavigationMessage::RotateCanvasBegin { was_dispatched_from_menu: false }),
entry!(KeyDown(Mmb); modifiers=[Alt], action_dispatch=NavigationMessage::RotateCanvasBegin { was_dispatched_from_menu: false }),
entry!(KeyDown(Mmb); modifiers=[Shift], action_dispatch=NavigationMessage::ZoomCanvasBegin),
entry!(KeyDown(Lmb); modifiers=[Shift, Space], action_dispatch=NavigationMessage::ZoomCanvasBegin),
entry!(KeyDown(Mmb); action_dispatch=NavigationMessage::TranslateCanvasBegin),
entry!(KeyUp(Mmb); action_dispatch=NavigationMessage::TransformCanvasEnd),
entry!(KeyUp(Mmb); action_dispatch=NavigationMessage::TransformCanvasEnd { abort_transform: false }),
entry!(KeyDown(Lmb); modifiers=[Space], action_dispatch=NavigationMessage::TranslateCanvasBegin),
entry!(KeyUp(Lmb); action_dispatch=NavigationMessage::TransformCanvasEnd),
entry!(KeyUp(Lmb); action_dispatch=NavigationMessage::TransformCanvasEnd { abort_transform: false }),
entry!(KeyUp(Rmb); action_dispatch=NavigationMessage::TransformCanvasEnd { abort_transform: true }),
entry!(KeyDown(NumpadAdd); modifiers=[Accel], action_dispatch=NavigationMessage::IncreaseCanvasZoom { center_on_mouse: false }),
entry!(KeyDown(Equal); modifiers=[Accel], action_dispatch=NavigationMessage::IncreaseCanvasZoom { center_on_mouse: false }),
entry!(KeyDown(Minus); modifiers=[Accel], action_dispatch=NavigationMessage::DecreaseCanvasZoom { center_on_mouse: false }),
@@ -334,8 +339,8 @@ pub fn default_mapping() -> Mapping {
entry!(KeyDown(Period); action_dispatch=NavigationMessage::FitViewportToSelection),
//
// PortfolioMessage
entry!(KeyUp(Space); action_dispatch=PortfolioMessage::GraphViewOverlayToggle),
entry!(KeyDownNoRepeat(Space); action_dispatch=PortfolioMessage::GraphViewOverlayToggleDisabled { disabled: false }),
entry!(KeyDown(Space); modifiers=[Control], action_dispatch=PortfolioMessage::GraphViewOverlayToggle),
entry!(KeyUp(Escape); action_dispatch=PortfolioMessage::GraphViewOverlay { open: false }),
entry!(KeyDown(Tab); modifiers=[Control], action_dispatch=PortfolioMessage::NextDocument),
entry!(KeyDown(Tab); modifiers=[Control, Shift], action_dispatch=PortfolioMessage::PrevDocument),
entry!(KeyDown(KeyW); modifiers=[Accel], action_dispatch=PortfolioMessage::CloseActiveDocumentWithConfirmation),

View File

@@ -27,14 +27,21 @@ pub enum NavigationMessage {
snap_zoom: Key,
zoom_from_viewport: Option<DVec2>,
},
RotateCanvasBegin,
RotateCanvasBegin {
was_dispatched_from_menu: bool,
},
SetCanvasRotation {
angle_radians: f64,
},
SetCanvasZoom {
zoom_factor: f64,
},
TransformCanvasEnd,
TransformCanvasEnd {
abort_transform: bool,
},
TransformFromMenuEnd {
commit_key: Key,
},
TranslateCanvas {
delta: DVec2,
},

View File

@@ -3,7 +3,7 @@ use crate::consts::{
VIEWPORT_ZOOM_TO_FIT_PADDING_SCALE_FACTOR, VIEWPORT_ZOOM_WHEEL_RATE,
};
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, MouseMotion};
use crate::messages::input_mapper::utility_types::input_mouse::{ViewportBounds, ViewportPosition};
use crate::messages::prelude::*;
use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo};
@@ -15,39 +15,35 @@ use graphene_core::renderer::format_transform_matrix;
use glam::{DAffine2, DVec2};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
enum TransformOperation {
None,
Pan { pre_commit_pan: DVec2 },
Rotate { pre_commit_tilt: f64, snap_tilt: bool, snap_tilt_released: bool },
Zoom { pre_commit_zoom: f64, snap_zoom_enabled: bool },
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct NavigationMessageHandler {
pub pan: DVec2,
panning: bool,
snap_tilt: bool,
snap_tilt_released: bool,
pub tilt: f64,
tilting: bool,
pub zoom: f64,
zooming: bool,
snap_zoom: bool,
transform_operation: TransformOperation,
mouse_position: ViewportPosition,
finish_operation_with_click: bool,
}
impl Default for NavigationMessageHandler {
fn default() -> Self {
Self {
pan: DVec2::ZERO,
panning: false,
snap_tilt: false,
snap_tilt_released: false,
tilt: 0.,
tilting: false,
zoom: 1.,
zooming: false,
snap_zoom: false,
mouse_position: ViewportPosition::default(),
finish_operation_with_click: false,
transform_operation: TransformOperation::None,
}
}
}
@@ -124,75 +120,99 @@ impl MessageHandler<NavigationMessage, (&Document, Option<[DVec2; 2]>, &InputPre
snap_zoom,
zoom_from_viewport,
} => {
if self.panning {
let delta = ipp.mouse.position - self.mouse_position;
match self.transform_operation {
TransformOperation::None => {}
TransformOperation::Pan { .. } => {
let delta = ipp.mouse.position - self.mouse_position;
responses.add(TranslateCanvas { delta });
}
TransformOperation::Rotate {
snap_tilt,
snap_tilt_released,
pre_commit_tilt,
} => {
let new_snap = ipp.keyboard.get(snap_angle as usize);
responses.add(TranslateCanvas { delta });
}
if self.tilting {
let new_snap = ipp.keyboard.get(snap_angle as usize);
if !(wait_for_snap_angle_release && new_snap && !self.snap_tilt_released) {
// When disabling snap, keep the viewed rotation as it was previously.
if !new_snap && self.snap_tilt {
self.tilt = self.snapped_angle();
if !(wait_for_snap_angle_release && new_snap && !snap_tilt_released) {
// When disabling snap, keep the viewed rotation as it was previously.
if !new_snap && snap_tilt {
self.tilt = self.snapped_angle();
}
self.transform_operation = TransformOperation::Rotate {
pre_commit_tilt,
snap_tilt: new_snap,
snap_tilt_released: true,
};
}
self.snap_tilt = new_snap;
self.snap_tilt_released = true;
let half_viewport = ipp.viewport_bounds.size() / 2.;
let rotation = {
let start_offset = self.mouse_position - half_viewport;
let end_offset = ipp.mouse.position - half_viewport;
start_offset.angle_between(end_offset)
};
responses.add(SetCanvasRotation { angle_radians: self.tilt + rotation });
}
TransformOperation::Zoom { snap_zoom_enabled, pre_commit_zoom } => {
let zoom_start = self.snapped_scale();
let half_viewport = ipp.viewport_bounds.size() / 2.;
let rotation = {
let start_offset = self.mouse_position - half_viewport;
let end_offset = ipp.mouse.position - half_viewport;
start_offset.angle_between(end_offset)
};
let new_snap = ipp.keyboard.get(snap_zoom as usize);
// When disabling snap, keep the viewed zoom as it was previously
if !new_snap && snap_zoom_enabled {
self.zoom = self.snapped_scale();
}
responses.add(SetCanvasRotation { angle_radians: self.tilt + rotation });
}
if snap_zoom_enabled != new_snap {
self.transform_operation = TransformOperation::Zoom {
pre_commit_zoom,
snap_zoom_enabled: new_snap,
};
}
if self.zooming {
let zoom_start = self.snapped_scale();
let difference = self.mouse_position.y - ipp.mouse.position.y;
let amount = 1. + difference * VIEWPORT_ZOOM_MOUSE_RATE;
let new_snap = ipp.keyboard.get(snap_zoom as usize);
// When disabling snap, keep the viewed zoom as it was previously
if !new_snap && self.snap_zoom {
self.zoom = self.snapped_scale();
}
self.snap_zoom = new_snap;
self.zoom *= amount;
self.zoom *= Self::clamp_zoom(self.zoom, document_bounds, old_zoom, ipp);
let difference = self.mouse_position.y - ipp.mouse.position.y;
let amount = 1. + difference * VIEWPORT_ZOOM_MOUSE_RATE;
if let Some(mouse) = zoom_from_viewport {
let zoom_factor = self.snapped_scale() / zoom_start;
self.zoom *= amount;
self.zoom *= Self::clamp_zoom(self.zoom, document_bounds, old_zoom, ipp);
if let Some(mouse) = zoom_from_viewport {
let zoom_factor = self.snapped_scale() / zoom_start;
responses.add(SetCanvasZoom { zoom_factor: self.zoom });
responses.add(self.center_zoom(ipp.viewport_bounds.size(), zoom_factor, mouse));
} else {
responses.add(SetCanvasZoom { zoom_factor: self.zoom });
responses.add(SetCanvasZoom { zoom_factor: self.zoom });
responses.add(self.center_zoom(ipp.viewport_bounds.size(), zoom_factor, mouse));
} else {
responses.add(SetCanvasZoom { zoom_factor: self.zoom });
}
}
}
self.mouse_position = ipp.mouse.position;
}
RotateCanvasBegin => {
RotateCanvasBegin { was_dispatched_from_menu } => {
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default });
responses.add(FrontendMessage::UpdateInputHints {
hint_data: HintData(vec![HintGroup(vec![HintInfo {
key_groups: vec![KeysGroup(vec![Key::Control]).into()],
key_groups_mac: None,
mouse: None,
label: String::from("Snap 15°"),
plus: false,
}])]),
hint_data: HintData(vec![
HintGroup(vec![HintInfo {
key_groups: vec![KeysGroup(vec![Key::Control]).into()],
key_groups_mac: None,
mouse: None,
label: String::from("Snap 15°"),
plus: false,
}]),
HintGroup(vec![HintInfo::mouse(MouseMotion::Lmb, "Confirm")]),
HintGroup(vec![HintInfo::mouse(MouseMotion::Rmb, "Abort")]),
]),
});
self.tilting = true;
self.transform_operation = TransformOperation::Rotate {
pre_commit_tilt: self.tilt,
snap_tilt_released: false,
snap_tilt: false,
};
self.mouse_position = ipp.mouse.position;
self.finish_operation_with_click = was_dispatched_from_menu;
}
SetCanvasRotation { angle_radians } => {
self.tilt = angle_radians;
@@ -208,19 +228,38 @@ impl MessageHandler<NavigationMessage, (&Document, Option<[DVec2; 2]>, &InputPre
responses.add(PortfolioMessage::UpdateDocumentWidgets);
self.create_document_transform(&ipp.viewport_bounds, responses);
}
TransformCanvasEnd => {
TransformCanvasEnd { abort_transform } => {
if abort_transform {
match self.transform_operation {
TransformOperation::None => {}
TransformOperation::Rotate { pre_commit_tilt, .. } => {
responses.add(SetCanvasRotation { angle_radians: pre_commit_tilt });
}
TransformOperation::Pan { pre_commit_pan, .. } => {
self.pan = pre_commit_pan;
self.create_document_transform(&ipp.viewport_bounds, responses);
}
TransformOperation::Zoom { pre_commit_zoom, .. } => {
self.zoom = pre_commit_zoom;
responses.add(PortfolioMessage::UpdateDocumentWidgets);
self.create_document_transform(&ipp.viewport_bounds, responses);
}
}
}
self.tilt = self.snapped_angle();
self.zoom = self.snapped_scale();
responses.add(BroadcastEvent::CanvasTransformed);
responses.add(BroadcastEvent::DocumentIsDirty);
responses.add(ToolMessage::UpdateCursor);
responses.add(ToolMessage::UpdateHints);
self.snap_tilt = false;
self.snap_tilt_released = false;
self.snap_zoom = false;
self.panning = false;
self.tilting = false;
self.zooming = false;
self.transform_operation = TransformOperation::None;
responses.add(PortfolioMessage::GraphViewOverlayToggleDisabled { disabled: false });
}
TransformFromMenuEnd { commit_key } => {
let abort_transform = commit_key == Key::Rmb;
self.finish_operation_with_click = false;
responses.add(TransformCanvasEnd { abort_transform });
}
TranslateCanvas { delta } => {
let transformed_delta = document.root.transform.inverse().transform_vector2(delta);
@@ -232,13 +271,16 @@ impl MessageHandler<NavigationMessage, (&Document, Option<[DVec2; 2]>, &InputPre
}
TranslateCanvasBegin => {
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Grabbing });
responses.add(FrontendMessage::UpdateInputHints { hint_data: HintData(Vec::new()) });
responses.add(FrontendMessage::UpdateInputHints {
hint_data: HintData(vec![HintGroup(vec![HintInfo::mouse(MouseMotion::Rmb, "Abort")])]),
});
// Because the pan key shares the Spacebar with toggling the graph view overlay, now that we've begun panning,
// we need to prevent the graph view overlay from toggling when the Spacebar is released.
// we need to prevent the graph view overlay from toggling when the control key is pressed.
responses.add(PortfolioMessage::GraphViewOverlayToggleDisabled { disabled: true });
self.panning = true;
self.mouse_position = ipp.mouse.position;
self.transform_operation = TransformOperation::Pan { pre_commit_pan: self.pan };
}
TranslateCanvasByViewportFraction { delta } => {
let transformed_delta = document.root.transform.inverse().transform_vector2(delta * ipp.viewport_bounds.size());
@@ -268,17 +310,27 @@ impl MessageHandler<NavigationMessage, (&Document, Option<[DVec2; 2]>, &InputPre
ZoomCanvasBegin => {
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::ZoomIn });
responses.add(FrontendMessage::UpdateInputHints {
hint_data: HintData(vec![HintGroup(vec![HintInfo {
key_groups: vec![KeysGroup(vec![Key::Control]).into()],
key_groups_mac: None,
mouse: None,
label: String::from("Snap Increments"),
plus: false,
}])]),
hint_data: HintData(vec![
HintGroup(vec![HintInfo {
key_groups: vec![KeysGroup(vec![Key::Control]).into()],
key_groups_mac: None,
mouse: None,
label: String::from("Snap Increments"),
plus: false,
}]),
HintGroup(vec![HintInfo::mouse(MouseMotion::Rmb, "Abort")]),
]),
});
self.zooming = true;
self.transform_operation = TransformOperation::Zoom {
pre_commit_zoom: self.zoom,
snap_zoom_enabled: false,
};
self.mouse_position = ipp.mouse.position;
// Because the zoom key shares the Spacebar with toggling the graph view overlay, now that we've begun zooming,
// we need to prevent the graph view overlay from toggling when the control key is pressed.
responses.add(PortfolioMessage::GraphViewOverlayToggleDisabled { disabled: true });
}
}
}
@@ -298,13 +350,22 @@ impl MessageHandler<NavigationMessage, (&Document, Option<[DVec2; 2]>, &InputPre
FitViewportToSelection,
);
if self.panning || self.tilting || self.zooming {
if self.transform_operation != TransformOperation::None {
let transforming = actions!(NavigationMessageDiscriminant;
PointerMove,
TransformCanvasEnd,
);
common.extend(transforming);
}
if self.finish_operation_with_click {
let transforming_from_menu = actions!(NavigationMessageDiscriminant;
TransformFromMenuEnd,
);
common.extend(transforming_from_menu);
}
common
}
}
@@ -312,7 +373,7 @@ impl MessageHandler<NavigationMessage, (&Document, Option<[DVec2; 2]>, &InputPre
impl NavigationMessageHandler {
pub fn snapped_angle(&self) -> f64 {
let increment_radians: f64 = VIEWPORT_ROTATE_SNAP_INTERVAL.to_radians();
if self.snap_tilt {
if let TransformOperation::Rotate { snap_tilt: true, .. } = self.transform_operation {
(self.tilt / increment_radians).round() * increment_radians
} else {
self.tilt
@@ -320,7 +381,7 @@ impl NavigationMessageHandler {
}
pub fn snapped_scale(&self) -> f64 {
if self.snap_zoom {
if let TransformOperation::Zoom { snap_zoom_enabled: true, .. } = self.transform_operation {
*VIEWPORT_ZOOM_LEVELS
.iter()
.min_by(|a, b| (**a - self.zoom).abs().partial_cmp(&(**b - self.zoom).abs()).unwrap())

View File

@@ -257,36 +257,68 @@ impl LayoutHolder for MenuBarMessageHandler {
MenuBarEntry::new_root(
"View".into(),
no_active_document,
MenuBarEntryChildren(vec![vec![
MenuBarEntry {
label: "Zoom to Selected".into(),
MenuBarEntryChildren(vec![
vec![
MenuBarEntry {
label: "Tilt".into(),
shortcut: action_keys!(NavigationMessageDiscriminant::RotateCanvasBegin),
action: MenuBarEntry::create_action(|_| NavigationMessage::RotateCanvasBegin { was_dispatched_from_menu: true }.into()),
disabled: no_active_document,
..MenuBarEntry::default()
},
MenuBarEntry {
label: "Reset Tilt".into(),
shortcut: action_keys!(NavigationMessageDiscriminant::SetCanvasRotation),
action: MenuBarEntry::create_action(|_| NavigationMessage::SetCanvasRotation { angle_radians: 0.into() }.into()),
disabled: no_active_document,
..MenuBarEntry::default()
},
],
vec![
MenuBarEntry {
label: "Zoom In".into(),
shortcut: action_keys!(NavigationMessageDiscriminant::IncreaseCanvasZoom),
action: MenuBarEntry::create_action(|_| NavigationMessage::IncreaseCanvasZoom { center_on_mouse: false }.into()),
disabled: no_active_document,
..MenuBarEntry::default()
},
MenuBarEntry {
label: "Zoom Out".into(),
shortcut: action_keys!(NavigationMessageDiscriminant::DecreaseCanvasZoom),
action: MenuBarEntry::create_action(|_| NavigationMessage::DecreaseCanvasZoom { center_on_mouse: false }.into()),
disabled: no_active_document,
..MenuBarEntry::default()
},
MenuBarEntry {
label: "Zoom to Fit".into(),
shortcut: action_keys!(DocumentMessageDiscriminant::ZoomCanvasToFitAll),
action: MenuBarEntry::create_action(|_| DocumentMessage::ZoomCanvasToFitAll.into()),
disabled: no_active_document,
..MenuBarEntry::default()
},
MenuBarEntry {
label: "Zoom to 100%".into(),
shortcut: action_keys!(DocumentMessageDiscriminant::ZoomCanvasTo100Percent),
action: MenuBarEntry::create_action(|_| DocumentMessage::ZoomCanvasTo100Percent.into()),
disabled: no_active_document,
..MenuBarEntry::default()
},
MenuBarEntry {
label: "Zoom to 200%".into(),
shortcut: action_keys!(DocumentMessageDiscriminant::ZoomCanvasTo200Percent),
action: MenuBarEntry::create_action(|_| DocumentMessage::ZoomCanvasTo200Percent.into()),
disabled: no_active_document,
..MenuBarEntry::default()
},
],
vec![MenuBarEntry {
label: "Frame Selected".into(),
shortcut: action_keys!(NavigationMessageDiscriminant::FitViewportToSelection),
action: MenuBarEntry::create_action(|_| NavigationMessage::FitViewportToSelection.into()),
disabled: no_active_document,
..MenuBarEntry::default()
},
MenuBarEntry {
label: "Zoom to Fit".into(),
shortcut: action_keys!(DocumentMessageDiscriminant::ZoomCanvasToFitAll),
action: MenuBarEntry::create_action(|_| DocumentMessage::ZoomCanvasToFitAll.into()),
disabled: no_active_document,
..MenuBarEntry::default()
},
MenuBarEntry {
label: "Zoom to 100%".into(),
shortcut: action_keys!(DocumentMessageDiscriminant::ZoomCanvasTo100Percent),
action: MenuBarEntry::create_action(|_| DocumentMessage::ZoomCanvasTo100Percent.into()),
disabled: no_active_document,
..MenuBarEntry::default()
},
MenuBarEntry {
label: "Zoom to 200%".into(),
shortcut: action_keys!(DocumentMessageDiscriminant::ZoomCanvasTo200Percent),
action: MenuBarEntry::create_action(|_| DocumentMessage::ZoomCanvasTo200Percent.into()),
disabled: no_active_document,
..MenuBarEntry::default()
},
]]),
}],
]),
),
MenuBarEntry::new_root(
"Help".into(),

View File

@@ -557,6 +557,11 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
PrevDocument,
);
if self.graph_view_overlay_open {
let escape = actions!(PortfolioMessageDiscriminant; GraphViewOverlay);
common.extend(escape);
}
if let Some(document) = self.active_document() {
if document.layer_metadata.values().any(|data| data.selected) {
let select = actions!(PortfolioMessageDiscriminant;

View File

@@ -117,7 +117,7 @@ impl Fsm for NavigateToolFsmState {
match navigate {
ClickZoom { zoom_in } => {
responses.add_front(NavigationMessage::TransformCanvasEnd);
responses.add_front(NavigationMessage::TransformCanvasEnd { abort_transform: false });
// Mouse has not moved from pointerdown to pointerup
if tool_data.drag_start == input.mouse.position {
@@ -146,7 +146,7 @@ impl Fsm for NavigateToolFsmState {
}
RotateCanvasBegin => {
tool_data.drag_start = input.mouse.position;
responses.add_front(NavigationMessage::RotateCanvasBegin);
responses.add_front(NavigationMessage::RotateCanvasBegin { was_dispatched_from_menu: false });
NavigateToolFsmState::Tilting
}
ZoomCanvasBegin => {
@@ -155,11 +155,11 @@ impl Fsm for NavigateToolFsmState {
NavigateToolFsmState::Zooming
}
TransformCanvasEnd => {
responses.add_front(NavigationMessage::TransformCanvasEnd);
responses.add_front(NavigationMessage::TransformCanvasEnd { abort_transform: false });
NavigateToolFsmState::Ready
}
Abort => {
responses.add_front(NavigationMessage::TransformCanvasEnd);
responses.add_front(NavigationMessage::TransformCanvasEnd { abort_transform: false });
NavigateToolFsmState::Ready
}
}
@@ -173,8 +173,12 @@ impl Fsm for NavigateToolFsmState {
NavigateToolFsmState::Ready => HintData(vec![
HintGroup(vec![HintInfo::mouse(MouseMotion::Lmb, "Zoom In"), HintInfo::keys([Key::Shift], "Zoom Out").prepend_plus()]),
HintGroup(vec![HintInfo::mouse(MouseMotion::LmbDrag, "Zoom"), HintInfo::keys([Key::Control], "Snap Increments").prepend_plus()]),
HintGroup(vec![HintInfo::mouse(MouseMotion::MmbDrag, "Pan")]),
HintGroup(vec![HintInfo::mouse(MouseMotion::RmbDrag, "Tilt"), HintInfo::keys([Key::Control], "Snap 15°").prepend_plus()]),
HintGroup(vec![
HintInfo::mouse(MouseMotion::LmbDrag, " "),
HintInfo::keys([Key::Space], "Or").prepend_plus(),
HintInfo::mouse(MouseMotion::MmbDrag, "Pan"),
]),
HintGroup(vec![HintInfo::mouse(MouseMotion::LmbDrag, ""), HintInfo::keys([Key::Alt], "Tilt").prepend_plus()]),
]),
NavigateToolFsmState::Tilting => HintData(vec![HintGroup(vec![HintInfo::keys([Key::Control], "Snap 15°")])]),
NavigateToolFsmState::Zooming => HintData(vec![HintGroup(vec![HintInfo::keys([Key::Control], "Snap Increments")])]),