On HiDPI screens with low resolution, allow widgetry applications to (#521)

* On HiDPI screens with low resolution, allow widgetry applications to
override the default scale factor in order to achieve a minimum width.
This commit is contained in:
Dustin Carlino 2021-02-22 15:59:57 -08:00 committed by GitHub
parent 03989bf3a6
commit ecf7c0c836
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 35 additions and 13 deletions

View File

@ -44,7 +44,9 @@ pub fn main() {
let mut settings = widgetry::Settings::new("A/B Street")
.read_svg(Box::new(abstio::slurp_bytes))
.window_icon(abstio::path("system/assets/pregame/icon.png"))
.loading_tips(map_gui::tools::loading_tips());
.loading_tips(map_gui::tools::loading_tips())
// This is approximately how much the 3 top panels in sandbox mode require.
.require_minimum_width(1500.0);
if args.enabled("--dump_raw_events") {
settings = settings.dump_raw_events();
}

View File

@ -15,8 +15,7 @@ pub struct Assets {
pub default_line_height: RefCell<f64>,
text_cache: RefCell<LruCache<String, GeomBatch>>,
line_height_cache: RefCell<HashMap<(Font, usize), f64>>,
// Keyed by filename, then scale factor mangled into a hashable form. Tuple doesn't work
// because of borrowing.
// Keyed by filename
svg_cache: RefCell<HashMap<String, (GeomBatch, Bounds)>>,
font_to_id: HashMap<Font, fontdb::ID>,
pub text_opts: Options,

View File

@ -1,4 +1,4 @@
use std::cell::{Cell, RefCell};
use std::cell::Cell;
use geom::{Bounds, Polygon, Pt2D};
@ -246,7 +246,7 @@ pub struct Prerender {
pub(crate) inner: PrerenderInnards,
pub(crate) assets: Assets,
pub(crate) num_uploads: Cell<usize>,
pub(crate) scale_factor: RefCell<f64>,
pub(crate) scale_factor: f64,
}
impl Prerender {
@ -274,7 +274,7 @@ impl Prerender {
}
pub(crate) fn get_scale_factor(&self) -> f64 {
*self.scale_factor.borrow()
self.scale_factor
}
pub(crate) fn window_size(&self) -> ScreenDims {

View File

@ -1,4 +1,4 @@
use std::cell::{Cell, RefCell};
use std::cell::Cell;
use std::panic;
use image::{GenericImageView, Pixel};
@ -159,6 +159,7 @@ pub struct Settings {
window_title: String,
dump_raw_events: bool,
scale_factor: Option<f64>,
require_minimum_width: Option<f64>,
window_icon: Option<String>,
loading_tips: Option<Text>,
read_svg: Box<dyn Fn(&str) -> Vec<u8>>,
@ -171,6 +172,7 @@ impl Settings {
window_title: window_title.to_string(),
dump_raw_events: false,
scale_factor: None,
require_minimum_width: None,
window_icon: None,
loading_tips: None,
read_svg: Box::new(|path| {
@ -198,6 +200,17 @@ impl Settings {
self
}
/// If the screen width using the monitor's detected scale factor is below this value (in units
/// of logical pixels, not physical), then force the scale factor to be 1. If `scale_factor()`
/// has been called, always use that override. This is helpful for users with HiDPI displays at
/// low resolutions, for applications designed for screens with some minimum width. Scaling
/// down UI elements isn't ideal (since it doesn't respect the user's device settings), but
/// having panels overlap is worse.
pub fn require_minimum_width(mut self, width: f64) -> Self {
self.require_minimum_width = Some(width);
self
}
/// Sets the window icon. This should be a 32x32 image.
pub fn window_icon(mut self, path: String) -> Self {
self.window_icon = Some(path);
@ -246,12 +259,24 @@ pub fn run<
}
let monitor_scale_factor = prerender_innards.monitor_scale_factor();
let prerender = Prerender {
let mut prerender = Prerender {
assets: Assets::new(settings.read_svg),
num_uploads: Cell::new(0),
inner: prerender_innards,
scale_factor: RefCell::new(settings.scale_factor.unwrap_or(monitor_scale_factor)),
scale_factor: settings.scale_factor.unwrap_or(monitor_scale_factor),
};
if let Some(min_width) = settings.require_minimum_width {
let initial_size = prerender.window_size();
if initial_size.width < min_width && settings.scale_factor.is_none() {
warn!(
"Monitor scale factor is {}, screen window is {}, but the application requires \
{}. Overriding the scale factor to 1.",
monitor_scale_factor, initial_size.width, min_width
);
prerender.scale_factor = 1.0;
}
}
let mut style = Style::standard();
style.loading_tips = settings.loading_tips.unwrap_or_else(Text::new);

View File

@ -139,10 +139,6 @@ impl ScreenDims {
}
}
}
pub fn scaled(&self, factor: f64) -> ScreenDims {
ScreenDims::new(self.width * factor, self.height * factor)
}
}
impl From<winit::dpi::LogicalSize<f64>> for ScreenDims {