Replace scroll_delta and zoom_delta in RawInput with events

Part of https://github.com/emilk/egui/issues/843
This commit is contained in:
Emil Ernerfeldt 2021-11-03 22:57:13 +01:00
parent 49e43885ff
commit 6d33beabb1
5 changed files with 54 additions and 38 deletions

View file

@ -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))

View file

@ -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));
}
}

View file

@ -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(

View file

@ -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",

View file

@ -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();