2019-04-26 04:29:35 +00:00
|
|
|
use crate::{render::Renderer, window::Window};
|
2019-07-26 02:28:53 +00:00
|
|
|
use serde_derive::{Deserialize, Serialize};
|
2019-04-26 04:29:35 +00:00
|
|
|
use vek::*;
|
|
|
|
|
2019-05-17 09:22:32 +00:00
|
|
|
/// Type of scaling to use.
|
2019-07-26 02:28:53 +00:00
|
|
|
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
2019-04-26 04:29:35 +00:00
|
|
|
pub enum ScaleMode {
|
2019-05-17 09:22:32 +00:00
|
|
|
// Scale against physical size.
|
2019-04-26 04:29:35 +00:00
|
|
|
Absolute(f64),
|
2019-05-17 09:22:32 +00:00
|
|
|
// Use the dpi factor provided by the windowing system (i.e. use logical size).
|
2019-04-26 04:29:35 +00:00
|
|
|
DpiFactor,
|
2019-05-17 09:22:32 +00:00
|
|
|
// Scale based on the window's physical size, but maintain aspect ratio of widgets.
|
|
|
|
// Contains width and height of the "default" window size (ie where there should be no scaling).
|
2019-04-26 04:29:35 +00:00
|
|
|
RelativeToWindow(Vec2<f64>),
|
|
|
|
}
|
|
|
|
|
2019-07-26 02:28:53 +00:00
|
|
|
#[derive(Clone, Copy)]
|
2019-04-26 04:29:35 +00:00
|
|
|
pub struct Scale {
|
|
|
|
mode: ScaleMode,
|
|
|
|
// Current dpi factor
|
|
|
|
dpi_factor: f64,
|
|
|
|
// Current logical window size
|
|
|
|
window_dims: Vec2<f64>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Scale {
|
|
|
|
pub fn new(window: &Window, mode: ScaleMode) -> Self {
|
|
|
|
let window_dims = window.logical_size();
|
|
|
|
let dpi_factor = window.renderer().get_resolution().x as f64 / window_dims.x;
|
|
|
|
Scale {
|
|
|
|
mode,
|
|
|
|
dpi_factor,
|
|
|
|
window_dims,
|
|
|
|
}
|
|
|
|
}
|
2019-05-17 09:22:32 +00:00
|
|
|
// Change the scaling mode.
|
2019-07-26 02:28:53 +00:00
|
|
|
pub fn set_scaling_mode(&mut self, mode: ScaleMode) {
|
2019-04-26 04:29:35 +00:00
|
|
|
self.mode = mode;
|
|
|
|
}
|
2019-07-26 02:28:53 +00:00
|
|
|
// Get scaling mode transformed into absolute scaling
|
|
|
|
pub fn scaling_mode_as_absolute(&self) -> ScaleMode {
|
|
|
|
ScaleMode::Absolute(self.scale_factor_physical())
|
|
|
|
}
|
|
|
|
// Get scaling mode transformed to be relative to the window with the same aspect ratio as the current window
|
|
|
|
pub fn scaling_mode_as_relative(&self) -> ScaleMode {
|
|
|
|
let scale = self.scale_factor_logical();
|
|
|
|
ScaleMode::RelativeToWindow(self.window_dims.map(|e| e / scale))
|
|
|
|
}
|
2019-05-17 09:22:32 +00:00
|
|
|
// Calculate factor to transform between logical coordinates and our scaled coordinates.
|
2019-04-26 04:29:35 +00:00
|
|
|
pub fn scale_factor_logical(&self) -> f64 {
|
|
|
|
match self.mode {
|
|
|
|
ScaleMode::Absolute(scale) => scale / self.dpi_factor,
|
|
|
|
ScaleMode::DpiFactor => 1.0,
|
|
|
|
ScaleMode::RelativeToWindow(dims) => {
|
|
|
|
(self.window_dims.x / dims.x).min(self.window_dims.y / dims.y)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-05-17 09:22:32 +00:00
|
|
|
// Calculate factor to transform between physical coordinates and our scaled coordinates.
|
2019-04-26 04:29:35 +00:00
|
|
|
pub fn scale_factor_physical(&self) -> f64 {
|
|
|
|
self.scale_factor_logical() * self.dpi_factor
|
|
|
|
}
|
2019-05-17 09:22:32 +00:00
|
|
|
// Updates internal window size (and/or dpi_factor).
|
2019-04-26 04:29:35 +00:00
|
|
|
pub fn window_resized(&mut self, new_dims: Vec2<f64>, renderer: &Renderer) {
|
|
|
|
self.dpi_factor = renderer.get_resolution().x as f64 / new_dims.x;
|
|
|
|
self.window_dims = new_dims;
|
|
|
|
}
|
2019-05-17 09:22:32 +00:00
|
|
|
// Get scaled window size.
|
2019-04-26 04:29:35 +00:00
|
|
|
pub fn scaled_window_size(&self) -> Vec2<f64> {
|
|
|
|
self.window_dims / self.scale_factor_logical()
|
|
|
|
}
|
2019-05-17 09:22:32 +00:00
|
|
|
// Transform point from logical to scaled coordinates.
|
2019-04-26 04:29:35 +00:00
|
|
|
pub fn scale_point(&self, point: Vec2<f64>) -> Vec2<f64> {
|
|
|
|
point / self.scale_factor_logical()
|
|
|
|
}
|
|
|
|
}
|