consolidate composite layouting... just need to know alignment and percentage of screen

This commit is contained in:
Dustin Carlino 2020-01-11 14:59:27 -06:00
parent 0023002935
commit f1b42ecdb9
6 changed files with 102 additions and 124 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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