Skip to content

Commit 14606a7

Browse files
committed
Add helper module egui::gui_zoom for zooming an app
1 parent 9be128e commit 14606a7

File tree

5 files changed

+115
-37
lines changed

5 files changed

+115
-37
lines changed

crates/egui/src/data/input.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ impl ModifierNames<'static> {
522522
alt: "Alt",
523523
ctrl: "Ctrl",
524524
shift: "Shift",
525-
mac_cmd: "Command",
525+
mac_cmd: "Cmd",
526526
concat: "+",
527527
};
528528
}

crates/egui/src/gui_zoom.rs

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
//! Helpers for zooming the whole GUI (changing [`Context::pixels_per_point`].
2+
use crate::*;
3+
4+
/// The suggested keyboard shortcuts for global gui zooming.
5+
pub mod kb_shortcuts {
6+
use super::*;
7+
8+
// Using winit on Mac the key with the Plus sign on it is reported as the Equals key
9+
// (with both English and Swedish keyboard).
10+
pub const ZOOM_IN: KeyboardShortcut = KeyboardShortcut::new(Modifiers::COMMAND, Key::Equals);
11+
pub const ZOOM_OUT: KeyboardShortcut = KeyboardShortcut::new(Modifiers::COMMAND, Key::Minus);
12+
pub const ZOOM_RESET: KeyboardShortcut = KeyboardShortcut::new(Modifiers::COMMAND, Key::Num0);
13+
}
14+
15+
/// Let the user scale the GUI (change `Context::pixels_per_point`) by pressing
16+
/// Cmd+Plus, Cmd+Minus or Cmd+0, just like in a browser.
17+
///
18+
/// When using [`eframe`](https://github.com/emilk/egui/tree/master/crates/eframe), you want to call this as:
19+
/// ```ignore
20+
/// // On web, the browser controls `pixels_per_point`.
21+
/// if !frame.is_web() {
22+
/// egui::gui_zoom::scale_ui_with_keyboard_shortcuts(
23+
/// ctx,
24+
/// frame.info().native_pixels_per_point,
25+
/// );
26+
/// }
27+
/// ```
28+
pub fn scale_ui_with_keyboard_shortcuts(ctx: &Context, native_pixels_per_point: Option<f32>) {
29+
if ctx.input_mut().consume_shortcut(&kb_shortcuts::ZOOM_RESET) {
30+
if let Some(native_pixels_per_point) = native_pixels_per_point {
31+
ctx.set_pixels_per_point(native_pixels_per_point);
32+
}
33+
} else {
34+
if ctx.input_mut().consume_shortcut(&kb_shortcuts::ZOOM_IN) {
35+
zoom_in(ctx);
36+
}
37+
if ctx.input_mut().consume_shortcut(&kb_shortcuts::ZOOM_OUT) {
38+
zoom_out(ctx);
39+
}
40+
}
41+
}
42+
43+
const MIN_PIXELS_PER_POINT: f32 = 0.2;
44+
const MAX_PIXELS_PER_POINT: f32 = 4.0;
45+
46+
/// Make everything larger.
47+
pub fn zoom_in(ctx: &Context) {
48+
let mut pixels_per_point = ctx.pixels_per_point();
49+
pixels_per_point += 0.1;
50+
pixels_per_point = pixels_per_point.clamp(MIN_PIXELS_PER_POINT, MAX_PIXELS_PER_POINT);
51+
pixels_per_point = (pixels_per_point * 10.).round() / 10.;
52+
ctx.set_pixels_per_point(pixels_per_point);
53+
}
54+
55+
/// Make everything smaller.
56+
pub fn zoom_out(ctx: &Context) {
57+
let mut pixels_per_point = ctx.pixels_per_point();
58+
pixels_per_point -= 0.1;
59+
pixels_per_point = pixels_per_point.clamp(MIN_PIXELS_PER_POINT, MAX_PIXELS_PER_POINT);
60+
pixels_per_point = (pixels_per_point * 10.).round() / 10.;
61+
ctx.set_pixels_per_point(pixels_per_point);
62+
}
63+
64+
/// Show buttons for zooming the ui.
65+
pub fn zoom_menu_buttons(ui: &mut Ui, native_pixels_per_point: Option<f32>) {
66+
if ui
67+
.add_enabled(
68+
ui.ctx().pixels_per_point() < MAX_PIXELS_PER_POINT,
69+
Button::new("Zoom In").shortcut_text(ui.ctx().format_shortcut(&kb_shortcuts::ZOOM_IN)),
70+
)
71+
.clicked()
72+
{
73+
zoom_in(ui.ctx());
74+
ui.close_menu();
75+
}
76+
77+
if ui
78+
.add_enabled(
79+
ui.ctx().pixels_per_point() > MIN_PIXELS_PER_POINT,
80+
Button::new("Zoom Out")
81+
.shortcut_text(ui.ctx().format_shortcut(&kb_shortcuts::ZOOM_OUT)),
82+
)
83+
.clicked()
84+
{
85+
zoom_out(ui.ctx());
86+
ui.close_menu();
87+
}
88+
89+
if let Some(native_pixels_per_point) = native_pixels_per_point {
90+
if ui
91+
.add_enabled(
92+
ui.ctx().pixels_per_point() != native_pixels_per_point,
93+
Button::new("Reset Zoom")
94+
.shortcut_text(ui.ctx().format_shortcut(&kb_shortcuts::ZOOM_RESET)),
95+
)
96+
.clicked()
97+
{
98+
ui.ctx().set_pixels_per_point(native_pixels_per_point);
99+
ui.close_menu();
100+
}
101+
}
102+
}

crates/egui/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ mod context;
305305
mod data;
306306
mod frame_state;
307307
pub(crate) mod grid;
308+
pub mod gui_zoom;
308309
mod id;
309310
mod input_state;
310311
pub mod introspection;

crates/egui_demo_app/src/wrap_app.rs

+4-36
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,10 @@ impl eframe::App for WrapApp {
212212

213213
// On web, the browser controls `pixels_per_point`.
214214
if !frame.is_web() {
215-
scale_ui_with_keyboard_shortcuts(ctx, frame.info().native_pixels_per_point);
215+
egui::gui_zoom::scale_ui_with_keyboard_shortcuts(
216+
ctx,
217+
frame.info().native_pixels_per_point,
218+
);
216219
}
217220
}
218221

@@ -404,38 +407,3 @@ fn clock_button(ui: &mut egui::Ui, seconds_since_midnight: f64) -> egui::Respons
404407

405408
ui.button(egui::RichText::new(time).monospace())
406409
}
407-
408-
/// Let the user scale the GUI (change `pixels_per_point`) by pressing
409-
/// Cmd+Plus, Cmd+Minus or Cmd+0, just like in a browser.
410-
fn scale_ui_with_keyboard_shortcuts(ctx: &egui::Context, native_pixels_per_point: Option<f32>) {
411-
// Using winit on Mac the key with the Plus sign on it is reported as the Equals key
412-
// (with both English and Swedish keyboard).
413-
let zoom_in = egui::KeyboardShortcut::new(egui::Modifiers::COMMAND, egui::Key::Equals);
414-
let zoom_out = egui::KeyboardShortcut::new(egui::Modifiers::COMMAND, egui::Key::Minus);
415-
let reset = egui::KeyboardShortcut::new(egui::Modifiers::COMMAND, egui::Key::Num0);
416-
417-
let zoom_in = ctx.input_mut().consume_shortcut(&zoom_in);
418-
let zoom_out = ctx.input_mut().consume_shortcut(&zoom_out);
419-
let reset = ctx.input_mut().consume_shortcut(&reset);
420-
421-
let mut pixels_per_point = ctx.pixels_per_point();
422-
423-
if zoom_in {
424-
pixels_per_point += 0.1;
425-
}
426-
if zoom_out {
427-
pixels_per_point -= 0.1;
428-
}
429-
pixels_per_point = pixels_per_point.clamp(0.2, 5.);
430-
pixels_per_point = (pixels_per_point * 10.).round() / 10.;
431-
if reset {
432-
if let Some(native_pixels_per_point) = native_pixels_per_point {
433-
pixels_per_point = native_pixels_per_point;
434-
}
435-
}
436-
437-
if pixels_per_point != ctx.pixels_per_point() {
438-
tracing::debug!("Changed GUI scale to {}", pixels_per_point);
439-
ctx.set_pixels_per_point(pixels_per_point);
440-
}
441-
}

crates/egui_demo_lib/src/demo/demo_app_windows.rs

+7
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,13 @@ fn file_menu_button(ui: &mut Ui) {
321321
ui.set_min_width(220.0);
322322
ui.style_mut().wrap = Some(false);
323323

324+
// On the web the browser controls the zoom
325+
#[cfg(not(target_arch = "wasm32"))]
326+
{
327+
egui::gui_zoom::zoom_menu_buttons(ui, None);
328+
ui.separator();
329+
}
330+
324331
if ui
325332
.add(
326333
egui::Button::new("Organize Windows")

0 commit comments

Comments
 (0)