mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-24 09:24:26 +03:00
Style the loading screen and add tips/news. Closes #180 [rebuild]
This commit is contained in:
parent
990aa74d03
commit
8e32314979
@ -587,3 +587,14 @@ changes here.
|
|||||||
- small UI tweaks for parking, editing multiple signals
|
- small UI tweaks for parking, editing multiple signals
|
||||||
- fixed last bugs for left-handed driving, should work just as well now
|
- fixed last bugs for left-handed driving, should work just as well now
|
||||||
- lots of graphics experiments from the hackathon, not merged yet
|
- lots of graphics experiments from the hackathon, not merged yet
|
||||||
|
|
||||||
|
0.2.12
|
||||||
|
|
||||||
|
- new textured color scheme and isometric buildings, in settings
|
||||||
|
- new layer to show how far away people parked
|
||||||
|
- Massive UI overhauls: jump to time/delay, edit mode, traffic signal editor (now with offsets), lane editor, bulk lane edit, traffic signal demand (individual intersections and all), loading screen
|
||||||
|
- the Go API example compares trip times and detects gridlock
|
||||||
|
- infinite parking mode
|
||||||
|
- show how long a car has been parked in one spot
|
||||||
|
- bugfix for some pathfinding costs around uber-turns
|
||||||
|
- start to show a trip's purpose
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::common::ColorScale;
|
use crate::common::ColorScale;
|
||||||
|
use crate::helpers::loading_tips;
|
||||||
use widgetry::{Choice, Color, Fill, Style, Texture};
|
use widgetry::{Choice, Color, Fill, Style, Texture};
|
||||||
|
|
||||||
// I've gone back and forth how to organize color scheme code. I was previously against having one
|
// I've gone back and forth how to organize color scheme code. I was previously against having one
|
||||||
@ -141,7 +142,8 @@ impl ColorScheme {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn standard() -> ColorScheme {
|
fn standard() -> ColorScheme {
|
||||||
let gui_style = Style::standard();
|
let mut gui_style = Style::standard();
|
||||||
|
gui_style.loading_tips = loading_tips();
|
||||||
ColorScheme {
|
ColorScheme {
|
||||||
// UI
|
// UI
|
||||||
hovering: gui_style.hovering_color,
|
hovering: gui_style.hovering_color,
|
||||||
|
@ -287,3 +287,15 @@ pub fn open_browser(url: String) {
|
|||||||
let _ = webbrowser::open(&url);
|
let _ = webbrowser::open(&url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn loading_tips() -> Text {
|
||||||
|
Text::from_multiline(vec![
|
||||||
|
Line("Recent changes (September 20)"),
|
||||||
|
Line(""),
|
||||||
|
Line("- Try out the new traffic signal editor!"),
|
||||||
|
Line("- The \"traffic signal demand\" layer shows all intersections through the whole day"),
|
||||||
|
Line("- New 3D buildings and textured color schemes in settings"),
|
||||||
|
Line("- Support for bidirectional cycletracks"),
|
||||||
|
Line("- An API to control A/B Street from any language"),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
@ -76,6 +76,7 @@ fn main() {
|
|||||||
if let Some(s) = args.optional_parse("--scale_factor", |s| s.parse::<f64>()) {
|
if let Some(s) = args.optional_parse("--scale_factor", |s| s.parse::<f64>()) {
|
||||||
settings.scale_factor(s);
|
settings.scale_factor(s);
|
||||||
}
|
}
|
||||||
|
settings.loading_tips(helpers::loading_tips());
|
||||||
|
|
||||||
let mut mode = None;
|
let mut mode = None;
|
||||||
if let Some(x) = args.optional("--challenge") {
|
if let Some(x) = args.optional("--challenge") {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
svg, text, Canvas, Color, Drawable, Event, GeomBatch, GfxCtx, Line, Prerender, ScreenDims,
|
svg, text, Canvas, Color, Drawable, Event, GeomBatch, GfxCtx, HorizontalAlignment, Line, Panel,
|
||||||
ScreenPt, Style, Text, UserInput,
|
Prerender, ScreenDims, Style, Text, UserInput, VerticalAlignment, Widget,
|
||||||
};
|
};
|
||||||
use abstutil::{elapsed_seconds, Timer, TimerSink};
|
use abstutil::{elapsed_seconds, Timer, TimerSink};
|
||||||
use geom::Polygon;
|
use geom::{Percent, Polygon};
|
||||||
use instant::Instant;
|
use instant::Instant;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
@ -41,6 +41,7 @@ impl<'a> EventCtx<'a> {
|
|||||||
&timer_name,
|
&timer_name,
|
||||||
Box::new(LoadingScreen::new(
|
Box::new(LoadingScreen::new(
|
||||||
self.prerender,
|
self.prerender,
|
||||||
|
self.style.clone(),
|
||||||
self.canvas.get_window_dims(),
|
self.canvas.get_window_dims(),
|
||||||
timer_name.clone(),
|
timer_name.clone(),
|
||||||
)),
|
)),
|
||||||
@ -140,6 +141,7 @@ pub struct LoadingScreen<'a> {
|
|||||||
impl<'a> LoadingScreen<'a> {
|
impl<'a> LoadingScreen<'a> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
prerender: &'a Prerender,
|
prerender: &'a Prerender,
|
||||||
|
style: Style,
|
||||||
initial_size: ScreenDims,
|
initial_size: ScreenDims,
|
||||||
title: String,
|
title: String,
|
||||||
) -> LoadingScreen<'a> {
|
) -> LoadingScreen<'a> {
|
||||||
@ -154,7 +156,7 @@ impl<'a> LoadingScreen<'a> {
|
|||||||
last_drawn: Instant::now(),
|
last_drawn: Instant::now(),
|
||||||
title,
|
title,
|
||||||
canvas,
|
canvas,
|
||||||
style: Style::standard(),
|
style,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,26 +166,72 @@ impl<'a> LoadingScreen<'a> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.last_drawn = Instant::now();
|
self.last_drawn = Instant::now();
|
||||||
|
let mut ctx = EventCtx {
|
||||||
|
fake_mouseover: true,
|
||||||
|
input: UserInput::new(Event::NoOp, &self.canvas),
|
||||||
|
canvas: &mut self.canvas,
|
||||||
|
prerender: self.prerender,
|
||||||
|
style: &mut self.style,
|
||||||
|
updates_requested: vec![],
|
||||||
|
};
|
||||||
|
|
||||||
let mut txt = Text::from(Line(&self.title).small_heading());
|
let mut txt = Text::from(Line(&self.title).small_heading());
|
||||||
for l in &self.lines {
|
for l in &self.lines {
|
||||||
txt.add(Line(l));
|
txt.add(Line(l));
|
||||||
}
|
}
|
||||||
|
let border = Color::hex("#F4DA22");
|
||||||
|
let panel = Panel::new(Widget::row(vec![
|
||||||
|
Widget::custom_col(vec![
|
||||||
|
Widget::draw_batch(
|
||||||
|
&ctx,
|
||||||
|
GeomBatch::load_svg(ctx.prerender, "system/assets/map/dont_walk.svg")
|
||||||
|
.scale(5.0),
|
||||||
|
)
|
||||||
|
.container()
|
||||||
|
.bg(Color::BLACK)
|
||||||
|
.padding(15)
|
||||||
|
.outline(5.0, border)
|
||||||
|
.centered_horiz()
|
||||||
|
.margin_below(5),
|
||||||
|
Widget::draw_batch(
|
||||||
|
&ctx,
|
||||||
|
GeomBatch::from(vec![(Color::grey(0.5), Polygon::rectangle(10.0, 30.0))]),
|
||||||
|
)
|
||||||
|
.centered_horiz(),
|
||||||
|
ctx.style
|
||||||
|
.loading_tips
|
||||||
|
.clone()
|
||||||
|
.wrap_to_pct(&ctx, 25)
|
||||||
|
.draw(&ctx)
|
||||||
|
.container()
|
||||||
|
.bg(Color::BLACK)
|
||||||
|
.padding(15)
|
||||||
|
.outline(5.0, Color::YELLOW)
|
||||||
|
.force_width_pct(&ctx, Percent::int(30))
|
||||||
|
.margin_below(5),
|
||||||
|
Widget::draw_batch(
|
||||||
|
&ctx,
|
||||||
|
GeomBatch::from(vec![(Color::grey(0.5), Polygon::rectangle(10.0, 100.0))]),
|
||||||
|
)
|
||||||
|
.centered_horiz(),
|
||||||
|
])
|
||||||
|
.centered_vert(),
|
||||||
|
Widget::draw_batch(
|
||||||
|
&ctx,
|
||||||
|
txt.inner_render(&ctx.prerender.assets, svg::LOW_QUALITY),
|
||||||
|
)
|
||||||
|
.container()
|
||||||
|
.fill_width()
|
||||||
|
.padding(16)
|
||||||
|
.bg(text::BG_COLOR),
|
||||||
|
]))
|
||||||
|
.exact_size_percent(80, 80)
|
||||||
|
.aligned(HorizontalAlignment::Center, VerticalAlignment::Center)
|
||||||
|
.build_custom(&mut ctx);
|
||||||
|
|
||||||
let mut g = GfxCtx::new(self.prerender, &self.canvas, &self.style, false);
|
let mut g = GfxCtx::new(self.prerender, &self.canvas, &self.style, false);
|
||||||
g.clear(Color::BLACK);
|
g.clear(Color::BLACK);
|
||||||
|
panel.draw(&mut g);
|
||||||
let mut batch = GeomBatch::from(vec![(
|
|
||||||
text::BG_COLOR,
|
|
||||||
Polygon::rectangle(0.8 * g.canvas.window_width, 0.8 * g.canvas.window_height),
|
|
||||||
)]);
|
|
||||||
batch.append(txt.inner_render(&g.prerender.assets, svg::LOW_QUALITY));
|
|
||||||
let draw = g.upload(batch);
|
|
||||||
g.redraw_at(
|
|
||||||
ScreenPt::new(0.1 * g.canvas.window_width, 0.1 * g.canvas.window_height),
|
|
||||||
&draw,
|
|
||||||
);
|
|
||||||
|
|
||||||
g.prerender.inner.draw_finished(g.inner);
|
g.prerender.inner.draw_finished(g.inner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::assets::Assets;
|
use crate::assets::Assets;
|
||||||
use crate::tools::screenshot::screenshot_everything;
|
use crate::tools::screenshot::screenshot_everything;
|
||||||
use crate::{Canvas, Event, EventCtx, GfxCtx, Key, Prerender, Style, UpdateType, UserInput};
|
use crate::{Canvas, Event, EventCtx, GfxCtx, Key, Prerender, Style, Text, UpdateType, UserInput};
|
||||||
use geom::Duration;
|
use geom::Duration;
|
||||||
use image::{GenericImageView, Pixel};
|
use image::{GenericImageView, Pixel};
|
||||||
use instant::Instant;
|
use instant::Instant;
|
||||||
@ -160,6 +160,7 @@ pub struct Settings {
|
|||||||
dump_raw_events: bool,
|
dump_raw_events: bool,
|
||||||
scale_factor: Option<f64>,
|
scale_factor: Option<f64>,
|
||||||
window_icon: Option<String>,
|
window_icon: Option<String>,
|
||||||
|
loading_tips: Option<Text>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Settings {
|
impl Settings {
|
||||||
@ -170,6 +171,7 @@ impl Settings {
|
|||||||
dump_raw_events: false,
|
dump_raw_events: false,
|
||||||
scale_factor: None,
|
scale_factor: None,
|
||||||
window_icon: None,
|
window_icon: None,
|
||||||
|
loading_tips: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,6 +192,10 @@ impl Settings {
|
|||||||
pub fn window_icon(&mut self, path: String) {
|
pub fn window_icon(&mut self, path: String) {
|
||||||
self.window_icon = Some(path);
|
self.window_icon = Some(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn loading_tips(&mut self, txt: Text) {
|
||||||
|
self.loading_tips = Some(txt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run<G: 'static + GUI, F: FnOnce(&mut EventCtx) -> G>(settings: Settings, make_gui: F) -> ! {
|
pub fn run<G: 'static + GUI, F: FnOnce(&mut EventCtx) -> G>(settings: Settings, make_gui: F) -> ! {
|
||||||
@ -216,6 +222,7 @@ pub fn run<G: 'static + GUI, F: FnOnce(&mut EventCtx) -> G>(settings: Settings,
|
|||||||
scale_factor: RefCell::new(settings.scale_factor.unwrap_or(monitor_scale_factor)),
|
scale_factor: RefCell::new(settings.scale_factor.unwrap_or(monitor_scale_factor)),
|
||||||
};
|
};
|
||||||
let mut style = Style::standard();
|
let mut style = Style::standard();
|
||||||
|
style.loading_tips = settings.loading_tips.unwrap_or_else(Text::new);
|
||||||
|
|
||||||
let initial_size = prerender.window_size();
|
let initial_size = prerender.window_size();
|
||||||
let mut canvas = Canvas::new(initial_size);
|
let mut canvas = Canvas::new(initial_size);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::Color;
|
use crate::{Color, Text};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Style {
|
pub struct Style {
|
||||||
@ -7,6 +7,7 @@ pub struct Style {
|
|||||||
pub panel_bg: Color,
|
pub panel_bg: Color,
|
||||||
pub hotkey_color: Color,
|
pub hotkey_color: Color,
|
||||||
pub hovering_color: Color,
|
pub hovering_color: Color,
|
||||||
|
pub loading_tips: Text,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Style {
|
impl Style {
|
||||||
@ -17,6 +18,7 @@ impl Style {
|
|||||||
panel_bg: Color::grey(0.4),
|
panel_bg: Color::grey(0.4),
|
||||||
hotkey_color: Color::GREEN,
|
hotkey_color: Color::GREEN,
|
||||||
hovering_color: Color::ORANGE,
|
hovering_color: Color::ORANGE,
|
||||||
|
loading_tips: Text::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,6 +135,10 @@ impl Widget {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fill_width(mut self) -> Widget {
|
||||||
|
self.layout.style.size.width = Dimension::Percent(1.0);
|
||||||
|
self
|
||||||
|
}
|
||||||
pub fn fill_height(mut self) -> Widget {
|
pub fn fill_height(mut self) -> Widget {
|
||||||
self.layout.style.size.height = Dimension::Percent(1.0);
|
self.layout.style.size.height = Dimension::Percent(1.0);
|
||||||
self
|
self
|
||||||
|
Loading…
Reference in New Issue
Block a user