Style the loading screen and add tips/news. Closes #180 [rebuild]

This commit is contained in:
Dustin Carlino 2020-09-20 13:02:27 -07:00
parent 990aa74d03
commit 8e32314979
8 changed files with 106 additions and 19 deletions

View File

@ -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

View File

@ -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,

View File

@ -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"),
])
}

View File

@ -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") {

View File

@ -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);
} }
} }

View File

@ -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);

View File

@ -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(),
} }
} }
} }

View File

@ -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