mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-26 16:02:23 +03:00
more synthetic fixes: redo mouseover when model changes, avoid panic
with 0-len new road line, fix reused IDs, fix contains_pt for some precomputed polygons
This commit is contained in:
parent
92a4f304f7
commit
353d89cd25
@ -51,9 +51,6 @@ impl<ID: ObjectID> World<ID> {
|
||||
}
|
||||
|
||||
pub fn handle_mouseover(&mut self, ctx: &EventCtx) {
|
||||
if !ctx.redo_mouseover() {
|
||||
return;
|
||||
}
|
||||
self.current_selection = None;
|
||||
|
||||
let cursor = if let Some(pt) = ctx.canvas.get_cursor_in_map_space() {
|
||||
@ -111,6 +108,6 @@ impl<ID: ObjectID> World<ID> {
|
||||
|
||||
pub fn delete_obj(&mut self, id: ID) {
|
||||
let obj = self.objects.remove(&id).unwrap();
|
||||
self.quadtree.remove(obj.quadtree_id);
|
||||
self.quadtree.remove(obj.quadtree_id).unwrap();
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,9 @@ impl GUI for UI {
|
||||
ref mut osd,
|
||||
} => {
|
||||
{
|
||||
self.world.handle_mouseover(ctx);
|
||||
if ctx.redo_mouseover() {
|
||||
self.world.handle_mouseover(ctx);
|
||||
}
|
||||
|
||||
let len = self.hints.hints.len();
|
||||
let mut txt = Text::prompt("Fix Map Geometry");
|
||||
@ -284,7 +286,9 @@ impl GUI for UI {
|
||||
}
|
||||
State::BanTurnsBetween { from, ref mut osd } => {
|
||||
ctx.canvas.handle_event(ctx.input);
|
||||
self.world.handle_mouseover(ctx);
|
||||
if ctx.redo_mouseover() {
|
||||
self.world.handle_mouseover(ctx);
|
||||
}
|
||||
|
||||
if ctx.input.key_pressed(Key::Escape, "cancel") {
|
||||
self.state = State::main(ctx);
|
||||
|
@ -148,7 +148,7 @@ impl Polygon {
|
||||
top_left.offset(width, height),
|
||||
top_left.offset(Distance::ZERO, height),
|
||||
],
|
||||
indices: vec![0, 1, 2, 2, 3, 0],
|
||||
indices: vec![0, 1, 2, 0, 2, 3],
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,8 @@ pub struct Model {
|
||||
intersections: BTreeMap<StableIntersectionID, Intersection>,
|
||||
roads: BTreeMap<StableRoadID, Road>,
|
||||
buildings: BTreeMap<BuildingID, Building>,
|
||||
// Never reuse IDs, and don't worry about being sequential
|
||||
id_counter: usize,
|
||||
|
||||
world: World<ID>,
|
||||
}
|
||||
@ -137,6 +139,7 @@ impl Model {
|
||||
intersections: BTreeMap::new(),
|
||||
roads: BTreeMap::new(),
|
||||
buildings: BTreeMap::new(),
|
||||
id_counter: 0,
|
||||
world: World::new(&Bounds::new()),
|
||||
}
|
||||
}
|
||||
@ -263,6 +266,7 @@ impl Model {
|
||||
roads: HashSet::new(),
|
||||
};
|
||||
m.intersections.insert(*id, i);
|
||||
m.id_counter = m.id_counter.max(id.0 + 1);
|
||||
}
|
||||
|
||||
for (id, r) in &data.roads {
|
||||
@ -279,6 +283,7 @@ impl Model {
|
||||
);
|
||||
m.intersections.get_mut(&i1).unwrap().roads.insert(*id);
|
||||
m.intersections.get_mut(&i2).unwrap().roads.insert(*id);
|
||||
m.id_counter = m.id_counter.max(id.0 + 1);
|
||||
}
|
||||
|
||||
if !exclude_bldgs {
|
||||
@ -288,6 +293,7 @@ impl Model {
|
||||
center: b.polygon.center(),
|
||||
};
|
||||
m.buildings.insert(idx, b);
|
||||
m.id_counter = m.id_counter.max(idx + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -328,7 +334,8 @@ impl Model {
|
||||
}
|
||||
|
||||
pub fn create_i(&mut self, center: Pt2D, prerender: &Prerender) {
|
||||
let id = StableIntersectionID(self.intersections.len());
|
||||
let id = StableIntersectionID(self.id_counter);
|
||||
self.id_counter += 1;
|
||||
self.intersections.insert(
|
||||
id,
|
||||
Intersection {
|
||||
@ -431,7 +438,8 @@ impl Model {
|
||||
println!("Road already exists");
|
||||
return;
|
||||
}
|
||||
let id = StableRoadID(self.roads.len());
|
||||
let id = StableRoadID(self.id_counter);
|
||||
self.id_counter += 1;
|
||||
self.roads.insert(
|
||||
id,
|
||||
Road {
|
||||
@ -514,7 +522,8 @@ impl Model {
|
||||
}
|
||||
|
||||
pub fn create_b(&mut self, center: Pt2D, prerender: &Prerender) {
|
||||
let id = self.buildings.len();
|
||||
let id = self.id_counter;
|
||||
self.id_counter += 1;
|
||||
self.buildings.insert(
|
||||
id,
|
||||
Building {
|
||||
|
@ -40,7 +40,9 @@ impl UI {
|
||||
impl GUI for UI {
|
||||
fn event(&mut self, ctx: &mut EventCtx) -> EventLoopMode {
|
||||
ctx.canvas.handle_event(ctx.input);
|
||||
self.model.handle_mouseover(ctx);
|
||||
if ctx.redo_mouseover() {
|
||||
self.model.handle_mouseover(ctx);
|
||||
}
|
||||
|
||||
let cursor = {
|
||||
if let Some(c) = ctx.canvas.get_cursor_in_map_space() {
|
||||
@ -99,10 +101,12 @@ impl GUI for UI {
|
||||
State::CreatingRoad(i1) => {
|
||||
if ctx.input.key_pressed(Key::Escape, "stop defining road") {
|
||||
self.state = State::Viewing;
|
||||
self.model.handle_mouseover(ctx);
|
||||
} else if let Some(ID::Intersection(i2)) = self.model.get_selection() {
|
||||
if i1 != i2 && ctx.input.key_pressed(Key::R, "finalize road") {
|
||||
self.model.create_road(i1, i2, ctx.prerender);
|
||||
self.state = State::Viewing;
|
||||
self.model.handle_mouseover(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -113,8 +117,10 @@ impl GUI for UI {
|
||||
{
|
||||
self.model.edit_lanes(id, s, ctx.prerender);
|
||||
self.state = State::Viewing;
|
||||
self.model.handle_mouseover(ctx);
|
||||
} else if wizard.aborted() {
|
||||
self.state = State::Viewing;
|
||||
self.model.handle_mouseover(ctx);
|
||||
}
|
||||
}
|
||||
State::SavingModel(ref mut wizard) => {
|
||||
@ -134,6 +140,7 @@ impl GUI for UI {
|
||||
self.state = State::CreatingRoad(i);
|
||||
} else if ctx.input.key_pressed(Key::Backspace, "delete intersection") {
|
||||
self.model.remove_i(i);
|
||||
self.model.handle_mouseover(ctx);
|
||||
} else if ctx.input.key_pressed(Key::T, "toggle intersection type") {
|
||||
self.model.toggle_i_type(i, ctx.prerender);
|
||||
} else if ctx.input.key_pressed(Key::L, "label intersection") {
|
||||
@ -144,6 +151,7 @@ impl GUI for UI {
|
||||
self.state = State::MovingBuilding(b);
|
||||
} else if ctx.input.key_pressed(Key::Backspace, "delete building") {
|
||||
self.model.remove_b(b);
|
||||
self.model.handle_mouseover(ctx);
|
||||
} else if ctx.input.key_pressed(Key::L, "label building") {
|
||||
self.state = State::LabelingBuilding(b, Wizard::new());
|
||||
}
|
||||
@ -153,6 +161,7 @@ impl GUI for UI {
|
||||
.key_pressed(Key::Backspace, &format!("delete road {}", r))
|
||||
{
|
||||
self.model.remove_road(r);
|
||||
self.model.handle_mouseover(ctx);
|
||||
} else if ctx.input.key_pressed(Key::E, "edit lanes") {
|
||||
self.state = State::EditingRoad(r, Wizard::new());
|
||||
} else if ctx.input.key_pressed(Key::S, "swap lanes") {
|
||||
@ -170,8 +179,12 @@ impl GUI for UI {
|
||||
}
|
||||
} else if ctx.input.key_pressed(Key::I, "create intersection") {
|
||||
self.model.create_i(cursor, ctx.prerender);
|
||||
self.model.handle_mouseover(ctx);
|
||||
// TODO Silly bug: Mouseover doesn't actually work! I think the cursor being
|
||||
// dead-center messes up the precomputed triangles.
|
||||
} else if ctx.input.key_pressed(Key::B, "create building") {
|
||||
self.model.create_b(cursor, ctx.prerender);
|
||||
self.model.handle_mouseover(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -187,11 +200,9 @@ impl GUI for UI {
|
||||
match self.state {
|
||||
State::CreatingRoad(i1) => {
|
||||
if let Some(cursor) = g.get_cursor_in_map_space() {
|
||||
g.draw_line(
|
||||
Color::GREEN,
|
||||
Distance::meters(5.0),
|
||||
&Line::new(self.model.get_i_center(i1), cursor),
|
||||
);
|
||||
if let Some(l) = Line::maybe_new(self.model.get_i_center(i1), cursor) {
|
||||
g.draw_line(Color::GREEN, Distance::meters(5.0), &l);
|
||||
}
|
||||
}
|
||||
}
|
||||
State::LabelingBuilding(_, ref wizard)
|
||||
|
Loading…
Reference in New Issue
Block a user