mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-27 00:12:55 +03:00
remove legacy mode, UI's new_event, the top_menu... impl GUI on Game, no
more forwarding to UI ever
This commit is contained in:
parent
9ed882a31c
commit
a72e779a89
@ -5,7 +5,7 @@ use crate::mission::MissionEditMode;
|
||||
use crate::sandbox::SandboxMode;
|
||||
use crate::state::{Flags, UIState};
|
||||
use crate::tutorial::TutorialMode;
|
||||
use crate::ui::{EditorState, UI};
|
||||
use crate::ui::{EditorState, ShowEverything, UI};
|
||||
use abstutil::elapsed_seconds;
|
||||
use ezgui::{
|
||||
Canvas, EventCtx, EventLoopMode, GfxCtx, Key, LogScroller, ModalMenu, Prerender, TopMenu,
|
||||
@ -15,6 +15,7 @@ use geom::{Duration, Line, Pt2D, Speed};
|
||||
use map_model::Map;
|
||||
use rand::Rng;
|
||||
use rand_xorshift::XorShiftRng;
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use std::time::Instant;
|
||||
|
||||
@ -27,7 +28,6 @@ pub struct GameState {
|
||||
|
||||
pub enum Mode {
|
||||
SplashScreen(Wizard, Option<(Screensaver, XorShiftRng)>),
|
||||
Legacy,
|
||||
Edit(EditMode),
|
||||
Tutorial(TutorialMode),
|
||||
Sandbox(SandboxMode),
|
||||
@ -70,13 +70,149 @@ impl GameState {
|
||||
}
|
||||
|
||||
impl GUI for GameState {
|
||||
// TODO Totally get rid of this...
|
||||
fn top_menu(&self, canvas: &Canvas) -> Option<TopMenu> {
|
||||
self.ui.top_menu(canvas)
|
||||
fn top_menu(&self, _: &Canvas) -> Option<TopMenu> {
|
||||
None
|
||||
}
|
||||
|
||||
fn modal_menus(&self) -> Vec<ModalMenu> {
|
||||
self.ui.modal_menus()
|
||||
vec![
|
||||
ModalMenu::new(
|
||||
"Map Edit Mode",
|
||||
vec![
|
||||
(Key::Escape, "quit"),
|
||||
(Key::S, "save edits"),
|
||||
(Key::L, "load different edits"),
|
||||
],
|
||||
),
|
||||
ModalMenu::new(
|
||||
"Stop Sign Editor",
|
||||
vec![(Key::Escape, "quit"), (Key::R, "reset to default")],
|
||||
),
|
||||
ModalMenu::new(
|
||||
"Traffic Signal Editor",
|
||||
vec![
|
||||
(Key::Escape, "quit"),
|
||||
(Key::D, "change cycle duration"),
|
||||
(Key::P, "choose a preset signal"),
|
||||
(Key::K, "move current cycle up"),
|
||||
(Key::J, "move current cycle down"),
|
||||
(Key::UpArrow, "select previous cycle"),
|
||||
(Key::DownArrow, "select next cycle"),
|
||||
(Key::Backspace, "delete current cycle"),
|
||||
(Key::N, "add a new empty cycle"),
|
||||
(Key::M, "add a new pedestrian scramble cycle"),
|
||||
],
|
||||
),
|
||||
ModalMenu::new(
|
||||
"Sandbox Mode",
|
||||
vec![
|
||||
(Key::Escape, "quit"),
|
||||
(Key::LeftBracket, "slow down sim"),
|
||||
(Key::RightBracket, "speed up sim"),
|
||||
(Key::O, "save sim state"),
|
||||
(Key::Y, "load previous sim state"),
|
||||
(Key::U, "load next sim state"),
|
||||
(Key::Space, "run/pause sim"),
|
||||
(Key::M, "run one step of sim"),
|
||||
(Key::X, "reset sim"),
|
||||
(Key::S, "seed the sim with agents"),
|
||||
// TODO Strange to always have this. Really it's a case of stacked modal?
|
||||
(Key::F, "stop following agent"),
|
||||
(Key::R, "stop showing agent's route"),
|
||||
// TODO This should probably be a debug thing instead
|
||||
(Key::L, "show/hide route for all agents"),
|
||||
(Key::A, "show/hide active traffic"),
|
||||
(Key::T, "start time traveling"),
|
||||
],
|
||||
),
|
||||
ModalMenu::new("Agent Spawner", vec![(Key::Escape, "quit")]),
|
||||
ModalMenu::new(
|
||||
"Time Traveler",
|
||||
vec![
|
||||
(Key::Escape, "quit"),
|
||||
(Key::Comma, "rewind"),
|
||||
(Key::Dot, "forwards"),
|
||||
],
|
||||
),
|
||||
ModalMenu::new(
|
||||
"Debug Mode",
|
||||
vec![
|
||||
(Key::Escape, "quit"),
|
||||
(Key::C, "show/hide chokepoints"),
|
||||
(Key::O, "clear original roads shown"),
|
||||
(Key::K, "unhide everything"),
|
||||
(Key::Num1, "show/hide buildings"),
|
||||
(Key::Num2, "show/hide intersections"),
|
||||
(Key::Num3, "show/hide lanes"),
|
||||
(Key::Num4, "show/hide areas"),
|
||||
(Key::Num5, "show/hide extra shapes"),
|
||||
(Key::Num6, "show/hide geometry debug mode"),
|
||||
(Key::F1, "screenshot everything"),
|
||||
(Key::Slash, "search OSM metadata"),
|
||||
(Key::M, "clear OSM search results"),
|
||||
(Key::S, "configure colors"),
|
||||
(Key::N, "show/hide neighborhood summaries"),
|
||||
],
|
||||
),
|
||||
ModalMenu::new(
|
||||
"Polygon Debugger",
|
||||
vec![
|
||||
(Key::Escape, "quit"),
|
||||
(Key::Dot, "next item"),
|
||||
(Key::Comma, "prev item"),
|
||||
(Key::F, "first item"),
|
||||
(Key::L, "last item"),
|
||||
],
|
||||
),
|
||||
ModalMenu::new(
|
||||
"Color Picker",
|
||||
vec![(Key::Backspace, "revert"), (Key::Escape, "finalize")],
|
||||
),
|
||||
ModalMenu::new(
|
||||
"Mission Edit Mode",
|
||||
vec![
|
||||
(Key::Escape, "quit"),
|
||||
(Key::N, "manage neighborhoods"),
|
||||
(Key::W, "manage scenarios"),
|
||||
],
|
||||
),
|
||||
ModalMenu::new(
|
||||
"A/B Test Mode",
|
||||
vec![
|
||||
(Key::Escape, "quit"),
|
||||
(Key::LeftBracket, "slow down sim"),
|
||||
(Key::RightBracket, "speed up sim"),
|
||||
(Key::Space, "run/pause sim"),
|
||||
(Key::M, "run one step of sim"),
|
||||
(Key::S, "swap"),
|
||||
(Key::D, "diff all trips"),
|
||||
(Key::B, "stop diffing trips"),
|
||||
],
|
||||
),
|
||||
ModalMenu::new(
|
||||
"Neighborhood Editor",
|
||||
vec![
|
||||
(Key::Escape, "quit"),
|
||||
(Key::S, "save"),
|
||||
(Key::X, "export as an Osmosis polygon filter"),
|
||||
(Key::P, "add a new point"),
|
||||
],
|
||||
),
|
||||
ModalMenu::new(
|
||||
"Scenario Editor",
|
||||
vec![
|
||||
(Key::Escape, "quit"),
|
||||
(Key::S, "save"),
|
||||
(Key::E, "edit"),
|
||||
(Key::I, "instantiate"),
|
||||
(Key::V, "visualize"),
|
||||
],
|
||||
),
|
||||
ModalMenu::new(
|
||||
"A/B Test Editor",
|
||||
vec![(Key::Escape, "quit"), (Key::R, "run A/B test")],
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
fn event(&mut self, ctx: &mut EventCtx) -> EventLoopMode {
|
||||
@ -90,18 +226,11 @@ impl GUI for GameState {
|
||||
{
|
||||
self.mode = new_mode;
|
||||
} else if wizard.aborted() {
|
||||
self.ui.before_quit(ctx.canvas);
|
||||
self.before_quit(ctx.canvas);
|
||||
std::process::exit(0);
|
||||
}
|
||||
EventLoopMode::Animation
|
||||
}
|
||||
Mode::Legacy => {
|
||||
let (event_mode, pause) = self.ui.new_event(ctx);
|
||||
if pause {
|
||||
self.mode = Mode::SplashScreen(Wizard::new(), None);
|
||||
}
|
||||
event_mode
|
||||
}
|
||||
Mode::Edit(_) => EditMode::event(self, ctx),
|
||||
Mode::Tutorial(_) => TutorialMode::event(self, ctx),
|
||||
Mode::Sandbox(_) => SandboxMode::event(self, ctx),
|
||||
@ -114,10 +243,15 @@ impl GUI for GameState {
|
||||
fn draw(&self, g: &mut GfxCtx) {
|
||||
match self.mode {
|
||||
Mode::SplashScreen(ref wizard, _) => {
|
||||
self.ui.draw(g);
|
||||
self.ui.new_draw(
|
||||
g,
|
||||
None,
|
||||
HashMap::new(),
|
||||
&self.ui.state.primary.sim,
|
||||
&ShowEverything::new(),
|
||||
);
|
||||
wizard.draw(g);
|
||||
}
|
||||
Mode::Legacy => self.ui.draw(g),
|
||||
Mode::Edit(_) => EditMode::draw(self, g),
|
||||
Mode::Tutorial(_) => TutorialMode::draw(self, g),
|
||||
Mode::Sandbox(_) => SandboxMode::draw(self, g),
|
||||
@ -215,7 +349,6 @@ fn splash_screen(
|
||||
let debug = "Debug mode";
|
||||
let mission = "Mission Edit Mode";
|
||||
let abtest = "A/B Test Mode";
|
||||
let legacy = "Legacy mode (ignore this)";
|
||||
let about = "About";
|
||||
let quit = "Quit";
|
||||
|
||||
@ -233,8 +366,7 @@ fn splash_screen(
|
||||
(Some(Key::D), debug),
|
||||
(Some(Key::M), mission),
|
||||
(Some(Key::A), abtest),
|
||||
(None, legacy),
|
||||
(Some(Key::A), about),
|
||||
(None, about),
|
||||
(None, quit),
|
||||
],
|
||||
)?
|
||||
@ -272,7 +404,6 @@ fn splash_screen(
|
||||
x if x == debug => break Some(Mode::Debug(DebugMode::new(ctx, ui))),
|
||||
x if x == mission => break Some(Mode::Mission(MissionEditMode::new())),
|
||||
x if x == abtest => break Some(Mode::ABTest(ABTestMode::new())),
|
||||
x if x == legacy => break Some(Mode::Legacy),
|
||||
x if x == about => {
|
||||
if wizard.acknowledge(LogScroller::new(
|
||||
"About A/B Street".to_string(),
|
||||
@ -290,7 +421,8 @@ fn splash_screen(
|
||||
}
|
||||
}
|
||||
x if x == quit => {
|
||||
ui.before_quit(ctx.canvas);
|
||||
// Not important to call before_quit... if we're here, we're bouncing around
|
||||
// aimlessly anyway
|
||||
std::process::exit(0);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
|
@ -1,8 +1,10 @@
|
||||
use crate::game::{GameState, Mode};
|
||||
use crate::ui::ShowEverything;
|
||||
use ezgui::{
|
||||
EventCtx, EventLoopMode, GfxCtx, HorizontalAlignment, Key, Text, VerticalAlignment, Wizard, GUI,
|
||||
EventCtx, EventLoopMode, GfxCtx, HorizontalAlignment, Key, Text, VerticalAlignment, Wizard,
|
||||
};
|
||||
use geom::Pt2D;
|
||||
use std::collections::HashMap;
|
||||
|
||||
// Does CommonState make sense?
|
||||
pub enum TutorialMode {
|
||||
@ -12,6 +14,8 @@ pub enum TutorialMode {
|
||||
|
||||
impl TutorialMode {
|
||||
pub fn event(state: &mut GameState, ctx: &mut EventCtx) -> EventLoopMode {
|
||||
ctx.canvas.handle_event(ctx.input);
|
||||
|
||||
match state.mode {
|
||||
Mode::Tutorial(TutorialMode::Part1(orig_center)) => {
|
||||
// TODO Zooming also changes this. :(
|
||||
@ -31,15 +35,17 @@ impl TutorialMode {
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
let (event_mode, pause) = state.ui.new_event(ctx);
|
||||
if pause {
|
||||
state.mode = Mode::SplashScreen(Wizard::new(), None);
|
||||
}
|
||||
event_mode
|
||||
EventLoopMode::InputOnly
|
||||
}
|
||||
|
||||
pub fn draw(state: &GameState, g: &mut GfxCtx) {
|
||||
state.ui.draw(g);
|
||||
state.ui.new_draw(
|
||||
g,
|
||||
None,
|
||||
HashMap::new(),
|
||||
&state.ui.state.primary.sim,
|
||||
&ShowEverything::new(),
|
||||
);
|
||||
|
||||
let mut txt = Text::new();
|
||||
match state.mode {
|
||||
|
206
editor/src/ui.rs
206
editor/src/ui.rs
@ -4,10 +4,7 @@ use crate::render::{
|
||||
};
|
||||
use crate::state::UIState;
|
||||
use abstutil;
|
||||
use ezgui::{
|
||||
Canvas, Color, EventCtx, EventLoopMode, Folder, GfxCtx, Key, ModalMenu, Prerender, Text,
|
||||
TopMenu, BOTTOM_LEFT, GUI,
|
||||
};
|
||||
use ezgui::{Canvas, Color, EventCtx, EventLoopMode, GfxCtx, Prerender, Text, BOTTOM_LEFT};
|
||||
use geom::{Bounds, Circle, Distance, Polygon};
|
||||
use map_model::{BuildingID, IntersectionID, LaneID, Traversable};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
@ -20,178 +17,6 @@ pub struct UI {
|
||||
pub state: UIState,
|
||||
}
|
||||
|
||||
impl GUI for UI {
|
||||
fn top_menu(&self, canvas: &Canvas) -> Option<TopMenu> {
|
||||
let mut folders = Vec::new();
|
||||
folders.push(Folder::new("File", vec![(Some(Key::Escape), "pause game")]));
|
||||
Some(TopMenu::new(folders, canvas))
|
||||
}
|
||||
|
||||
fn modal_menus(&self) -> Vec<ModalMenu> {
|
||||
vec![
|
||||
ModalMenu::new(
|
||||
"Map Edit Mode",
|
||||
vec![
|
||||
(Key::Escape, "quit"),
|
||||
(Key::S, "save edits"),
|
||||
(Key::L, "load different edits"),
|
||||
],
|
||||
),
|
||||
ModalMenu::new(
|
||||
"Stop Sign Editor",
|
||||
vec![(Key::Escape, "quit"), (Key::R, "reset to default")],
|
||||
),
|
||||
ModalMenu::new(
|
||||
"Traffic Signal Editor",
|
||||
vec![
|
||||
(Key::Escape, "quit"),
|
||||
(Key::D, "change cycle duration"),
|
||||
(Key::P, "choose a preset signal"),
|
||||
(Key::K, "move current cycle up"),
|
||||
(Key::J, "move current cycle down"),
|
||||
(Key::UpArrow, "select previous cycle"),
|
||||
(Key::DownArrow, "select next cycle"),
|
||||
(Key::Backspace, "delete current cycle"),
|
||||
(Key::N, "add a new empty cycle"),
|
||||
(Key::M, "add a new pedestrian scramble cycle"),
|
||||
],
|
||||
),
|
||||
ModalMenu::new(
|
||||
"Sandbox Mode",
|
||||
vec![
|
||||
(Key::Escape, "quit"),
|
||||
(Key::LeftBracket, "slow down sim"),
|
||||
(Key::RightBracket, "speed up sim"),
|
||||
(Key::O, "save sim state"),
|
||||
(Key::Y, "load previous sim state"),
|
||||
(Key::U, "load next sim state"),
|
||||
(Key::Space, "run/pause sim"),
|
||||
(Key::M, "run one step of sim"),
|
||||
(Key::X, "reset sim"),
|
||||
(Key::S, "seed the sim with agents"),
|
||||
// TODO Strange to always have this. Really it's a case of stacked modal?
|
||||
(Key::F, "stop following agent"),
|
||||
(Key::R, "stop showing agent's route"),
|
||||
// TODO This should probably be a debug thing instead
|
||||
(Key::L, "show/hide route for all agents"),
|
||||
(Key::A, "show/hide active traffic"),
|
||||
(Key::T, "start time traveling"),
|
||||
],
|
||||
),
|
||||
ModalMenu::new("Agent Spawner", vec![(Key::Escape, "quit")]),
|
||||
ModalMenu::new(
|
||||
"Time Traveler",
|
||||
vec![
|
||||
(Key::Escape, "quit"),
|
||||
(Key::Comma, "rewind"),
|
||||
(Key::Dot, "forwards"),
|
||||
],
|
||||
),
|
||||
ModalMenu::new(
|
||||
"Debug Mode",
|
||||
vec![
|
||||
(Key::Escape, "quit"),
|
||||
(Key::C, "show/hide chokepoints"),
|
||||
(Key::O, "clear original roads shown"),
|
||||
(Key::K, "unhide everything"),
|
||||
(Key::Num1, "show/hide buildings"),
|
||||
(Key::Num2, "show/hide intersections"),
|
||||
(Key::Num3, "show/hide lanes"),
|
||||
(Key::Num4, "show/hide areas"),
|
||||
(Key::Num5, "show/hide extra shapes"),
|
||||
(Key::Num6, "show/hide geometry debug mode"),
|
||||
(Key::F1, "screenshot everything"),
|
||||
(Key::Slash, "search OSM metadata"),
|
||||
(Key::M, "clear OSM search results"),
|
||||
(Key::S, "configure colors"),
|
||||
(Key::N, "show/hide neighborhood summaries"),
|
||||
],
|
||||
),
|
||||
ModalMenu::new(
|
||||
"Polygon Debugger",
|
||||
vec![
|
||||
(Key::Escape, "quit"),
|
||||
(Key::Dot, "next item"),
|
||||
(Key::Comma, "prev item"),
|
||||
(Key::F, "first item"),
|
||||
(Key::L, "last item"),
|
||||
],
|
||||
),
|
||||
ModalMenu::new(
|
||||
"Color Picker",
|
||||
vec![(Key::Backspace, "revert"), (Key::Escape, "finalize")],
|
||||
),
|
||||
ModalMenu::new(
|
||||
"Mission Edit Mode",
|
||||
vec![
|
||||
(Key::Escape, "quit"),
|
||||
(Key::N, "manage neighborhoods"),
|
||||
(Key::W, "manage scenarios"),
|
||||
],
|
||||
),
|
||||
ModalMenu::new(
|
||||
"A/B Test Mode",
|
||||
vec![
|
||||
(Key::Escape, "quit"),
|
||||
(Key::LeftBracket, "slow down sim"),
|
||||
(Key::RightBracket, "speed up sim"),
|
||||
(Key::Space, "run/pause sim"),
|
||||
(Key::M, "run one step of sim"),
|
||||
(Key::S, "swap"),
|
||||
(Key::D, "diff all trips"),
|
||||
(Key::B, "stop diffing trips"),
|
||||
],
|
||||
),
|
||||
ModalMenu::new(
|
||||
"Neighborhood Editor",
|
||||
vec![
|
||||
(Key::Escape, "quit"),
|
||||
(Key::S, "save"),
|
||||
(Key::X, "export as an Osmosis polygon filter"),
|
||||
(Key::P, "add a new point"),
|
||||
],
|
||||
),
|
||||
ModalMenu::new(
|
||||
"Scenario Editor",
|
||||
vec![
|
||||
(Key::Escape, "quit"),
|
||||
(Key::S, "save"),
|
||||
(Key::E, "edit"),
|
||||
(Key::I, "instantiate"),
|
||||
(Key::V, "visualize"),
|
||||
],
|
||||
),
|
||||
ModalMenu::new(
|
||||
"A/B Test Editor",
|
||||
vec![(Key::Escape, "quit"), (Key::R, "run A/B test")],
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
// TODO This hacky wrapper will soon disappear, when UI stops implementing GUI
|
||||
fn event(&mut self, ctx: &mut EventCtx) -> EventLoopMode {
|
||||
self.new_event(ctx).0
|
||||
}
|
||||
|
||||
fn draw(&self, g: &mut GfxCtx) {
|
||||
self.new_draw(
|
||||
g,
|
||||
None,
|
||||
HashMap::new(),
|
||||
&self.state.primary.sim,
|
||||
&ShowEverything::new(),
|
||||
)
|
||||
}
|
||||
|
||||
fn dump_before_abort(&self, _: &Canvas) {}
|
||||
|
||||
fn before_quit(&self, _: &Canvas) {}
|
||||
|
||||
fn profiling_enabled(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl UI {
|
||||
pub fn new(state: UIState, canvas: &mut Canvas) -> UI {
|
||||
match abstutil::read_json::<EditorState>("../editor_state") {
|
||||
@ -232,35 +57,6 @@ impl UI {
|
||||
}
|
||||
}
|
||||
|
||||
// True if we should pause.
|
||||
pub fn new_event(&mut self, ctx: &mut EventCtx) -> (EventLoopMode, bool) {
|
||||
self.hints = RenderingHints {
|
||||
mode: EventLoopMode::InputOnly,
|
||||
osd: Text::new(),
|
||||
suppress_traffic_signal_details: None,
|
||||
hide_turn_icons: HashSet::new(),
|
||||
};
|
||||
|
||||
// First update the camera
|
||||
ctx.canvas.handle_event(ctx.input);
|
||||
|
||||
// Always handle mouseover
|
||||
self.state.primary.current_selection = self.handle_mouseover(
|
||||
ctx,
|
||||
None,
|
||||
&self.state.primary.sim,
|
||||
&ShowEverything::new(),
|
||||
false,
|
||||
);
|
||||
|
||||
ctx.input.populate_osd(&mut self.hints.osd);
|
||||
|
||||
(
|
||||
self.hints.mode.clone(),
|
||||
ctx.input.action_chosen("pause game"),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_draw(
|
||||
&self,
|
||||
g: &mut GfxCtx,
|
||||
|
@ -40,6 +40,7 @@ impl<T: Clone> Menu<T> {
|
||||
// Calculate geometry.
|
||||
let mut txt = prompt.clone().unwrap_or_else(|| Text::new());
|
||||
let (_, prompt_height) = canvas.text_dims(&txt);
|
||||
// TODO Make sure hotkeys aren't used twice.
|
||||
for (hotkey, choice, _) in &choices {
|
||||
if let Some(key) = hotkey {
|
||||
txt.add_line(format!("{} - {}", key.describe(), choice));
|
||||
|
Loading…
Reference in New Issue
Block a user