From a0b3f1126b158d41db91c3418695f12133bc1329 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Sat, 5 Nov 2022 11:18:13 +0100 Subject: [PATCH] Add helpers for zooming an app using Ctrl+Plus and Ctrl+Minus (#2239) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Using tracing-subscriber in hello_world example * Add Key::Plus/Minus/Equals * Warn if failing to guess OS from User-Agent * Remove jitter when using Context::set_pixels_per_point * Demo app: zoom in/out using ⌘+ and ⌘- * Demo app: make backend panel GUI scale slider better * Optimize debug builds a bit * typo * Update changelog * Add helper module `egui::gui_zoom` for zooming an app * Better names, and update changelog * Combine Plus and Equals keys * Last fix * Fix docs --- CHANGELOG.md | 3 + Cargo.lock | 1 + Cargo.toml | 12 +- crates/eframe/src/web/input.rs | 147 +++++++++--------- crates/egui-winit/src/lib.rs | 5 + crates/egui/src/context.rs | 17 +- crates/egui/src/data/input.rs | 17 +- crates/egui/src/gui_zoom.rs | 117 ++++++++++++++ crates/egui/src/lib.rs | 1 + crates/egui/src/os.rs | 5 + crates/egui_demo_app/src/backend_panel.rs | 61 ++++---- crates/egui_demo_app/src/wrap_app.rs | 5 + .../src/demo/demo_app_windows.rs | 7 + examples/hello_world/Cargo.toml | 1 + examples/hello_world/src/main.rs | 3 + 15 files changed, 290 insertions(+), 112 deletions(-) create mode 100644 crates/egui/src/gui_zoom.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bb2a06a..55db4ebe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,10 +13,13 @@ NOTE: [`epaint`](crates/epaint/CHANGELOG.md), [`eframe`](crates/eframe/CHANGELOG * Added `Button::shortcut_text` for showing keyboard shortcuts in menu buttons ([#2202](https://github.com/emilk/egui/pull/2202)). * Added `egui::KeyboardShortcut` for showing keyboard shortcuts in menu buttons ([#2202](https://github.com/emilk/egui/pull/2202)). * Texture loading now takes a `TexureOptions` with minification and magnification filters ([#2224](https://github.com/emilk/egui/pull/2224)). +* Added `Key::Minus` and `Key::Equals` ([#2239](https://github.com/emilk/egui/pull/2239)). +* Added `egui::gui_zoom` module with helpers for scaling the whole GUI of an app ([#2239](https://github.com/emilk/egui/pull/2239)). ### Fixed 🐛 * ⚠️ BREAKING: Fix text being too small ([#2069](https://github.com/emilk/egui/pull/2069)). * Improved text rendering ([#2071](https://github.com/emilk/egui/pull/2071)). +* Less jitter when calling `Context::set_pixels_per_point` ([#2239](https://github.com/emilk/egui/pull/2239)). ## 0.19.0 - 2022-08-20 diff --git a/Cargo.lock b/Cargo.lock index 3c6a95c2..b46c6297 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1926,6 +1926,7 @@ name = "hello_world" version = "0.1.0" dependencies = [ "eframe", + "tracing-subscriber", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index b8e0adc2..06ee751e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,9 +15,6 @@ members = [ "examples/*", ] -[profile.dev] -split-debuginfo = "unpacked" # faster debug builds on mac - [profile.release] # lto = true # VERY slightly smaller wasm # opt-level = 's' # 10-20% smaller wasm compared to `opt-level = 3` @@ -26,3 +23,12 @@ opt-level = 2 # fast and small wasm, basically same as `opt-level = 's'` # opt-level = 3 # unecessarily large wasm for no performance gain # debug = true # include debug symbols, useful when profiling wasm + + +[profile.dev] +split-debuginfo = "unpacked" # faster debug builds on mac +opt-level = 1 # Make debug builds run faster + +# Optimize all dependencies even in debug builds (does not affect workspace packages): +[profile.dev.package."*"] +opt-level = 2 diff --git a/crates/eframe/src/web/input.rs b/crates/eframe/src/web/input.rs index 0c9dc9fd..443c26fe 100644 --- a/crates/eframe/src/web/input.rs +++ b/crates/eframe/src/web/input.rs @@ -113,83 +113,88 @@ pub fn should_ignore_key(key: &str) -> bool { /// Web sends all all keys as strings, so it is up to us to figure out if it is /// a real text input or the name of a key. pub fn translate_key(key: &str) -> Option { + use egui::Key; + match key { - "ArrowDown" => Some(egui::Key::ArrowDown), - "ArrowLeft" => Some(egui::Key::ArrowLeft), - "ArrowRight" => Some(egui::Key::ArrowRight), - "ArrowUp" => Some(egui::Key::ArrowUp), + "ArrowDown" => Some(Key::ArrowDown), + "ArrowLeft" => Some(Key::ArrowLeft), + "ArrowRight" => Some(Key::ArrowRight), + "ArrowUp" => Some(Key::ArrowUp), - "Esc" | "Escape" => Some(egui::Key::Escape), - "Tab" => Some(egui::Key::Tab), - "Backspace" => Some(egui::Key::Backspace), - "Enter" => Some(egui::Key::Enter), - "Space" | " " => Some(egui::Key::Space), + "Esc" | "Escape" => Some(Key::Escape), + "Tab" => Some(Key::Tab), + "Backspace" => Some(Key::Backspace), + "Enter" => Some(Key::Enter), + "Space" | " " => Some(Key::Space), - "Help" | "Insert" => Some(egui::Key::Insert), - "Delete" => Some(egui::Key::Delete), - "Home" => Some(egui::Key::Home), - "End" => Some(egui::Key::End), - "PageUp" => Some(egui::Key::PageUp), - "PageDown" => Some(egui::Key::PageDown), + "Help" | "Insert" => Some(Key::Insert), + "Delete" => Some(Key::Delete), + "Home" => Some(Key::Home), + "End" => Some(Key::End), + "PageUp" => Some(Key::PageUp), + "PageDown" => Some(Key::PageDown), - "0" => Some(egui::Key::Num0), - "1" => Some(egui::Key::Num1), - "2" => Some(egui::Key::Num2), - "3" => Some(egui::Key::Num3), - "4" => Some(egui::Key::Num4), - "5" => Some(egui::Key::Num5), - "6" => Some(egui::Key::Num6), - "7" => Some(egui::Key::Num7), - "8" => Some(egui::Key::Num8), - "9" => Some(egui::Key::Num9), + "-" => Some(Key::Minus), + "+" | "=" => Some(Key::PlusEquals), - "a" | "A" => Some(egui::Key::A), - "b" | "B" => Some(egui::Key::B), - "c" | "C" => Some(egui::Key::C), - "d" | "D" => Some(egui::Key::D), - "e" | "E" => Some(egui::Key::E), - "f" | "F" => Some(egui::Key::F), - "g" | "G" => Some(egui::Key::G), - "h" | "H" => Some(egui::Key::H), - "i" | "I" => Some(egui::Key::I), - "j" | "J" => Some(egui::Key::J), - "k" | "K" => Some(egui::Key::K), - "l" | "L" => Some(egui::Key::L), - "m" | "M" => Some(egui::Key::M), - "n" | "N" => Some(egui::Key::N), - "o" | "O" => Some(egui::Key::O), - "p" | "P" => Some(egui::Key::P), - "q" | "Q" => Some(egui::Key::Q), - "r" | "R" => Some(egui::Key::R), - "s" | "S" => Some(egui::Key::S), - "t" | "T" => Some(egui::Key::T), - "u" | "U" => Some(egui::Key::U), - "v" | "V" => Some(egui::Key::V), - "w" | "W" => Some(egui::Key::W), - "x" | "X" => Some(egui::Key::X), - "y" | "Y" => Some(egui::Key::Y), - "z" | "Z" => Some(egui::Key::Z), + "0" => Some(Key::Num0), + "1" => Some(Key::Num1), + "2" => Some(Key::Num2), + "3" => Some(Key::Num3), + "4" => Some(Key::Num4), + "5" => Some(Key::Num5), + "6" => Some(Key::Num6), + "7" => Some(Key::Num7), + "8" => Some(Key::Num8), + "9" => Some(Key::Num9), - "F1" => Some(egui::Key::F1), - "F2" => Some(egui::Key::F2), - "F3" => Some(egui::Key::F3), - "F4" => Some(egui::Key::F4), - "F5" => Some(egui::Key::F5), - "F6" => Some(egui::Key::F6), - "F7" => Some(egui::Key::F7), - "F8" => Some(egui::Key::F8), - "F9" => Some(egui::Key::F9), - "F10" => Some(egui::Key::F10), - "F11" => Some(egui::Key::F11), - "F12" => Some(egui::Key::F12), - "F13" => Some(egui::Key::F13), - "F14" => Some(egui::Key::F14), - "F15" => Some(egui::Key::F15), - "F16" => Some(egui::Key::F16), - "F17" => Some(egui::Key::F17), - "F18" => Some(egui::Key::F18), - "F19" => Some(egui::Key::F19), - "F20" => Some(egui::Key::F20), + "a" | "A" => Some(Key::A), + "b" | "B" => Some(Key::B), + "c" | "C" => Some(Key::C), + "d" | "D" => Some(Key::D), + "e" | "E" => Some(Key::E), + "f" | "F" => Some(Key::F), + "g" | "G" => Some(Key::G), + "h" | "H" => Some(Key::H), + "i" | "I" => Some(Key::I), + "j" | "J" => Some(Key::J), + "k" | "K" => Some(Key::K), + "l" | "L" => Some(Key::L), + "m" | "M" => Some(Key::M), + "n" | "N" => Some(Key::N), + "o" | "O" => Some(Key::O), + "p" | "P" => Some(Key::P), + "q" | "Q" => Some(Key::Q), + "r" | "R" => Some(Key::R), + "s" | "S" => Some(Key::S), + "t" | "T" => Some(Key::T), + "u" | "U" => Some(Key::U), + "v" | "V" => Some(Key::V), + "w" | "W" => Some(Key::W), + "x" | "X" => Some(Key::X), + "y" | "Y" => Some(Key::Y), + "z" | "Z" => Some(Key::Z), + + "F1" => Some(Key::F1), + "F2" => Some(Key::F2), + "F3" => Some(Key::F3), + "F4" => Some(Key::F4), + "F5" => Some(Key::F5), + "F6" => Some(Key::F6), + "F7" => Some(Key::F7), + "F8" => Some(Key::F8), + "F9" => Some(Key::F9), + "F10" => Some(Key::F10), + "F11" => Some(Key::F11), + "F12" => Some(Key::F12), + "F13" => Some(Key::F13), + "F14" => Some(Key::F14), + "F15" => Some(Key::F15), + "F16" => Some(Key::F16), + "F17" => Some(Key::F17), + "F18" => Some(Key::F18), + "F19" => Some(Key::F19), + "F20" => Some(Key::F20), _ => None, } diff --git a/crates/egui-winit/src/lib.rs b/crates/egui-winit/src/lib.rs index e9e99783..6dde4124 100644 --- a/crates/egui-winit/src/lib.rs +++ b/crates/egui-winit/src/lib.rs @@ -710,6 +710,11 @@ fn translate_virtual_key_code(key: winit::event::VirtualKeyCode) -> Option Key::PageUp, VirtualKeyCode::PageDown => Key::PageDown, + VirtualKeyCode::Minus => Key::Minus, + // Using Mac the key with the Plus sign on it is reported as the Equals key + // (with both English and Swedish keyboard). + VirtualKeyCode::Equals => Key::PlusEquals, + VirtualKeyCode::Key0 | VirtualKeyCode::Numpad0 => Key::Num0, VirtualKeyCode::Key1 | VirtualKeyCode::Numpad1 => Key::Num1, VirtualKeyCode::Key2 | VirtualKeyCode::Numpad2 => Key::Num2, diff --git a/crates/egui/src/context.rs b/crates/egui/src/context.rs index ca74b0f4..92b1c364 100644 --- a/crates/egui/src/context.rs +++ b/crates/egui/src/context.rs @@ -65,18 +65,25 @@ struct ContextImpl { } impl ContextImpl { - fn begin_frame_mut(&mut self, new_raw_input: RawInput) { + fn begin_frame_mut(&mut self, mut new_raw_input: RawInput) { self.has_requested_repaint_this_frame = false; // allow new calls during the frame + if let Some(new_pixels_per_point) = self.memory.new_pixels_per_point.take() { + new_raw_input.pixels_per_point = Some(new_pixels_per_point); + + // This is a bit hacky, but is required to avoid jitter: + let ratio = self.input.pixels_per_point / new_pixels_per_point; + let mut rect = self.input.screen_rect; + rect.min = (ratio * rect.min.to_vec2()).to_pos2(); + rect.max = (ratio * rect.max.to_vec2()).to_pos2(); + new_raw_input.screen_rect = Some(rect); + } + self.memory.begin_frame(&self.input, &new_raw_input); self.input = std::mem::take(&mut self.input) .begin_frame(new_raw_input, self.requested_repaint_last_frame); - if let Some(new_pixels_per_point) = self.memory.new_pixels_per_point.take() { - self.input.pixels_per_point = new_pixels_per_point; - } - self.frame_state.begin_frame(&self.input); self.update_fonts_mut(); diff --git a/crates/egui/src/data/input.rs b/crates/egui/src/data/input.rs index 6c3dfcc8..d87caec2 100644 --- a/crates/egui/src/data/input.rs +++ b/crates/egui/src/data/input.rs @@ -13,10 +13,10 @@ use crate::emath::*; #[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub struct RawInput { - /// Position and size of the area that egui should use. + /// Position and size of the area that egui should use, in points. /// Usually you would set this to /// - /// `Some(Rect::from_pos_size(Default::default(), screen_size))`. + /// `Some(Rect::from_pos_size(Default::default(), screen_size_in_points))`. /// /// but you could also constrain egui to some smaller portion of your window if you like. /// @@ -516,13 +516,13 @@ impl ModifierNames<'static> { concat: "", }; - /// Alt, Ctrl, Shift, Command + /// Alt, Ctrl, Shift, Cmd pub const NAMES: Self = Self { is_short: false, alt: "Alt", ctrl: "Ctrl", shift: "Shift", - mac_cmd: "Command", + mac_cmd: "Cmd", concat: "+", }; } @@ -585,6 +585,11 @@ pub enum Key { PageUp, PageDown, + /// The virtual keycode for the Minus key. + Minus, + /// The virtual keycode for the Plus/Equals key. + PlusEquals, + /// Either from the main row or from the numpad. Num0, /// Either from the main row or from the numpad. @@ -667,6 +672,8 @@ impl Key { Key::ArrowLeft => "⏴", Key::ArrowRight => "⏵", Key::ArrowUp => "⏶", + Key::Minus => "-", + Key::PlusEquals => "+", _ => self.name(), } } @@ -689,6 +696,8 @@ impl Key { Key::End => "End", Key::PageUp => "PageUp", Key::PageDown => "PageDown", + Key::Minus => "Minus", + Key::PlusEquals => "Plus", Key::Num0 => "0", Key::Num1 => "1", Key::Num2 => "2", diff --git a/crates/egui/src/gui_zoom.rs b/crates/egui/src/gui_zoom.rs new file mode 100644 index 00000000..9fb10957 --- /dev/null +++ b/crates/egui/src/gui_zoom.rs @@ -0,0 +1,117 @@ +//! Helpers for zooming the whole GUI of an app (changing [`Context::pixels_per_point`]. +//! +use crate::*; + +/// The suggested keyboard shortcuts for global gui zooming. +pub mod kb_shortcuts { + use super::*; + + pub const ZOOM_IN: KeyboardShortcut = + KeyboardShortcut::new(Modifiers::COMMAND, Key::PlusEquals); + pub const ZOOM_OUT: KeyboardShortcut = KeyboardShortcut::new(Modifiers::COMMAND, Key::Minus); + pub const ZOOM_RESET: KeyboardShortcut = KeyboardShortcut::new(Modifiers::COMMAND, Key::Num0); +} + +/// Let the user scale the GUI (change `Context::pixels_per_point`) by pressing +/// Cmd+Plus, Cmd+Minus or Cmd+0, just like in a browser. +/// +/// When using [`eframe`](https://github.com/emilk/egui/tree/master/crates/eframe), you want to call this as: +/// ```ignore +/// // On web, the browser controls the gui zoom. +/// if !frame.is_web() { +/// egui::gui_zoom::zoom_with_keyboard_shortcuts( +/// ctx, +/// frame.info().native_pixels_per_point, +/// ); +/// } +/// ``` +pub fn zoom_with_keyboard_shortcuts(ctx: &Context, native_pixels_per_point: Option) { + if ctx.input_mut().consume_shortcut(&kb_shortcuts::ZOOM_RESET) { + if let Some(native_pixels_per_point) = native_pixels_per_point { + ctx.set_pixels_per_point(native_pixels_per_point); + } + } else { + if ctx.input_mut().consume_shortcut(&kb_shortcuts::ZOOM_IN) { + zoom_in(ctx); + } + if ctx.input_mut().consume_shortcut(&kb_shortcuts::ZOOM_OUT) { + zoom_out(ctx); + } + } +} + +const MIN_PIXELS_PER_POINT: f32 = 0.2; +const MAX_PIXELS_PER_POINT: f32 = 4.0; + +/// Make everything larger. +pub fn zoom_in(ctx: &Context) { + let mut pixels_per_point = ctx.pixels_per_point(); + pixels_per_point += 0.1; + pixels_per_point = pixels_per_point.clamp(MIN_PIXELS_PER_POINT, MAX_PIXELS_PER_POINT); + pixels_per_point = (pixels_per_point * 10.).round() / 10.; + ctx.set_pixels_per_point(pixels_per_point); +} + +/// Make everything smaller. +pub fn zoom_out(ctx: &Context) { + let mut pixels_per_point = ctx.pixels_per_point(); + pixels_per_point -= 0.1; + pixels_per_point = pixels_per_point.clamp(MIN_PIXELS_PER_POINT, MAX_PIXELS_PER_POINT); + pixels_per_point = (pixels_per_point * 10.).round() / 10.; + ctx.set_pixels_per_point(pixels_per_point); +} + +/// Show buttons for zooming the ui. +/// +/// This is meant to be called from within a menu (See [`Ui::menu_button`]). +/// +/// When using [`eframe`](https://github.com/emilk/egui/tree/master/crates/eframe), you want to call this as: +/// ```ignore +/// // On web, the browser controls the gui zoom. +/// if !frame.is_web() { +/// ui.menu_button("View", |ui| { +/// egui::gui_zoom::zoom_menu_buttons( +/// ui, +/// frame.info().native_pixels_per_point, +/// ); +/// }); +/// } +/// ``` +pub fn zoom_menu_buttons(ui: &mut Ui, native_pixels_per_point: Option) { + if ui + .add_enabled( + ui.ctx().pixels_per_point() < MAX_PIXELS_PER_POINT, + Button::new("Zoom In").shortcut_text(ui.ctx().format_shortcut(&kb_shortcuts::ZOOM_IN)), + ) + .clicked() + { + zoom_in(ui.ctx()); + ui.close_menu(); + } + + if ui + .add_enabled( + ui.ctx().pixels_per_point() > MIN_PIXELS_PER_POINT, + Button::new("Zoom Out") + .shortcut_text(ui.ctx().format_shortcut(&kb_shortcuts::ZOOM_OUT)), + ) + .clicked() + { + zoom_out(ui.ctx()); + ui.close_menu(); + } + + if let Some(native_pixels_per_point) = native_pixels_per_point { + if ui + .add_enabled( + ui.ctx().pixels_per_point() != native_pixels_per_point, + Button::new("Reset Zoom") + .shortcut_text(ui.ctx().format_shortcut(&kb_shortcuts::ZOOM_RESET)), + ) + .clicked() + { + ui.ctx().set_pixels_per_point(native_pixels_per_point); + ui.close_menu(); + } + } +} diff --git a/crates/egui/src/lib.rs b/crates/egui/src/lib.rs index 352369de..fe4c0491 100644 --- a/crates/egui/src/lib.rs +++ b/crates/egui/src/lib.rs @@ -305,6 +305,7 @@ mod context; mod data; mod frame_state; pub(crate) mod grid; +pub mod gui_zoom; mod id; mod input_state; pub mod introspection; diff --git a/crates/egui/src/os.rs b/crates/egui/src/os.rs index dea4dee1..fb59469d 100644 --- a/crates/egui/src/os.rs +++ b/crates/egui/src/os.rs @@ -65,6 +65,11 @@ impl OperatingSystem { { Self::Nix } else { + #[cfg(feature = "tracing")] + tracing::warn!( + "egui: Failed to guess operating system from User-Agent {:?}. Please file an issue at https://github.com/emilk/egui/issues", + user_agent); + Self::Unknown } } diff --git a/crates/egui_demo_app/src/backend_panel.rs b/crates/egui_demo_app/src/backend_panel.rs index 4fe61728..5d1b9a2c 100644 --- a/crates/egui_demo_app/src/backend_panel.rs +++ b/crates/egui_demo_app/src/backend_panel.rs @@ -161,13 +161,10 @@ impl BackendPanel { ui.monospace(format!("{:#?}", frame.info().web_info.location)); }); - // For instance: `eframe` web sets `pixels_per_point` every frame to force - // egui to use the same scale as the web zoom factor. - let integration_controls_pixels_per_point = ui.input().raw.pixels_per_point.is_some(); + // On web, the browser controls `pixels_per_point`. + let integration_controls_pixels_per_point = frame.is_web(); if !integration_controls_pixels_per_point { - if let Some(new_pixels_per_point) = self.pixels_per_point_ui(ui, &frame.info()) { - ui.ctx().set_pixels_per_point(new_pixels_per_point); - } + self.pixels_per_point_ui(ui, &frame.info()); } #[cfg(not(target_arch = "wasm32"))] @@ -202,27 +199,36 @@ impl BackendPanel { } } - fn pixels_per_point_ui( - &mut self, - ui: &mut egui::Ui, - info: &eframe::IntegrationInfo, - ) -> Option { - let pixels_per_point = self.pixels_per_point.get_or_insert_with(|| { - info.native_pixels_per_point - .unwrap_or_else(|| ui.ctx().pixels_per_point()) - }); + fn pixels_per_point_ui(&mut self, ui: &mut egui::Ui, info: &eframe::IntegrationInfo) { + let pixels_per_point = self + .pixels_per_point + .get_or_insert_with(|| ui.ctx().pixels_per_point()); + + let mut reset = false; ui.horizontal(|ui| { ui.spacing_mut().slider_width = 90.0; - ui.add( - egui::Slider::new(pixels_per_point, 0.5..=5.0) - .logarithmic(true) - .clamp_to_range(true) - .text("Scale"), - ) - .on_hover_text("Physical pixels per point."); + + let response = ui + .add( + egui::Slider::new(pixels_per_point, 0.5..=5.0) + .logarithmic(true) + .clamp_to_range(true) + .text("Scale"), + ) + .on_hover_text("Physical pixels per point."); + + if response.drag_released() { + // We wait until mouse release to activate: + ui.ctx().set_pixels_per_point(*pixels_per_point); + reset = true; + } else if !response.is_pointer_button_down_on() { + // When not dragging, show the current pixels_per_point so others can change it. + reset = true; + } + if let Some(native_pixels_per_point) = info.native_pixels_per_point { - let enabled = *pixels_per_point != native_pixels_per_point; + let enabled = ui.ctx().pixels_per_point() != native_pixels_per_point; if ui .add_enabled(enabled, egui::Button::new("Reset")) .on_hover_text(format!( @@ -231,16 +237,13 @@ impl BackendPanel { )) .clicked() { - *pixels_per_point = native_pixels_per_point; + ui.ctx().set_pixels_per_point(native_pixels_per_point); } } }); - // We wait until mouse release to activate: - if ui.ctx().is_using_pointer() { - None - } else { - Some(*pixels_per_point) + if reset { + self.pixels_per_point = None; } } diff --git a/crates/egui_demo_app/src/wrap_app.rs b/crates/egui_demo_app/src/wrap_app.rs index f68cdb05..dfe5e784 100644 --- a/crates/egui_demo_app/src/wrap_app.rs +++ b/crates/egui_demo_app/src/wrap_app.rs @@ -209,6 +209,11 @@ impl eframe::App for WrapApp { self.state.backend_panel.end_of_frame(ctx); self.ui_file_drag_and_drop(ctx); + + // On web, the browser controls `pixels_per_point`. + if !frame.is_web() { + egui::gui_zoom::zoom_with_keyboard_shortcuts(ctx, frame.info().native_pixels_per_point); + } } #[cfg(feature = "glow")] diff --git a/crates/egui_demo_lib/src/demo/demo_app_windows.rs b/crates/egui_demo_lib/src/demo/demo_app_windows.rs index be5b2b1f..1d772da7 100644 --- a/crates/egui_demo_lib/src/demo/demo_app_windows.rs +++ b/crates/egui_demo_lib/src/demo/demo_app_windows.rs @@ -321,6 +321,13 @@ fn file_menu_button(ui: &mut Ui) { ui.set_min_width(220.0); ui.style_mut().wrap = Some(false); + // On the web the browser controls the zoom + #[cfg(not(target_arch = "wasm32"))] + { + egui::gui_zoom::zoom_menu_buttons(ui, None); + ui.separator(); + } + if ui .add( egui::Button::new("Organize Windows") diff --git a/examples/hello_world/Cargo.toml b/examples/hello_world/Cargo.toml index c25ab134..45570bc0 100644 --- a/examples/hello_world/Cargo.toml +++ b/examples/hello_world/Cargo.toml @@ -10,3 +10,4 @@ publish = false [dependencies] eframe = { path = "../../crates/eframe" } +tracing-subscriber = "0.3" diff --git a/examples/hello_world/src/main.rs b/examples/hello_world/src/main.rs index 1936b8aa..a1f91f05 100644 --- a/examples/hello_world/src/main.rs +++ b/examples/hello_world/src/main.rs @@ -3,6 +3,9 @@ use eframe::egui; fn main() { + // Log to stdout (if you run with `RUST_LOG=debug`). + tracing_subscriber::fmt::init(); + let options = eframe::NativeOptions::default(); eframe::run_native( "My egui App",