mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-28 03:35:51 +03:00
make the pan buttons do something
This commit is contained in:
parent
517a35775f
commit
38bc88d54b
@ -8,17 +8,21 @@ use ezgui::{
|
||||
};
|
||||
use geom::{Circle, Distance, Pt2D, Ring};
|
||||
|
||||
// TODO Some of the math in here might assume map bound minimums start at (0, 0).
|
||||
pub struct Minimap {
|
||||
dragging: bool,
|
||||
nav_panel: Composite,
|
||||
|
||||
controls: VisibilityPanel,
|
||||
|
||||
zoom: f64,
|
||||
offset_x: f64,
|
||||
offset_y: f64,
|
||||
}
|
||||
|
||||
impl Minimap {
|
||||
pub fn new(ctx: &EventCtx, ui: &UI) -> Minimap {
|
||||
let square_len = 0.15 * ctx.canvas.window_width;
|
||||
Minimap {
|
||||
let mut m = Minimap {
|
||||
dragging: false,
|
||||
nav_panel: Composite::minimal_size_with_fillers(
|
||||
ctx,
|
||||
@ -70,7 +74,16 @@ impl Minimap {
|
||||
)],
|
||||
),
|
||||
controls: VisibilityPanel::new(ctx, ui),
|
||||
}
|
||||
|
||||
zoom: 0.0,
|
||||
offset_x: 0.0,
|
||||
offset_y: 0.0,
|
||||
};
|
||||
// Initially pick a zoom to fit the entire map's width in the minimap. Arbitrary and
|
||||
// probably pretty weird.
|
||||
let bounds = ui.primary.map.get_bounds();
|
||||
m.zoom = m.nav_panel.filler_rect("minimap").width() / (bounds.max_x - bounds.min_x);
|
||||
m
|
||||
}
|
||||
|
||||
pub fn event(&mut self, ui: &mut UI, ctx: &mut EventCtx) -> Option<Transition> {
|
||||
@ -78,10 +91,15 @@ impl Minimap {
|
||||
return Some(t);
|
||||
}
|
||||
|
||||
let pan_speed = 100.0;
|
||||
match self.nav_panel.event(ctx) {
|
||||
Some(Outcome::Clicked(x)) => {
|
||||
println!("clicked {}", x);
|
||||
}
|
||||
Some(Outcome::Clicked(x)) => match x {
|
||||
x if x == "pan up" => self.offset_y -= pan_speed * self.zoom,
|
||||
x if x == "pan down" => self.offset_y += pan_speed * self.zoom,
|
||||
x if x == "pan left" => self.offset_x -= pan_speed * self.zoom,
|
||||
x if x == "pan right" => self.offset_x += pan_speed * self.zoom,
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => {}
|
||||
}
|
||||
|
||||
@ -101,17 +119,13 @@ impl Minimap {
|
||||
return None;
|
||||
}
|
||||
|
||||
let percent_x = (pt.x - inner_rect.x1) / (inner_rect.x2 - inner_rect.x1);
|
||||
let percent_y = (pt.y - inner_rect.y1) / (inner_rect.y2 - inner_rect.y1);
|
||||
let percent_x = (pt.x - inner_rect.x1) / inner_rect.width();
|
||||
let percent_y = (pt.y - inner_rect.y1) / inner_rect.height();
|
||||
|
||||
let bounds = ui.primary.map.get_bounds();
|
||||
let zoom = inner_rect.width() / (bounds.max_x - bounds.min_x);
|
||||
|
||||
// We're stretching to fit the entire width, so...
|
||||
let map_x = percent_x * (bounds.max_x - bounds.min_x);
|
||||
// The y2 on the map that we're currently displaying
|
||||
let map_y2 = bounds.min_y + (inner_rect.y2 - inner_rect.y1) / zoom;
|
||||
let map_pt = Pt2D::new(map_x, percent_y * (map_y2 - bounds.min_y));
|
||||
let map_pt = Pt2D::new(
|
||||
(self.offset_x + percent_x * inner_rect.width()) / self.zoom,
|
||||
(self.offset_y + percent_y * inner_rect.height()) / self.zoom,
|
||||
);
|
||||
ctx.canvas.center_on_map_pt(map_pt);
|
||||
|
||||
None
|
||||
@ -126,16 +140,19 @@ impl Minimap {
|
||||
|
||||
self.nav_panel.draw(g);
|
||||
|
||||
// The map
|
||||
let inner_rect = self.nav_panel.filler_rect("minimap");
|
||||
let bounds = ui.primary.map.get_bounds();
|
||||
// Fit the entire width of the map in the box, to start
|
||||
let zoom = inner_rect.width() / (bounds.max_x - bounds.min_x);
|
||||
|
||||
let mut map_bounds = ui.primary.map.get_bounds().clone();
|
||||
// Adjust bounds to account for the current pan and zoom
|
||||
map_bounds.min_x = (map_bounds.min_x + self.offset_x) / self.zoom;
|
||||
map_bounds.min_y = (map_bounds.min_y + self.offset_y) / self.zoom;
|
||||
map_bounds.max_x = map_bounds.min_x + inner_rect.width() / self.zoom;
|
||||
map_bounds.max_y = map_bounds.min_y + inner_rect.height() / self.zoom;
|
||||
|
||||
g.fork(
|
||||
Pt2D::new(0.0, 0.0),
|
||||
Pt2D::new(map_bounds.min_x, map_bounds.min_y),
|
||||
ScreenPt::new(inner_rect.x1, inner_rect.y1),
|
||||
zoom,
|
||||
self.zoom,
|
||||
);
|
||||
g.redraw_clipped(&ui.primary.draw_map.boundary_polygon, &inner_rect);
|
||||
g.redraw_clipped(&ui.primary.draw_map.draw_all_areas, &inner_rect);
|
||||
@ -153,7 +170,7 @@ impl Minimap {
|
||||
&ui.agent_cs,
|
||||
g,
|
||||
Some(&inner_rect),
|
||||
zoom,
|
||||
self.zoom,
|
||||
Distance::meters(5.0),
|
||||
);
|
||||
|
||||
@ -161,8 +178,8 @@ impl Minimap {
|
||||
let (x1, y1) = {
|
||||
let pt = g.canvas.screen_to_map(ScreenPt::new(0.0, 0.0));
|
||||
(
|
||||
clamp(pt.x(), 0.0, bounds.max_x),
|
||||
clamp(pt.y(), 0.0, bounds.max_y),
|
||||
clamp(pt.x(), map_bounds.min_x, map_bounds.max_x),
|
||||
clamp(pt.y(), map_bounds.min_y, map_bounds.max_y),
|
||||
)
|
||||
};
|
||||
let (x2, y2) = {
|
||||
@ -170,8 +187,8 @@ impl Minimap {
|
||||
.canvas
|
||||
.screen_to_map(ScreenPt::new(g.canvas.window_width, g.canvas.window_height));
|
||||
(
|
||||
clamp(pt.x(), 0.0, bounds.max_x),
|
||||
clamp(pt.y(), 0.0, bounds.max_y),
|
||||
clamp(pt.x(), map_bounds.min_x, map_bounds.max_x),
|
||||
clamp(pt.y(), map_bounds.min_y, map_bounds.max_y),
|
||||
)
|
||||
};
|
||||
if x1 != x2 && y1 != y2 {
|
||||
|
@ -67,6 +67,14 @@ impl Bounds {
|
||||
Pt2D::new(self.min_x, self.min_y),
|
||||
])
|
||||
}
|
||||
|
||||
// TODO Really should be Distace
|
||||
pub fn width(&self) -> f64 {
|
||||
self.max_x - self.min_x
|
||||
}
|
||||
pub fn height(&self) -> f64 {
|
||||
self.max_y - self.min_y
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
|
Loading…
Reference in New Issue
Block a user