diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d16fcc5..bd9cfd90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_w * `ui.add(Button::new("…").text_color(…))` is now `ui.button(RichText::new("…").color(…))` (same for `Label` )([#855](https://github.com/emilk/egui/pull/855)). * Replace `CtxRef::begin_frame` and `end_frame` with `CtxRef::run` ([#872](https://github.com/emilk/egui/pull/872)). * Replace `Ui::__test` with `egui::__run_test_ui` ([#872](https://github.com/emilk/egui/pull/872)). +* Replace `scroll_delta` and `zoom_delta` in `RawInput` with `Event::Scroll` and `Event::Zoom`. ### Contributors 🙏 * [mankinskin](https://github.com/mankinskin) ([#543](https://github.com/emilk/egui/pull/543)) diff --git a/egui-winit/src/lib.rs b/egui-winit/src/lib.rs index 40d181cb..6ae789fa 100644 --- a/egui-winit/src/lib.rs +++ b/egui-winit/src/lib.rs @@ -461,9 +461,10 @@ impl State { if self.egui_input.modifiers.ctrl || self.egui_input.modifiers.command { // Treat as zoom instead: - self.egui_input.zoom_delta *= (delta.y / 200.0).exp(); + let factor = (delta.y / 200.0).exp(); + self.egui_input.events.push(egui::Event::Zoom(factor)); } else { - self.egui_input.scroll_delta += delta; + self.egui_input.events.push(egui::Event::Scroll(delta)); } } diff --git a/egui/src/data/input.rs b/egui/src/data/input.rs index e3762b02..1f7c4bf2 100644 --- a/egui/src/data/input.rs +++ b/egui/src/data/input.rs @@ -13,15 +13,6 @@ use crate::emath::*; #[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub struct RawInput { - /// How many points (logical pixels) the user scrolled - pub scroll_delta: Vec2, - - /// Zoom scale factor this frame (e.g. from ctrl-scroll or pinch gesture). - /// * `zoom = 1`: no change (default). - /// * `zoom < 1`: pinch together - /// * `zoom > 1`: pinch spread - pub zoom_delta: f32, - /// Position and size of the area that egui should use. /// Usually you would set this to /// @@ -69,8 +60,6 @@ pub struct RawInput { impl Default for RawInput { fn default() -> Self { Self { - scroll_delta: Vec2::ZERO, - zoom_delta: 1.0, screen_rect: None, pixels_per_point: None, time: None, @@ -89,11 +78,7 @@ impl RawInput { /// * [`Self::hovered_files`] is cloned. /// * [`Self::dropped_files`] is moved. pub fn take(&mut self) -> RawInput { - let zoom = self.zoom_delta; - self.zoom_delta = 1.0; RawInput { - scroll_delta: std::mem::take(&mut self.scroll_delta), - zoom_delta: zoom, screen_rect: self.screen_rect.take(), pixels_per_point: self.pixels_per_point.take(), time: self.time.take(), @@ -108,8 +93,6 @@ impl RawInput { /// Add on new input. pub fn append(&mut self, newer: Self) { let Self { - scroll_delta, - zoom_delta, screen_rect, pixels_per_point, time, @@ -120,8 +103,6 @@ impl RawInput { mut dropped_files, } = newer; - self.scroll_delta += scroll_delta; - self.zoom_delta *= zoom_delta; self.screen_rect = screen_rect.or(self.screen_rect); self.pixels_per_point = pixels_per_point.or(self.pixels_per_point); self.time = time; // use latest time @@ -192,6 +173,15 @@ pub enum Event { /// On touch-up first send `PointerButton{pressed: false, …}` followed by `PointerLeft`. PointerGone, + /// How many points (logical pixels) the user scrolled. + Scroll(Vec2), + + /// Zoom scale factor this frame (e.g. from ctrl-scroll or pinch gesture). + /// * `zoom = 1`: no change. + /// * `zoom < 1`: pinch together + /// * `zoom > 1`: pinch spread + Zoom(f32), + /// IME composition start. CompositionStart, /// A new IME candidate is being suggested. @@ -357,8 +347,6 @@ pub enum Key { impl RawInput { pub fn ui(&self, ui: &mut crate::Ui) { let Self { - scroll_delta, - zoom_delta, screen_rect, pixels_per_point, time, @@ -369,8 +357,6 @@ impl RawInput { dropped_files, } = self; - ui.label(format!("scroll_delta: {:?} points", scroll_delta)); - ui.label(format!("zoom_delta: {:.3?} x", zoom_delta)); ui.label(format!("screen_rect: {:?} points", screen_rect)); ui.label(format!("pixels_per_point: {:?}", pixels_per_point)) .on_hover_text( diff --git a/egui/src/input_state.rs b/egui/src/input_state.rs index 196e9a7e..f2cbddf7 100644 --- a/egui/src/input_state.rs +++ b/egui/src/input_state.rs @@ -36,6 +36,13 @@ pub struct InputState { /// How many pixels the user scrolled. pub scroll_delta: Vec2, + /// Zoom scale factor this frame (e.g. from ctrl-scroll or pinch gesture). + /// + /// * `zoom = 1`: no change. + /// * `zoom < 1`: pinch together + /// * `zoom > 1`: pinch spread + zoom_factor_delta: f32, + /// Position and size of the egui area. pub screen_rect: Rect, @@ -71,7 +78,8 @@ impl Default for InputState { raw: Default::default(), pointer: Default::default(), touch_states: Default::default(), - scroll_delta: Default::default(), + scroll_delta: Vec2::ZERO, + zoom_factor_delta: 1.0, screen_rect: Rect::from_min_size(Default::default(), vec2(10_000.0, 10_000.0)), pixels_per_point: 1.0, time: 0.0, @@ -97,20 +105,33 @@ impl InputState { touch_state.begin_frame(time, &new, self.pointer.interact_pos); } let pointer = self.pointer.begin_frame(time, &new); + let mut keys_down = self.keys_down; + let mut scroll_delta = Vec2::ZERO; + let mut zoom_factor_delta = 1.0; for event in &new.events { - if let Event::Key { key, pressed, .. } = event { - if *pressed { - keys_down.insert(*key); - } else { - keys_down.remove(key); + match event { + Event::Key { key, pressed, .. } => { + if *pressed { + keys_down.insert(*key); + } else { + keys_down.remove(key); + } } + Event::Scroll(delta) => { + scroll_delta += *delta; + } + Event::Zoom(factor) => { + zoom_factor_delta *= *factor; + } + _ => {} } } InputState { pointer, touch_states: self.touch_states, - scroll_delta: new.scroll_delta, + scroll_delta, + zoom_factor_delta, screen_rect, pixels_per_point: new.pixels_per_point.unwrap_or(self.pixels_per_point), time, @@ -136,10 +157,10 @@ impl InputState { pub fn zoom_delta(&self) -> f32 { // If a multi touch gesture is detected, it measures the exact and linear proportions of // the distances of the finger tips. It is therefore potentially more accurate than - // `raw.zoom_delta` which is based on the `ctrl-scroll` event which, in turn, may be + // `zoom_factor_delta` which is based on the `ctrl-scroll` event which, in turn, may be // synthesized from an original touch gesture. self.multi_touch() - .map_or(self.raw.zoom_delta, |touch| touch.zoom_delta) + .map_or(self.zoom_factor_delta, |touch| touch.zoom_delta) } /// 2D non-proportional zoom scale factor this frame (e.g. from ctrl-scroll or pinch gesture). @@ -159,10 +180,10 @@ impl InputState { pub fn zoom_delta_2d(&self) -> Vec2 { // If a multi touch gesture is detected, it measures the exact and linear proportions of // the distances of the finger tips. It is therefore potentially more accurate than - // `raw.zoom_delta` which is based on the `ctrl-scroll` event which, in turn, may be + // `zoom_factor_delta` which is based on the `ctrl-scroll` event which, in turn, may be // synthesized from an original touch gesture. self.multi_touch().map_or_else( - || Vec2::splat(self.raw.zoom_delta), + || Vec2::splat(self.zoom_factor_delta), |touch| touch.zoom_delta_2d, ) } @@ -667,6 +688,7 @@ impl InputState { pointer, touch_states, scroll_delta, + zoom_factor_delta, screen_rect, pixels_per_point, time, @@ -693,6 +715,7 @@ impl InputState { } ui.label(format!("scroll_delta: {:?} points", scroll_delta)); + ui.label(format!("zoom_factor_delta: {:4.2}x", zoom_factor_delta)); ui.label(format!("screen_rect: {:?} points", screen_rect)); ui.label(format!( "{:?} physical pixels for each logical point", diff --git a/egui_web/src/lib.rs b/egui_web/src/lib.rs index c5c9ecf1..698dedb6 100644 --- a/egui_web/src/lib.rs +++ b/egui_web/src/lib.rs @@ -1029,9 +1029,14 @@ fn install_canvas_events(runner_ref: &AppRunnerRef) -> Result<(), JsValue> { // This if-statement is equivalent to how `Modifiers.command` is determined in // `modifiers_from_event()`, but we cannot directly use that fn for a `WheelEvent`. if event.ctrl_key() || event.meta_key() { - runner_lock.input.raw.zoom_delta *= (delta.y / 200.0).exp(); + let factor = (delta.y / 200.0).exp(); + runner_lock.input.raw.events.push(egui::Event::Zoom(factor)); } else { - runner_lock.input.raw.scroll_delta += delta; + runner_lock + .input + .raw + .events + .push(egui::Event::Scroll(delta)); } runner_lock.needs_repaint.set_true();