1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use std::collections::BTreeSet;
use serde::{Deserialize, Serialize};
use abstutil::Timer;
use map_model::osm::OsmID;
use map_model::BuildingID;
use widgetry::{
Color, Drawable, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Panel, RewriteColor,
StyledButtons, TextExt, VerticalAlignment, Widget,
};
use crate::app::App;
use crate::layer::{Layer, LayerOutcome};
#[derive(Serialize, Deserialize)]
pub struct Favorites {
pub buildings: BTreeSet<OsmID>,
}
impl Favorites {
fn load(app: &App) -> Favorites {
abstio::maybe_read_json::<Favorites>(Favorites::path(app), &mut Timer::throwaway())
.unwrap_or_else(|_| Favorites {
buildings: BTreeSet::new(),
})
}
fn path(app: &App) -> String {
let name = app.primary.map.get_name();
abstio::path_player(format!("favorites/{}/{}.json", name.city, name.map))
}
pub fn contains(app: &App, b: BuildingID) -> bool {
Favorites::load(app)
.buildings
.contains(&app.primary.map.get_b(b).orig_id)
}
pub fn add(app: &App, b: BuildingID) {
let mut faves = Favorites::load(app);
faves.buildings.insert(app.primary.map.get_b(b).orig_id);
abstio::write_json(Favorites::path(app), &faves);
}
pub fn remove(app: &App, b: BuildingID) {
let mut faves = Favorites::load(app);
faves.buildings.remove(&app.primary.map.get_b(b).orig_id);
abstio::write_json(Favorites::path(app), &faves);
}
}
pub struct ShowFavorites {
panel: Panel,
draw: Drawable,
}
impl Layer for ShowFavorites {
fn name(&self) -> Option<&'static str> {
Some("favorites")
}
fn event(&mut self, ctx: &mut EventCtx, _: &mut App, minimap: &Panel) -> Option<LayerOutcome> {
Layer::simple_event(ctx, minimap, &mut self.panel)
}
fn draw(&self, g: &mut GfxCtx, _: &App) {
self.panel.draw(g);
g.redraw(&self.draw);
}
fn draw_minimap(&self, g: &mut GfxCtx) {
g.redraw(&self.draw);
}
}
impl ShowFavorites {
pub fn new(ctx: &mut EventCtx, app: &App) -> ShowFavorites {
let mut batch = GeomBatch::new();
for orig_id in Favorites::load(app).buildings.into_iter() {
if let Some(b) = app.primary.map.find_b_by_osm_id(orig_id) {
batch.append(
GeomBatch::load_svg(ctx, "system/assets/tools/star.svg")
.centered_on(app.primary.map.get_b(b).polygon.center())
.color(RewriteColor::ChangeAll(Color::RED)),
);
}
}
let panel = Panel::new(Widget::row(vec![
Widget::draw_svg(ctx, "system/assets/tools/layers.svg"),
"Your favorite buildings".draw_text(ctx),
ctx.style().btn_close_widget(ctx),
]))
.aligned(HorizontalAlignment::Right, VerticalAlignment::Center)
.build(ctx);
ShowFavorites {
panel,
draw: ctx.upload(batch),
}
}
}