Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ NOTE: [`eframe`](eframe/CHANGELOG.md), [`egui_web`](egui_web/CHANGELOG.md) and [
* Add `Response::request_focus` and `Response::surrender_focus`.
* [Pan and zoom plots](https://github.com/emilk/egui/pull/317).
* [Users can now store custom state in `egui::Memory`.](https://github.com/emilk/egui/pull/257).
* Zoom input: ctrl-scroll and (on `egui_web`) trackpad-pinch gesture.

### Changed 🔧
* Make `Memory::has_focus` public (again).
Expand Down
12 changes: 12 additions & 0 deletions egui/src/data/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ 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,

#[deprecated = "Use instead: `screen_rect: Some(Rect::from_pos_size(Default::default(), screen_size))`"]
pub screen_size: Vec2,

Expand Down Expand Up @@ -55,6 +61,7 @@ impl Default for RawInput {
#![allow(deprecated)] // for screen_size
Self {
scroll_delta: Vec2::ZERO,
zoom_delta: 1.0,
screen_size: Default::default(),
screen_rect: None,
pixels_per_point: None,
Expand All @@ -70,8 +77,11 @@ impl RawInput {
/// Helper: move volatile (deltas and events), clone the rest
pub fn take(&mut self) -> RawInput {
#![allow(deprecated)] // for screen_size
let zoom = self.zoom_delta;
self.zoom_delta = 1.0;
RawInput {
scroll_delta: std::mem::take(&mut self.scroll_delta),
zoom_delta: zoom,
screen_size: self.screen_size,
screen_rect: self.screen_rect.take(),
pixels_per_point: self.pixels_per_point.take(),
Expand Down Expand Up @@ -258,6 +268,7 @@ impl RawInput {
#![allow(deprecated)] // for screen_size
let Self {
scroll_delta,
zoom_delta,
screen_size: _,
screen_rect,
pixels_per_point,
Expand All @@ -268,6 +279,7 @@ impl RawInput {
} = 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(
Expand Down
9 changes: 9 additions & 0 deletions egui/src/input_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,15 @@ impl InputState {
self.screen_rect
}

/// 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
#[inline(always)]
pub fn zoom_delta(&self) -> f32 {
self.raw.zoom_delta
}

pub fn wants_repaint(&self) -> bool {
self.pointer.wants_repaint() || self.scroll_delta != Vec2::ZERO || !self.events.is_empty()
}
Expand Down
12 changes: 9 additions & 3 deletions egui/src/widgets/plot/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,9 +339,15 @@ impl Widget for Plot {
// Zooming
if allow_zoom {
if let Some(hover_pos) = response.hover_pos() {
let scroll_delta = ui.input().scroll_delta[1];
if scroll_delta != 0. {
transform.zoom(-0.01 * scroll_delta, hover_pos);
let zoom_factor = ui.input().zoom_delta();
#[allow(clippy::float_cmp)]
if zoom_factor != 1.0 {
transform.zoom(zoom_factor, hover_pos);
auto_bounds = false;
}
let scroll_delta = ui.input().scroll_delta;
if scroll_delta != Vec2::ZERO {
transform.translate_bounds(-scroll_delta);
auto_bounds = false;
}
}
Expand Down
31 changes: 13 additions & 18 deletions egui/src/widgets/plot/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,25 +159,20 @@ impl ScreenTransform {
self.bounds.translate(delta_pos);
}

/// Zoom by a relative amount with the given screen position as center.
pub fn zoom(&mut self, delta: f32, mut center: Pos2) {
if self.x_centered {
center.x = self.frame.center().x as f32;
}
if self.y_centered {
center.y = self.frame.center().y as f32;
/// Zoom by a relative factor with the given screen position as center.
pub fn zoom(&mut self, zoom_factor: f32, center: Pos2) {
let zoom_factor = zoom_factor as f64;
let center = self.value_from_position(center);

let mut new_bounds = self.bounds;
new_bounds.min[0] = center.x + (new_bounds.min[0] - center.x) / zoom_factor;
new_bounds.max[0] = center.x + (new_bounds.max[0] - center.x) / zoom_factor;
new_bounds.min[1] = center.y + (new_bounds.min[1] - center.y) / zoom_factor;
new_bounds.max[1] = center.y + (new_bounds.max[1] - center.y) / zoom_factor;

if new_bounds.is_valid() {
self.bounds = new_bounds;
}
let delta = delta.clamp(-1., 1.);
let frame_width = self.frame.width();
let frame_height = self.frame.height();
let bounds_width = self.bounds.width() as f32;
let bounds_height = self.bounds.height() as f32;
let t_x = (center.x - self.frame.min[0]) / frame_width;
let t_y = (self.frame.max[1] - center.y) / frame_height;
self.bounds.min[0] -= ((t_x * delta) * bounds_width) as f64;
self.bounds.min[1] -= ((t_y * delta) * bounds_height) as f64;
self.bounds.max[0] += (((1. - t_x) * delta) * bounds_width) as f64;
self.bounds.max[1] += (((1. - t_y) * delta) * bounds_height) as f64;
}

pub fn position_from_value(&self, value: &Value) -> Pos2 {
Expand Down
2 changes: 2 additions & 0 deletions egui_demo_lib/src/apps/demo/plot_demo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ impl PlotDemo {
ui.checkbox(proportional, "proportional data axes");
});
});

ui.label("Drag to pan, ctrl + scroll to zoom. Double-click to reset view.");
}

fn circle(&self) -> Curve {
Expand Down
21 changes: 16 additions & 5 deletions egui_glium/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,15 +162,26 @@ pub fn input_to_egui(
}
}
WindowEvent::MouseWheel { delta, .. } => {
match delta {
let mut delta = match delta {
glutin::event::MouseScrollDelta::LineDelta(x, y) => {
let line_height = 24.0; // TODO
input_state.raw.scroll_delta = vec2(x, y) * line_height;
let line_height = 8.0; // magic value!
vec2(x, y) * line_height
}
glutin::event::MouseScrollDelta::PixelDelta(delta) => {
// Actually point delta
input_state.raw.scroll_delta = vec2(delta.x as f32, delta.y as f32);
vec2(delta.x as f32, delta.y as f32) / pixels_per_point
}
};
if cfg!(target_os = "macos") {
// This is still buggy in winit despite
// https://github.com/rust-windowing/winit/issues/1695 being closed
delta.x *= -1.0;
}

if input_state.raw.modifiers.ctrl {
// Treat as zoom instead:
input_state.raw.zoom_delta *= (delta.y / 200.0).exp();
} else {
input_state.raw.scroll_delta += delta;
}
}
_ => {
Expand Down
13 changes: 10 additions & 3 deletions egui_web/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -963,13 +963,20 @@ fn install_canvas_events(runner_ref: &AppRunnerRef) -> Result<(), JsValue> {
canvas_size_in_points(runner_ref.0.lock().canvas_id()).y
}
web_sys::WheelEvent::DOM_DELTA_LINE => {
24.0 // TODO: tweak this
8.0 // magic value!
}
_ => 1.0,
};

runner_lock.input.raw.scroll_delta.x -= scroll_multiplier * event.delta_x() as f32;
runner_lock.input.raw.scroll_delta.y -= scroll_multiplier * event.delta_y() as f32;
let delta = -scroll_multiplier
* egui::Vec2::new(event.delta_x() as f32, event.delta_y() as f32);

if event.ctrl_key() {
runner_lock.input.raw.zoom_delta *= (delta.y / 200.0).exp();
} else {
runner_lock.input.raw.scroll_delta += delta;
}

runner_lock.needs_repaint.set_true();
event.stop_propagation();
event.prevent_default();
Expand Down