Set the mouse cursor in the canvas based on the current tool and its state (#480)
* Add FrontendMouseCursor and DisplayMouseCursor * Add update_cursor method to the Fsm trait and implement it for all tools * Rename DisplayMouseCursor to UpdateMouseCursor * Add 'To CSS Cursor Property' transform decorator and change the mouse cursor in the canvas based on the current tool and its state * Implement update_cursor for Navigate tool properly * Keep the cursor when dragging outside of the canvas * Change the mouse cursor to 'zoom-in' when LMB dragging on canvas with Navigate tool * Rename FrontendMouseCursor to MouseCursorIcon * Rename 'event' to 'e' and replace v-on with @ * Change the definition of the MouseCursorIcon type in TS * Replace switch with dictionary look-up * Move the definition of MouseCursorIcon closer to where it's used
This commit is contained in:
parent
e877eea457
commit
0515cc4eca
|
|
@ -1,4 +1,4 @@
|
|||
use super::utility_types::FrontendDocumentDetails;
|
||||
use super::utility_types::{FrontendDocumentDetails, MouseCursorIcon};
|
||||
use crate::document::layer_panel::{LayerPanelEntry, RawBuffer};
|
||||
use crate::message_prelude::*;
|
||||
use crate::misc::HintData;
|
||||
|
|
@ -37,6 +37,7 @@ pub enum FrontendMessage {
|
|||
UpdateDocumentRulers { origin: (f64, f64), spacing: f64, interval: f64 },
|
||||
UpdateDocumentScrollbars { position: (f64, f64), size: (f64, f64), multiplier: (f64, f64) },
|
||||
UpdateInputHints { hint_data: HintData },
|
||||
UpdateMouseCursor { cursor: MouseCursorIcon },
|
||||
UpdateOpenDocumentsList { open_documents: Vec<FrontendDocumentDetails> },
|
||||
UpdateWorkingColors { primary: Color, secondary: Color },
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,3 +6,12 @@ pub struct FrontendDocumentDetails {
|
|||
pub name: String,
|
||||
pub id: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Deserialize, PartialEq, Serialize)]
|
||||
pub enum MouseCursorIcon {
|
||||
Default,
|
||||
ZoomIn,
|
||||
ZoomOut,
|
||||
Grabbing,
|
||||
Crosshair,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ pub trait Fsm {
|
|||
) -> Self;
|
||||
|
||||
fn update_hints(&self, responses: &mut VecDeque<Message>);
|
||||
fn update_cursor(&self, responses: &mut VecDeque<Message>);
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
|
|||
|
|
@ -49,5 +49,6 @@ pub enum ToolMessage {
|
|||
#[child]
|
||||
Shape(ShapeMessage),
|
||||
SwapColors,
|
||||
UpdateCursor,
|
||||
UpdateHints,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,12 +31,13 @@ impl MessageHandler<ToolMessage, (&DocumentMessageHandler, &InputPreprocessorMes
|
|||
}
|
||||
|
||||
// Send the Abort state transition to the tool
|
||||
let mut send_abort_to_tool = |tool_type, message: ToolMessage, update_hints: bool| {
|
||||
let mut send_abort_to_tool = |tool_type, message: ToolMessage, update_hints_and_cursor: bool| {
|
||||
if let Some(tool) = tool_data.tools.get_mut(&tool_type) {
|
||||
tool.process_action(message, (document, document_data, input), responses);
|
||||
|
||||
if update_hints {
|
||||
if update_hints_and_cursor {
|
||||
tool.process_action(ToolMessage::UpdateHints, (document, document_data, input), responses);
|
||||
tool.process_action(ToolMessage::UpdateCursor, (document, document_data, input), responses);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use super::shared::resize::Resize;
|
||||
use crate::document::DocumentMessageHandler;
|
||||
use crate::frontend::utility_types::MouseCursorIcon;
|
||||
use crate::input::keyboard::{Key, MouseMotion};
|
||||
use crate::input::InputPreprocessorMessageHandler;
|
||||
use crate::message_prelude::*;
|
||||
|
|
@ -35,11 +36,17 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Ellipse {
|
|||
return;
|
||||
}
|
||||
|
||||
if action == ToolMessage::UpdateCursor {
|
||||
self.fsm_state.update_cursor(responses);
|
||||
return;
|
||||
}
|
||||
|
||||
let new_state = self.fsm_state.transition(action, data.0, data.1, &mut self.data, data.2, responses);
|
||||
|
||||
if self.fsm_state != new_state {
|
||||
self.fsm_state = new_state;
|
||||
self.fsm_state.update_hints(responses);
|
||||
self.fsm_state.update_cursor(responses);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -177,4 +184,8 @@ impl Fsm for EllipseToolFsmState {
|
|||
|
||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
||||
}
|
||||
|
||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair }.into());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use crate::consts::SELECTION_TOLERANCE;
|
||||
use crate::document::DocumentMessageHandler;
|
||||
use crate::frontend::utility_types::MouseCursorIcon;
|
||||
use crate::input::keyboard::MouseMotion;
|
||||
use crate::input::InputPreprocessorMessageHandler;
|
||||
use crate::message_prelude::*;
|
||||
|
|
@ -34,11 +35,17 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Eyedropper {
|
|||
return;
|
||||
}
|
||||
|
||||
if action == ToolMessage::UpdateCursor {
|
||||
self.fsm_state.update_cursor(responses);
|
||||
return;
|
||||
}
|
||||
|
||||
let new_state = self.fsm_state.transition(action, data.0, data.1, &mut self.data, data.2, responses);
|
||||
|
||||
if self.fsm_state != new_state {
|
||||
self.fsm_state = new_state;
|
||||
self.fsm_state.update_hints(responses);
|
||||
self.fsm_state.update_cursor(responses);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -127,4 +134,8 @@ impl Fsm for EyedropperToolFsmState {
|
|||
|
||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
||||
}
|
||||
|
||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default }.into());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use crate::consts::SELECTION_TOLERANCE;
|
||||
use crate::document::DocumentMessageHandler;
|
||||
use crate::frontend::utility_types::MouseCursorIcon;
|
||||
use crate::input::keyboard::MouseMotion;
|
||||
use crate::input::InputPreprocessorMessageHandler;
|
||||
use crate::message_prelude::*;
|
||||
|
|
@ -34,11 +35,17 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Fill {
|
|||
return;
|
||||
}
|
||||
|
||||
if action == ToolMessage::UpdateCursor {
|
||||
self.fsm_state.update_cursor(responses);
|
||||
return;
|
||||
}
|
||||
|
||||
let new_state = self.fsm_state.transition(action, data.0, data.1, &mut self.data, data.2, responses);
|
||||
|
||||
if self.fsm_state != new_state {
|
||||
self.fsm_state = new_state;
|
||||
self.fsm_state.update_hints(responses);
|
||||
self.fsm_state.update_cursor(responses);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -121,4 +128,8 @@ impl Fsm for FillToolFsmState {
|
|||
|
||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
||||
}
|
||||
|
||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default }.into());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use crate::consts::LINE_ROTATE_SNAP_ANGLE;
|
||||
use crate::document::DocumentMessageHandler;
|
||||
use crate::frontend::utility_types::MouseCursorIcon;
|
||||
use crate::input::keyboard::{Key, MouseMotion};
|
||||
use crate::input::mouse::ViewportPosition;
|
||||
use crate::input::InputPreprocessorMessageHandler;
|
||||
|
|
@ -38,11 +39,17 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Line {
|
|||
return;
|
||||
}
|
||||
|
||||
if action == ToolMessage::UpdateCursor {
|
||||
self.fsm_state.update_cursor(responses);
|
||||
return;
|
||||
}
|
||||
|
||||
let new_state = self.fsm_state.transition(action, data.0, data.1, &mut self.data, data.2, responses);
|
||||
|
||||
if self.fsm_state != new_state {
|
||||
self.fsm_state = new_state;
|
||||
self.fsm_state.update_hints(responses);
|
||||
self.fsm_state.update_cursor(responses);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -207,6 +214,10 @@ impl Fsm for LineToolFsmState {
|
|||
|
||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
||||
}
|
||||
|
||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair }.into());
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_transform(data: &mut LineToolData, lock: bool, snap: bool, center: bool) -> Message {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use crate::document::DocumentMessageHandler;
|
||||
use crate::frontend::utility_types::MouseCursorIcon;
|
||||
use crate::input::keyboard::{Key, MouseMotion};
|
||||
use crate::input::InputPreprocessorMessageHandler;
|
||||
use crate::message_prelude::*;
|
||||
|
|
@ -34,11 +35,17 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Navigate {
|
|||
return;
|
||||
}
|
||||
|
||||
if action == ToolMessage::UpdateCursor {
|
||||
self.fsm_state.update_cursor(responses);
|
||||
return;
|
||||
}
|
||||
|
||||
let new_state = self.fsm_state.transition(action, data.0, data.1, &mut self.data, data.2, responses);
|
||||
|
||||
if self.fsm_state != new_state {
|
||||
self.fsm_state = new_state;
|
||||
self.fsm_state.update_hints(responses);
|
||||
self.fsm_state.update_cursor(responses);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -211,4 +218,15 @@ impl Fsm for NavigateToolFsmState {
|
|||
|
||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
||||
}
|
||||
|
||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||
let cursor = match *self {
|
||||
NavigateToolFsmState::Ready => MouseCursorIcon::ZoomIn,
|
||||
NavigateToolFsmState::Panning => MouseCursorIcon::Grabbing,
|
||||
NavigateToolFsmState::Tilting => MouseCursorIcon::Default,
|
||||
NavigateToolFsmState::Zooming => MouseCursorIcon::ZoomIn,
|
||||
};
|
||||
|
||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor }.into());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use crate::consts::{COLOR_ACCENT, VECTOR_MANIPULATOR_ANCHOR_MARKER_SIZE};
|
||||
use crate::document::utility_types::{VectorManipulatorSegment, VectorManipulatorShape};
|
||||
use crate::document::DocumentMessageHandler;
|
||||
use crate::frontend::utility_types::MouseCursorIcon;
|
||||
use crate::input::keyboard::{Key, MouseMotion};
|
||||
use crate::input::InputPreprocessorMessageHandler;
|
||||
use crate::message_prelude::*;
|
||||
|
|
@ -41,11 +42,17 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Path {
|
|||
return;
|
||||
}
|
||||
|
||||
if action == ToolMessage::UpdateCursor {
|
||||
self.fsm_state.update_cursor(responses);
|
||||
return;
|
||||
}
|
||||
|
||||
let new_state = self.fsm_state.transition(action, data.0, data.1, &mut self.data, data.2, responses);
|
||||
|
||||
if self.fsm_state != new_state {
|
||||
self.fsm_state = new_state;
|
||||
self.fsm_state.update_hints(responses);
|
||||
self.fsm_state.update_cursor(responses);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -476,6 +483,10 @@ impl Fsm for PathToolFsmState {
|
|||
|
||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
||||
}
|
||||
|
||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default }.into());
|
||||
}
|
||||
}
|
||||
|
||||
struct VectorManipulatorTypes {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use crate::document::DocumentMessageHandler;
|
||||
use crate::frontend::utility_types::MouseCursorIcon;
|
||||
use crate::input::keyboard::{Key, MouseMotion};
|
||||
use crate::input::InputPreprocessorMessageHandler;
|
||||
use crate::message_prelude::*;
|
||||
|
|
@ -44,11 +45,17 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Pen {
|
|||
return;
|
||||
}
|
||||
|
||||
if action == ToolMessage::UpdateCursor {
|
||||
self.fsm_state.update_cursor(responses);
|
||||
return;
|
||||
}
|
||||
|
||||
let new_state = self.fsm_state.transition(action, data.0, data.1, &mut self.data, data.2, responses);
|
||||
|
||||
if self.fsm_state != new_state {
|
||||
self.fsm_state = new_state;
|
||||
self.fsm_state.update_hints(responses);
|
||||
self.fsm_state.update_cursor(responses);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -193,6 +200,10 @@ impl Fsm for PenToolFsmState {
|
|||
|
||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
||||
}
|
||||
|
||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default }.into());
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_preview(data: &PenToolData) -> Message {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use super::shared::resize::Resize;
|
||||
use crate::document::DocumentMessageHandler;
|
||||
use crate::frontend::utility_types::MouseCursorIcon;
|
||||
use crate::input::keyboard::{Key, MouseMotion};
|
||||
use crate::input::InputPreprocessorMessageHandler;
|
||||
use crate::message_prelude::*;
|
||||
|
|
@ -35,11 +36,17 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Rectangle {
|
|||
return;
|
||||
}
|
||||
|
||||
if action == ToolMessage::UpdateCursor {
|
||||
self.fsm_state.update_cursor(responses);
|
||||
return;
|
||||
}
|
||||
|
||||
let new_state = self.fsm_state.transition(action, data.0, data.1, &mut self.data, data.2, responses);
|
||||
|
||||
if self.fsm_state != new_state {
|
||||
self.fsm_state = new_state;
|
||||
self.fsm_state.update_hints(responses);
|
||||
self.fsm_state.update_cursor(responses);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -177,4 +184,8 @@ impl Fsm for RectangleToolFsmState {
|
|||
|
||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
||||
}
|
||||
|
||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair }.into());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use crate::consts::{COLOR_ACCENT, SELECTION_DRAG_ANGLE, SELECTION_TOLERANCE};
|
||||
use crate::document::utility_types::{AlignAggregate, AlignAxis, FlipAxis};
|
||||
use crate::document::DocumentMessageHandler;
|
||||
use crate::frontend::utility_types::MouseCursorIcon;
|
||||
use crate::input::keyboard::{Key, MouseMotion};
|
||||
use crate::input::mouse::ViewportPosition;
|
||||
use crate::input::InputPreprocessorMessageHandler;
|
||||
|
|
@ -46,11 +47,17 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Select {
|
|||
return;
|
||||
}
|
||||
|
||||
if action == ToolMessage::UpdateCursor {
|
||||
self.fsm_state.update_cursor(responses);
|
||||
return;
|
||||
}
|
||||
|
||||
let new_state = self.fsm_state.transition(action, data.0, data.1, &mut self.data, data.2, responses);
|
||||
|
||||
if self.fsm_state != new_state {
|
||||
self.fsm_state = new_state;
|
||||
self.fsm_state.update_hints(responses);
|
||||
self.fsm_state.update_cursor(responses);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -420,4 +427,8 @@ impl Fsm for SelectToolFsmState {
|
|||
|
||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
||||
}
|
||||
|
||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default }.into());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use super::shared::resize::Resize;
|
||||
use crate::document::DocumentMessageHandler;
|
||||
use crate::frontend::utility_types::MouseCursorIcon;
|
||||
use crate::input::keyboard::{Key, MouseMotion};
|
||||
use crate::input::InputPreprocessorMessageHandler;
|
||||
use crate::message_prelude::*;
|
||||
|
|
@ -36,11 +37,17 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Shape {
|
|||
return;
|
||||
}
|
||||
|
||||
if action == ToolMessage::UpdateCursor {
|
||||
self.fsm_state.update_cursor(responses);
|
||||
return;
|
||||
}
|
||||
|
||||
let new_state = self.fsm_state.transition(action, data.0, data.1, &mut self.data, data.2, responses);
|
||||
|
||||
if self.fsm_state != new_state {
|
||||
self.fsm_state = new_state;
|
||||
self.fsm_state.update_hints(responses);
|
||||
self.fsm_state.update_cursor(responses);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -185,4 +192,8 @@ impl Fsm for ShapeToolFsmState {
|
|||
|
||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
||||
}
|
||||
|
||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair }.into());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@
|
|||
<CanvasRuler :origin="rulerOrigin.y" :majorMarkSpacing="rulerSpacing" :numberInterval="rulerInterval" :direction="'Vertical'" />
|
||||
</LayoutCol>
|
||||
<LayoutCol :class="'canvas-area'">
|
||||
<div class="canvas" ref="canvas">
|
||||
<div class="canvas" ref="canvas" :style="{ cursor: canvasCursor }" @pointerdown="(e: PointerEvent) => canvasPointerDown(e)">
|
||||
<svg class="artboards" v-html="artboardSvg" :style="{ width: canvasSvgWidth, height: canvasSvgHeight }"></svg>
|
||||
<svg class="artwork" v-html="artworkSvg" :style="{ width: canvasSvgWidth, height: canvasSvgHeight }"></svg>
|
||||
<svg class="overlays" v-html="overlaysSvg" :style="{ width: canvasSvgWidth, height: canvasSvgHeight }"></svg>
|
||||
|
|
@ -261,6 +261,7 @@ import {
|
|||
UpdateCanvasRotation,
|
||||
ToolName,
|
||||
UpdateDocumentArtboards,
|
||||
UpdateMouseCursor,
|
||||
} from "@/dispatcher/js-messages";
|
||||
|
||||
import LayoutCol from "@/components/layout/LayoutCol.vue";
|
||||
|
|
@ -338,6 +339,10 @@ export default defineComponent({
|
|||
resetWorkingColors() {
|
||||
this.editor.instance.reset_colors();
|
||||
},
|
||||
canvasPointerDown(e: PointerEvent) {
|
||||
const canvas = this.$refs.canvas as HTMLElement;
|
||||
canvas.setPointerCapture(e.pointerId);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.editor.dispatcher.subscribeJsMessage(UpdateDocumentArtwork, (UpdateDocumentArtwork) => {
|
||||
|
|
@ -378,6 +383,10 @@ export default defineComponent({
|
|||
this.documentRotation = (360 + (newRotation % 360)) % 360;
|
||||
});
|
||||
|
||||
this.editor.dispatcher.subscribeJsMessage(UpdateMouseCursor, (updateMouseCursor) => {
|
||||
this.canvasCursor = updateMouseCursor.cursor;
|
||||
});
|
||||
|
||||
window.addEventListener("resize", this.viewportResize);
|
||||
window.addEventListener("DOMContentLoaded", this.viewportResize);
|
||||
},
|
||||
|
|
@ -401,6 +410,7 @@ export default defineComponent({
|
|||
overlaysSvg: "",
|
||||
canvasSvgWidth: "100%",
|
||||
canvasSvgHeight: "100%",
|
||||
canvasCursor: "default",
|
||||
activeTool: "Select" as ToolName,
|
||||
activeToolOptions: {},
|
||||
documentModeEntries,
|
||||
|
|
|
|||
|
|
@ -201,6 +201,24 @@ export class UpdateDocumentRulers extends JsMessage {
|
|||
readonly interval!: number;
|
||||
}
|
||||
|
||||
export type MouseCursorIcon = "default" | "zoom-in" | "zoom-out" | "grabbing" | "crosshair";
|
||||
|
||||
const ToCssCursorProperty = Transform(({ value }) => {
|
||||
const cssNames: Record<string, MouseCursorIcon> = {
|
||||
ZoomIn: "zoom-in",
|
||||
ZoomOut: "zoom-out",
|
||||
Grabbing: "grabbing",
|
||||
Crosshair: "crosshair",
|
||||
};
|
||||
|
||||
return cssNames[value] || "default";
|
||||
});
|
||||
|
||||
export class UpdateMouseCursor extends JsMessage {
|
||||
@ToCssCursorProperty
|
||||
readonly cursor!: MouseCursorIcon;
|
||||
}
|
||||
|
||||
export class TriggerFileDownload extends JsMessage {
|
||||
readonly document!: string;
|
||||
|
||||
|
|
@ -378,6 +396,7 @@ export const messageConstructors: Record<string, MessageMaker> = {
|
|||
UpdateWorkingColors,
|
||||
UpdateCanvasZoom,
|
||||
UpdateCanvasRotation,
|
||||
UpdateMouseCursor,
|
||||
DisplayDialogError,
|
||||
DisplayDialogPanic,
|
||||
DisplayConfirmationToCloseDocument,
|
||||
|
|
|
|||
Loading…
Reference in New Issue