Skip to content

Commit

Permalink
Add helper module egui::gui_zoom for zooming an app
Browse files Browse the repository at this point in the history
  • Loading branch information
emilk committed Nov 5, 2022
1 parent 9be128e commit 14606a7
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 37 deletions.
2 changes: 1 addition & 1 deletion crates/egui/src/data/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ impl ModifierNames<'static> {
alt: "Alt",
ctrl: "Ctrl",
shift: "Shift",
mac_cmd: "Command",
mac_cmd: "Cmd",
concat: "+",
};
}
Expand Down
102 changes: 102 additions & 0 deletions crates/egui/src/gui_zoom.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
//! Helpers for zooming the whole GUI (changing [`Context::pixels_per_point`].
use crate::*;

/// The suggested keyboard shortcuts for global gui zooming.
pub mod kb_shortcuts {
use super::*;

// Using winit on Mac the key with the Plus sign on it is reported as the Equals key
// (with both English and Swedish keyboard).
pub const ZOOM_IN: KeyboardShortcut = KeyboardShortcut::new(Modifiers::COMMAND, Key::Equals);
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 `pixels_per_point`.
/// if !frame.is_web() {
/// egui::gui_zoom::scale_ui_with_keyboard_shortcuts(
/// ctx,
/// frame.info().native_pixels_per_point,
/// );
/// }
/// ```
pub fn scale_ui_with_keyboard_shortcuts(ctx: &Context, native_pixels_per_point: Option<f32>) {
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.
pub fn zoom_menu_buttons(ui: &mut Ui, native_pixels_per_point: Option<f32>) {
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();
}
}
}
1 change: 1 addition & 0 deletions crates/egui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
40 changes: 4 additions & 36 deletions crates/egui_demo_app/src/wrap_app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,10 @@ impl eframe::App for WrapApp {

// On web, the browser controls `pixels_per_point`.
if !frame.is_web() {
scale_ui_with_keyboard_shortcuts(ctx, frame.info().native_pixels_per_point);
egui::gui_zoom::scale_ui_with_keyboard_shortcuts(
ctx,
frame.info().native_pixels_per_point,
);
}
}

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

ui.button(egui::RichText::new(time).monospace())
}

/// Let the user scale the GUI (change `pixels_per_point`) by pressing
/// Cmd+Plus, Cmd+Minus or Cmd+0, just like in a browser.
fn scale_ui_with_keyboard_shortcuts(ctx: &egui::Context, native_pixels_per_point: Option<f32>) {
// Using winit on Mac the key with the Plus sign on it is reported as the Equals key
// (with both English and Swedish keyboard).
let zoom_in = egui::KeyboardShortcut::new(egui::Modifiers::COMMAND, egui::Key::Equals);
let zoom_out = egui::KeyboardShortcut::new(egui::Modifiers::COMMAND, egui::Key::Minus);
let reset = egui::KeyboardShortcut::new(egui::Modifiers::COMMAND, egui::Key::Num0);

let zoom_in = ctx.input_mut().consume_shortcut(&zoom_in);
let zoom_out = ctx.input_mut().consume_shortcut(&zoom_out);
let reset = ctx.input_mut().consume_shortcut(&reset);

let mut pixels_per_point = ctx.pixels_per_point();

if zoom_in {
pixels_per_point += 0.1;
}
if zoom_out {
pixels_per_point -= 0.1;
}
pixels_per_point = pixels_per_point.clamp(0.2, 5.);
pixels_per_point = (pixels_per_point * 10.).round() / 10.;
if reset {
if let Some(native_pixels_per_point) = native_pixels_per_point {
pixels_per_point = native_pixels_per_point;
}
}

if pixels_per_point != ctx.pixels_per_point() {
tracing::debug!("Changed GUI scale to {}", pixels_per_point);
ctx.set_pixels_per_point(pixels_per_point);
}
}
7 changes: 7 additions & 0 deletions crates/egui_demo_lib/src/demo/demo_app_windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down

0 comments on commit 14606a7

Please sign in to comment.