mirror of
https://github.com/a-b-street/abstreet.git
synced 2025-01-03 12:03:30 +03:00
button in info panels to follow an agent, aka, unpause sim
This commit is contained in:
parent
06b83a5f73
commit
f8501ace6a
@ -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) {
|
||||
|
@ -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)));
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user