Make iced ui use scale from the settings

This commit is contained in:
Imbris 2020-10-31 16:04:20 -04:00
parent eda7b380dd
commit d2166fed3d
8 changed files with 83 additions and 40 deletions

5
Cargo.lock generated
View File

@ -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"

View File

@ -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" }

View File

@ -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");

View File

@ -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");

View File

@ -30,10 +30,15 @@ pub struct IcedUi {
// Scaling of the ui
scale: Scale,
window_resized: Option<Vec2<u32>>,
scale_mode_changed: bool,
}
impl IcedUi {
pub fn new(window: &mut Window, default_font: Font) -> Result<Self, Error> {
let scale = Scale::new(window, ScaleMode::Absolute(1.0));
pub fn new(
window: &mut Window,
default_font: Font,
scale_mode: ScaleMode,
) -> Result<Self, Error> {
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<M>, 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);
}

View File

@ -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 = {

View File

@ -125,7 +125,7 @@ pub struct Ui {
impl Ui {
pub fn new(window: &mut Window) -> Result<Self, Error> {
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();

View File

@ -22,16 +22,19 @@ pub struct Scale {
scale_factor: f64,
// Current logical window size
window_dims: Vec2<f64>,
// 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<f64> { self.window_dims / self.scale_factor_logical() }
/// Get logical window size
pub fn window_size(&self) -> Vec2<f64> { self.window_dims }
// Transform point from logical to scaled coordinates.
pub fn scale_point(&self, point: Vec2<f64>) -> Vec2<f64> { point / self.scale_factor_logical() }
}