From d2166fed3d3f9e18a464fa720eb29294b28c2996 Mon Sep 17 00:00:00 2001 From: Imbris Date: Sat, 31 Oct 2020 16:04:20 -0400 Subject: [PATCH] Make iced ui use scale from the settings --- Cargo.lock | 5 --- Cargo.toml | 1 - voxygen/src/menu/char_selection/ui/mod.rs | 7 +++- voxygen/src/menu/main/ui/mod.rs | 7 +++- voxygen/src/ui/ice/mod.rs | 51 ++++++++++++++++------- voxygen/src/ui/ice/renderer/mod.rs | 15 +++++-- voxygen/src/ui/mod.rs | 2 +- voxygen/src/ui/scale.rs | 35 ++++++++++------ 8 files changed, 83 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2405bc9387..abf6abc16f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5838,8 +5838,3 @@ name = "xml-rs" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b07db065a5cf61a7e4ba64f29e67db906fb1787316516c4e6e5ff0fea1efcd8a" - -[[patch.unused]] -name = "glutin" -version = "0.24.1" -source = "git+https://github.com/rust-windowing/glutin.git?rev=63a1ea7d6e64c5112418cab9f21cd409f0afd7c2#63a1ea7d6e64c5112418cab9f21cd409f0afd7c2" diff --git a/Cargo.toml b/Cargo.toml index b58a64ead1..2c2721a2f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -80,5 +80,4 @@ debug = 1 [patch.crates-io] # cpal conflict fix isn't released yet winit = { git = "https://gitlab.com/veloren/winit.git", branch = "macos-test-spiffed" } -glutin = {git = "https://github.com/rust-windowing/glutin.git", rev="63a1ea7d6e64c5112418cab9f21cd409f0afd7c2"} vek = { git = "https://gitlab.com/veloren/vek.git", branch = "fix_intrinsics" } diff --git a/voxygen/src/menu/char_selection/ui/mod.rs b/voxygen/src/menu/char_selection/ui/mod.rs index 444a554dbc..3993ff82f5 100644 --- a/voxygen/src/menu/char_selection/ui/mod.rs +++ b/voxygen/src/menu/char_selection/ui/mod.rs @@ -1305,7 +1305,12 @@ impl CharSelectionUi { ui::ice::Font::try_from_vec(buf).unwrap() }; - let mut ui = Ui::new(&mut global_state.window, font).unwrap(); + let mut ui = Ui::new( + &mut global_state.window, + font, + global_state.settings.gameplay.ui_scale, + ) + .unwrap(); let fonts = Fonts::load(&i18n.fonts, &mut ui).expect("Impossible to load fonts"); diff --git a/voxygen/src/menu/main/ui/mod.rs b/voxygen/src/menu/main/ui/mod.rs index eabcd0d706..9ccbb7b7d7 100644 --- a/voxygen/src/menu/main/ui/mod.rs +++ b/voxygen/src/menu/main/ui/mod.rs @@ -505,7 +505,12 @@ impl<'a> MainMenuUi { Font::try_from_vec(buf).unwrap() }; - let mut ui = Ui::new(&mut global_state.window, font).unwrap(); + let mut ui = Ui::new( + &mut global_state.window, + font, + global_state.settings.gameplay.ui_scale, + ) + .unwrap(); let fonts = Fonts::load(&i18n.fonts, &mut ui).expect("Impossible to load fonts"); diff --git a/voxygen/src/ui/ice/mod.rs b/voxygen/src/ui/ice/mod.rs index 6538cef61a..aba416c448 100644 --- a/voxygen/src/ui/ice/mod.rs +++ b/voxygen/src/ui/ice/mod.rs @@ -30,10 +30,15 @@ pub struct IcedUi { // Scaling of the ui scale: Scale, window_resized: Option>, + scale_mode_changed: bool, } impl IcedUi { - pub fn new(window: &mut Window, default_font: Font) -> Result { - let scale = Scale::new(window, ScaleMode::Absolute(1.0)); + pub fn new( + window: &mut Window, + default_font: Font, + scale_mode: ScaleMode, + ) -> Result { + let scale = Scale::new(window, scale_mode, 1.2); let renderer = window.renderer_mut(); let scaled_dims = scale.scaled_window_size().map(|e| e as f32); @@ -48,6 +53,7 @@ impl IcedUi { cursor_position: Vec2::zero(), scale, window_resized: None, + scale_mode_changed: false, }) } @@ -59,6 +65,14 @@ impl IcedUi { self.renderer.add_graphic(graphic) } + pub fn scale(&self) -> Scale { self.scale } + + pub fn set_scaling_mode(&mut self, mode: ScaleMode) { + self.scale.set_scaling_mode(mode); + // Signal that change needs to be handled + self.scale_mode_changed = true; + } + pub fn handle_event(&mut self, event: Event) { use iced::window; match event { @@ -66,7 +80,9 @@ impl IcedUi { // TODO: examine if we are handling dpi properly here // ideally these values should be the logical ones Event::Window(window::Event::Resized { width, height }) => { - self.window_resized = Some(Vec2::new(width, height)); + if width != 0 && height != 0 { + self.window_resized = Some(Vec2::new(width, height)); + } }, // Scale cursor movement events // Note: in some cases the scaling could be off if a resized event occured in the same @@ -78,12 +94,12 @@ impl IcedUi { // may need to handle this in a different way to address // whatever issue iced was trying to address self.cursor_position = Vec2 { - x: x * scale, - y: y * scale, + x: x / scale, + y: y / scale, }; self.events.push(Event::Mouse(mouse::Event::CursorMoved { - x: x * scale, - y: y * scale, + x: x / scale, + y: y / scale, })); }, // Scale pixel scrolling events @@ -94,8 +110,8 @@ impl IcedUi { let scale = self.scale.scale_factor_logical() as f32; self.events.push(Event::Mouse(mouse::Event::WheelScrolled { delta: mouse::ScrollDelta::Pixels { - x: x * scale, - y: y * scale, + x: x / scale, + y: y / scale, }, })); }, @@ -111,26 +127,33 @@ impl IcedUi { root: E, renderer: &mut Renderer, ) -> (Vec, mouse::Interaction) { - // Handle window resizing - if let Some(new_dims) = self.window_resized.take() { + // Handle window resizing and scale mode changing + let scaled_dims = if let Some(new_dims) = self.window_resized.take() { let old_scaled_dims = self.scale.scaled_window_size(); // TODO maybe use u32 in Scale to be consistent with iced self.scale .window_resized(new_dims.map(|e| e as f64), renderer); let scaled_dims = self.scale.scaled_window_size(); + // Avoid resetting cache if window size didn't change + (scaled_dims != old_scaled_dims).then_some(scaled_dims) + } else if self.scale_mode_changed { + Some(self.scale.scaled_window_size()) + } else { + None + }; + if let Some(scaled_dims) = scaled_dims { + self.scale_mode_changed = false; self.events .push(Event::Window(iced::window::Event::Resized { width: scaled_dims.x as u32, height: scaled_dims.y as u32, })); - // Avoid panic in graphic cache when minimizing. - // Avoid resetting cache if window size didn't change // Somewhat inefficient for elements that won't change size after a window // resize let res = renderer.get_resolution(); - if res.x > 0 && res.y > 0 && scaled_dims != old_scaled_dims { + if res.x > 0 && res.y > 0 { self.renderer .resize(scaled_dims.map(|e| e as f32), renderer); } diff --git a/voxygen/src/ui/ice/renderer/mod.rs b/voxygen/src/ui/ice/renderer/mod.rs index c507b4c42f..45c72d5736 100644 --- a/voxygen/src/ui/ice/renderer/mod.rs +++ b/voxygen/src/ui/ice/renderer/mod.rs @@ -466,6 +466,17 @@ impl IcedRenderer { ..bounds }); + let resolution = Vec2::new( + (gl_aabr.size().w * self.half_res.x).round() as u16, + (gl_aabr.size().h * self.half_res.y).round() as u16, + ); + + // Don't do anything if resolution is zero + if resolution.map(|e| e == 0).reduce_or() { + return; + // TODO: consider logging uneeded elements + } + let graphic_cache = self.cache.graphic_cache_mut(); match graphic_cache.get_graphic(graphic_id) { @@ -473,10 +484,6 @@ impl IcedRenderer { _ => {}, } - let resolution = Vec2::new( - (gl_aabr.size().w * self.half_res.x).round() as u16, - (gl_aabr.size().h * self.half_res.y).round() as u16, - ); // Transform the source rectangle into uv coordinate. // TODO: Make sure this is right. let source_aabr = { diff --git a/voxygen/src/ui/mod.rs b/voxygen/src/ui/mod.rs index 6ff7d67c8c..e7fc961c17 100644 --- a/voxygen/src/ui/mod.rs +++ b/voxygen/src/ui/mod.rs @@ -125,7 +125,7 @@ pub struct Ui { impl Ui { pub fn new(window: &mut Window) -> Result { - let scale = Scale::new(window, ScaleMode::Absolute(1.0)); + let scale = Scale::new(window, ScaleMode::Absolute(1.0), 1.0); let win_dims = scale.scaled_window_size().into_array(); let renderer = window.renderer_mut(); diff --git a/voxygen/src/ui/scale.rs b/voxygen/src/ui/scale.rs index 2845585b77..6b7ecfde42 100644 --- a/voxygen/src/ui/scale.rs +++ b/voxygen/src/ui/scale.rs @@ -22,16 +22,19 @@ pub struct Scale { scale_factor: f64, // Current logical window size window_dims: Vec2, + // TEMP + extra_factor: f64, } impl Scale { - pub fn new(window: &Window, mode: ScaleMode) -> Self { + pub fn new(window: &Window, mode: ScaleMode, extra_factor: f64) -> Self { let window_dims = window.logical_size(); let scale_factor = window.renderer().get_resolution().x as f64 / window_dims.x; Scale { mode, scale_factor, window_dims, + extra_factor, } } @@ -50,20 +53,23 @@ impl Scale { ScaleMode::RelativeToWindow(self.window_dims.map(|e| e / scale)) } - // Calculate factor to transform between logical coordinates and our scaled - // coordinates. + /// Calculate factor to transform between logical coordinates and our scaled + /// coordinates. + /// Multiply by scaled coordinates to get the logical coordinates pub fn scale_factor_logical(&self) -> f64 { - match self.mode { - ScaleMode::Absolute(scale) => scale / self.scale_factor, - ScaleMode::DpiFactor => 1.0, - ScaleMode::RelativeToWindow(dims) => { - (self.window_dims.x / dims.x).min(self.window_dims.y / dims.y) - }, - } + self.extra_factor + * match self.mode { + ScaleMode::Absolute(scale) => scale / self.scale_factor, + ScaleMode::DpiFactor => 1.0, + ScaleMode::RelativeToWindow(dims) => { + (self.window_dims.x / dims.x).min(self.window_dims.y / dims.y) + }, + } } - // Calculate factor to transform between physical coordinates and our scaled - // coordinates. + /// Calculate factor to transform between physical coordinates and our + /// scaled coordinates. + /// Multiply by scaled coordinates to get the physical coordinates pub fn scale_factor_physical(&self) -> f64 { self.scale_factor_logical() * self.scale_factor } // Updates internal window size (and/or scale_factor). @@ -72,9 +78,12 @@ impl Scale { self.window_dims = new_dims; } - // Get scaled window size. + /// Get scaled window size. pub fn scaled_window_size(&self) -> Vec2 { self.window_dims / self.scale_factor_logical() } + /// Get logical window size + pub fn window_size(&self) -> Vec2 { self.window_dims } + // Transform point from logical to scaled coordinates. pub fn scale_point(&self, point: Vec2) -> Vec2 { point / self.scale_factor_logical() } }