Add auto-panning to the Artboard tool (#1652)
* Move panning functionality to auto_panning.rs * Add auto-panning to Artboard tool * Hide debug messages containing AnimationFrame
This commit is contained in:
parent
ea3f834b64
commit
d780602ecd
|
|
@ -222,7 +222,9 @@ impl Dispatcher {
|
|||
/// Logs a message that is about to be executed,
|
||||
/// either as a tree with a discriminant or the entire payload (depending on settings)
|
||||
fn log_message(&self, message: &Message, queues: &[VecDeque<Message>], message_logging_verbosity: MessageLoggingVerbosity) {
|
||||
if !MessageDiscriminant::from(message).local_name().ends_with("PointerMove") {
|
||||
let message_name = MessageDiscriminant::from(message).local_name();
|
||||
|
||||
if !(message_name.ends_with("PointerMove") || message_name.ends_with("AnimationFrame")) {
|
||||
match message_logging_verbosity {
|
||||
MessageLoggingVerbosity::Off => {}
|
||||
MessageLoggingVerbosity::Names => {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
use crate::consts::{DRAG_BEYOND_VIEWPORT_MAX_OVEREXTENSION_PIXELS, DRAG_BEYOND_VIEWPORT_SPEED_FACTOR};
|
||||
use crate::messages::prelude::*;
|
||||
use crate::messages::tool::tool_messages::tool_prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct AutoPanning {
|
||||
subscribed_to_animation_frame: bool,
|
||||
}
|
||||
|
||||
impl AutoPanning {
|
||||
pub fn start(&mut self, messages: &[Message], responses: &mut VecDeque<Message>) {
|
||||
if !self.subscribed_to_animation_frame {
|
||||
self.subscribed_to_animation_frame = true;
|
||||
|
||||
for message in messages {
|
||||
responses.add(BroadcastMessage::SubscribeEvent {
|
||||
on: BroadcastEvent::AnimationFrame,
|
||||
send: Box::new(message.clone()),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn stop(&mut self, messages: &[Message], responses: &mut VecDeque<Message>) {
|
||||
if self.subscribed_to_animation_frame {
|
||||
self.subscribed_to_animation_frame = false;
|
||||
|
||||
for message in messages {
|
||||
responses.add(BroadcastMessage::UnsubscribeEvent {
|
||||
on: BroadcastEvent::AnimationFrame,
|
||||
message: Box::new(message.clone()),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setup_by_mouse_position(&mut self, mouse_position: DVec2, viewport_size: DVec2, messages: &[Message], responses: &mut VecDeque<Message>) {
|
||||
let is_pointer_outside_edge = mouse_position.x < 0. || mouse_position.x > viewport_size.x || mouse_position.y < 0. || mouse_position.y > viewport_size.y;
|
||||
|
||||
match is_pointer_outside_edge {
|
||||
true => self.start(messages, responses),
|
||||
false => self.stop(messages, responses),
|
||||
}
|
||||
}
|
||||
|
||||
/// Shifts the viewport when the mouse reaches the edge of the viewport.
|
||||
///
|
||||
/// If the mouse was beyond any edge, it returns the amount shifted. Otherwise it returns None.
|
||||
/// The shift is proportional to the distance between edge and mouse. It is also guaranteed to be integral.
|
||||
pub fn shift_viewport(mouse_position: DVec2, viewport_size: DVec2, responses: &mut VecDeque<Message>) -> Option<DVec2> {
|
||||
let mouse_position = mouse_position.clamp(
|
||||
DVec2::ZERO - DVec2::splat(DRAG_BEYOND_VIEWPORT_MAX_OVEREXTENSION_PIXELS),
|
||||
viewport_size + DVec2::splat(DRAG_BEYOND_VIEWPORT_MAX_OVEREXTENSION_PIXELS),
|
||||
);
|
||||
let mouse_position_percent = mouse_position / viewport_size;
|
||||
|
||||
let mut shift_percent = DVec2::ZERO;
|
||||
|
||||
if mouse_position_percent.x < 0. {
|
||||
shift_percent.x = -mouse_position_percent.x;
|
||||
} else if mouse_position_percent.x > 1. {
|
||||
shift_percent.x = 1. - mouse_position_percent.x;
|
||||
}
|
||||
|
||||
if mouse_position_percent.y < 0. {
|
||||
shift_percent.y = -mouse_position_percent.y;
|
||||
} else if mouse_position_percent.y > 1. {
|
||||
shift_percent.y = 1. - mouse_position_percent.y;
|
||||
}
|
||||
|
||||
if shift_percent.x == 0. && shift_percent.y == 0. {
|
||||
return None;
|
||||
}
|
||||
|
||||
let delta = (shift_percent * DRAG_BEYOND_VIEWPORT_SPEED_FACTOR * viewport_size).round();
|
||||
responses.add(NavigationMessage::TranslateCanvas { delta });
|
||||
Some(delta)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
pub mod auto_panning;
|
||||
pub mod color_selector;
|
||||
pub mod graph_modification_utils;
|
||||
pub mod pivot;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use super::tool_prelude::*;
|
|||
use crate::application::generate_uuid;
|
||||
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||
use crate::messages::tool::common_functionality::auto_panning::AutoPanning;
|
||||
use crate::messages::tool::common_functionality::graph_modification_utils::is_layer_fed_by_node_of_name;
|
||||
use crate::messages::tool::common_functionality::snapping::SnapManager;
|
||||
use crate::messages::tool::common_functionality::transformation_cage::*;
|
||||
|
|
@ -27,6 +28,7 @@ pub enum ArtboardToolMessage {
|
|||
NudgeSelected { delta_x: f64, delta_y: f64 },
|
||||
PointerDown,
|
||||
PointerMove { constrain_axis_or_aspect: Key, center: Key },
|
||||
PointerOutsideViewport { constrain_axis_or_aspect: Key, center: Key },
|
||||
PointerUp,
|
||||
}
|
||||
|
||||
|
|
@ -90,6 +92,7 @@ struct ArtboardToolData {
|
|||
cursor: MouseCursorIcon,
|
||||
drag_start: DVec2,
|
||||
drag_current: DVec2,
|
||||
auto_panning: AutoPanning,
|
||||
}
|
||||
|
||||
impl ArtboardToolData {
|
||||
|
|
@ -201,10 +204,20 @@ impl Fsm for ArtboardToolFsmState {
|
|||
let mouse_position = input.mouse.position;
|
||||
tool_data.resize_artboard(responses, document, mouse_position, from_center, constrain_square);
|
||||
|
||||
tool_data.auto_panning.setup_by_mouse_position(
|
||||
mouse_position,
|
||||
input.viewport_bounds.size(),
|
||||
&[
|
||||
ArtboardToolMessage::PointerOutsideViewport { constrain_axis_or_aspect, center }.into(),
|
||||
ArtboardToolMessage::PointerMove { constrain_axis_or_aspect, center }.into(),
|
||||
],
|
||||
responses,
|
||||
);
|
||||
|
||||
ArtboardToolFsmState::ResizingBounds
|
||||
}
|
||||
(ArtboardToolFsmState::Dragging, ArtboardToolMessage::PointerMove { constrain_axis_or_aspect, .. }) => {
|
||||
if let Some(bounds) = &tool_data.bounding_box_manager {
|
||||
(ArtboardToolFsmState::Dragging, ArtboardToolMessage::PointerMove { constrain_axis_or_aspect, center }) => {
|
||||
if let Some(ref mut bounds) = &mut tool_data.bounding_box_manager {
|
||||
let axis_align = input.keyboard.get(constrain_axis_or_aspect as usize);
|
||||
let mouse_position = axis_align_drag(axis_align, input.mouse.position, tool_data.drag_start);
|
||||
let size = bounds.bounds[1] - bounds.bounds[0];
|
||||
|
|
@ -216,7 +229,22 @@ impl Fsm for ArtboardToolFsmState {
|
|||
dimensions: size.round().as_ivec2(),
|
||||
});
|
||||
|
||||
tool_data.drag_current = mouse_position;
|
||||
// The second term is added to prevent the slow change in position due to rounding errors.
|
||||
tool_data.drag_current = mouse_position + bounds.transform.transform_vector2(position.round() - position);
|
||||
|
||||
// Update bounds if another `PointerMove` message comes before `ResizeArtboard` is finished.
|
||||
bounds.bounds[0] = position.round();
|
||||
bounds.bounds[1] = position.round() + size.round();
|
||||
|
||||
tool_data.auto_panning.setup_by_mouse_position(
|
||||
mouse_position,
|
||||
input.viewport_bounds.size(),
|
||||
&[
|
||||
ArtboardToolMessage::PointerOutsideViewport { constrain_axis_or_aspect, center }.into(),
|
||||
ArtboardToolMessage::PointerMove { constrain_axis_or_aspect, center }.into(),
|
||||
],
|
||||
responses,
|
||||
);
|
||||
}
|
||||
ArtboardToolFsmState::Dragging
|
||||
}
|
||||
|
|
@ -266,6 +294,16 @@ impl Fsm for ArtboardToolFsmState {
|
|||
})
|
||||
}
|
||||
|
||||
tool_data.auto_panning.setup_by_mouse_position(
|
||||
mouse_position,
|
||||
input.viewport_bounds.size(),
|
||||
&[
|
||||
ArtboardToolMessage::PointerOutsideViewport { constrain_axis_or_aspect, center }.into(),
|
||||
ArtboardToolMessage::PointerMove { constrain_axis_or_aspect, center }.into(),
|
||||
],
|
||||
responses,
|
||||
);
|
||||
|
||||
ArtboardToolFsmState::Drawing
|
||||
}
|
||||
(ArtboardToolFsmState::Ready, ArtboardToolMessage::PointerMove { .. }) => {
|
||||
|
|
@ -278,6 +316,37 @@ impl Fsm for ArtboardToolFsmState {
|
|||
|
||||
ArtboardToolFsmState::Ready
|
||||
}
|
||||
(ArtboardToolFsmState::ResizingBounds, ArtboardToolMessage::PointerOutsideViewport { .. }) => {
|
||||
let _ = AutoPanning::shift_viewport(input.mouse.position, input.viewport_bounds.size(), responses);
|
||||
|
||||
ArtboardToolFsmState::ResizingBounds
|
||||
}
|
||||
(ArtboardToolFsmState::Dragging, ArtboardToolMessage::PointerOutsideViewport { .. }) => {
|
||||
if let Some(shift) = AutoPanning::shift_viewport(input.mouse.position, input.viewport_bounds.size(), responses) {
|
||||
tool_data.drag_current += shift;
|
||||
tool_data.drag_start += shift;
|
||||
}
|
||||
|
||||
ArtboardToolFsmState::Dragging
|
||||
}
|
||||
(ArtboardToolFsmState::Drawing, ArtboardToolMessage::PointerOutsideViewport { .. }) => {
|
||||
if let Some(shift) = AutoPanning::shift_viewport(input.mouse.position, input.viewport_bounds.size(), responses) {
|
||||
tool_data.drag_start += shift;
|
||||
}
|
||||
|
||||
ArtboardToolFsmState::Drawing
|
||||
}
|
||||
(state, ArtboardToolMessage::PointerOutsideViewport { constrain_axis_or_aspect, center }) => {
|
||||
tool_data.auto_panning.stop(
|
||||
&[
|
||||
ArtboardToolMessage::PointerOutsideViewport { constrain_axis_or_aspect, center }.into(),
|
||||
ArtboardToolMessage::PointerMove { constrain_axis_or_aspect, center }.into(),
|
||||
],
|
||||
responses,
|
||||
);
|
||||
|
||||
state
|
||||
}
|
||||
(ArtboardToolFsmState::ResizingBounds, ArtboardToolMessage::PointerUp) => {
|
||||
tool_data.snap_manager.cleanup(responses);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,12 +2,13 @@
|
|||
|
||||
use super::tool_prelude::*;
|
||||
use crate::application::generate_uuid;
|
||||
use crate::consts::{DRAG_BEYOND_VIEWPORT_MAX_OVEREXTENSION_PIXELS, DRAG_BEYOND_VIEWPORT_SPEED_FACTOR, ROTATE_SNAP_ANGLE, SELECTION_TOLERANCE};
|
||||
use crate::consts::{ROTATE_SNAP_ANGLE, SELECTION_TOLERANCE};
|
||||
use crate::messages::input_mapper::utility_types::input_mouse::ViewportPosition;
|
||||
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||
use crate::messages::portfolio::document::utility_types::misc::{AlignAggregate, AlignAxis, FlipAxis};
|
||||
use crate::messages::portfolio::document::utility_types::transformation::Selected;
|
||||
use crate::messages::tool::common_functionality::auto_panning::AutoPanning;
|
||||
use crate::messages::tool::common_functionality::graph_modification_utils::is_layer_fed_by_node_of_name;
|
||||
use crate::messages::tool::common_functionality::pivot::Pivot;
|
||||
use crate::messages::tool::common_functionality::snapping::{self, SnapCandidatePoint, SnapConstraint, SnapData, SnapManager, SnappedPoint};
|
||||
|
|
@ -75,7 +76,6 @@ pub enum SelectToolMessage {
|
|||
PointerOutsideViewport(SelectToolPointerKeys),
|
||||
SelectOptions(SelectOptionsUpdate),
|
||||
SetPivot { position: PivotPosition },
|
||||
ShiftViewport,
|
||||
}
|
||||
|
||||
impl ToolMetadata for SelectTool {
|
||||
|
|
@ -263,7 +263,7 @@ struct SelectToolData {
|
|||
selected_layers_count: usize,
|
||||
selected_layers_changed: bool,
|
||||
snap_candidates: Vec<SnapCandidatePoint>,
|
||||
subscribed_to_animation_frame: bool,
|
||||
auto_panning: AutoPanning,
|
||||
}
|
||||
|
||||
impl SelectToolData {
|
||||
|
|
@ -645,7 +645,15 @@ impl Fsm for SelectToolFsmState {
|
|||
}
|
||||
tool_data.drag_current += mouse_delta;
|
||||
|
||||
setup_pointer_outside_edge_event(input.mouse.position, input.viewport_bounds.size(), tool_data, modifier_keys, responses);
|
||||
tool_data.auto_panning.setup_by_mouse_position(
|
||||
input.mouse.position,
|
||||
input.viewport_bounds.size(),
|
||||
&[
|
||||
SelectToolMessage::PointerOutsideViewport(modifier_keys.clone()).into(),
|
||||
SelectToolMessage::PointerMove(modifier_keys).into(),
|
||||
],
|
||||
responses,
|
||||
);
|
||||
|
||||
SelectToolFsmState::Dragging
|
||||
}
|
||||
|
|
@ -681,7 +689,15 @@ impl Fsm for SelectToolFsmState {
|
|||
|
||||
selected.apply_transformation(bounds.original_bound_transform * transformation * bounds.original_bound_transform.inverse());
|
||||
|
||||
setup_pointer_outside_edge_event(input.mouse.position, input.viewport_bounds.size(), tool_data, modifier_keys, responses);
|
||||
tool_data.auto_panning.setup_by_mouse_position(
|
||||
input.mouse.position,
|
||||
input.viewport_bounds.size(),
|
||||
&[
|
||||
SelectToolMessage::PointerOutsideViewport(modifier_keys.clone()).into(),
|
||||
SelectToolMessage::PointerMove(modifier_keys).into(),
|
||||
],
|
||||
responses,
|
||||
);
|
||||
}
|
||||
}
|
||||
SelectToolFsmState::ResizingBounds
|
||||
|
|
@ -726,7 +742,15 @@ impl Fsm for SelectToolFsmState {
|
|||
let snapped_mouse_position = mouse_position; //tool_data.snap_manager.snap_position(responses, document, mouse_position);
|
||||
tool_data.pivot.set_viewport_position(snapped_mouse_position, document, responses);
|
||||
|
||||
setup_pointer_outside_edge_event(mouse_position, input.viewport_bounds.size(), tool_data, modifier_keys, responses);
|
||||
tool_data.auto_panning.setup_by_mouse_position(
|
||||
input.mouse.position,
|
||||
input.viewport_bounds.size(),
|
||||
&[
|
||||
SelectToolMessage::PointerOutsideViewport(modifier_keys.clone()).into(),
|
||||
SelectToolMessage::PointerMove(modifier_keys).into(),
|
||||
],
|
||||
responses,
|
||||
);
|
||||
|
||||
SelectToolFsmState::DraggingPivot
|
||||
}
|
||||
|
|
@ -734,7 +758,15 @@ impl Fsm for SelectToolFsmState {
|
|||
tool_data.drag_current = input.mouse.position;
|
||||
responses.add(OverlaysMessage::Draw);
|
||||
|
||||
setup_pointer_outside_edge_event(input.mouse.position, input.viewport_bounds.size(), tool_data, modifier_keys, responses);
|
||||
tool_data.auto_panning.setup_by_mouse_position(
|
||||
input.mouse.position,
|
||||
input.viewport_bounds.size(),
|
||||
&[
|
||||
SelectToolMessage::PointerOutsideViewport(modifier_keys.clone()).into(),
|
||||
SelectToolMessage::PointerMove(modifier_keys).into(),
|
||||
],
|
||||
responses,
|
||||
);
|
||||
|
||||
SelectToolFsmState::DrawingBox
|
||||
}
|
||||
|
|
@ -756,25 +788,16 @@ impl Fsm for SelectToolFsmState {
|
|||
|
||||
SelectToolFsmState::Ready
|
||||
}
|
||||
(SelectToolFsmState::Dragging, SelectToolMessage::PointerOutsideViewport(modifier_keys)) => {
|
||||
responses.add(SelectToolMessage::PointerMove(modifier_keys));
|
||||
|
||||
if let Some(shift) = shift_viewport_if_mouse_beyond_edge(input.mouse.position, input.viewport_bounds.size(), responses) {
|
||||
(SelectToolFsmState::Dragging, SelectToolMessage::PointerOutsideViewport(_)) => {
|
||||
if let Some(shift) = AutoPanning::shift_viewport(input.mouse.position, input.viewport_bounds.size(), responses) {
|
||||
tool_data.drag_current += shift;
|
||||
tool_data.drag_start += shift;
|
||||
}
|
||||
|
||||
SelectToolFsmState::Dragging
|
||||
}
|
||||
(SelectToolFsmState::ResizingBounds | SelectToolFsmState::DraggingPivot | SelectToolFsmState::DrawingBox, SelectToolMessage::PointerOutsideViewport(modifier_keys)) => {
|
||||
responses.add(SelectToolMessage::PointerMove(modifier_keys));
|
||||
|
||||
responses.add(SelectToolMessage::ShiftViewport);
|
||||
|
||||
self
|
||||
}
|
||||
(SelectToolFsmState::ResizingBounds, SelectToolMessage::ShiftViewport) => {
|
||||
if let Some(shift) = shift_viewport_if_mouse_beyond_edge(input.mouse.position, input.viewport_bounds.size(), responses) {
|
||||
(SelectToolFsmState::ResizingBounds, SelectToolMessage::PointerOutsideViewport(_)) => {
|
||||
if let Some(shift) = AutoPanning::shift_viewport(input.mouse.position, input.viewport_bounds.size(), responses) {
|
||||
if let Some(ref mut bounds) = &mut tool_data.bounding_box_manager {
|
||||
bounds.center_of_transformation += shift;
|
||||
bounds.original_bound_transform.translation += shift;
|
||||
|
|
@ -783,20 +806,26 @@ impl Fsm for SelectToolFsmState {
|
|||
|
||||
self
|
||||
}
|
||||
(SelectToolFsmState::DraggingPivot, SelectToolMessage::ShiftViewport) => {
|
||||
let _ = shift_viewport_if_mouse_beyond_edge(input.mouse.position, input.viewport_bounds.size(), responses);
|
||||
(SelectToolFsmState::DraggingPivot, SelectToolMessage::PointerOutsideViewport(_)) => {
|
||||
let _ = AutoPanning::shift_viewport(input.mouse.position, input.viewport_bounds.size(), responses);
|
||||
|
||||
self
|
||||
}
|
||||
(SelectToolFsmState::DrawingBox, SelectToolMessage::ShiftViewport) => {
|
||||
if let Some(shift) = shift_viewport_if_mouse_beyond_edge(input.mouse.position, input.viewport_bounds.size(), responses) {
|
||||
(SelectToolFsmState::DrawingBox, SelectToolMessage::PointerOutsideViewport(_)) => {
|
||||
if let Some(shift) = AutoPanning::shift_viewport(input.mouse.position, input.viewport_bounds.size(), responses) {
|
||||
tool_data.drag_start += shift;
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
(state, SelectToolMessage::PointerOutsideViewport(modifier_keys)) => {
|
||||
unsubscribe_animation_frame(tool_data, modifier_keys, responses);
|
||||
tool_data.auto_panning.stop(
|
||||
&[
|
||||
SelectToolMessage::PointerOutsideViewport(modifier_keys.clone()).into(),
|
||||
SelectToolMessage::PointerMove(modifier_keys).into(),
|
||||
],
|
||||
responses,
|
||||
);
|
||||
|
||||
state
|
||||
}
|
||||
|
|
@ -1064,68 +1093,3 @@ fn edit_layer_deepest_manipulation(layer: LayerNodeIdentifier, document_network:
|
|||
responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Path });
|
||||
}
|
||||
}
|
||||
|
||||
/// Shifts the viewport when the mouse reaches the edge of the viewport.
|
||||
///
|
||||
/// If the mouse was beyond any edge, it returns the amount shifted. Otherwise it returns None.
|
||||
/// The shift is proportional to the distance between edge and mouse. It is also guaranteed to be integral.
|
||||
fn shift_viewport_if_mouse_beyond_edge(mouse_position: DVec2, viewport_size: DVec2, responses: &mut VecDeque<Message>) -> Option<DVec2> {
|
||||
let mouse_position = mouse_position.clamp(
|
||||
DVec2::ZERO - DVec2::splat(DRAG_BEYOND_VIEWPORT_MAX_OVEREXTENSION_PIXELS),
|
||||
viewport_size + DVec2::splat(DRAG_BEYOND_VIEWPORT_MAX_OVEREXTENSION_PIXELS),
|
||||
);
|
||||
let mouse_position_percent = mouse_position / viewport_size;
|
||||
|
||||
let mut shift_percent = DVec2::ZERO;
|
||||
|
||||
if mouse_position_percent.x < 0. {
|
||||
shift_percent.x = -mouse_position_percent.x;
|
||||
} else if mouse_position_percent.x > 1. {
|
||||
shift_percent.x = 1. - mouse_position_percent.x;
|
||||
}
|
||||
|
||||
if mouse_position_percent.y < 0. {
|
||||
shift_percent.y = -mouse_position_percent.y;
|
||||
} else if mouse_position_percent.y > 1. {
|
||||
shift_percent.y = 1. - mouse_position_percent.y;
|
||||
}
|
||||
|
||||
if shift_percent.x == 0. && shift_percent.y == 0. {
|
||||
return None;
|
||||
}
|
||||
|
||||
let delta = (shift_percent * DRAG_BEYOND_VIEWPORT_SPEED_FACTOR * viewport_size).round();
|
||||
responses.add(NavigationMessage::TranslateCanvas { delta });
|
||||
Some(delta)
|
||||
}
|
||||
|
||||
fn setup_pointer_outside_edge_event(mouse_position: DVec2, viewport_size: DVec2, tool_data: &mut SelectToolData, modifier_keys: SelectToolPointerKeys, responses: &mut VecDeque<Message>) {
|
||||
let is_pointer_outside_edge = mouse_position.x < 0. || mouse_position.x > viewport_size.x || mouse_position.y < 0. || mouse_position.y > viewport_size.y;
|
||||
|
||||
match is_pointer_outside_edge {
|
||||
true => subscribe_animation_frame(tool_data, modifier_keys, responses),
|
||||
false => unsubscribe_animation_frame(tool_data, modifier_keys, responses),
|
||||
}
|
||||
}
|
||||
|
||||
fn subscribe_animation_frame(tool_data: &mut SelectToolData, modifier_keys: SelectToolPointerKeys, responses: &mut VecDeque<Message>) {
|
||||
if !tool_data.subscribed_to_animation_frame {
|
||||
tool_data.subscribed_to_animation_frame = true;
|
||||
|
||||
responses.add(BroadcastMessage::SubscribeEvent {
|
||||
on: BroadcastEvent::AnimationFrame,
|
||||
send: Box::new(SelectToolMessage::PointerOutsideViewport(modifier_keys).into()),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn unsubscribe_animation_frame(tool_data: &mut SelectToolData, modifier_keys: SelectToolPointerKeys, responses: &mut VecDeque<Message>) {
|
||||
if tool_data.subscribed_to_animation_frame {
|
||||
tool_data.subscribed_to_animation_frame = false;
|
||||
|
||||
responses.add(BroadcastMessage::UnsubscribeEvent {
|
||||
on: BroadcastEvent::AnimationFrame,
|
||||
message: Box::new(SelectToolMessage::PointerOutsideViewport(modifier_keys).into()),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue