mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-29 17:34:58 +03:00
consolidate composite layouting... just need to know alignment and percentage of screen
This commit is contained in:
parent
0023002935
commit
f1b42ecdb9
@ -473,7 +473,7 @@ impl ManagedWidget {
|
||||
|
||||
pub struct CompositeBuilder {
|
||||
top_level: ManagedWidget,
|
||||
pos: CompositePosition,
|
||||
layout: Layout,
|
||||
sliders: HashMap<String, Slider>,
|
||||
menus: HashMap<String, Menu>,
|
||||
fillers: HashMap<String, Filler>,
|
||||
@ -481,7 +481,7 @@ pub struct CompositeBuilder {
|
||||
|
||||
pub struct Composite {
|
||||
top_level: ManagedWidget,
|
||||
pos: CompositePosition,
|
||||
layout: Layout,
|
||||
|
||||
sliders: HashMap<String, Slider>,
|
||||
menus: HashMap<String, Menu>,
|
||||
@ -497,10 +497,12 @@ pub enum Outcome {
|
||||
Clicked(String),
|
||||
}
|
||||
|
||||
enum CompositePosition {
|
||||
FillScreen,
|
||||
Aligned(HorizontalAlignment, VerticalAlignment),
|
||||
AlignedSizePercent(HorizontalAlignment, VerticalAlignment, f64, f64),
|
||||
struct Layout {
|
||||
horiz: HorizontalAlignment,
|
||||
vert: VerticalAlignment,
|
||||
// If None, then be just as large as needed. But still don't exceed screen.
|
||||
percent_width: Option<f64>,
|
||||
percent_height: Option<f64>,
|
||||
}
|
||||
|
||||
const SCROLL_SPEED: f64 = 5.0;
|
||||
@ -511,7 +513,12 @@ impl Composite {
|
||||
pub fn new(top_level: ManagedWidget) -> CompositeBuilder {
|
||||
CompositeBuilder {
|
||||
top_level,
|
||||
pos: CompositePosition::FillScreen,
|
||||
layout: Layout {
|
||||
horiz: HorizontalAlignment::Center,
|
||||
vert: VerticalAlignment::Center,
|
||||
percent_width: None,
|
||||
percent_height: None,
|
||||
},
|
||||
sliders: HashMap::new(),
|
||||
menus: HashMap::new(),
|
||||
fillers: HashMap::new(),
|
||||
@ -522,29 +529,20 @@ impl Composite {
|
||||
let mut stretch = Stretch::new();
|
||||
let root = stretch
|
||||
.new_node(
|
||||
match self.pos {
|
||||
CompositePosition::FillScreen => Style {
|
||||
size: Size {
|
||||
width: Dimension::Points(ctx.canvas.window_width as f32),
|
||||
height: Dimension::Points(ctx.canvas.window_height as f32),
|
||||
Style {
|
||||
size: Size {
|
||||
width: if let Some(pct) = self.layout.percent_width {
|
||||
Dimension::Points((ctx.canvas.window_width * pct) as f32)
|
||||
} else {
|
||||
Dimension::Undefined
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
CompositePosition::Aligned(_, _) => Style {
|
||||
// TODO There a way to encode the offset in stretch?
|
||||
..Default::default()
|
||||
},
|
||||
CompositePosition::AlignedSizePercent(_, _, pct_width, pct_height) => Style {
|
||||
size: Size {
|
||||
width: Dimension::Points(
|
||||
(ctx.canvas.window_width * (pct_width / 100.0)) as f32,
|
||||
),
|
||||
height: Dimension::Points(
|
||||
(ctx.canvas.window_height * pct_height / 100.0) as f32,
|
||||
),
|
||||
height: if let Some(pct) = self.layout.percent_height {
|
||||
Dimension::Points((ctx.canvas.window_height * pct) as f32)
|
||||
} else {
|
||||
Dimension::Undefined
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
Vec::new(),
|
||||
)
|
||||
@ -562,18 +560,12 @@ impl Composite {
|
||||
nodes.reverse();
|
||||
|
||||
stretch.compute_layout(root, Size::undefined()).unwrap();
|
||||
let top_left = match self.pos {
|
||||
CompositePosition::FillScreen => ScreenPt::new(0.0, 0.0),
|
||||
CompositePosition::Aligned(horiz, vert)
|
||||
| CompositePosition::AlignedSizePercent(horiz, vert, _, _) => {
|
||||
let result = stretch.layout(root).unwrap();
|
||||
ctx.canvas.align_window(
|
||||
ScreenDims::new(result.size.width.into(), result.size.height.into()),
|
||||
horiz,
|
||||
vert,
|
||||
)
|
||||
}
|
||||
};
|
||||
let result = stretch.layout(root).unwrap();
|
||||
let top_left = ctx.canvas.align_window(
|
||||
ScreenDims::new(result.size.width.into(), result.size.height.into()),
|
||||
self.layout.horiz,
|
||||
self.layout.vert,
|
||||
);
|
||||
let offset = self.scroll_y_offset(ctx);
|
||||
self.top_level.apply_flexbox(
|
||||
&mut self.sliders,
|
||||
@ -685,7 +677,7 @@ impl CompositeBuilder {
|
||||
pub fn build(self, ctx: &mut EventCtx) -> Composite {
|
||||
let mut c = Composite {
|
||||
top_level: self.top_level,
|
||||
pos: self.pos,
|
||||
layout: self.layout,
|
||||
sliders: self.sliders,
|
||||
menus: self.menus,
|
||||
fillers: self.fillers,
|
||||
@ -698,7 +690,7 @@ impl CompositeBuilder {
|
||||
pub fn build_scrollable(self, ctx: &mut EventCtx) -> Composite {
|
||||
let mut c = Composite {
|
||||
top_level: self.top_level,
|
||||
pos: self.pos,
|
||||
layout: self.layout,
|
||||
sliders: self.sliders,
|
||||
menus: self.menus,
|
||||
fillers: self.fillers,
|
||||
@ -706,6 +698,7 @@ impl CompositeBuilder {
|
||||
};
|
||||
// If the panel fits without a scrollbar, don't add one.
|
||||
c.recompute_layout(ctx);
|
||||
// TODO Max size is a little different...
|
||||
if c.top_level.rect.height() > ctx.canvas.window_height {
|
||||
c.scrollable = true;
|
||||
c.sliders.insert(
|
||||
@ -724,19 +717,19 @@ impl CompositeBuilder {
|
||||
horiz: HorizontalAlignment,
|
||||
vert: VerticalAlignment,
|
||||
) -> CompositeBuilder {
|
||||
self.pos = CompositePosition::Aligned(horiz, vert);
|
||||
self.layout.horiz = horiz;
|
||||
self.layout.vert = vert;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn aligned_size_percent(
|
||||
mut self,
|
||||
horiz: HorizontalAlignment,
|
||||
vert: VerticalAlignment,
|
||||
pct_width: usize,
|
||||
pct_height: usize,
|
||||
) -> CompositeBuilder {
|
||||
self.pos =
|
||||
CompositePosition::AlignedSizePercent(horiz, vert, pct_width as f64, pct_height as f64);
|
||||
pub fn size_percent(mut self, pct_width: usize, pct_height: usize) -> CompositeBuilder {
|
||||
self.layout.percent_width = Some((pct_width as f64) / 100.0);
|
||||
self.layout.percent_height = Some((pct_height as f64) / 100.0);
|
||||
self
|
||||
}
|
||||
pub fn fullscreen(mut self) -> CompositeBuilder {
|
||||
self.layout.percent_width = Some(1.0);
|
||||
self.layout.percent_height = Some(1.0);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
use crate::widgets::text_box::TextBox;
|
||||
use crate::widgets::PopupMenu;
|
||||
use crate::{
|
||||
hotkey, layout, Button, Color, Composite, EventCtx, GfxCtx, HorizontalAlignment, InputResult,
|
||||
Key, Line, ManagedWidget, MultiKey, Outcome, SliderWithTextBox, Text, VerticalAlignment,
|
||||
hotkey, layout, Button, Color, Composite, EventCtx, GfxCtx, InputResult, Key, Line,
|
||||
ManagedWidget, MultiKey, Outcome, SliderWithTextBox, Text,
|
||||
};
|
||||
use abstutil::Cloneable;
|
||||
use geom::Time;
|
||||
@ -280,7 +280,6 @@ impl<'a, 'b> WrappedWizard<'a, 'b> {
|
||||
])
|
||||
.bg(Color::grey(0.4)),
|
||||
)
|
||||
.aligned(HorizontalAlignment::Center, VerticalAlignment::Center)
|
||||
.menu(
|
||||
"menu",
|
||||
PopupMenu::new(
|
||||
@ -398,7 +397,6 @@ impl<'a, 'b> WrappedWizard<'a, 'b> {
|
||||
])
|
||||
.bg(Color::grey(0.4)),
|
||||
)
|
||||
.aligned(HorizontalAlignment::Center, VerticalAlignment::Center)
|
||||
.build(self.ctx),
|
||||
);
|
||||
}
|
||||
|
@ -26,26 +26,22 @@ impl TitleScreen {
|
||||
pub fn new(ctx: &mut EventCtx, ui: &UI) -> TitleScreen {
|
||||
let mut rng = ui.primary.current_flags.sim_flags.make_rng();
|
||||
TitleScreen {
|
||||
// TODO Double column to get the vertical centering. For some reason, the horizontal
|
||||
// centering isn't working.
|
||||
composite: Composite::new(
|
||||
ezgui::Composite::new(
|
||||
ManagedWidget::col(vec![ManagedWidget::col(vec![
|
||||
ManagedWidget::just_draw(JustDraw::image("assets/pregame/logo.png", ctx))
|
||||
.bg(Color::GREEN.alpha(0.2)),
|
||||
// TODO that nicer font
|
||||
// TODO Any key
|
||||
ManagedWidget::btn(Button::text(
|
||||
Text::from(Line("PLAY")),
|
||||
Color::BLUE,
|
||||
Color::ORANGE,
|
||||
hotkey(Key::Space),
|
||||
"start game",
|
||||
ctx,
|
||||
)),
|
||||
])])
|
||||
ezgui::Composite::new(ManagedWidget::col(vec![
|
||||
ManagedWidget::just_draw(JustDraw::image("assets/pregame/logo.png", ctx))
|
||||
.bg(Color::GREEN.alpha(0.2)),
|
||||
// TODO that nicer font
|
||||
// TODO Any key
|
||||
ManagedWidget::row(vec![ManagedWidget::btn(Button::text(
|
||||
Text::from(Line("PLAY")),
|
||||
Color::BLUE,
|
||||
Color::ORANGE,
|
||||
hotkey(Key::Space),
|
||||
"start game",
|
||||
ctx,
|
||||
))])
|
||||
.centered(),
|
||||
)
|
||||
]))
|
||||
.build(ctx),
|
||||
)
|
||||
.cb(
|
||||
@ -122,42 +118,43 @@ pub fn main_menu(ctx: &mut EventCtx, ui: &UI) -> Box<dyn State> {
|
||||
}
|
||||
col.push(Composite::text_button(ctx, "About A/B Street", None));
|
||||
|
||||
let mut c =
|
||||
Composite::new(ezgui::Composite::new(ManagedWidget::col(col).centered()).build(ctx))
|
||||
.cb(
|
||||
"quit",
|
||||
Box::new(|_, _| {
|
||||
// TODO before_quit?
|
||||
std::process::exit(0);
|
||||
}),
|
||||
)
|
||||
.cb(
|
||||
"Tutorial",
|
||||
Box::new(|ctx, _| Some(Transition::Push(Box::new(TutorialMode::new(ctx))))),
|
||||
)
|
||||
.cb(
|
||||
"Sandbox mode",
|
||||
Box::new(|ctx, ui| {
|
||||
Some(Transition::PushWithMode(
|
||||
Box::new(SandboxMode::new(
|
||||
ctx,
|
||||
ui,
|
||||
GameplayMode::PlayScenario(
|
||||
"random scenario with some agents".to_string(),
|
||||
),
|
||||
)),
|
||||
EventLoopMode::Animation,
|
||||
))
|
||||
}),
|
||||
)
|
||||
.cb(
|
||||
"Challenges",
|
||||
Box::new(|ctx, _| Some(Transition::Push(challenges_picker(ctx)))),
|
||||
)
|
||||
.cb(
|
||||
"About A/B Street",
|
||||
Box::new(|ctx, _| Some(Transition::Push(about(ctx)))),
|
||||
);
|
||||
let mut c = Composite::new(
|
||||
ezgui::Composite::new(ManagedWidget::col(col).centered())
|
||||
.fullscreen()
|
||||
.build(ctx),
|
||||
)
|
||||
.cb(
|
||||
"quit",
|
||||
Box::new(|_, _| {
|
||||
// TODO before_quit?
|
||||
std::process::exit(0);
|
||||
}),
|
||||
)
|
||||
.cb(
|
||||
"Tutorial",
|
||||
Box::new(|ctx, _| Some(Transition::Push(Box::new(TutorialMode::new(ctx))))),
|
||||
)
|
||||
.cb(
|
||||
"Sandbox mode",
|
||||
Box::new(|ctx, ui| {
|
||||
Some(Transition::PushWithMode(
|
||||
Box::new(SandboxMode::new(
|
||||
ctx,
|
||||
ui,
|
||||
GameplayMode::PlayScenario("random scenario with some agents".to_string()),
|
||||
)),
|
||||
EventLoopMode::Animation,
|
||||
))
|
||||
}),
|
||||
)
|
||||
.cb(
|
||||
"Challenges",
|
||||
Box::new(|ctx, _| Some(Transition::Push(challenges_picker(ctx)))),
|
||||
)
|
||||
.cb(
|
||||
"About A/B Street",
|
||||
Box::new(|ctx, _| Some(Transition::Push(about(ctx)))),
|
||||
);
|
||||
if ui.opts.dev {
|
||||
c = c
|
||||
.cb(
|
||||
|
@ -7,8 +7,7 @@ use crate::ui::UI;
|
||||
use abstutil::prettyprint_usize;
|
||||
use abstutil::Counter;
|
||||
use ezgui::{
|
||||
hotkey, Color, EventCtx, EventLoopMode, Histogram, HorizontalAlignment, Key, Line,
|
||||
ManagedWidget, Plot, Series, Text, VerticalAlignment,
|
||||
hotkey, Color, EventCtx, EventLoopMode, Histogram, Key, Line, ManagedWidget, Plot, Series, Text,
|
||||
};
|
||||
use geom::{Duration, Statistic, Time};
|
||||
use map_model::BusRouteID;
|
||||
@ -63,7 +62,7 @@ pub fn make(ctx: &mut EventCtx, ui: &UI, tab: Tab) -> Box<dyn State> {
|
||||
.padding(10),
|
||||
content,
|
||||
]))
|
||||
.aligned(HorizontalAlignment::Left, VerticalAlignment::Top)
|
||||
.fullscreen()
|
||||
.build_scrollable(ctx),
|
||||
)
|
||||
.cb("BACK", Box::new(|_, _| Some(Transition::Pop)));
|
||||
|
@ -9,8 +9,7 @@ use crate::sandbox::{bus_explorer, SandboxMode};
|
||||
use crate::ui::UI;
|
||||
use ezgui::{
|
||||
hotkey, Button, Choice, Color, Composite, DrawBoth, EventCtx, EventLoopMode, GeomBatch,
|
||||
HorizontalAlignment, JustDraw, Key, Line, ManagedWidget, ModalMenu, Plot, Series, Text,
|
||||
VerticalAlignment,
|
||||
JustDraw, Key, Line, ManagedWidget, ModalMenu, Plot, Series, Text,
|
||||
};
|
||||
use geom::{Circle, Distance, Polygon, Pt2D, Statistic, Time};
|
||||
use map_model::BusRouteID;
|
||||
@ -260,9 +259,7 @@ fn bus_passengers(id: BusRouteID, ui: &UI, ctx: &mut EventCtx) -> crate::managed
|
||||
]));
|
||||
|
||||
let mut c = crate::managed::Composite::new(
|
||||
Composite::new(ManagedWidget::col(master_col).bg(Color::grey(0.4)))
|
||||
.aligned(HorizontalAlignment::Center, VerticalAlignment::Center)
|
||||
.build(ctx),
|
||||
Composite::new(ManagedWidget::col(master_col).bg(Color::grey(0.4))).build(ctx),
|
||||
);
|
||||
for (idx, stop) in route.stops.iter().enumerate() {
|
||||
let id = ID::BusStop(*stop);
|
||||
@ -315,6 +312,5 @@ fn bus_delays(id: BusRouteID, ui: &UI, ctx: &mut EventCtx) -> Composite {
|
||||
])
|
||||
.bg(Color::grey(0.3)),
|
||||
)
|
||||
.aligned(HorizontalAlignment::Center, VerticalAlignment::Center)
|
||||
.build(ctx)
|
||||
}
|
||||
|
@ -172,12 +172,7 @@ impl Overlays {
|
||||
])
|
||||
.bg(Color::hex("#5B5B5B")),
|
||||
)
|
||||
.aligned_size_percent(
|
||||
HorizontalAlignment::Center,
|
||||
VerticalAlignment::Center,
|
||||
30,
|
||||
50,
|
||||
)
|
||||
.size_percent(30, 50)
|
||||
.build(ctx),
|
||||
)
|
||||
.cb("X", Box::new(|_, _| Some(Transition::Pop)))
|
||||
|
Loading…
Reference in New Issue
Block a user