button in info panels to follow an agent, aka, unpause sim

This commit is contained in:
Dustin Carlino 2020-01-22 15:17:33 -08:00
parent 06b83a5f73
commit f8501ace6a
9 changed files with 62 additions and 16 deletions

View File

@ -156,7 +156,7 @@ impl State for ABTestMode {
self.recalculate_stuff(ui, ctx);
}*/
if let Some(t) = self.common.event(ctx, ui) {
if let Some(t) = self.common.event(ctx, ui, None) {
return t;
}
match self.tool_panel.event(ctx, ui) {

View File

@ -3,6 +3,7 @@ use crate::game::{msg, Transition};
use crate::helpers::{rotating_color, rotating_color_map, ID};
use crate::managed::WrappedComposite;
use crate::render::{dashed_lines, MIN_ZOOM_FOR_DETAIL};
use crate::sandbox::SpeedControls;
use crate::ui::UI;
use abstutil::prettyprint_usize;
use ezgui::{
@ -25,7 +26,23 @@ pub struct InfoPanel {
}
impl InfoPanel {
pub fn new(id: ID, ctx: &mut EventCtx, ui: &UI, actions: Vec<(Key, String)>) -> InfoPanel {
pub fn new(
id: ID,
ctx: &mut EventCtx,
ui: &UI,
mut actions: Vec<(Key, String)>,
maybe_speed: Option<&mut SpeedControls>,
) -> InfoPanel {
if maybe_speed.map(|s| s.is_paused()).unwrap_or(false)
&& id.agent_id().is_some()
&& actions
.get(0)
.map(|(_, a)| a != "follow agent")
.unwrap_or(true)
{
actions.insert(0, (Key::F, "follow agent".to_string()));
}
let mut col = vec![ManagedWidget::row(vec![
{
let mut txt = CommonState::default_osd(id.clone(), ui);
@ -135,7 +152,12 @@ impl InfoPanel {
}
// (Are we done, optional transition)
pub fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (bool, Option<Transition>) {
pub fn event(
&mut self,
ctx: &mut EventCtx,
ui: &mut UI,
maybe_speed: Option<&mut SpeedControls>,
) -> (bool, Option<Transition>) {
// Can click on the map to cancel
if ctx.canvas.get_cursor_in_map_space().is_some()
&& ui.primary.current_selection.is_none()
@ -160,9 +182,9 @@ impl InfoPanel {
}
let preserve_scroll = self.composite.preserve_scroll();
// TODO Can we be more efficient here?
*self = InfoPanel::new(self.id.clone(), ctx, ui, self.actions.clone());
*self = InfoPanel::new(self.id.clone(), ctx, ui, self.actions.clone(), maybe_speed);
self.composite.restore_scroll(ctx, preserve_scroll);
return (false, None);
}
match self.composite.event(ctx) {
@ -180,6 +202,9 @@ impl InfoPanel {
&mut ui.primary,
))),
);
} else if action == "follow agent" {
maybe_speed.unwrap().resume_realtime(ctx);
return (false, None);
} else {
ui.primary.current_selection = Some(self.id.clone());
return (true, Some(Transition::ApplyObjectAction(action)));

View File

@ -18,6 +18,7 @@ pub use self::warp::Warping;
use crate::game::Transition;
use crate::helpers::{list_names, ID};
use crate::render::DrawOptions;
use crate::sandbox::SpeedControls;
use crate::ui::UI;
use ezgui::{
lctrl, Color, EventCtx, GfxCtx, HorizontalAlignment, Key, Line, Text, VerticalAlignment,
@ -39,7 +40,12 @@ impl CommonState {
// This has to be called after anything that calls ui.per_obj.action(). Oof.
// TODO This'll be really clear once we consume. Hah!
pub fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Option<Transition> {
pub fn event(
&mut self,
ctx: &mut EventCtx,
ui: &mut UI,
maybe_speed: Option<&mut SpeedControls>,
) -> Option<Transition> {
if ctx.input.new_was_pressed(lctrl(Key::S).unwrap()) {
ui.opts.dev = !ui.opts.dev;
}
@ -57,12 +63,19 @@ impl CommonState {
{
ui.per_obj.info_panel_open = true;
let actions = ui.per_obj.consume();
self.info_panel = Some(info::InfoPanel::new(id.clone(), ctx, ui, actions));
self.info_panel = Some(info::InfoPanel::new(
id.clone(),
ctx,
ui,
actions,
maybe_speed,
));
}
return None;
}
if let Some(ref mut info) = self.info_panel {
let (closed, maybe_t) = info.event(ctx, ui);
let (closed, maybe_t) = info.event(ctx, ui, maybe_speed);
if closed {
self.info_panel = None;
assert!(ui.per_obj.info_panel_open);
@ -246,7 +259,7 @@ impl CommonState {
// Meant to be used for launching from other states
pub fn launch_info_panel(&mut self, id: ID, ctx: &mut EventCtx, ui: &mut UI) {
self.info_panel = Some(info::InfoPanel::new(id, ctx, ui, Vec::new()));
self.info_panel = Some(info::InfoPanel::new(id, ctx, ui, Vec::new(), None));
ui.per_obj.info_panel_open = true;
}
}

View File

@ -261,7 +261,7 @@ impl State for DebugMode {
return Transition::Push(floodfiller);
}
if let Some(t) = self.common.event(ctx, ui) {
if let Some(t) = self.common.event(ctx, ui, None) {
return t;
}
match self.tool_panel.event(ctx, ui) {

View File

@ -206,7 +206,7 @@ impl State for EditMode {
));
}
if let Some(t) = self.common.event(ctx, ui) {
if let Some(t) = self.common.event(ctx, ui, None) {
return t;
}
match self.tool_panel.event(ctx, ui) {

View File

@ -239,7 +239,7 @@ impl State for ScenarioManager {
}
}
if let Some(t) = self.common.event(ctx, ui) {
if let Some(t) = self.common.event(ctx, ui, None) {
return t;
}
match self.tool_panel.event(ctx, ui) {

View File

@ -27,7 +27,7 @@ pub struct SandboxMode {
time_panel: TimePanel,
agent_meter: AgentMeter,
gameplay: gameplay::GameplayRunner,
pub common: CommonState,
common: CommonState,
tool_panel: WrappedComposite,
minimap: Option<Minimap>,
}
@ -150,7 +150,7 @@ impl State for SandboxMode {
None => {}
}
if let Some(t) = self.common.event(ctx, ui) {
if let Some(t) = self.common.event(ctx, ui, Some(&mut self.speed)) {
return t;
}
if let Some(t) = Overlays::update(ctx, ui) {

View File

@ -15,7 +15,7 @@ pub struct SpeedControls {
setting: SpeedSetting,
}
#[derive(Clone, Copy)]
#[derive(Clone, Copy, PartialEq)]
enum SpeedSetting {
Realtime,
Faster,
@ -302,6 +302,14 @@ impl SpeedControls {
}
}
pub fn resume_realtime(&mut self, ctx: &mut EventCtx) {
if self.paused || self.setting != SpeedSetting::Realtime {
self.paused = false;
self.setting = SpeedSetting::Realtime;
self.composite = SpeedControls::make_panel(ctx, self.paused, self.setting);
}
}
pub fn is_paused(&self) -> bool {
self.paused
}

View File

@ -270,7 +270,7 @@ impl State for TutorialMode {
}
if let Some(ref mut common) = self.common {
if let Some(t) = common.event(ctx, ui) {
if let Some(t) = common.event(ctx, ui, self.speed.as_mut()) {
return t;
}
}