mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-24 01:15:12 +03:00
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:
parent
bc3a121cd6
commit
0697e1f649
@ -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);
|
||||
|
@ -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) {}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user