Add helpers for zooming an app using Ctrl+Plus and Ctrl+Minus (#2239)
* 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
This commit is contained in:
parent
25718f2774
commit
a0b3f1126b
15 changed files with 290 additions and 112 deletions
|
@ -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
|
||||
|
|
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1926,6 +1926,7 @@ name = "hello_world"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"eframe",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
12
Cargo.toml
12
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
|
||||
|
|
|
@ -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<egui::Key> {
|
||||
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,
|
||||
}
|
||||
|
|
|
@ -710,6 +710,11 @@ fn translate_virtual_key_code(key: winit::event::VirtualKeyCode) -> Option<egui:
|
|||
VirtualKeyCode::PageUp => 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,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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",
|
||||
|
|
117
crates/egui/src/gui_zoom.rs
Normal file
117
crates/egui/src/gui_zoom.rs
Normal file
|
@ -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<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.
|
||||
///
|
||||
/// 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<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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<f32> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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")]
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -10,3 +10,4 @@ publish = false
|
|||
|
||||
[dependencies]
|
||||
eframe = { path = "../../crates/eframe" }
|
||||
tracing-subscriber = "0.3"
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in a new issue