mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-16 06:38:03 +08:00
Desktop: Support input from drawing tablets (#4354)
This commit is contained in:
58
Cargo.lock
generated
58
Cargo.lock
generated
@@ -1375,7 +1375,8 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "dpi"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/rust-windowing/winit.git#bd6fef1d80ba063cbe91e150b3fb343927cdc72b"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@@ -7669,8 +7670,9 @@ checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
||||
|
||||
[[package]]
|
||||
name = "winit"
|
||||
version = "0.30.12"
|
||||
source = "git+https://github.com/rust-windowing/winit.git#bd6fef1d80ba063cbe91e150b3fb343927cdc72b"
|
||||
version = "0.31.0-beta.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2879d2854d1a43e48f67322d4bd097afcb6eb8f8f775c8de0260a71aea1df1aa"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"cfg_aliases",
|
||||
@@ -7696,8 +7698,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "winit-android"
|
||||
version = "0.30.12"
|
||||
source = "git+https://github.com/rust-windowing/winit.git#bd6fef1d80ba063cbe91e150b3fb343927cdc72b"
|
||||
version = "0.31.0-beta.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51d9c0d2cd93efec3a9f9ad819cfaf0834782403af7c0d248c784ec0c61761df"
|
||||
dependencies = [
|
||||
"android-activity",
|
||||
"bitflags 2.11.0",
|
||||
@@ -7711,8 +7714,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "winit-appkit"
|
||||
version = "0.30.12"
|
||||
source = "git+https://github.com/rust-windowing/winit.git#bd6fef1d80ba063cbe91e150b3fb343927cdc72b"
|
||||
version = "0.31.0-beta.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21310ca07851a49c348e0c2cc768e36b52ca65afda2c2354d78ed4b90074d8aa"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"block2 0.6.2",
|
||||
@@ -7733,8 +7737,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "winit-common"
|
||||
version = "0.30.12"
|
||||
source = "git+https://github.com/rust-windowing/winit.git#bd6fef1d80ba063cbe91e150b3fb343927cdc72b"
|
||||
version = "0.31.0-beta.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45375fbac4cbb77260d83a30b1f9d8105880dbac99a9ae97f56656694680ff69"
|
||||
dependencies = [
|
||||
"memmap2 0.9.10",
|
||||
"objc2 0.6.3",
|
||||
@@ -7748,8 +7753,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "winit-core"
|
||||
version = "0.30.12"
|
||||
source = "git+https://github.com/rust-windowing/winit.git#bd6fef1d80ba063cbe91e150b3fb343927cdc72b"
|
||||
version = "0.31.0-beta.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4f0ccd7abb43740e2c6124ac7cae7d865ecec74eec63783e8922577ac232583"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"cursor-icon",
|
||||
@@ -7763,8 +7769,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "winit-orbital"
|
||||
version = "0.30.12"
|
||||
source = "git+https://github.com/rust-windowing/winit.git#bd6fef1d80ba063cbe91e150b3fb343927cdc72b"
|
||||
version = "0.31.0-beta.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51ea1fb262e7209f265f12bd0cc792c399b14355675e65531e9c8a87db287d46"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"dpi",
|
||||
@@ -7778,8 +7785,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "winit-uikit"
|
||||
version = "0.30.12"
|
||||
source = "git+https://github.com/rust-windowing/winit.git#bd6fef1d80ba063cbe91e150b3fb343927cdc72b"
|
||||
version = "0.31.0-beta.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "680a356e798837d8eb274d4556e83bceaf81698194e31aafc5cfb8a9f2fab643"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"block2 0.6.2",
|
||||
@@ -7799,8 +7807,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "winit-wayland"
|
||||
version = "0.30.12"
|
||||
source = "git+https://github.com/rust-windowing/winit.git#bd6fef1d80ba063cbe91e150b3fb343927cdc72b"
|
||||
version = "0.31.0-beta.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ce5afb2ba07da603f84b722c95f9f9396d2cedae3944fb6c0cda4a6f88de545"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"bitflags 2.11.0",
|
||||
@@ -7825,8 +7834,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "winit-web"
|
||||
version = "0.30.12"
|
||||
source = "git+https://github.com/rust-windowing/winit.git#bd6fef1d80ba063cbe91e150b3fb343927cdc72b"
|
||||
version = "0.31.0-beta.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c2490a953fb776fbbd5e295d54f1c3847f4f15b6c3929ec53c09acda6487a92"
|
||||
dependencies = [
|
||||
"atomic-waker",
|
||||
"bitflags 2.11.0",
|
||||
@@ -7847,8 +7857,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "winit-win32"
|
||||
version = "0.30.12"
|
||||
source = "git+https://github.com/rust-windowing/winit.git#bd6fef1d80ba063cbe91e150b3fb343927cdc72b"
|
||||
version = "0.31.0-beta.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "644ea78af0e858aa3b092e5d1c67c41995a98220c81813f1353b28bc8bb91eaa"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"cursor-icon",
|
||||
@@ -7863,8 +7874,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "winit-x11"
|
||||
version = "0.30.12"
|
||||
source = "git+https://github.com/rust-windowing/winit.git#bd6fef1d80ba063cbe91e150b3fb343927cdc72b"
|
||||
version = "0.31.0-beta.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa5b600756534c7041aa93cd0d244d44b09fca1b89e202bd1cd80dd9f3636c46"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"bytemuck",
|
||||
|
||||
@@ -160,7 +160,7 @@ web-sys = { version = "=0.3.98", features = [
|
||||
"HtmlImageElement",
|
||||
"ImageBitmapRenderingContext",
|
||||
] }
|
||||
winit = { git = "https://github.com/rust-windowing/winit.git" }
|
||||
winit = "0.31.0-beta.2"
|
||||
keyboard-types = "0.8"
|
||||
url = "2.5"
|
||||
tokio = { version = "1.29", features = ["fs", "macros", "io-std", "rt", "rt-multi-thread"] }
|
||||
@@ -260,8 +260,6 @@ lto = "thin"
|
||||
debug = true
|
||||
|
||||
[patch.crates-io]
|
||||
# Force cargo to use only one version of the dpi crate (vendoring breaks without this)
|
||||
dpi = { git = "https://github.com/rust-windowing/winit.git" }
|
||||
rfd = { git = "https://github.com/timon-schelling/rfd.git", branch = "graphite" } # TODO: Remove this once https://github.com/PolyMeilex/rfd/pull/317 is merged and released
|
||||
cef = { git = "https://github.com/timon-schelling/cef-rs.git", branch = "graphite-149" }
|
||||
cef-dll-sys = { git = "https://github.com/timon-schelling/cef-rs.git", branch = "graphite-149" }
|
||||
|
||||
@@ -9,19 +9,21 @@ use std::sync::mpsc::{Receiver, SyncSender};
|
||||
use std::thread;
|
||||
use std::time::{Duration, Instant};
|
||||
use winit::application::ApplicationHandler;
|
||||
use winit::dpi::{PhysicalPosition, PhysicalSize};
|
||||
use winit::event::{ButtonSource, ElementState, MouseButton, StartCause, WindowEvent};
|
||||
use winit::dpi::PhysicalSize;
|
||||
use winit::event::{ElementState, MouseButton, StartCause, WindowEvent};
|
||||
use winit::event_loop::run_on_demand::EventLoopExtRunOnDemand;
|
||||
use winit::event_loop::{ActiveEventLoop, ControlFlow, EventLoop};
|
||||
use winit::window::WindowId;
|
||||
|
||||
use crate::dirs;
|
||||
use crate::event::{AppEvent, AppEventScheduler};
|
||||
use crate::input::{InputAction, InputState};
|
||||
use crate::persist;
|
||||
use crate::preferences;
|
||||
use crate::render::{RenderError, RenderState};
|
||||
use crate::ui::{UiCommand, UiInstance};
|
||||
use crate::window::Window;
|
||||
use crate::wrapper::messages::{DesktopFrontendMessage, DesktopWrapperMessage, InputMessage, MouseKeys, MouseState, Preferences};
|
||||
use crate::wrapper::messages::{DesktopFrontendMessage, DesktopWrapperMessage, Preferences};
|
||||
use crate::wrapper::{DesktopWrapper, MmapResourceStorage, NodeGraphExecutionResult, WgpuContext, serialize_frontend_messages};
|
||||
|
||||
pub(crate) struct App {
|
||||
@@ -33,8 +35,7 @@ pub(crate) struct App {
|
||||
window_maximized: bool,
|
||||
window_fullscreen: bool,
|
||||
window_pending_drag: bool,
|
||||
pointer_position: PhysicalPosition<f64>,
|
||||
pointer_lock_position: Option<PhysicalPosition<f64>>,
|
||||
input_state: InputState,
|
||||
ui_scale: f64,
|
||||
app_event_receiver: Receiver<AppEvent>,
|
||||
app_event_scheduler: AppEventScheduler,
|
||||
@@ -111,8 +112,7 @@ impl App {
|
||||
window_maximized: false,
|
||||
window_fullscreen: false,
|
||||
window_pending_drag: false,
|
||||
pointer_position: Default::default(),
|
||||
pointer_lock_position: Default::default(),
|
||||
input_state: InputState::new(),
|
||||
ui_scale: 1.,
|
||||
app_event_receiver,
|
||||
app_event_scheduler,
|
||||
@@ -130,8 +130,8 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn run(mut self, event_loop: EventLoop) -> ExitReason {
|
||||
event_loop.run_app(&mut self).unwrap();
|
||||
pub(crate) fn run(mut self, mut event_loop: EventLoop) -> ExitReason {
|
||||
event_loop.run_app_on_demand(&mut self).unwrap();
|
||||
self.exit_reason
|
||||
}
|
||||
|
||||
@@ -269,6 +269,8 @@ impl App {
|
||||
});
|
||||
}
|
||||
DesktopFrontendMessage::UpdateViewportPhysicalBounds { x, y, width, height } => {
|
||||
self.input_state.set_viewport_info(x, y, width, height, self.window_scale);
|
||||
|
||||
if let Some(render_state) = &mut self.render_state
|
||||
&& let Some(window) = &self.window
|
||||
{
|
||||
@@ -347,7 +349,7 @@ impl App {
|
||||
}
|
||||
}
|
||||
DesktopFrontendMessage::PointerLock => {
|
||||
self.pointer_lock_position = Some(self.pointer_position);
|
||||
self.input_state.lock_pointer();
|
||||
if let Some(window) = &self.window {
|
||||
window.start_pointer_lock();
|
||||
}
|
||||
@@ -540,14 +542,13 @@ impl ApplicationHandler for App {
|
||||
|
||||
fn window_event(&mut self, _event_loop: &dyn ActiveEventLoop, _window_id: WindowId, event: WindowEvent) {
|
||||
// Handle pointer lock release
|
||||
if let Some(pointer_lock_position) = self.pointer_lock_position
|
||||
&& let WindowEvent::PointerButton {
|
||||
state: ElementState::Released,
|
||||
button: ButtonSource::Mouse(MouseButton::Left),
|
||||
..
|
||||
} = event
|
||||
if let WindowEvent::PointerButton {
|
||||
state: ElementState::Released,
|
||||
button,
|
||||
..
|
||||
} = &event && button.clone().mouse_button() == Some(MouseButton::Left)
|
||||
&& let Some(pointer_lock_position) = self.input_state.unlock_pointer()
|
||||
{
|
||||
self.pointer_lock_position = None;
|
||||
if let Some(window) = &self.window {
|
||||
window.end_pointer_lock();
|
||||
}
|
||||
@@ -559,7 +560,12 @@ impl ApplicationHandler for App {
|
||||
}));
|
||||
}
|
||||
|
||||
self.ui.send(UiCommand::Input(event.clone()));
|
||||
for action in self.input_state.process(&event) {
|
||||
match action {
|
||||
InputAction::Ui(event) => self.ui.send(UiCommand::Input(event)),
|
||||
InputAction::Editor(message) => self.app_event_scheduler.schedule(AppEvent::DesktopWrapperMessage(message)),
|
||||
}
|
||||
}
|
||||
|
||||
match event {
|
||||
WindowEvent::CloseRequested => {
|
||||
@@ -616,50 +622,20 @@ impl ApplicationHandler for App {
|
||||
}
|
||||
}
|
||||
|
||||
// Forward and Back buttons are not supported by CEF and thus need to be directly forwarded the editor
|
||||
WindowEvent::PointerButton {
|
||||
button: ButtonSource::Mouse(button),
|
||||
state: ElementState::Pressed,
|
||||
..
|
||||
} => {
|
||||
let mouse_keys = match button {
|
||||
MouseButton::Back => Some(MouseKeys::BACK),
|
||||
MouseButton::Forward => Some(MouseKeys::FORWARD),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(mouse_keys) = mouse_keys {
|
||||
let message = DesktopWrapperMessage::Input(InputMessage::PointerDown {
|
||||
editor_mouse_state: MouseState { mouse_keys, ..Default::default() },
|
||||
modifier_keys: Default::default(),
|
||||
});
|
||||
self.app_event_scheduler.schedule(AppEvent::DesktopWrapperMessage(message));
|
||||
|
||||
let message = DesktopWrapperMessage::Input(InputMessage::PointerUp {
|
||||
editor_mouse_state: Default::default(),
|
||||
modifier_keys: Default::default(),
|
||||
});
|
||||
self.app_event_scheduler.schedule(AppEvent::DesktopWrapperMessage(message));
|
||||
}
|
||||
}
|
||||
|
||||
WindowEvent::PointerMoved { position, .. } | WindowEvent::PointerLeft { position: Some(position), .. } | WindowEvent::PointerEntered { position, .. }
|
||||
if self.pointer_lock_position.is_none() =>
|
||||
WindowEvent::PointerMoved { .. } | WindowEvent::PointerLeft { position: Some(_), .. } | WindowEvent::PointerEntered { .. }
|
||||
if !self.input_state.pointer_locked() && self.window_pending_drag =>
|
||||
{
|
||||
self.pointer_position = position;
|
||||
|
||||
if self.window_pending_drag {
|
||||
self.window_pending_drag = false;
|
||||
if let Some(window) = &self.window {
|
||||
window.start_drag();
|
||||
}
|
||||
self.window_pending_drag = false;
|
||||
if let Some(window) = &self.window {
|
||||
window.start_drag();
|
||||
}
|
||||
}
|
||||
|
||||
WindowEvent::PointerButton {
|
||||
button: ButtonSource::Mouse(MouseButton::Left),
|
||||
button,
|
||||
state: ElementState::Released,
|
||||
..
|
||||
} => {
|
||||
} if button.clone().mouse_button() == Some(MouseButton::Left) => {
|
||||
self.window_pending_drag = false;
|
||||
}
|
||||
|
||||
@@ -668,7 +644,7 @@ impl ApplicationHandler for App {
|
||||
}
|
||||
|
||||
fn device_event(&mut self, _event_loop: &dyn ActiveEventLoop, _device_id: Option<winit::event::DeviceId>, event: winit::event::DeviceEvent) {
|
||||
if self.pointer_lock_position.is_some()
|
||||
if self.input_state.pointer_locked()
|
||||
&& let winit::event::DeviceEvent::PointerMotion { delta: (x, y) } = event
|
||||
{
|
||||
let message = DesktopWrapperMessage::PointerLockMove { x, y };
|
||||
|
||||
242
desktop/src/input.rs
Normal file
242
desktop/src/input.rs
Normal file
@@ -0,0 +1,242 @@
|
||||
use std::time::Instant;
|
||||
use winit::dpi::PhysicalPosition;
|
||||
use winit::event::{ButtonSource, ElementState, MouseButton, MouseScrollDelta, PointerSource, TabletToolData, TabletToolKind, WindowEvent};
|
||||
|
||||
use crate::ui::{MULTICLICK_ALLOWED_TRAVEL, MULTICLICK_TIMEOUT, PINCH_ZOOM_SPEED, SCROLL_LINE_HEIGHT, SCROLL_LINE_WIDTH, SCROLL_SPEED_X, SCROLL_SPEED_Y};
|
||||
use crate::wrapper::messages::{DesktopWrapperMessage, InputMessage, ModifierKeys, MouseKeys, PointerState, ScrollDelta};
|
||||
|
||||
pub(crate) struct InputState {
|
||||
viewport_info: Option<ViewportInfo>,
|
||||
pointer_lock_position: Option<PhysicalPosition<f64>>,
|
||||
modifier_keys: ModifierKeys,
|
||||
pointer_position: PhysicalPosition<f64>,
|
||||
pointer_keys: MouseKeys,
|
||||
ui_capture: bool,
|
||||
multiclick: Option<Multiclick>,
|
||||
}
|
||||
|
||||
pub(crate) enum InputAction {
|
||||
Ui(WindowEvent),
|
||||
Editor(DesktopWrapperMessage),
|
||||
}
|
||||
|
||||
impl InputAction {
|
||||
fn editor(message: InputMessage) -> Self {
|
||||
Self::Editor(DesktopWrapperMessage::Input(message))
|
||||
}
|
||||
}
|
||||
|
||||
impl InputState {
|
||||
pub(crate) fn new() -> Self {
|
||||
Self {
|
||||
viewport_info: None,
|
||||
pointer_lock_position: None,
|
||||
modifier_keys: ModifierKeys::empty(),
|
||||
pointer_position: PhysicalPosition::default(),
|
||||
pointer_keys: MouseKeys::empty(),
|
||||
ui_capture: true,
|
||||
multiclick: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn set_viewport_info(&mut self, x: f64, y: f64, width: f64, height: f64, scale: f64) {
|
||||
self.viewport_info = Some(ViewportInfo { x, y, width, height, scale });
|
||||
}
|
||||
|
||||
pub(crate) fn lock_pointer(&mut self) {
|
||||
self.pointer_lock_position = Some(self.pointer_position);
|
||||
}
|
||||
|
||||
pub(crate) fn unlock_pointer(&mut self) -> Option<PhysicalPosition<f64>> {
|
||||
let position = self.pointer_lock_position.take();
|
||||
if let Some(position) = position {
|
||||
self.pointer_position = position;
|
||||
}
|
||||
position
|
||||
}
|
||||
|
||||
pub(crate) fn pointer_locked(&self) -> bool {
|
||||
self.pointer_lock_position.is_some()
|
||||
}
|
||||
|
||||
pub(crate) fn process(&mut self, event: &WindowEvent) -> Vec<InputAction> {
|
||||
match event {
|
||||
WindowEvent::PointerMoved { position, source, .. } => {
|
||||
self.pointer_position = *position;
|
||||
|
||||
let PointerSource::TabletTool { kind, data } = source else {
|
||||
return vec![InputAction::Ui(event.clone())];
|
||||
};
|
||||
let ui_capture = if self.pointer_keys.is_empty() {
|
||||
self.pointer_locked() || !self.in_viewport(*position)
|
||||
} else {
|
||||
self.ui_capture
|
||||
};
|
||||
if ui_capture {
|
||||
return vec![InputAction::Ui(event.clone())];
|
||||
}
|
||||
|
||||
vec![InputAction::editor(InputMessage::PointerMove {
|
||||
editor_mouse_state: self.tablet_pointer_state(kind, data),
|
||||
modifier_keys: self.modifier_keys,
|
||||
})]
|
||||
}
|
||||
WindowEvent::PointerEntered { position, .. } | WindowEvent::PointerLeft { position: Some(position), .. } => {
|
||||
self.pointer_position = *position;
|
||||
vec![InputAction::Ui(event.clone())]
|
||||
}
|
||||
WindowEvent::PointerButton { state, button, position, .. } => {
|
||||
self.pointer_position = *position;
|
||||
|
||||
let tablet = matches!(button, ButtonSource::TabletTool { .. });
|
||||
|
||||
// Stroke keeps capture decided from first button press until all buttons are released.
|
||||
if state.is_pressed() && self.pointer_keys.is_empty() {
|
||||
self.ui_capture = self.pointer_locked() || !tablet || !self.in_viewport(*position);
|
||||
}
|
||||
|
||||
let mouse_button = button.clone().mouse_button();
|
||||
let keys = match mouse_button {
|
||||
Some(MouseButton::Left) => MouseKeys::LEFT,
|
||||
Some(MouseButton::Right) => MouseKeys::RIGHT,
|
||||
Some(MouseButton::Middle) => MouseKeys::MIDDLE,
|
||||
Some(MouseButton::Back) => MouseKeys::BACK,
|
||||
Some(MouseButton::Forward) => MouseKeys::FORWARD,
|
||||
_ => MouseKeys::NONE,
|
||||
};
|
||||
match state {
|
||||
ElementState::Pressed => self.pointer_keys.insert(keys),
|
||||
ElementState::Released => self.pointer_keys.remove(keys),
|
||||
}
|
||||
|
||||
let back_or_forward = matches!(mouse_button, Some(MouseButton::Back | MouseButton::Forward));
|
||||
if self.pointer_locked() || !(back_or_forward || (tablet && !self.ui_capture)) {
|
||||
return vec![InputAction::Ui(event.clone())];
|
||||
}
|
||||
|
||||
let editor_mouse_state = match button {
|
||||
ButtonSource::TabletTool { kind, data, .. } => self.tablet_pointer_state(kind, data),
|
||||
_ => self.pointer_state(),
|
||||
};
|
||||
let modifier_keys = self.modifier_keys;
|
||||
match state {
|
||||
ElementState::Pressed => vec![InputAction::editor(InputMessage::PointerDown { editor_mouse_state, modifier_keys })],
|
||||
ElementState::Released => {
|
||||
let mut actions = vec![InputAction::editor(InputMessage::PointerUp { editor_mouse_state, modifier_keys })];
|
||||
if let Some(mouse_button) = mouse_button
|
||||
&& self.track_multiclick(mouse_button, *position)
|
||||
{
|
||||
actions.push(InputAction::editor(InputMessage::DoubleClick {
|
||||
editor_mouse_state: PointerState {
|
||||
mouse_keys: keys,
|
||||
..editor_mouse_state
|
||||
},
|
||||
modifier_keys,
|
||||
}));
|
||||
}
|
||||
actions
|
||||
}
|
||||
}
|
||||
}
|
||||
WindowEvent::MouseWheel { delta, .. } => {
|
||||
if self.pointer_locked() || !self.in_viewport(self.pointer_position) {
|
||||
return vec![InputAction::Ui(event.clone())];
|
||||
}
|
||||
|
||||
let (x, y) = match delta {
|
||||
MouseScrollDelta::LineDelta(x, y) => (f64::from(*x) * SCROLL_LINE_WIDTH, f64::from(*y) * SCROLL_LINE_HEIGHT),
|
||||
MouseScrollDelta::PixelDelta(position) => (position.x, position.y),
|
||||
};
|
||||
|
||||
let scroll_delta = ScrollDelta::new(-x * SCROLL_SPEED_X, -y * SCROLL_SPEED_Y, 0.);
|
||||
|
||||
vec![InputAction::editor(InputMessage::WheelScroll {
|
||||
editor_mouse_state: PointerState { scroll_delta, ..self.pointer_state() },
|
||||
modifier_keys: self.modifier_keys,
|
||||
})]
|
||||
}
|
||||
WindowEvent::PinchGesture { delta, .. } => {
|
||||
if self.pointer_locked() || !self.in_viewport(self.pointer_position) || !delta.is_normal() {
|
||||
return vec![InputAction::Ui(event.clone())];
|
||||
}
|
||||
|
||||
// TODO: This is a temporary solution to handle pinch gestures, we should handle pinch gestures editor-side instead.
|
||||
let scroll_delta = ScrollDelta::new(0., -delta * PINCH_ZOOM_SPEED, 0.);
|
||||
vec![InputAction::editor(InputMessage::WheelScroll {
|
||||
editor_mouse_state: PointerState { scroll_delta, ..self.pointer_state() },
|
||||
modifier_keys: self.modifier_keys | ModifierKeys::CONTROL,
|
||||
})]
|
||||
}
|
||||
WindowEvent::ModifiersChanged(modifiers) => {
|
||||
let modifiers = modifiers.state();
|
||||
self.modifier_keys = ModifierKeys::empty();
|
||||
self.modifier_keys.set(ModifierKeys::SHIFT, modifiers.shift_key());
|
||||
self.modifier_keys.set(ModifierKeys::CONTROL, modifiers.control_key());
|
||||
self.modifier_keys.set(ModifierKeys::ALT, modifiers.alt_key());
|
||||
self.modifier_keys.set(ModifierKeys::META_OR_COMMAND, modifiers.meta_key());
|
||||
|
||||
vec![InputAction::Ui(event.clone())]
|
||||
}
|
||||
_ => vec![InputAction::Ui(event.clone())],
|
||||
}
|
||||
}
|
||||
|
||||
fn scale(&self) -> f64 {
|
||||
self.viewport_info.as_ref().map_or(1., |info| info.scale)
|
||||
}
|
||||
|
||||
fn in_viewport(&self, position: PhysicalPosition<f64>) -> bool {
|
||||
self.viewport_info.as_ref().is_some_and(|info| info.contains(position))
|
||||
}
|
||||
|
||||
fn pointer_state(&self) -> PointerState {
|
||||
PointerState {
|
||||
editor_position: (self.pointer_position.x / self.scale(), self.pointer_position.y / self.scale()).into(),
|
||||
mouse_keys: self.pointer_keys,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn tablet_pointer_state(&self, kind: &TabletToolKind, data: &TabletToolData) -> PointerState {
|
||||
PointerState {
|
||||
pressure: data.force.map(|force| force.normalized(None)),
|
||||
tilt: data.clone().tilt().map(|tilt| (f64::from(tilt.x), f64::from(tilt.y)).into()),
|
||||
twist: data.twist.map(f64::from),
|
||||
wheel: data.tangential_force.map(f64::from),
|
||||
eraser: matches!(kind, TabletToolKind::Eraser),
|
||||
..self.pointer_state()
|
||||
}
|
||||
}
|
||||
|
||||
fn track_multiclick(&mut self, button: MouseButton, position: PhysicalPosition<f64>) -> bool {
|
||||
let now = Instant::now();
|
||||
let travel = MULTICLICK_ALLOWED_TRAVEL as f64;
|
||||
let double = self.multiclick.take().is_some_and(|click| {
|
||||
click.button == button && now.duration_since(click.time) <= MULTICLICK_TIMEOUT && (position.x - click.position.x).abs() <= travel && (position.y - click.position.y).abs() <= travel
|
||||
});
|
||||
if !double {
|
||||
self.multiclick = Some(Multiclick { button, time: now, position });
|
||||
}
|
||||
double
|
||||
}
|
||||
}
|
||||
|
||||
struct ViewportInfo {
|
||||
x: f64,
|
||||
y: f64,
|
||||
width: f64,
|
||||
height: f64,
|
||||
scale: f64,
|
||||
}
|
||||
|
||||
impl ViewportInfo {
|
||||
fn contains(&self, position: PhysicalPosition<f64>) -> bool {
|
||||
position.x >= self.x && position.y >= self.y && position.x <= self.x + self.width && position.y <= self.y + self.height
|
||||
}
|
||||
}
|
||||
|
||||
struct Multiclick {
|
||||
button: MouseButton,
|
||||
time: Instant,
|
||||
position: PhysicalPosition<f64>,
|
||||
}
|
||||
@@ -17,6 +17,7 @@ mod cli;
|
||||
mod dirs;
|
||||
mod event;
|
||||
mod gpu_context;
|
||||
mod input;
|
||||
mod persist;
|
||||
mod preferences;
|
||||
mod render;
|
||||
|
||||
@@ -344,6 +344,14 @@ unsafe fn position_helper(main: HWND, helper: HWND) {
|
||||
let h = (r.bottom - r.top) + RESIZE_BAND_THICKNESS * 2;
|
||||
|
||||
let _ = unsafe { SetWindowPos(helper, Some(main), x, y, w, h, SWP_NOACTIVATE | SWP_NOSENDCHANGING) };
|
||||
|
||||
let outer = unsafe { CreateRectRgn(0, 0, w, h) };
|
||||
let inner = unsafe { CreateRectRgn(RESIZE_BAND_THICKNESS, RESIZE_BAND_THICKNESS, w - RESIZE_BAND_THICKNESS, h - RESIZE_BAND_THICKNESS) };
|
||||
let _ = unsafe { CombineRgn(Some(outer), Some(outer), Some(inner), RGN_DIFF) };
|
||||
let _ = unsafe { DeleteObject(inner.into()) };
|
||||
if unsafe { SetWindowRgn(helper, Some(outer), false) } == 0 {
|
||||
let _ = unsafe { DeleteObject(outer.into()) };
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn calculate_hit(helper: HWND, lparam: LPARAM) -> u32 {
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
use std::time::Duration;
|
||||
|
||||
pub const MULTICLICK_TIMEOUT: Duration = Duration::from_millis(500);
|
||||
pub const MULTICLICK_ALLOWED_TRAVEL: usize = 4;
|
||||
|
||||
pub const SCROLL_LINE_HEIGHT: f64 = 40.;
|
||||
pub const SCROLL_LINE_WIDTH: f64 = 40.;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub const SCROLL_SPEED_X: f64 = 3.;
|
||||
#[cfg(target_os = "linux")]
|
||||
pub const SCROLL_SPEED_Y: f64 = 3.;
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
pub const SCROLL_SPEED_X: f64 = 1.;
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
pub const SCROLL_SPEED_Y: f64 = 1.;
|
||||
|
||||
pub const PINCH_ZOOM_SPEED: f64 = 300.;
|
||||
|
||||
pub(crate) const RESOURCE_SCHEME: &str = "resources";
|
||||
pub(crate) const RESOURCE_DOMAIN: &str = "resources";
|
||||
|
||||
@@ -17,21 +35,3 @@ pub(crate) const HOST_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub(crate) const IPC_BOOTSTRAP_PREFIX: &str = "art.graphite.Graphite.ipc.";
|
||||
|
||||
pub(crate) const SCROLL_LINE_HEIGHT: usize = 40;
|
||||
pub(crate) const SCROLL_LINE_WIDTH: usize = 40;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub(crate) const SCROLL_SPEED_X: f32 = 3.;
|
||||
#[cfg(target_os = "linux")]
|
||||
pub(crate) const SCROLL_SPEED_Y: f32 = 3.;
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
pub(crate) const SCROLL_SPEED_X: f32 = 1.;
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
pub(crate) const SCROLL_SPEED_Y: f32 = 1.;
|
||||
|
||||
pub(crate) const PINCH_ZOOM_SPEED: f64 = 300.;
|
||||
|
||||
pub(crate) const MULTICLICK_TIMEOUT: Duration = Duration::from_millis(500);
|
||||
pub(crate) const MULTICLICK_ALLOWED_TRAVEL: usize = 4;
|
||||
|
||||
@@ -82,14 +82,16 @@ pub(crate) fn translate(input_state: &mut InputState, event: &WindowEvent) -> Ve
|
||||
}
|
||||
WindowEvent::PointerButton { state, button, position, .. } => {
|
||||
let mouse_button = match button {
|
||||
ButtonSource::Mouse(mouse_button) => mouse_button,
|
||||
_ => {
|
||||
return Vec::new(); // TODO: Handle touch input
|
||||
}
|
||||
ButtonSource::Mouse(mouse_button) => Some(*mouse_button),
|
||||
ButtonSource::TabletTool { button, .. } => (*button).into(),
|
||||
_ => None, // TODO: Handle touch input
|
||||
};
|
||||
let Some(mouse_button) = mouse_button else {
|
||||
return Vec::new();
|
||||
};
|
||||
|
||||
let _ = input_state.cursor_move(position);
|
||||
let click_count = input_state.mouse_input(mouse_button, state).into();
|
||||
let click_count = input_state.mouse_input(&mouse_button, state).into();
|
||||
let up = matches!(state, ElementState::Released);
|
||||
let button = match mouse_button {
|
||||
MouseButton::Left => MouseButtonKind::Left,
|
||||
@@ -110,8 +112,8 @@ pub(crate) fn translate(input_state: &mut InputState, event: &WindowEvent) -> Ve
|
||||
MouseScrollDelta::LineDelta(x, y) => (x * SCROLL_LINE_WIDTH as f32, y * SCROLL_LINE_HEIGHT as f32),
|
||||
MouseScrollDelta::PixelDelta(physical_position) => (physical_position.x as f32, physical_position.y as f32),
|
||||
};
|
||||
delta_x *= SCROLL_SPEED_X;
|
||||
delta_y *= SCROLL_SPEED_Y;
|
||||
delta_x *= SCROLL_SPEED_X as f32;
|
||||
delta_y *= SCROLL_SPEED_Y as f32;
|
||||
|
||||
vec![InputEvent::MouseWheel {
|
||||
data: input_state.mouse_data(),
|
||||
|
||||
@@ -22,6 +22,8 @@ mod resources;
|
||||
mod utility;
|
||||
mod view;
|
||||
|
||||
pub use consts::{MULTICLICK_ALLOWED_TRAVEL, MULTICLICK_TIMEOUT, PINCH_ZOOM_SPEED, SCROLL_LINE_HEIGHT, SCROLL_LINE_WIDTH, SCROLL_SPEED_X, SCROLL_SPEED_Y};
|
||||
|
||||
pub struct UiContext<S: Stage = Started> {
|
||||
inner: S::ContextData,
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ use std::path::PathBuf;
|
||||
pub(crate) use graphite_editor::messages::prelude::Message as EditorMessage;
|
||||
|
||||
pub use graphite_editor::messages::frontend::utility_types::{DocumentInfo, PersistedState};
|
||||
pub use graphite_editor::messages::input_mapper::utility_types::input_keyboard::{Key, ModifierKeys};
|
||||
pub use graphite_editor::messages::input_mapper::utility_types::input_mouse::{EditorMouseState as MouseState, EditorPosition as Position, MouseKeys};
|
||||
pub use graphite_editor::messages::input_mapper::utility_types::keyboard::{Key, ModifierKeys};
|
||||
pub use graphite_editor::messages::input_mapper::utility_types::pointer::{EditorPointerState as PointerState, EditorPosition as Position, MouseKeys, ScrollDelta};
|
||||
pub use graphite_editor::messages::prelude::DocumentId;
|
||||
pub use graphite_editor::messages::prelude::InputPreprocessorMessage as InputMessage;
|
||||
pub use graphite_editor::messages::prelude::PreferencesMessageHandler as Preferences;
|
||||
|
||||
@@ -3,7 +3,7 @@ pub(crate) mod menu {
|
||||
use base64::engine::Engine;
|
||||
use base64::engine::general_purpose::STANDARD as BASE64;
|
||||
|
||||
use graphite_editor::messages::input_mapper::utility_types::input_keyboard::{Key, LabeledKeyOrMouseMotion, LabeledShortcut};
|
||||
use graphite_editor::messages::input_mapper::utility_types::keyboard::{Key, LabeledKeyOrMouseMotion, LabeledShortcut};
|
||||
use graphite_editor::messages::input_mapper::utility_types::misc::ActionShortcut;
|
||||
use graphite_editor::messages::layout::LayoutMessage;
|
||||
use graphite_editor::messages::tool::tool_messages::tool_prelude::{Layout, LayoutGroup, LayoutTarget, MenuListEntry, Widget, WidgetId, WidgetRow};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::Key;
|
||||
use crate::messages::input_mapper::utility_types::input_mouse::MouseButton;
|
||||
use crate::messages::input_mapper::utility_types::keyboard::Key;
|
||||
use crate::messages::input_mapper::utility_types::pointer::MouseButton;
|
||||
use crate::messages::prelude::*;
|
||||
|
||||
#[impl_message(Message, KeyMappingMessage, Lookup)]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use super::utility_types::input_keyboard::KeysGroup;
|
||||
use super::utility_types::keyboard::KeysGroup;
|
||||
use super::utility_types::misc::Mapping;
|
||||
use crate::application::Editor;
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::{self, Key};
|
||||
use crate::messages::input_mapper::utility_types::keyboard::{self, Key};
|
||||
use crate::messages::input_mapper::utility_types::misc::MappingEntry;
|
||||
use crate::messages::prelude::*;
|
||||
|
||||
@@ -58,7 +58,7 @@ impl InputMapperMessageHandler {
|
||||
.map(|i| {
|
||||
// TODO: Use a safe solution eventually
|
||||
assert!(
|
||||
i < input_keyboard::NUMBER_OF_KEYS,
|
||||
i < keyboard::NUMBER_OF_KEYS,
|
||||
"Attempting to convert a Key with enum index {i}, which is larger than the number of Key enums",
|
||||
);
|
||||
(i as u8).try_into().unwrap()
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use crate::application::Editor;
|
||||
use crate::consts::{BIG_NUDGE_AMOUNT, BRUSH_SIZE_CHANGE_KEYBOARD, NUDGE_AMOUNT};
|
||||
use crate::messages::input_mapper::key_mapping::MappingVariant;
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, KeyStates};
|
||||
use crate::messages::input_mapper::utility_types::input_mouse::MouseButton;
|
||||
use crate::messages::input_mapper::utility_types::keyboard::{Key, KeyStates};
|
||||
use crate::messages::input_mapper::utility_types::macros::*;
|
||||
use crate::messages::input_mapper::utility_types::misc::MappingEntry;
|
||||
use crate::messages::input_mapper::utility_types::misc::{KeyMappingEntries, Mapping};
|
||||
use crate::messages::input_mapper::utility_types::pointer::MouseButton;
|
||||
use crate::messages::portfolio::document::node_graph::utility_types::Direction;
|
||||
use crate::messages::portfolio::document::utility_types::misc::GroupFolderType;
|
||||
use crate::messages::prelude::*;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::messages::input_mapper::input_mapper_message_handler::InputMapperMessageContext;
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::KeysGroup;
|
||||
use crate::messages::input_mapper::utility_types::keyboard::KeysGroup;
|
||||
use crate::messages::prelude::*;
|
||||
|
||||
#[derive(ExtractField)]
|
||||
|
||||
@@ -162,7 +162,7 @@ macro_rules! action_shortcut {
|
||||
macro_rules! action_shortcut_manual {
|
||||
($($keys:expr),*) => {
|
||||
Some(crate::messages::input_mapper::utility_types::misc::ActionShortcut::Shortcut(
|
||||
crate::messages::input_mapper::utility_types::input_keyboard::LabeledShortcut(vec![$($keys.into()),*]).into(),
|
||||
crate::messages::input_mapper::utility_types::keyboard::LabeledShortcut(vec![$($keys.into()),*]).into(),
|
||||
))
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use super::input_keyboard::{KeysGroup, LabeledShortcut, all_required_modifiers_pressed};
|
||||
use super::keyboard::{KeysGroup, LabeledShortcut, all_required_modifiers_pressed};
|
||||
use crate::messages::input_mapper::key_mapping::MappingVariant;
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::{KeyStates, NUMBER_OF_KEYS};
|
||||
use crate::messages::input_mapper::utility_types::input_mouse::NUMBER_OF_MOUSE_BUTTONS;
|
||||
use crate::messages::input_mapper::utility_types::keyboard::{KeyStates, NUMBER_OF_KEYS};
|
||||
use crate::messages::input_mapper::utility_types::pointer::NUMBER_OF_MOUSE_BUTTONS;
|
||||
use crate::messages::prelude::*;
|
||||
use core::time::Duration;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
pub mod input_keyboard;
|
||||
pub mod input_mouse;
|
||||
pub mod keyboard;
|
||||
pub mod pointer;
|
||||
|
||||
pub mod macros;
|
||||
pub mod misc;
|
||||
|
||||
@@ -50,15 +50,20 @@ impl ScrollDelta {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Document the difference between this and EditorMouseState
|
||||
// TODO: Document the difference between this and EditorPointerState
|
||||
#[derive(Debug, Copy, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct MouseState {
|
||||
pub struct PointerState {
|
||||
pub position: ViewportPosition,
|
||||
pub mouse_keys: MouseKeys,
|
||||
pub scroll_delta: ScrollDelta,
|
||||
pub pressure: Option<f64>,
|
||||
pub tilt: Option<DVec2>,
|
||||
pub twist: Option<f64>,
|
||||
pub wheel: Option<f64>,
|
||||
pub eraser: bool,
|
||||
}
|
||||
|
||||
impl MouseState {
|
||||
impl PointerState {
|
||||
pub fn finish_transaction(&self, drag_start: DVec2, responses: &mut VecDeque<Message>) {
|
||||
let drag_too_small = drag_start.distance(self.position) <= DRAG_THRESHOLD;
|
||||
let response = if drag_too_small { DocumentMessage::AbortTransaction } else { DocumentMessage::EndTransaction };
|
||||
@@ -66,15 +71,20 @@ impl MouseState {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Document the difference between this and MouseState
|
||||
// TODO: Document the difference between this and PointerState
|
||||
#[derive(Debug, Copy, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct EditorMouseState {
|
||||
pub struct EditorPointerState {
|
||||
pub editor_position: EditorPosition,
|
||||
pub mouse_keys: MouseKeys,
|
||||
pub scroll_delta: ScrollDelta,
|
||||
pub pressure: Option<f64>,
|
||||
pub tilt: Option<DVec2>,
|
||||
pub twist: Option<f64>,
|
||||
pub wheel: Option<f64>,
|
||||
pub eraser: bool,
|
||||
}
|
||||
|
||||
impl EditorMouseState {
|
||||
impl EditorPointerState {
|
||||
pub fn from_keys_and_editor_position(keys: u8, editor_position: EditorPosition) -> Self {
|
||||
// TODO: Some graphic tablets send key codes not mentioned in the spec. In the future we would like to support these as well.
|
||||
let mouse_keys = MouseKeys::from_bits_truncate(keys);
|
||||
@@ -82,15 +92,20 @@ impl EditorMouseState {
|
||||
Self {
|
||||
editor_position,
|
||||
mouse_keys,
|
||||
scroll_delta: ScrollDelta::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_mouse_state(&self, viewport: &ViewportMessageHandler) -> MouseState {
|
||||
MouseState {
|
||||
pub fn to_pointer_state(&self, viewport: &ViewportMessageHandler) -> PointerState {
|
||||
PointerState {
|
||||
position: (viewport.logical(self.editor_position) - viewport.offset()).into(),
|
||||
mouse_keys: self.mouse_keys,
|
||||
scroll_delta: self.scroll_delta,
|
||||
pressure: self.pressure,
|
||||
tilt: self.tilt,
|
||||
twist: self.twist,
|
||||
wheel: self.wheel,
|
||||
eraser: self.eraser,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, ModifierKeys};
|
||||
use crate::messages::input_mapper::utility_types::input_mouse::EditorMouseState;
|
||||
use crate::messages::input_mapper::utility_types::keyboard::{Key, ModifierKeys};
|
||||
use crate::messages::input_mapper::utility_types::pointer::EditorPointerState;
|
||||
use crate::messages::prelude::*;
|
||||
|
||||
#[impl_message(Message, InputPreprocessor)]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum InputPreprocessorMessage {
|
||||
DoubleClick { editor_mouse_state: EditorMouseState, modifier_keys: ModifierKeys },
|
||||
DoubleClick { editor_mouse_state: EditorPointerState, modifier_keys: ModifierKeys },
|
||||
KeyDown { key: Key, key_repeat: bool, modifier_keys: ModifierKeys },
|
||||
KeyUp { key: Key, key_repeat: bool, modifier_keys: ModifierKeys },
|
||||
PointerDown { editor_mouse_state: EditorMouseState, modifier_keys: ModifierKeys },
|
||||
PointerMove { editor_mouse_state: EditorMouseState, modifier_keys: ModifierKeys },
|
||||
PointerUp { editor_mouse_state: EditorMouseState, modifier_keys: ModifierKeys },
|
||||
PointerShake { editor_mouse_state: EditorMouseState, modifier_keys: ModifierKeys },
|
||||
PointerDown { editor_mouse_state: EditorPointerState, modifier_keys: ModifierKeys },
|
||||
PointerMove { editor_mouse_state: EditorPointerState, modifier_keys: ModifierKeys },
|
||||
PointerUp { editor_mouse_state: EditorPointerState, modifier_keys: ModifierKeys },
|
||||
PointerShake { editor_mouse_state: EditorPointerState, modifier_keys: ModifierKeys },
|
||||
CurrentTime { timestamp: u64 },
|
||||
WheelScroll { editor_mouse_state: EditorMouseState, modifier_keys: ModifierKeys },
|
||||
WheelScroll { editor_mouse_state: EditorPointerState, modifier_keys: ModifierKeys },
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::application::Editor;
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, KeyStates, ModifierKeys};
|
||||
use crate::messages::input_mapper::utility_types::input_mouse::{MouseButton, MouseKeys, MouseState};
|
||||
use crate::messages::input_mapper::utility_types::keyboard::{Key, KeyStates, ModifierKeys};
|
||||
use crate::messages::input_mapper::utility_types::misc::FrameTimeInfo;
|
||||
use crate::messages::input_mapper::utility_types::pointer::{MouseButton, MouseKeys, PointerState};
|
||||
use crate::messages::prelude::*;
|
||||
use std::time::Duration;
|
||||
|
||||
@@ -15,7 +15,7 @@ pub struct InputPreprocessorMessageHandler {
|
||||
pub frame_time: FrameTimeInfo,
|
||||
pub time: u64,
|
||||
pub keyboard: KeyStates,
|
||||
pub mouse: MouseState,
|
||||
pub mouse: PointerState,
|
||||
}
|
||||
|
||||
#[message_handler_data]
|
||||
@@ -27,10 +27,10 @@ impl<'a> MessageHandler<InputPreprocessorMessage, InputPreprocessorMessageContex
|
||||
InputPreprocessorMessage::DoubleClick { editor_mouse_state, modifier_keys } => {
|
||||
self.update_states_of_modifier_keys(modifier_keys, responses);
|
||||
|
||||
let mouse_state = editor_mouse_state.to_mouse_state(viewport);
|
||||
self.mouse.position = mouse_state.position;
|
||||
let pointer_state = editor_mouse_state.to_pointer_state(viewport);
|
||||
self.mouse.position = pointer_state.position;
|
||||
|
||||
for key in mouse_state.mouse_keys {
|
||||
for key in pointer_state.mouse_keys {
|
||||
responses.add(InputMapperMessage::DoubleClick(match key {
|
||||
MouseKeys::LEFT => MouseButton::Left,
|
||||
MouseKeys::RIGHT => MouseButton::Right,
|
||||
@@ -60,35 +60,35 @@ impl<'a> MessageHandler<InputPreprocessorMessage, InputPreprocessorMessageContex
|
||||
InputPreprocessorMessage::PointerDown { editor_mouse_state, modifier_keys } => {
|
||||
self.update_states_of_modifier_keys(modifier_keys, responses);
|
||||
|
||||
let mouse_state = editor_mouse_state.to_mouse_state(viewport);
|
||||
self.mouse.position = mouse_state.position;
|
||||
let pointer_state = editor_mouse_state.to_pointer_state(viewport);
|
||||
self.mouse.position = pointer_state.position;
|
||||
|
||||
self.translate_mouse_event(mouse_state, true, responses);
|
||||
self.translate_mouse_event(pointer_state, true, responses);
|
||||
}
|
||||
InputPreprocessorMessage::PointerMove { editor_mouse_state, modifier_keys } => {
|
||||
self.update_states_of_modifier_keys(modifier_keys, responses);
|
||||
|
||||
let mouse_state = editor_mouse_state.to_mouse_state(viewport);
|
||||
self.mouse.position = mouse_state.position;
|
||||
let pointer_state = editor_mouse_state.to_pointer_state(viewport);
|
||||
self.mouse.position = pointer_state.position;
|
||||
|
||||
responses.add(InputMapperMessage::PointerMove);
|
||||
|
||||
// While any pointer button is already down, additional button down events are not reported, but they are sent as `pointermove` events
|
||||
self.translate_mouse_event(mouse_state, false, responses);
|
||||
self.translate_mouse_event(pointer_state, false, responses);
|
||||
}
|
||||
InputPreprocessorMessage::PointerUp { editor_mouse_state, modifier_keys } => {
|
||||
self.update_states_of_modifier_keys(modifier_keys, responses);
|
||||
|
||||
let mouse_state = editor_mouse_state.to_mouse_state(viewport);
|
||||
self.mouse.position = mouse_state.position;
|
||||
let pointer_state = editor_mouse_state.to_pointer_state(viewport);
|
||||
self.mouse.position = pointer_state.position;
|
||||
|
||||
self.translate_mouse_event(mouse_state, false, responses);
|
||||
self.translate_mouse_event(pointer_state, false, responses);
|
||||
}
|
||||
InputPreprocessorMessage::PointerShake { editor_mouse_state, modifier_keys } => {
|
||||
self.update_states_of_modifier_keys(modifier_keys, responses);
|
||||
|
||||
let mouse_state = editor_mouse_state.to_mouse_state(viewport);
|
||||
self.mouse.position = mouse_state.position;
|
||||
let pointer_state = editor_mouse_state.to_pointer_state(viewport);
|
||||
self.mouse.position = pointer_state.position;
|
||||
|
||||
responses.add(InputMapperMessage::PointerShake);
|
||||
}
|
||||
@@ -100,9 +100,9 @@ impl<'a> MessageHandler<InputPreprocessorMessage, InputPreprocessorMessageContex
|
||||
InputPreprocessorMessage::WheelScroll { editor_mouse_state, modifier_keys } => {
|
||||
self.update_states_of_modifier_keys(modifier_keys, responses);
|
||||
|
||||
let mouse_state = editor_mouse_state.to_mouse_state(viewport);
|
||||
self.mouse.position = mouse_state.position;
|
||||
self.mouse.scroll_delta = mouse_state.scroll_delta;
|
||||
let pointer_state = editor_mouse_state.to_pointer_state(viewport);
|
||||
self.mouse.position = pointer_state.position;
|
||||
self.mouse.scroll_delta = pointer_state.scroll_delta;
|
||||
|
||||
responses.add(InputMapperMessage::WheelScroll);
|
||||
}
|
||||
@@ -116,7 +116,7 @@ impl<'a> MessageHandler<InputPreprocessorMessage, InputPreprocessorMessageContex
|
||||
}
|
||||
|
||||
impl InputPreprocessorMessageHandler {
|
||||
fn translate_mouse_event(&mut self, mut new_state: MouseState, allow_first_button_down: bool, responses: &mut VecDeque<Message>) {
|
||||
fn translate_mouse_event(&mut self, mut new_state: PointerState, allow_first_button_down: bool, responses: &mut VecDeque<Message>) {
|
||||
let click_mappings = [
|
||||
(MouseKeys::LEFT, Key::MouseLeft),
|
||||
(MouseKeys::RIGHT, Key::MouseRight),
|
||||
@@ -185,18 +185,17 @@ impl InputPreprocessorMessageHandler {
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, ModifierKeys};
|
||||
use crate::messages::input_mapper::utility_types::input_mouse::{EditorMouseState, MouseKeys, ScrollDelta};
|
||||
use crate::messages::input_mapper::utility_types::keyboard::{Key, ModifierKeys};
|
||||
use crate::messages::input_mapper::utility_types::pointer::EditorPointerState;
|
||||
use crate::messages::prelude::*;
|
||||
|
||||
#[test]
|
||||
fn process_action_mouse_move_handle_modifier_keys() {
|
||||
let mut input_preprocessor = InputPreprocessorMessageHandler::default();
|
||||
|
||||
let editor_mouse_state = EditorMouseState {
|
||||
let editor_mouse_state = EditorPointerState {
|
||||
editor_position: (4., 809.).into(),
|
||||
mouse_keys: MouseKeys::default(),
|
||||
scroll_delta: ScrollDelta::default(),
|
||||
..Default::default()
|
||||
};
|
||||
let modifier_keys = ModifierKeys::ALT;
|
||||
let message = InputPreprocessorMessage::PointerMove { editor_mouse_state, modifier_keys };
|
||||
@@ -216,7 +215,7 @@ mod test {
|
||||
fn process_action_mouse_down_handle_modifier_keys() {
|
||||
let mut input_preprocessor = InputPreprocessorMessageHandler::default();
|
||||
|
||||
let editor_mouse_state = EditorMouseState::default();
|
||||
let editor_mouse_state = EditorPointerState::default();
|
||||
let modifier_keys = ModifierKeys::CONTROL;
|
||||
let message = InputPreprocessorMessage::PointerDown { editor_mouse_state, modifier_keys };
|
||||
|
||||
@@ -235,7 +234,7 @@ mod test {
|
||||
fn process_action_mouse_up_handle_modifier_keys() {
|
||||
let mut input_preprocessor = InputPreprocessorMessageHandler::default();
|
||||
|
||||
let editor_mouse_state = EditorMouseState::default();
|
||||
let editor_mouse_state = EditorPointerState::default();
|
||||
let modifier_keys = ModifierKeys::SHIFT;
|
||||
let message = InputPreprocessorMessage::PointerUp { editor_mouse_state, modifier_keys };
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::KeysGroup;
|
||||
use crate::messages::input_mapper::utility_types::keyboard::KeysGroup;
|
||||
use crate::messages::layout::utility_types::widget_prelude::*;
|
||||
use crate::messages::portfolio::document::node_graph::document_node_definitions::DefinitionIdentifier;
|
||||
use crate::messages::prelude::*;
|
||||
|
||||
@@ -2,7 +2,7 @@ use super::widgets::button_widgets::*;
|
||||
use super::widgets::input_widgets::*;
|
||||
use super::widgets::label_widgets::*;
|
||||
use crate::application::generate_uuid;
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::KeysGroup;
|
||||
use crate::messages::input_mapper::utility_types::keyboard::KeysGroup;
|
||||
use crate::messages::prelude::*;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::utility_types::misc::{GroupFolderType, SnappingState};
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::Key;
|
||||
use crate::messages::input_mapper::utility_types::keyboard::Key;
|
||||
use crate::messages::portfolio::document::data_panel::DataPanelMessage;
|
||||
use crate::messages::portfolio::document::overlays::utility_types::{OverlayContext, OverlaysType};
|
||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::Key;
|
||||
use crate::messages::input_mapper::utility_types::keyboard::Key;
|
||||
use crate::messages::prelude::*;
|
||||
use glam::DVec2;
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ use crate::consts::{
|
||||
VIEWPORT_ZOOM_TO_FIT_PADDING_SCALE_FACTOR,
|
||||
};
|
||||
use crate::messages::frontend::utility_types::MouseCursorIcon;
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion};
|
||||
use crate::messages::input_mapper::utility_types::input_mouse::ViewportPosition;
|
||||
use crate::messages::input_mapper::utility_types::keyboard::{Key, MouseMotion};
|
||||
use crate::messages::input_mapper::utility_types::pointer::ViewportPosition;
|
||||
use crate::messages::portfolio::document::navigation::utility_types::NavigationOperation;
|
||||
use crate::messages::portfolio::document::utility_types::misc::PTZ;
|
||||
use crate::messages::portfolio::document::utility_types::network_interface::NodeNetworkInterface;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::utility_types::Direction;
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::Key;
|
||||
use crate::messages::input_mapper::utility_types::keyboard::Key;
|
||||
use crate::messages::portfolio::document::node_graph::document_node_definitions::DefinitionIdentifier;
|
||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||
use crate::messages::portfolio::document::utility_types::network_interface::{ImportOrExport, InputConnector, NodeTemplate, OutputConnector};
|
||||
|
||||
@@ -392,7 +392,7 @@ impl TransformOperation {
|
||||
}
|
||||
|
||||
pub fn hints(&self, responses: &mut VecDeque<Message>, local: bool) {
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion};
|
||||
use crate::messages::input_mapper::utility_types::keyboard::{Key, MouseMotion};
|
||||
use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo};
|
||||
|
||||
let mut input_hints = Vec::new();
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::consts::{DEFAULT_DOCUMENT_NAME, FILE_EXTENSION, GDD_FILE_EXTENSION};
|
||||
use crate::messages::animation::TimingInformation;
|
||||
use crate::messages::dialog::simple_dialogs;
|
||||
use crate::messages::frontend::utility_types::{DocumentInfo, PersistedState};
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::Key;
|
||||
use crate::messages::input_mapper::utility_types::keyboard::Key;
|
||||
use crate::messages::input_mapper::utility_types::macros::{action_shortcut, action_shortcut_manual};
|
||||
use crate::messages::layout::utility_types::widget_prelude::*;
|
||||
use crate::messages::portfolio::document::DocumentMessageContext;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::Key;
|
||||
use crate::messages::input_mapper::utility_types::keyboard::Key;
|
||||
use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn;
|
||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||
use crate::messages::prelude::*;
|
||||
|
||||
@@ -420,7 +420,7 @@ fn extend_path_with_next_segment(tool_data: &mut FreehandToolData, position: DVe
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_freehand {
|
||||
use crate::messages::input_mapper::utility_types::input_mouse::{EditorMouseState, MouseKeys, ScrollDelta};
|
||||
use crate::messages::input_mapper::utility_types::pointer::{EditorPointerState, MouseKeys};
|
||||
use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn;
|
||||
use crate::messages::tool::common_functionality::graph_modification_utils::{NodeGraphLayer, get_stroke_width};
|
||||
use crate::messages::tool::common_functionality::stroke_options::StrokeOptionsUpdate;
|
||||
@@ -528,10 +528,10 @@ mod test_freehand {
|
||||
let last_initial_point = initial_points[initial_points.len() - 1];
|
||||
editor
|
||||
.mouseup(
|
||||
EditorMouseState {
|
||||
EditorPointerState {
|
||||
editor_position: last_initial_point,
|
||||
mouse_keys: MouseKeys::empty(),
|
||||
scroll_delta: ScrollDelta::default(),
|
||||
..Default::default()
|
||||
},
|
||||
ModifierKeys::empty(),
|
||||
)
|
||||
@@ -587,10 +587,10 @@ mod test_freehand {
|
||||
let last_extension_point = extension_points[extension_points.len() - 1];
|
||||
editor
|
||||
.mouseup(
|
||||
EditorMouseState {
|
||||
EditorPointerState {
|
||||
editor_position: last_extension_point,
|
||||
mouse_keys: MouseKeys::empty(),
|
||||
scroll_delta: ScrollDelta::default(),
|
||||
..Default::default()
|
||||
},
|
||||
ModifierKeys::empty(),
|
||||
)
|
||||
@@ -641,10 +641,10 @@ mod test_freehand {
|
||||
let last_initial_point = initial_points[initial_points.len() - 1];
|
||||
editor
|
||||
.mouseup(
|
||||
EditorMouseState {
|
||||
EditorPointerState {
|
||||
editor_position: last_initial_point,
|
||||
mouse_keys: MouseKeys::empty(),
|
||||
scroll_delta: ScrollDelta::default(),
|
||||
..Default::default()
|
||||
},
|
||||
ModifierKeys::empty(),
|
||||
)
|
||||
@@ -676,10 +676,10 @@ mod test_freehand {
|
||||
|
||||
editor
|
||||
.mousedown(
|
||||
EditorMouseState {
|
||||
EditorPointerState {
|
||||
editor_position: first_second_point,
|
||||
mouse_keys: MouseKeys::LEFT,
|
||||
scroll_delta: ScrollDelta::default(),
|
||||
..Default::default()
|
||||
},
|
||||
ModifierKeys::SHIFT,
|
||||
)
|
||||
@@ -692,10 +692,10 @@ mod test_freehand {
|
||||
let last_second_point = second_path_points[second_path_points.len() - 1];
|
||||
editor
|
||||
.mouseup(
|
||||
EditorMouseState {
|
||||
EditorPointerState {
|
||||
editor_position: last_second_point,
|
||||
mouse_keys: MouseKeys::empty(),
|
||||
scroll_delta: ScrollDelta::default(),
|
||||
..Default::default()
|
||||
},
|
||||
ModifierKeys::SHIFT,
|
||||
)
|
||||
@@ -765,10 +765,10 @@ mod test_freehand {
|
||||
let last_point = points[points.len() - 1];
|
||||
editor
|
||||
.mouseup(
|
||||
EditorMouseState {
|
||||
EditorPointerState {
|
||||
editor_position: last_point,
|
||||
mouse_keys: MouseKeys::empty(),
|
||||
scroll_delta: ScrollDelta::default(),
|
||||
..Default::default()
|
||||
},
|
||||
ModifierKeys::empty(),
|
||||
)
|
||||
|
||||
@@ -2051,8 +2051,7 @@ enum GradientDragHintState {
|
||||
mod test_gradient {
|
||||
use super::{gradient_to_viewport_transform, midpoint_diamonds, midpoint_ratio_at};
|
||||
use crate::consts::{GRADIENT_MIDPOINT_MAX, GRADIENT_MIDPOINT_MIN};
|
||||
use crate::messages::input_mapper::utility_types::input_mouse::EditorMouseState;
|
||||
use crate::messages::input_mapper::utility_types::input_mouse::ScrollDelta;
|
||||
use crate::messages::input_mapper::utility_types::pointer::EditorPointerState;
|
||||
use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn;
|
||||
use crate::messages::portfolio::document::utility_types::misc::GroupFolderType;
|
||||
use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, OutputConnector};
|
||||
@@ -2523,10 +2522,10 @@ mod test_gradient {
|
||||
editor.move_mouse(end_pos.x, end_pos.y, ModifierKeys::empty(), MouseKeys::LEFT).await;
|
||||
editor
|
||||
.mouseup(
|
||||
EditorMouseState {
|
||||
EditorPointerState {
|
||||
editor_position: end_pos,
|
||||
mouse_keys: MouseKeys::empty(),
|
||||
scroll_delta: ScrollDelta::default(),
|
||||
..Default::default()
|
||||
},
|
||||
ModifierKeys::empty(),
|
||||
)
|
||||
@@ -2577,10 +2576,10 @@ mod test_gradient {
|
||||
let click_position = DVec2::new(25., 0.);
|
||||
editor
|
||||
.mousedown(
|
||||
EditorMouseState {
|
||||
EditorPointerState {
|
||||
editor_position: click_position,
|
||||
mouse_keys: MouseKeys::LEFT,
|
||||
scroll_delta: ScrollDelta::default(),
|
||||
..Default::default()
|
||||
},
|
||||
ModifierKeys::empty(),
|
||||
)
|
||||
@@ -2591,10 +2590,10 @@ mod test_gradient {
|
||||
|
||||
editor
|
||||
.mouseup(
|
||||
EditorMouseState {
|
||||
EditorPointerState {
|
||||
editor_position: drag_position,
|
||||
mouse_keys: MouseKeys::empty(),
|
||||
scroll_delta: ScrollDelta::default(),
|
||||
..Default::default()
|
||||
},
|
||||
ModifierKeys::empty(),
|
||||
)
|
||||
@@ -2656,10 +2655,10 @@ mod test_gradient {
|
||||
editor.left_mousedown(position2.x, position2.y, ModifierKeys::empty()).await;
|
||||
editor
|
||||
.mouseup(
|
||||
EditorMouseState {
|
||||
EditorPointerState {
|
||||
editor_position: position2,
|
||||
mouse_keys: MouseKeys::empty(),
|
||||
scroll_delta: ScrollDelta::default(),
|
||||
..Default::default()
|
||||
},
|
||||
ModifierKeys::empty(),
|
||||
)
|
||||
@@ -2905,10 +2904,10 @@ mod test_gradient {
|
||||
editor.move_mouse(new_viewport_end.x, new_viewport_end.y, ModifierKeys::empty(), MouseKeys::LEFT).await;
|
||||
editor
|
||||
.mouseup(
|
||||
EditorMouseState {
|
||||
EditorPointerState {
|
||||
editor_position: new_viewport_end,
|
||||
mouse_keys: MouseKeys::empty(),
|
||||
scroll_delta: ScrollDelta::default(),
|
||||
..Default::default()
|
||||
},
|
||||
ModifierKeys::empty(),
|
||||
)
|
||||
@@ -2982,10 +2981,10 @@ mod test_gradient {
|
||||
editor.move_mouse(new_viewport_end.x, new_viewport_end.y, ModifierKeys::empty(), MouseKeys::LEFT).await;
|
||||
editor
|
||||
.mouseup(
|
||||
EditorMouseState {
|
||||
EditorPointerState {
|
||||
editor_position: new_viewport_end,
|
||||
mouse_keys: MouseKeys::empty(),
|
||||
scroll_delta: ScrollDelta::default(),
|
||||
..Default::default()
|
||||
},
|
||||
ModifierKeys::empty(),
|
||||
)
|
||||
|
||||
@@ -14,7 +14,7 @@ pub mod text_tool;
|
||||
|
||||
pub mod tool_prelude {
|
||||
pub use crate::messages::frontend::utility_types::MouseCursorIcon;
|
||||
pub use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion};
|
||||
pub use crate::messages::input_mapper::utility_types::keyboard::{Key, MouseMotion};
|
||||
pub use crate::messages::layout::utility_types::widget_prelude::*;
|
||||
pub use crate::messages::prelude::*;
|
||||
pub use crate::messages::tool::utility_types::{EventToMessageMap, Fsm, ToolActionMessageContext, ToolMetadata, ToolTransition, ToolType};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use super::tool_prelude::*;
|
||||
use crate::consts::{COLOR_OVERLAY_BLUE, COLOR_OVERLAY_BLUE_05, HIDE_HANDLE_DISTANCE, LINE_ROTATE_SNAP_ANGLE, SEGMENT_OVERLAY_SIZE};
|
||||
use crate::messages::input_mapper::utility_types::input_mouse::MouseKeys;
|
||||
use crate::messages::input_mapper::utility_types::pointer::MouseKeys;
|
||||
use crate::messages::portfolio::document::node_graph::document_node_definitions::resolve_network_node_type;
|
||||
use crate::messages::portfolio::document::overlays::utility_functions::path_overlays;
|
||||
use crate::messages::portfolio::document::overlays::utility_types::{DrawHandles, OverlayContext};
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
use super::tool_prelude::*;
|
||||
use crate::consts::*;
|
||||
use crate::messages::input_mapper::utility_types::input_mouse::ViewportPosition;
|
||||
use crate::messages::input_mapper::utility_types::pointer::ViewportPosition;
|
||||
use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn;
|
||||
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
||||
use crate::messages::portfolio::document::utility_types::document_metadata::{DocumentMetadata, LayerNodeIdentifier};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use super::tool_prelude::*;
|
||||
use crate::consts::{DRAG_THRESHOLD, PATH_JOIN_THRESHOLD, SNAP_POINT_TOLERANCE};
|
||||
use crate::messages::input_mapper::utility_types::input_mouse::MouseKeys;
|
||||
use crate::messages::input_mapper::utility_types::pointer::MouseKeys;
|
||||
use crate::messages::portfolio::document::node_graph::document_node_definitions::{resolve_network_node_type, resolve_proto_node_type};
|
||||
use crate::messages::portfolio::document::overlays::utility_functions::path_endpoint_overlays;
|
||||
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::Key;
|
||||
use crate::messages::input_mapper::utility_types::keyboard::Key;
|
||||
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
||||
use crate::messages::portfolio::document::utility_types::transformation::TransformType;
|
||||
use crate::messages::prelude::*;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::consts::{ANGLE_MEASURE_RADIUS_FACTOR, ARC_MEASURE_RADIUS_FACTOR_RANGE, COLOR_OVERLAY_BLUE, COLOR_OVERLAY_GRAY, SLOWING_DIVISOR};
|
||||
use crate::messages::input_mapper::utility_types::input_mouse::{DocumentPosition, ViewportPosition};
|
||||
use crate::messages::input_mapper::utility_types::pointer::{DocumentPosition, ViewportPosition};
|
||||
use crate::messages::portfolio::document::overlays::utility_functions::text_width;
|
||||
use crate::messages::portfolio::document::overlays::utility_types::{OverlayProvider, Pivot};
|
||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||
|
||||
@@ -4,7 +4,7 @@ use super::common_functionality::shape_editor::ShapeState;
|
||||
use super::tool_messages::*;
|
||||
use crate::messages::broadcast::BroadcastMessage;
|
||||
use crate::messages::broadcast::event::EventMessage;
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, KeysGroup, LabeledKeyOrMouseMotion, LabeledShortcut, MouseMotion};
|
||||
use crate::messages::input_mapper::utility_types::keyboard::{Key, KeysGroup, LabeledKeyOrMouseMotion, LabeledShortcut, MouseMotion};
|
||||
use crate::messages::input_mapper::utility_types::macros::action_shortcut;
|
||||
use crate::messages::input_mapper::utility_types::misc::ActionShortcut;
|
||||
use crate::messages::layout::utility_types::widget_prelude::*;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::application::Editor;
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::ModifierKeys;
|
||||
use crate::messages::input_mapper::utility_types::input_mouse::{EditorMouseState, MouseKeys, ScrollDelta, ViewportPosition};
|
||||
use crate::messages::input_mapper::utility_types::keyboard::ModifierKeys;
|
||||
use crate::messages::input_mapper::utility_types::pointer::{EditorPointerState, MouseKeys, ViewportPosition};
|
||||
use crate::messages::portfolio::document::node_graph::document_node_definitions::DefinitionIdentifier;
|
||||
use crate::messages::prelude::*;
|
||||
use crate::messages::tool::tool_messages::tool_prelude::Key;
|
||||
@@ -126,7 +126,7 @@ impl EditorTestUtils {
|
||||
self.move_mouse(position.x, position.y, modifier_keys, MouseKeys::empty()).await;
|
||||
|
||||
self.mousedown(
|
||||
EditorMouseState {
|
||||
EditorPointerState {
|
||||
editor_position: position,
|
||||
mouse_keys: button,
|
||||
..Default::default()
|
||||
@@ -136,7 +136,7 @@ impl EditorTestUtils {
|
||||
.await;
|
||||
|
||||
self.mouseup(
|
||||
EditorMouseState {
|
||||
EditorPointerState {
|
||||
editor_position: position,
|
||||
..Default::default()
|
||||
},
|
||||
@@ -155,10 +155,10 @@ impl EditorTestUtils {
|
||||
self.move_mouse(x2, y2, modifier_keys, MouseKeys::LEFT).await;
|
||||
|
||||
self.mouseup(
|
||||
EditorMouseState {
|
||||
EditorPointerState {
|
||||
editor_position: (x2, y2).into(),
|
||||
mouse_keys: MouseKeys::empty(),
|
||||
scroll_delta: ScrollDelta::default(),
|
||||
..Default::default()
|
||||
},
|
||||
modifier_keys,
|
||||
)
|
||||
@@ -175,10 +175,10 @@ impl EditorTestUtils {
|
||||
self.move_mouse(100., 100., ModifierKeys::default(), MouseKeys::LEFT).await;
|
||||
|
||||
self.mousedown(
|
||||
EditorMouseState {
|
||||
EditorPointerState {
|
||||
editor_position: (100., 100.).into(),
|
||||
mouse_keys: MouseKeys::LEFT | MouseKeys::RIGHT,
|
||||
scroll_delta: ScrollDelta::default(),
|
||||
..Default::default()
|
||||
},
|
||||
ModifierKeys::default(),
|
||||
)
|
||||
@@ -194,7 +194,7 @@ impl EditorTestUtils {
|
||||
}
|
||||
|
||||
pub async fn move_mouse(&mut self, x: f64, y: f64, modifier_keys: ModifierKeys, mouse_keys: MouseKeys) {
|
||||
let editor_mouse_state = EditorMouseState {
|
||||
let editor_mouse_state = EditorPointerState {
|
||||
editor_position: ViewportPosition::new(x, y),
|
||||
mouse_keys,
|
||||
..Default::default()
|
||||
@@ -202,11 +202,11 @@ impl EditorTestUtils {
|
||||
self.input(InputPreprocessorMessage::PointerMove { editor_mouse_state, modifier_keys }).await;
|
||||
}
|
||||
|
||||
pub async fn mousedown(&mut self, editor_mouse_state: EditorMouseState, modifier_keys: ModifierKeys) {
|
||||
pub async fn mousedown(&mut self, editor_mouse_state: EditorPointerState, modifier_keys: ModifierKeys) {
|
||||
self.input(InputPreprocessorMessage::PointerDown { editor_mouse_state, modifier_keys }).await;
|
||||
}
|
||||
|
||||
pub async fn mouseup(&mut self, editor_mouse_state: EditorMouseState, modifier_keys: ModifierKeys) {
|
||||
pub async fn mouseup(&mut self, editor_mouse_state: EditorPointerState, modifier_keys: ModifierKeys) {
|
||||
self.handle_message(InputPreprocessorMessage::PointerUp { editor_mouse_state, modifier_keys }).await;
|
||||
}
|
||||
|
||||
@@ -219,10 +219,10 @@ impl EditorTestUtils {
|
||||
|
||||
pub async fn left_mousedown(&mut self, x: f64, y: f64, modifier_keys: ModifierKeys) {
|
||||
self.mousedown(
|
||||
EditorMouseState {
|
||||
EditorPointerState {
|
||||
editor_position: (x, y).into(),
|
||||
mouse_keys: MouseKeys::LEFT,
|
||||
scroll_delta: ScrollDelta::default(),
|
||||
..Default::default()
|
||||
},
|
||||
modifier_keys,
|
||||
)
|
||||
@@ -231,10 +231,10 @@ impl EditorTestUtils {
|
||||
|
||||
pub async fn left_mouseup(&mut self, x: f64, y: f64, modifier_keys: ModifierKeys) {
|
||||
self.mouseup(
|
||||
EditorMouseState {
|
||||
EditorPointerState {
|
||||
editor_position: (x, y).into(),
|
||||
mouse_keys: MouseKeys::empty(),
|
||||
scroll_delta: ScrollDelta::default(),
|
||||
..Default::default()
|
||||
},
|
||||
modifier_keys,
|
||||
)
|
||||
@@ -287,10 +287,10 @@ impl EditorTestUtils {
|
||||
|
||||
pub async fn double_click(&mut self, position: DVec2) {
|
||||
self.handle_message(InputPreprocessorMessage::DoubleClick {
|
||||
editor_mouse_state: EditorMouseState {
|
||||
editor_mouse_state: EditorPointerState {
|
||||
editor_position: position,
|
||||
mouse_keys: MouseKeys::LEFT,
|
||||
scroll_delta: ScrollDelta::default(),
|
||||
..Default::default()
|
||||
},
|
||||
modifier_keys: ModifierKeys::empty(),
|
||||
})
|
||||
@@ -311,10 +311,10 @@ impl EditorTestUtils {
|
||||
}
|
||||
|
||||
self.mouseup(
|
||||
EditorMouseState {
|
||||
EditorPointerState {
|
||||
editor_position: points[points.len() - 1],
|
||||
mouse_keys: MouseKeys::empty(),
|
||||
scroll_delta: ScrollDelta::default(),
|
||||
..Default::default()
|
||||
},
|
||||
modifier_keys,
|
||||
)
|
||||
@@ -373,8 +373,8 @@ pub mod test_prelude {
|
||||
pub use crate::application::Editor;
|
||||
pub use crate::float_eq;
|
||||
pub use crate::messages::clipboard::utility_types::ClipboardContentRaw;
|
||||
pub use crate::messages::input_mapper::utility_types::input_keyboard::{Key, ModifierKeys};
|
||||
pub use crate::messages::input_mapper::utility_types::input_mouse::MouseKeys;
|
||||
pub use crate::messages::input_mapper::utility_types::keyboard::{Key, ModifierKeys};
|
||||
pub use crate::messages::input_mapper::utility_types::pointer::MouseKeys;
|
||||
pub use crate::messages::portfolio::document::node_graph::document_node_definitions::DefinitionIdentifier;
|
||||
pub use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||
pub use crate::messages::prelude::*;
|
||||
|
||||
@@ -15,8 +15,8 @@ use wasm_bindgen::prelude::*;
|
||||
mod editor_commands {
|
||||
use crate::helpers::translate_key;
|
||||
use editor::messages::clipboard::utility_types::ClipboardContentRaw;
|
||||
use editor::messages::input_mapper::utility_types::input_keyboard::ModifierKeys;
|
||||
use editor::messages::input_mapper::utility_types::input_mouse::{EditorMouseState, ScrollDelta};
|
||||
use editor::messages::input_mapper::utility_types::keyboard::ModifierKeys;
|
||||
use editor::messages::input_mapper::utility_types::pointer::{EditorPointerState, ScrollDelta};
|
||||
use editor::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||
use editor::messages::portfolio::document::utility_types::network_interface::ImportOrExport;
|
||||
use editor::messages::portfolio::utility_types::PanelGroupId;
|
||||
@@ -299,14 +299,14 @@ mod editor_commands {
|
||||
|
||||
/// Mouse movement within the screenspace bounds of the viewport
|
||||
fn on_mouse_move(x: f64, y: f64, mouse_keys: u8, modifiers: u8) -> Message {
|
||||
let editor_mouse_state = EditorMouseState::from_keys_and_editor_position(mouse_keys, (x, y).into());
|
||||
let editor_mouse_state = EditorPointerState::from_keys_and_editor_position(mouse_keys, (x, y).into());
|
||||
let modifier_keys = ModifierKeys::from_bits(modifiers).expect("Invalid modifier keys");
|
||||
InputPreprocessorMessage::PointerMove { editor_mouse_state, modifier_keys }.into()
|
||||
}
|
||||
|
||||
/// Mouse scrolling within the screenspace bounds of the viewport
|
||||
fn on_wheel_scroll(x: f64, y: f64, mouse_keys: u8, wheel_delta_x: f64, wheel_delta_y: f64, wheel_delta_z: f64, modifiers: u8) -> Message {
|
||||
let mut editor_mouse_state = EditorMouseState::from_keys_and_editor_position(mouse_keys, (x, y).into());
|
||||
let mut editor_mouse_state = EditorPointerState::from_keys_and_editor_position(mouse_keys, (x, y).into());
|
||||
editor_mouse_state.scroll_delta = ScrollDelta::new(wheel_delta_x, wheel_delta_y, wheel_delta_z);
|
||||
let modifier_keys = ModifierKeys::from_bits(modifiers).expect("Invalid modifier keys");
|
||||
InputPreprocessorMessage::WheelScroll { editor_mouse_state, modifier_keys }.into()
|
||||
@@ -314,28 +314,28 @@ mod editor_commands {
|
||||
|
||||
/// A mouse button depressed within screenspace the bounds of the viewport
|
||||
fn on_mouse_down(x: f64, y: f64, mouse_keys: u8, modifiers: u8) -> Message {
|
||||
let editor_mouse_state = EditorMouseState::from_keys_and_editor_position(mouse_keys, (x, y).into());
|
||||
let editor_mouse_state = EditorPointerState::from_keys_and_editor_position(mouse_keys, (x, y).into());
|
||||
let modifier_keys = ModifierKeys::from_bits(modifiers).expect("Invalid modifier keys");
|
||||
InputPreprocessorMessage::PointerDown { editor_mouse_state, modifier_keys }.into()
|
||||
}
|
||||
|
||||
/// A mouse button released
|
||||
fn on_mouse_up(x: f64, y: f64, mouse_keys: u8, modifiers: u8) -> Message {
|
||||
let editor_mouse_state = EditorMouseState::from_keys_and_editor_position(mouse_keys, (x, y).into());
|
||||
let editor_mouse_state = EditorPointerState::from_keys_and_editor_position(mouse_keys, (x, y).into());
|
||||
let modifier_keys = ModifierKeys::from_bits(modifiers).expect("Invalid modifier keys");
|
||||
InputPreprocessorMessage::PointerUp { editor_mouse_state, modifier_keys }.into()
|
||||
}
|
||||
|
||||
/// Mouse shaken
|
||||
fn on_mouse_shake(x: f64, y: f64, mouse_keys: u8, modifiers: u8) -> Message {
|
||||
let editor_mouse_state = EditorMouseState::from_keys_and_editor_position(mouse_keys, (x, y).into());
|
||||
let editor_mouse_state = EditorPointerState::from_keys_and_editor_position(mouse_keys, (x, y).into());
|
||||
let modifier_keys = ModifierKeys::from_bits(modifiers).expect("Invalid modifier keys");
|
||||
InputPreprocessorMessage::PointerShake { editor_mouse_state, modifier_keys }.into()
|
||||
}
|
||||
|
||||
/// Mouse double clicked
|
||||
fn on_double_click(x: f64, y: f64, mouse_keys: u8, modifiers: u8) -> Message {
|
||||
let editor_mouse_state = EditorMouseState::from_keys_and_editor_position(mouse_keys, (x, y).into());
|
||||
let editor_mouse_state = EditorPointerState::from_keys_and_editor_position(mouse_keys, (x, y).into());
|
||||
let modifier_keys = ModifierKeys::from_bits(modifiers).expect("Invalid modifier keys");
|
||||
InputPreprocessorMessage::DoubleClick { editor_mouse_state, modifier_keys }.into()
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::native_communication::RasterizedImage;
|
||||
#[cfg(not(feature = "native"))]
|
||||
use editor::application::Editor;
|
||||
#[cfg(feature = "editor")]
|
||||
use editor::messages::input_mapper::utility_types::input_keyboard::Key;
|
||||
use editor::messages::input_mapper::utility_types::keyboard::Key;
|
||||
#[cfg(not(feature = "native"))]
|
||||
use editor::messages::prelude::*;
|
||||
use js_sys::{Object, Reflect};
|
||||
|
||||
Reference in New Issue
Block a user