Implement more scrolling features (#256)
* Use sideways scrolling * Add horizontal scroll with shift * Combine WheelCanvasTranslate messages * Add zooming to current mouse position * Fix formatting * Fix scroll direction * Rename some Constants
This commit is contained in:
parent
3156b3af05
commit
246ca2c95b
|
|
@ -1,10 +1,12 @@
|
||||||
pub const PLUS_KEY_ZOOM_MULTIPLIER: f64 = 1.25;
|
pub const PLUS_KEY_ZOOM_RATE: f64 = 1.25;
|
||||||
pub const MINUS_KEY_ZOOM_MULTIPLIER: f64 = 0.8;
|
pub const MINUS_KEY_ZOOM_RATE: f64 = 0.8;
|
||||||
|
|
||||||
pub const VIEWPORT_ZOOM_SCALE_MIN: f64 = 0.000_001;
|
pub const VIEWPORT_ZOOM_SCALE_MIN: f64 = 0.000_001;
|
||||||
pub const VIEWPORT_ZOOM_SCALE_MAX: f64 = 1_000_000.;
|
pub const VIEWPORT_ZOOM_SCALE_MAX: f64 = 1_000_000.;
|
||||||
|
|
||||||
pub const WHEEL_ZOOM_DIVISOR: f64 = 500.;
|
pub const VIEWPORT_SCROLL_RATE: f64 = 0.6;
|
||||||
pub const MOUSE_ZOOM_DIVISOR: f64 = 400.;
|
|
||||||
|
pub const WHEEL_ZOOM_RATE: f64 = 1. / 600.;
|
||||||
|
pub const MOUSE_ZOOM_RATE: f64 = 1. / 400.;
|
||||||
|
|
||||||
pub const ROTATE_SNAP_INTERVAL: f64 = 15.;
|
pub const ROTATE_SNAP_INTERVAL: f64 = 15.;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::message_prelude::*;
|
use crate::message_prelude::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
consts::{MOUSE_ZOOM_DIVISOR, VIEWPORT_ZOOM_SCALE_MAX, VIEWPORT_ZOOM_SCALE_MIN, WHEEL_ZOOM_DIVISOR},
|
consts::{MOUSE_ZOOM_RATE, VIEWPORT_SCROLL_RATE, VIEWPORT_ZOOM_SCALE_MAX, VIEWPORT_ZOOM_SCALE_MIN, WHEEL_ZOOM_RATE},
|
||||||
input::{mouse::ViewportPosition, InputPreprocessor},
|
input::{mouse::ViewportPosition, InputPreprocessor},
|
||||||
};
|
};
|
||||||
use document_core::layers::Layer;
|
use document_core::layers::Layer;
|
||||||
|
|
@ -40,7 +40,7 @@ pub enum DocumentMessage {
|
||||||
Undo,
|
Undo,
|
||||||
MouseMove,
|
MouseMove,
|
||||||
TranslateCanvasBegin,
|
TranslateCanvasBegin,
|
||||||
WheelCanvasTranslate,
|
WheelCanvasTranslate { use_y_as_x: bool },
|
||||||
RotateCanvasBegin { snap: bool },
|
RotateCanvasBegin { snap: bool },
|
||||||
ZoomCanvasBegin,
|
ZoomCanvasBegin,
|
||||||
TranslateCanvasEnd,
|
TranslateCanvasEnd,
|
||||||
|
|
@ -111,7 +111,7 @@ impl DocumentMessageHandler {
|
||||||
let layerdata = self.layerdata(&path);
|
let layerdata = self.layerdata(&path);
|
||||||
responses.push_back(
|
responses.push_back(
|
||||||
DocumentOperation::SetLayerTransform {
|
DocumentOperation::SetLayerTransform {
|
||||||
path: path,
|
path,
|
||||||
transform: layerdata.calculate_transform().to_cols_array(),
|
transform: layerdata.calculate_transform().to_cols_array(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
|
|
@ -431,7 +431,7 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
|
||||||
}
|
}
|
||||||
if self.zooming {
|
if self.zooming {
|
||||||
let difference = self.mouse_pos.y as f64 - ipp.mouse.position.y as f64;
|
let difference = self.mouse_pos.y as f64 - ipp.mouse.position.y as f64;
|
||||||
let amount = 1. + difference / MOUSE_ZOOM_DIVISOR;
|
let amount = 1. + difference * MOUSE_ZOOM_RATE;
|
||||||
let layerdata = self.layerdata_mut(&vec![]);
|
let layerdata = self.layerdata_mut(&vec![]);
|
||||||
let new = (layerdata.scale * amount).clamp(VIEWPORT_ZOOM_SCALE_MIN, VIEWPORT_ZOOM_SCALE_MAX);
|
let new = (layerdata.scale * amount).clamp(VIEWPORT_ZOOM_SCALE_MIN, VIEWPORT_ZOOM_SCALE_MAX);
|
||||||
layerdata.scale = new;
|
layerdata.scale = new;
|
||||||
|
|
@ -454,20 +454,31 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
|
||||||
self.create_document_transform_from_layerdata(&ipp.viewport_size, responses);
|
self.create_document_transform_from_layerdata(&ipp.viewport_size, responses);
|
||||||
}
|
}
|
||||||
WheelCanvasZoom => {
|
WheelCanvasZoom => {
|
||||||
let scroll = ipp.mouse.scroll_delta.y as f64;
|
let scroll = ipp.mouse.scroll_delta.scroll_delta();
|
||||||
let amount = if ipp.mouse.scroll_delta.y > 0 {
|
let mouse = ipp.mouse.position.to_dvec2();
|
||||||
1. + scroll / -WHEEL_ZOOM_DIVISOR
|
let viewport_size = ipp.viewport_size.to_dvec2();
|
||||||
} else {
|
let mut zoom_factor = 1. + scroll.abs() * WHEEL_ZOOM_RATE;
|
||||||
1. / (1. + scroll / WHEEL_ZOOM_DIVISOR)
|
if ipp.mouse.scroll_delta.y > 0 {
|
||||||
|
zoom_factor = 1. / zoom_factor
|
||||||
};
|
};
|
||||||
|
let new_viewport_size = viewport_size * (1. / zoom_factor);
|
||||||
|
let delta_size = viewport_size - new_viewport_size;
|
||||||
|
let mouse_percent = mouse / viewport_size;
|
||||||
|
let delta = delta_size * -2. * (mouse_percent - (0.5, 0.5).into());
|
||||||
|
|
||||||
|
let transformed_delta = self.active_document().document.root.transform.inverse().transform_vector2(delta);
|
||||||
let layerdata = self.layerdata_mut(&vec![]);
|
let layerdata = self.layerdata_mut(&vec![]);
|
||||||
let new = (layerdata.scale * amount).clamp(VIEWPORT_ZOOM_SCALE_MIN, VIEWPORT_ZOOM_SCALE_MAX);
|
let new = (layerdata.scale * zoom_factor).clamp(VIEWPORT_ZOOM_SCALE_MIN, VIEWPORT_ZOOM_SCALE_MAX);
|
||||||
layerdata.scale = new;
|
layerdata.scale = new;
|
||||||
|
layerdata.translation += transformed_delta;
|
||||||
responses.push_back(FrontendMessage::SetCanvasZoom { new_zoom: layerdata.scale }.into());
|
responses.push_back(FrontendMessage::SetCanvasZoom { new_zoom: layerdata.scale }.into());
|
||||||
self.create_document_transform_from_layerdata(&ipp.viewport_size, responses);
|
self.create_document_transform_from_layerdata(&ipp.viewport_size, responses);
|
||||||
}
|
}
|
||||||
WheelCanvasTranslate => {
|
WheelCanvasTranslate { use_y_as_x } => {
|
||||||
let delta = -ipp.mouse.scroll_delta.to_dvec2();
|
let delta = match use_y_as_x {
|
||||||
|
false => -ipp.mouse.scroll_delta.to_dvec2(),
|
||||||
|
true => (-ipp.mouse.scroll_delta.y as f64, 0.).into(),
|
||||||
|
} * VIEWPORT_SCROLL_RATE;
|
||||||
let transformed_delta = self.active_document().document.root.transform.inverse().transform_vector2(delta);
|
let transformed_delta = self.active_document().document.root.transform.inverse().transform_vector2(delta);
|
||||||
let layerdata = self.layerdata_mut(&vec![]);
|
let layerdata = self.layerdata_mut(&vec![]);
|
||||||
layerdata.translation += transformed_delta;
|
layerdata.translation += transformed_delta;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::consts::{MINUS_KEY_ZOOM_MULTIPLIER, PLUS_KEY_ZOOM_MULTIPLIER};
|
use crate::consts::{MINUS_KEY_ZOOM_RATE, PLUS_KEY_ZOOM_RATE};
|
||||||
use crate::message_prelude::*;
|
use crate::message_prelude::*;
|
||||||
use crate::tool::ToolType;
|
use crate::tool::ToolType;
|
||||||
|
|
||||||
|
|
@ -191,13 +191,14 @@ impl Default for Mapping {
|
||||||
entry! {action=DocumentMessage::ZoomCanvasBegin, key_down=Mmb, modifiers=[KeyShift]},
|
entry! {action=DocumentMessage::ZoomCanvasBegin, key_down=Mmb, modifiers=[KeyShift]},
|
||||||
entry! {action=DocumentMessage::TranslateCanvasBegin, key_down=Mmb},
|
entry! {action=DocumentMessage::TranslateCanvasBegin, key_down=Mmb},
|
||||||
entry! {action=DocumentMessage::TranslateCanvasEnd, key_up=Mmb},
|
entry! {action=DocumentMessage::TranslateCanvasEnd, key_up=Mmb},
|
||||||
entry! {action=DocumentMessage::MultiplyCanvasZoom(PLUS_KEY_ZOOM_MULTIPLIER), key_down=KeyPlus, modifiers=[KeyControl]},
|
entry! {action=DocumentMessage::MultiplyCanvasZoom(PLUS_KEY_ZOOM_RATE), key_down=KeyPlus, modifiers=[KeyControl]},
|
||||||
entry! {action=DocumentMessage::MultiplyCanvasZoom(PLUS_KEY_ZOOM_MULTIPLIER), key_down=KeyEquals, modifiers=[KeyControl]},
|
entry! {action=DocumentMessage::MultiplyCanvasZoom(PLUS_KEY_ZOOM_RATE), key_down=KeyEquals, modifiers=[KeyControl]},
|
||||||
entry! {action=DocumentMessage::MultiplyCanvasZoom(MINUS_KEY_ZOOM_MULTIPLIER), key_down=KeyMinus, modifiers=[KeyControl]},
|
entry! {action=DocumentMessage::MultiplyCanvasZoom(MINUS_KEY_ZOOM_RATE), key_down=KeyMinus, modifiers=[KeyControl]},
|
||||||
entry! {action=DocumentMessage::SetCanvasZoom(1.), key_down=Key1, modifiers=[KeyControl]},
|
entry! {action=DocumentMessage::SetCanvasZoom(1.), key_down=Key1, modifiers=[KeyControl]},
|
||||||
entry! {action=DocumentMessage::SetCanvasZoom(2.), key_down=Key2, modifiers=[KeyControl]},
|
entry! {action=DocumentMessage::SetCanvasZoom(2.), key_down=Key2, modifiers=[KeyControl]},
|
||||||
entry! {action=DocumentMessage::WheelCanvasZoom, message=InputMapperMessage::MouseScroll, modifiers=[KeyControl]},
|
entry! {action=DocumentMessage::WheelCanvasZoom, message=InputMapperMessage::MouseScroll, modifiers=[KeyControl]},
|
||||||
entry! {action=DocumentMessage::WheelCanvasTranslate, message=InputMapperMessage::MouseScroll},
|
entry! {action=DocumentMessage::WheelCanvasTranslate{use_y_as_x: true}, message=InputMapperMessage::MouseScroll, modifiers=[KeyShift]},
|
||||||
|
entry! {action=DocumentMessage::WheelCanvasTranslate{use_y_as_x: false}, message=InputMapperMessage::MouseScroll},
|
||||||
entry! {action=DocumentMessage::NewDocument, key_down=KeyN, modifiers=[KeyShift]},
|
entry! {action=DocumentMessage::NewDocument, key_down=KeyN, modifiers=[KeyShift]},
|
||||||
entry! {action=DocumentMessage::NextDocument, key_down=KeyTab, modifiers=[KeyShift]},
|
entry! {action=DocumentMessage::NextDocument, key_down=KeyTab, modifiers=[KeyShift]},
|
||||||
entry! {action=DocumentMessage::CloseActiveDocument, key_down=KeyW, modifiers=[KeyShift]},
|
entry! {action=DocumentMessage::CloseActiveDocument, key_down=KeyW, modifiers=[KeyShift]},
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,10 @@ impl ScrollDelta {
|
||||||
pub fn to_dvec2(&self) -> DVec2 {
|
pub fn to_dvec2(&self) -> DVec2 {
|
||||||
DVec2::new(self.x as f64, self.y as f64)
|
DVec2::new(self.x as f64, self.y as f64)
|
||||||
}
|
}
|
||||||
|
pub fn scroll_delta(&self) -> f64 {
|
||||||
|
let (dx, dy) = (self.x, self.y);
|
||||||
|
dy.signum() as f64 * ((dy * dy + i32::min(dy.abs(), dx.abs()).pow(2)) as f64).sqrt()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq)]
|
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq)]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue