make minimap fixed size

On very large windows, the minimap felt a little weird.

Plus, looked weird on very short windows, since we were only considering
width, not height,

Now that layout is all in logical pixels, we're more likely to get
reasonable layout using "fixed-size" components, and only judicious use
of components that scale with the window.
This commit is contained in:
Michael Kirk 2021-04-14 14:25:59 -07:00 committed by Dustin Carlino
parent bc3a121cd6
commit 0697e1f649
2 changed files with 44 additions and 18 deletions

View File

@ -3,11 +3,14 @@ use std::marker::PhantomData;
use geom::{Distance, Pt2D, Ring, Time};
use widgetry::{
ControlState, Drawable, EventCtx, Filler, GfxCtx, HorizontalAlignment, Line, Outcome, Panel,
ScreenPt, Spinner, Transition, VerticalAlignment, Widget,
ScreenDims, ScreenPt, Spinner, Transition, VerticalAlignment, Widget,
};
use crate::AppLike;
static MINIMAP_WIDTH: f64 = 400.0;
static MINIMAP_HEIGHT: f64 = 300.0;
// TODO Some of the math in here might assume map bound minimums start at (0, 0).
pub struct Minimap<A: AppLike, T: MinimapControls<A>> {
controls: T,
@ -164,6 +167,9 @@ impl<A: AppLike + 'static, T: MinimapControls<A>> Minimap<A, T> {
.margin_above(26)
};
let minimap_widget =
Filler::fixed_dims(ScreenDims::new(MINIMAP_WIDTH, MINIMAP_HEIGHT)).named("minimap");
let minimap_controls = {
let buttons = ctx.style().btn_plain.btn().padding(4);
Widget::col(vec![
@ -178,7 +184,7 @@ impl<A: AppLike + 'static, T: MinimapControls<A>> Minimap<A, T> {
.image_path("system/assets/minimap/left.svg")
.build_widget(ctx, "pan left")
.centered_vert(),
Filler::square_width(ctx, 0.15).named("minimap"),
minimap_widget,
buttons
.clone()
.image_path("system/assets/minimap/right.svg")
@ -298,10 +304,11 @@ impl<A: AppLike + 'static, T: MinimapControls<A>> Minimap<A, T> {
// When the window is resized, just reset completely. This is important when the window
// size at startup is incorrect and immediately corrected by the window manager after
// Minimap::new happens.
let bounds = app.map().get_bounds();
// On Windows, apparently minimizing can cause some resize events with 0, 0 dimensions!
self.base_zoom =
(0.15 * ctx.canvas.window_width / bounds.width().min(bounds.height())).max(0.0001);
let map_bounds = app.map().get_bounds();
// scale minimap to cover area
self.base_zoom = (MINIMAP_WIDTH / map_bounds.width())
.max(MINIMAP_HEIGHT / map_bounds.height())
.max(0.001);
self.zoom = self.base_zoom;
if self.zoomed {
self.recenter(ctx, app);

View File

@ -3,38 +3,57 @@ use crate::{EventCtx, GfxCtx, ScreenDims, ScreenPt, Widget, WidgetImpl, WidgetOu
/// Doesn't do anything by itself, just used for widgetsing. Something else reaches in, asks for the
/// ScreenRectangle to use.
pub struct Filler {
dims: ScreenDims,
resize: ResizeRule,
}
square_width_pct: f64,
enum ResizeRule {
FixedSize(ScreenDims),
// (ratio_of_parent_width, parent_width)
RatioWidthSquare(f64, f64),
}
impl ResizeRule {
fn dims(&self) -> ScreenDims {
match self {
Self::FixedSize(dims) => *dims,
Self::RatioWidthSquare(pct_width, width) => ScreenDims::square(pct_width * width),
}
}
}
impl Filler {
/// Creates a square filler, always some percentage of the window width.
pub fn square_width(ctx: &EventCtx, pct_width: f64) -> Widget {
Widget::new(Box::new(Filler {
dims: ScreenDims::new(
pct_width * ctx.canvas.window_width,
pct_width * ctx.canvas.window_width,
),
square_width_pct: pct_width,
resize: ResizeRule::RatioWidthSquare(pct_width, ctx.canvas.window_width),
}))
}
pub fn fixed_dims(dims: ScreenDims) -> Widget {
Widget::new(Box::new(Filler {
resize: ResizeRule::FixedSize(dims),
}))
}
}
impl WidgetImpl for Filler {
fn get_dims(&self) -> ScreenDims {
self.dims
self.resize.dims()
}
fn set_pos(&mut self, _: ScreenPt) {}
fn event(&mut self, ctx: &mut EventCtx, _: &mut WidgetOutput) {
if ctx.input.is_window_resized() {
self.dims = ScreenDims::new(
self.square_width_pct * ctx.canvas.window_width,
self.square_width_pct * ctx.canvas.window_width,
);
match self.resize {
ResizeRule::RatioWidthSquare(_, ref mut parent_width) => {
*parent_width = ctx.canvas.window_width;
}
_ => {}
};
}
}
fn draw(&self, _g: &mut GfxCtx) {}
}