consolidate ezgui internals a little, and start a little bit of rustdoc

This commit is contained in:
Dustin Carlino 2020-03-20 18:05:50 -07:00
parent 9644ff24be
commit 81c5ae3700
22 changed files with 304 additions and 291 deletions

View File

@ -5,6 +5,7 @@ authors = ["Dustin Carlino <dabreegster@gmail.com>"]
edition = "2018"
[features]
default = ["glium-backend"]
glium-backend = ["glium", "glutin", "usvg/text"]
glow-backend = ["glow", "glutin", "usvg/text"]
wasm-backend = ["glow/stdweb", "instant/stdweb", "stdweb", "webgl_stdweb", "winit/stdweb"]

View File

@ -10,7 +10,7 @@ considering cleaning up the API surface and making it a proper standalone crate.
```
git clone https://github.com/dabreegster/abstreet.git
cd abstreet/ezgui
cargo run --example demo --features glium-backend
cargo run --example demo
```
![demo](demo.gif)

View File

@ -2,10 +2,11 @@
// images.
//
// To run:
// > cargo run --example demo --features glium-backend
// > cargo run --example demo
//
// Try the web version, but there's no text rendering yet:
// > cargo web start --target wasm32-unknown-unknown --features wasm-backend --example demo
// > cargo web start --target wasm32-unknown-unknown --no-default-features \
// --features wasm-backend --example demo
use ezgui::{
hotkey, lctrl, Btn, Color, Composite, Drawable, EventCtx, EventLoopMode, GeomBatch, GfxCtx,

View File

@ -1,11 +1,10 @@
use crate::assets::Assets;
use crate::backend::{GfxCtxInnards, PrerenderInnards};
use crate::svg;
use crate::{
Canvas, Color, Drawable, EventCtx, HorizontalAlignment, ScreenDims, ScreenPt, ScreenRectangle,
Canvas, Color, Drawable, GeomBatch, HorizontalAlignment, ScreenDims, ScreenPt, ScreenRectangle,
Text, VerticalAlignment,
};
use geom::{Angle, Bounds, Circle, Distance, Line, Polygon, Pt2D};
use geom::{Bounds, Circle, Distance, Line, Polygon, Pt2D};
use std::cell::Cell;
// Lower is more on top
@ -286,162 +285,6 @@ impl<'a> GfxCtx<'a> {
}
}
#[derive(Clone)]
pub struct GeomBatch {
list: Vec<(Color, Polygon)>,
// TODO A weird hack for text.
pub(crate) dims_text: bool,
}
impl GeomBatch {
pub fn new() -> GeomBatch {
GeomBatch {
list: Vec::new(),
dims_text: false,
}
}
pub fn from(list: Vec<(Color, Polygon)>) -> GeomBatch {
GeomBatch {
list,
dims_text: false,
}
}
pub fn push(&mut self, color: Color, p: Polygon) {
self.list.push((color, p));
}
pub fn extend(&mut self, color: Color, polys: Vec<Polygon>) {
for p in polys {
self.list.push((color, p));
}
}
pub fn append(&mut self, other: GeomBatch) {
self.list.extend(other.list);
}
pub fn consume(self) -> Vec<(Color, Polygon)> {
self.list
}
pub fn draw(self, g: &mut GfxCtx) {
let refs = self.list.iter().map(|(color, p)| (*color, p)).collect();
let obj = g.prerender.upload_temporary(refs);
g.redraw(&obj);
}
pub fn upload(self, ctx: &EventCtx) -> Drawable {
ctx.prerender.upload(self)
}
// Sets the top-left to 0, 0. Not sure exactly when this should be used.
pub(crate) fn autocrop(mut self) -> GeomBatch {
let mut bounds = Bounds::new();
for (_, poly) in &self.list {
bounds.union(poly.get_bounds());
}
if bounds.min_x == 0.0 && bounds.min_y == 0.0 {
return self;
}
for (_, poly) in &mut self.list {
*poly = poly.translate(-bounds.min_x, -bounds.min_y);
}
self
}
pub(crate) fn is_empty(&self) -> bool {
self.list.is_empty()
}
pub fn get_dims(&self) -> ScreenDims {
// TODO Maybe warn about this happening and avoid in the first place? Sometimes we wind up
// trying to draw completely empty text.
if self.is_empty() {
return ScreenDims::new(0.0, 0.0);
}
let mut bounds = Bounds::new();
for (_, poly) in &self.list {
bounds.union(poly.get_bounds());
}
if self.dims_text {
ScreenDims::new(bounds.max_x, bounds.max_y)
} else {
ScreenDims::new(bounds.width(), bounds.height())
}
}
// Slightly weird use case, but hotswap colors.
pub fn rewrite_color(&mut self, transformation: RewriteColor) {
for (c, _) in self.list.iter_mut() {
match transformation {
RewriteColor::NoOp => {}
RewriteColor::Change(from, to) => {
if *c == from {
*c = to;
}
}
RewriteColor::ChangeAll(to) => {
*c = to;
}
}
}
}
pub fn from_svg<I: Into<String>>(
ctx: &EventCtx,
path: I,
rewrite: RewriteColor,
) -> (GeomBatch, Bounds) {
let (mut batch, bounds) = svg::load_svg(ctx.prerender, &path.into());
batch.rewrite_color(rewrite);
(batch, bounds)
}
// TODO Weird API...
pub fn add_svg(
&mut self,
prerender: &Prerender,
filename: &str,
center: Pt2D,
scale: f64,
rotate: Angle,
) {
self.add_transformed(svg::load_svg(prerender, filename).0, center, scale, rotate);
}
// This centers on the pt!
pub fn add_transformed(&mut self, other: GeomBatch, center: Pt2D, scale: f64, rotate: Angle) {
let dims = other.get_dims();
let dx = center.x() - dims.width * scale / 2.0;
let dy = center.y() - dims.height * scale / 2.0;
for (color, mut poly) in other.consume() {
// Avoid unnecessary transformations for slight perf boost
if scale != 1.0 {
poly = poly.scale(scale);
}
poly = poly.translate(dx, dy);
if rotate != Angle::ZERO {
poly = poly.rotate(rotate);
}
self.push(color, poly);
}
}
pub fn add_translated(&mut self, other: GeomBatch, dx: f64, dy: f64) {
for (color, poly) in other.consume() {
self.push(color, poly.translate(dx, dy));
}
}
}
pub enum RewriteColor {
NoOp,
Change(Color, Color),
ChangeAll(Color),
}
// TODO Don't expose this directly
// TODO Rename or something maybe. This actually owns all the permanent state of everything.
pub struct Prerender {

178
ezgui/src/geom.rs Normal file
View File

@ -0,0 +1,178 @@
use crate::{svg, Color, Drawable, EventCtx, GfxCtx, Prerender, ScreenDims};
use geom::{Angle, Bounds, Polygon, Pt2D};
/// A mutable builder for a group of colored polygons.
#[derive(Clone)]
pub struct GeomBatch {
pub(crate) list: Vec<(Color, Polygon)>,
// TODO A weird hack for text.
pub(crate) dims_text: bool,
}
impl GeomBatch {
/// Creates an empty batch.
pub fn new() -> GeomBatch {
GeomBatch {
list: Vec::new(),
dims_text: false,
}
}
/// Creates a batch of colored polygons.
pub fn from(list: Vec<(Color, Polygon)>) -> GeomBatch {
GeomBatch {
list,
dims_text: false,
}
}
/// Adds a single colored polygon.
pub fn push(&mut self, color: Color, p: Polygon) {
self.list.push((color, p));
}
/// Applies one color to many polygons.
pub fn extend(&mut self, color: Color, polys: Vec<Polygon>) {
for p in polys {
self.list.push((color, p));
}
}
/// Appends all colored polygons from another batch to the current one.
pub fn append(&mut self, other: GeomBatch) {
self.list.extend(other.list);
}
/// Returns the colored polygons in this batch, destroying the batch.
pub fn consume(self) -> Vec<(Color, Polygon)> {
self.list
}
/// Draws the batch, consuming it. Only use this for drawing things once.
pub fn draw(self, g: &mut GfxCtx) {
let refs = self.list.iter().map(|(color, p)| (*color, p)).collect();
let obj = g.prerender.upload_temporary(refs);
g.redraw(&obj);
}
/// Upload the batch of polygons to the GPU, returning something that can be cheaply redrawn
/// many times later.
pub fn upload(self, ctx: &EventCtx) -> Drawable {
ctx.prerender.upload(self)
}
/// Sets the top-left to 0, 0. Not sure exactly when this should be used.
pub(crate) fn autocrop(mut self) -> GeomBatch {
let mut bounds = Bounds::new();
for (_, poly) in &self.list {
bounds.union(poly.get_bounds());
}
if bounds.min_x == 0.0 && bounds.min_y == 0.0 {
return self;
}
for (_, poly) in &mut self.list {
*poly = poly.translate(-bounds.min_x, -bounds.min_y);
}
self
}
/// True when the batch is empty.
pub(crate) fn is_empty(&self) -> bool {
self.list.is_empty()
}
/// Returns the width and height of all geometry contained in the batch.
pub fn get_dims(&self) -> ScreenDims {
// TODO Maybe warn about this happening and avoid in the first place? Sometimes we wind up
// trying to draw completely empty text.
if self.is_empty() {
return ScreenDims::new(0.0, 0.0);
}
let mut bounds = Bounds::new();
for (_, poly) in &self.list {
bounds.union(poly.get_bounds());
}
if self.dims_text {
ScreenDims::new(bounds.max_x, bounds.max_y)
} else {
ScreenDims::new(bounds.width(), bounds.height())
}
}
/// Transforms all colors in a batch.
pub fn rewrite_color(&mut self, transformation: RewriteColor) {
for (c, _) in self.list.iter_mut() {
match transformation {
RewriteColor::NoOp => {}
RewriteColor::Change(from, to) => {
if *c == from {
*c = to;
}
}
RewriteColor::ChangeAll(to) => {
*c = to;
}
}
}
}
// TODO Weird API.
/// Creates a new batch containing an SVG image, also returning the bounds of the SVG. The
/// dimensions come from the SVG image size -- if the image has blank padding on the right and
/// bottom side, this is captured by the bounds.
pub fn from_svg<I: Into<String>>(
ctx: &EventCtx,
path: I,
rewrite: RewriteColor,
) -> (GeomBatch, Bounds) {
let (mut batch, bounds) = svg::load_svg(ctx.prerender, &path.into());
batch.rewrite_color(rewrite);
(batch, bounds)
}
// TODO Weird API.
/// Adds an SVG image to the current batch, applying the transformations first.
pub fn add_svg(
&mut self,
prerender: &Prerender,
filename: &str,
center: Pt2D,
scale: f64,
rotate: Angle,
) {
self.add_transformed(svg::load_svg(prerender, filename).0, center, scale, rotate);
}
/// Adds geometry from another batch to the current batch, first transforming it. The
/// translation centers on the given point.
pub fn add_transformed(&mut self, other: GeomBatch, center: Pt2D, scale: f64, rotate: Angle) {
let dims = other.get_dims();
let dx = center.x() - dims.width * scale / 2.0;
let dy = center.y() - dims.height * scale / 2.0;
for (color, mut poly) in other.consume() {
// Avoid unnecessary transformations for slight perf boost
if scale != 1.0 {
poly = poly.scale(scale);
}
poly = poly.translate(dx, dy);
if rotate != Angle::ZERO {
poly = poly.rotate(rotate);
}
self.push(color, poly);
}
}
// TODO Weird API
/// Adds geometry from another batch to the current batch, first translating it.
pub fn add_translated(&mut self, other: GeomBatch, dx: f64, dy: f64) {
for (color, poly) in other.consume() {
self.push(color, poly.translate(dx, dy));
}
}
}
pub enum RewriteColor {
NoOp,
Change(Color, Color),
ChangeAll(Color),
}

View File

@ -1,52 +0,0 @@
use crate::{EventCtx, ScreenDims, ScreenPt};
use ordered_float::NotNan;
// TODO Move this to widgets/mod
pub trait Widget {
fn get_dims(&self) -> ScreenDims;
fn set_pos(&mut self, top_left: ScreenPt);
}
#[derive(Clone, Copy)]
pub enum ContainerOrientation {
TopLeft,
TopRight,
TopLeftButDownABit(f64),
Centered,
// Place the widget this percentage along the width of the screen
Top(f64),
}
pub fn stack_vertically(
orientation: ContainerOrientation,
ctx: &EventCtx,
widgets: Vec<&mut dyn Widget>,
) {
assert!(!widgets.is_empty());
let dims_per_widget: Vec<ScreenDims> = widgets.iter().map(|w| w.get_dims()).collect();
let total_width = dims_per_widget
.iter()
.map(|d| d.width)
.max_by_key(|x| NotNan::new(*x).unwrap())
.unwrap();
let total_height: f64 = dims_per_widget.iter().map(|d| d.height).sum();
let mut top_left = match orientation {
ContainerOrientation::TopLeft => ScreenPt::new(0.0, 0.0),
ContainerOrientation::TopRight => ScreenPt::new(ctx.canvas.window_width - total_width, 0.0),
ContainerOrientation::TopLeftButDownABit(y1) => ScreenPt::new(0.0, y1),
ContainerOrientation::Centered => {
let mut pt = ctx.canvas.center_to_screen_pt();
pt.x -= total_width / 2.0;
pt.y -= total_height / 2.0;
pt
}
ContainerOrientation::Top(percent) => ScreenPt::new(ctx.canvas.window_width * percent, 0.0),
};
for (w, dims) in widgets.into_iter().zip(dims_per_widget) {
w.set_pos(top_left);
top_left.y += dims.height;
}
}

View File

@ -10,8 +10,8 @@ mod color;
mod drawing;
mod event;
mod event_ctx;
mod geom;
mod input;
pub mod layout;
mod managed;
mod runner;
mod screen_geom;
@ -22,18 +22,29 @@ mod widgets;
pub use crate::backend::Drawable;
pub use crate::canvas::{Canvas, HorizontalAlignment, VerticalAlignment};
pub use crate::color::Color;
pub use crate::drawing::{GeomBatch, GfxCtx, Prerender, RewriteColor};
pub use crate::drawing::{GfxCtx, Prerender};
pub use crate::event::{hotkey, hotkeys, lctrl, Event, Key, MultiKey};
pub use crate::event_ctx::EventCtx;
pub use crate::geom::{GeomBatch, RewriteColor};
pub use crate::input::UserInput;
pub use crate::managed::{Composite, ManagedWidget, Outcome};
pub use crate::runner::{run, EventLoopMode, Settings, GUI};
pub use crate::screen_geom::{ScreenDims, ScreenPt, ScreenRectangle};
pub use crate::text::{Line, Text, TextExt, TextSpan, HOTKEY_COLOR};
pub use crate::widgets::{
Autocomplete, Btn, Button, Choice, Filler, Histogram, ItemSlider, JustDraw, ModalMenu, Plot,
PlotOptions, Series, Slider, Warper, WarpingItemSlider, Wizard, WrappedWizard,
};
pub use crate::widgets::autocomplete::Autocomplete;
pub use crate::widgets::button::{Btn, Button};
pub use crate::widgets::checkbox::Checkbox;
pub(crate) use crate::widgets::dropdown::Dropdown;
pub use crate::widgets::filler::Filler;
pub use crate::widgets::histogram::Histogram;
pub use crate::widgets::modal_menu::ModalMenu;
pub use crate::widgets::no_op::JustDraw;
pub use crate::widgets::plot::{Plot, PlotOptions, Series};
pub(crate) use crate::widgets::popup_menu::PopupMenu;
pub use crate::widgets::slider::{ItemSlider, Slider, WarpingItemSlider};
pub(crate) use crate::widgets::text_box::TextBox;
pub use crate::widgets::warper::Warper;
pub use crate::widgets::wizard::{Choice, Wizard, WrappedWizard};
pub enum InputResult<T: Clone> {
Canceled,

View File

@ -1,9 +1,8 @@
use crate::layout::Widget;
use crate::widgets::{Checkbox, Dropdown, PopupMenu, TextBox};
use crate::widgets::Widget;
use crate::{
Btn, Button, Choice, Color, Drawable, EventCtx, Filler, GeomBatch, GfxCtx, Histogram,
HorizontalAlignment, JustDraw, MultiKey, Plot, RewriteColor, ScreenDims, ScreenPt,
ScreenRectangle, Slider, Text, VerticalAlignment,
Btn, Button, Checkbox, Choice, Color, Drawable, Dropdown, EventCtx, Filler, GeomBatch, GfxCtx,
Histogram, HorizontalAlignment, JustDraw, MultiKey, Plot, PopupMenu, RewriteColor, ScreenDims,
ScreenPt, ScreenRectangle, Slider, Text, TextBox, VerticalAlignment,
};
use abstutil::Cloneable;
use geom::{Distance, Duration, Polygon};

View File

@ -1,5 +1,6 @@
use crate::assets::Assets;
use crate::{widgets, Canvas, Event, EventCtx, GfxCtx, Key, Prerender, UserInput};
use crate::widgets::screenshot::{screenshot_current, screenshot_everything};
use crate::{Canvas, Event, EventCtx, GfxCtx, Key, Prerender, UserInput};
use geom::Duration;
use instant::Instant;
use std::cell::Cell;
@ -297,10 +298,10 @@ pub fn run<G: 'static + GUI, F: FnOnce(&mut EventCtx) -> G>(settings: Settings,
max_x,
max_y,
} => {
widgets::screenshot_everything(&mut state, &dir, &prerender, zoom, max_x, max_y);
screenshot_everything(&mut state, &dir, &prerender, zoom, max_x, max_y);
}
EventLoopMode::ScreenCaptureCurrentShot => {
widgets::screenshot_current(&mut state, &prerender);
screenshot_current(&mut state, &prerender);
}
}
});

View File

@ -1,4 +1,4 @@
use crate::layout::Widget;
use crate::widgets::Widget;
use crate::{
text, Color, Drawable, EventCtx, GeomBatch, GfxCtx, JustDraw, Line, ManagedWidget, MultiKey,
RewriteColor, ScreenDims, ScreenPt, Text,

View File

@ -1,4 +1,4 @@
use crate::layout::Widget;
use crate::widgets::Widget;
use crate::{Button, EventCtx, GfxCtx, ScreenDims, ScreenPt};
pub struct Checkbox {
@ -24,7 +24,7 @@ impl Checkbox {
}
}
// If true, layout should be recomputed.
// If true, widgets should be recomputed.
pub(crate) fn event(&mut self, ctx: &mut EventCtx) -> bool {
self.btn.event(ctx);
if self.btn.clicked() {

View File

@ -1,7 +1,6 @@
use crate::layout::Widget;
use crate::widgets::PopupMenu;
use crate::widgets::Widget;
use crate::{
Btn, Button, Choice, Color, EventCtx, GfxCtx, InputResult, ScreenDims, ScreenPt,
Btn, Button, Choice, Color, EventCtx, GfxCtx, InputResult, PopupMenu, ScreenDims, ScreenPt,
ScreenRectangle,
};
use geom::{Polygon, Pt2D};
@ -51,7 +50,7 @@ impl Dropdown {
}
}
// If true, layout should be recomputed.
// If true, widgets should be recomputed.
pub fn event(&mut self, ctx: &mut EventCtx, our_rect: &ScreenRectangle) -> bool {
if let Some(ref mut m) = self.menu {
m.event(ctx);
@ -64,7 +63,7 @@ impl Dropdown {
self.menu = None;
self.current_idx = idx;
let top_left = self.btn.top_left;
// TODO Recalculate layout when this happens... outline around button should
// TODO Recalculate widgets when this happens... outline around button should
// change
self.btn = make_btn(ctx, &self.choices[self.current_idx].label, &self.label);
self.btn.set_pos(top_left);

View File

@ -1,7 +1,7 @@
use crate::layout::Widget;
use crate::widgets::Widget;
use crate::{ScreenDims, ScreenPt};
// Doesn't do anything by itself, just used for layouting. Something else reaches in, asks for the
// Doesn't do anything by itself, just used for widgetsing. Something else reaches in, asks for the
// ScreenRectangle to use.
pub struct Filler {
pub(crate) top_left: ScreenPt,

View File

@ -1,4 +1,4 @@
use crate::layout::Widget;
use crate::widgets::Widget;
use crate::{
Color, Drawable, EventCtx, GeomBatch, GfxCtx, Line, ManagedWidget, ScreenDims, ScreenPt, Text,
TextExt,

View File

@ -1,31 +1,66 @@
mod autocomplete;
mod button;
mod checkbox;
mod dropdown;
mod filler;
mod histogram;
mod modal_menu;
mod no_op;
mod plot;
mod popup_menu;
mod screenshot;
mod slider;
mod text_box;
mod warper;
mod wizard;
pub mod autocomplete;
pub mod button;
pub mod checkbox;
pub mod dropdown;
pub mod filler;
pub mod histogram;
pub mod modal_menu;
pub mod no_op;
pub mod plot;
pub mod popup_menu;
pub mod screenshot;
pub mod slider;
pub mod text_box;
pub mod warper;
pub mod wizard;
pub use self::autocomplete::Autocomplete;
pub use self::button::{Btn, Button};
pub use self::checkbox::Checkbox;
pub(crate) use self::dropdown::Dropdown;
pub use self::filler::Filler;
pub use self::histogram::Histogram;
pub use self::modal_menu::ModalMenu;
pub use self::no_op::JustDraw;
pub use self::plot::{Plot, PlotOptions, Series};
pub(crate) use self::popup_menu::PopupMenu;
pub(crate) use self::screenshot::{screenshot_current, screenshot_everything};
pub use self::slider::{ItemSlider, Slider, WarpingItemSlider};
pub(crate) use self::text_box::TextBox;
pub use self::warper::Warper;
pub use self::wizard::{Choice, Wizard, WrappedWizard};
use crate::{EventCtx, ScreenDims, ScreenPt};
use ordered_float::NotNan;
pub trait Widget {
fn get_dims(&self) -> ScreenDims;
fn set_pos(&mut self, top_left: ScreenPt);
}
#[derive(Clone, Copy)]
pub enum ContainerOrientation {
TopLeft,
TopRight,
TopLeftButDownABit(f64),
Centered,
// Place the widget this percentage along the width of the screen
Top(f64),
}
pub fn stack_vertically(
orientation: ContainerOrientation,
ctx: &EventCtx,
widgets: Vec<&mut dyn Widget>,
) {
assert!(!widgets.is_empty());
let dims_per_widget: Vec<ScreenDims> = widgets.iter().map(|w| w.get_dims()).collect();
let total_width = dims_per_widget
.iter()
.map(|d| d.width)
.max_by_key(|x| NotNan::new(*x).unwrap())
.unwrap();
let total_height: f64 = dims_per_widget.iter().map(|d| d.height).sum();
let mut top_left = match orientation {
ContainerOrientation::TopLeft => ScreenPt::new(0.0, 0.0),
ContainerOrientation::TopRight => ScreenPt::new(ctx.canvas.window_width - total_width, 0.0),
ContainerOrientation::TopLeftButDownABit(y1) => ScreenPt::new(0.0, y1),
ContainerOrientation::Centered => {
let mut pt = ctx.canvas.center_to_screen_pt();
pt.x -= total_width / 2.0;
pt.y -= total_height / 2.0;
pt
}
ContainerOrientation::Top(percent) => ScreenPt::new(ctx.canvas.window_width * percent, 0.0),
};
for (w, dims) in widgets.into_iter().zip(dims_per_widget) {
w.set_pos(top_left);
top_left.y += dims.height;
}
}

View File

@ -1,7 +1,5 @@
use crate::layout::Widget;
use crate::{
layout, text, EventCtx, GfxCtx, Line, MultiKey, ScreenDims, ScreenPt, ScreenRectangle, Text,
};
use crate::widgets::{stack_vertically, ContainerOrientation, Widget};
use crate::{text, EventCtx, GfxCtx, Line, MultiKey, ScreenDims, ScreenPt, ScreenRectangle, Text};
pub struct ModalMenu {
title: String,
@ -10,7 +8,7 @@ pub struct ModalMenu {
choices: Vec<Choice>,
// This can be inactive entries too.
hovering_idx: Option<usize>,
standalone_layout: Option<layout::ContainerOrientation>,
standalone_widgets: Option<ContainerOrientation>,
top_left: ScreenPt,
dims: ScreenDims,
@ -41,7 +39,7 @@ impl ModalMenu {
})
.collect(),
hovering_idx: None,
standalone_layout: Some(layout::ContainerOrientation::TopRight),
standalone_widgets: Some(ContainerOrientation::TopRight),
top_left: ScreenPt::new(0.0, 0.0),
dims: ScreenDims::new(0.0, 0.0),
@ -52,14 +50,14 @@ impl ModalMenu {
}
// It's part of something bigger
pub fn disable_standalone_layout(mut self) -> ModalMenu {
assert!(self.standalone_layout.is_some());
self.standalone_layout = None;
pub fn disable_standalone_widgets(mut self) -> ModalMenu {
assert!(self.standalone_widgets.is_some());
self.standalone_widgets = None;
self
}
pub fn set_standalone_layout(mut self, layout: layout::ContainerOrientation) -> ModalMenu {
self.standalone_layout = Some(layout);
pub fn set_standalone_widgets(mut self, widgets: ContainerOrientation) -> ModalMenu {
self.standalone_widgets = Some(widgets);
self
}
@ -73,8 +71,8 @@ impl ModalMenu {
panic!("Caller didn't consume modal action '{}'", action);
}
if let Some(o) = self.standalone_layout {
layout::stack_vertically(o, ctx, vec![self]);
if let Some(o) = self.standalone_widgets {
stack_vertically(o, ctx, vec![self]);
self.dims = self.calculate_txt().dims(&ctx.prerender.assets);
}

View File

@ -1,10 +1,10 @@
use crate::layout::Widget;
use crate::svg;
use crate::widgets::Widget;
use crate::{
Drawable, EventCtx, GeomBatch, GfxCtx, ManagedWidget, RewriteColor, ScreenDims, ScreenPt, Text,
};
// Just draw something. A widget just so layouting works.
// Just draw something. A widget just so widgetsing works.
pub struct JustDraw {
pub(crate) draw: Drawable,

View File

@ -1,4 +1,4 @@
use crate::layout::Widget;
use crate::widgets::Widget;
use crate::{
Color, Drawable, EventCtx, GeomBatch, GfxCtx, Line, ManagedWidget, ScreenDims, ScreenPt,
ScreenRectangle, Text, TextExt,

View File

@ -1,4 +1,4 @@
use crate::layout::Widget;
use crate::widgets::Widget;
use crate::{
hotkey, text, Choice, EventCtx, GfxCtx, InputResult, Key, Line, ScreenDims, ScreenPt,
ScreenRectangle, Text,

View File

@ -1,4 +1,4 @@
use crate::layout::{stack_vertically, ContainerOrientation, Widget};
use crate::widgets::{stack_vertically, ContainerOrientation, Widget};
use crate::{
hotkey, Color, Drawable, EventCtx, EventLoopMode, GeomBatch, GfxCtx, Key, Line, ModalMenu,
MultiKey, ScreenDims, ScreenPt, ScreenRectangle, Text, Warper,
@ -257,7 +257,7 @@ impl<T> ItemSlider<T> {
(hotkey(Key::Dot), last.as_str()),
]);
let menu = ModalMenu::new(menu_title, choices, ctx).disable_standalone_layout();
let menu = ModalMenu::new(menu_title, choices, ctx).disable_standalone_widgets();
ItemSlider {
items,
// TODO Number of items

View File

@ -1,4 +1,4 @@
use crate::layout::Widget;
use crate::widgets::Widget;
use crate::{
text, Color, EventCtx, GeomBatch, GfxCtx, Key, Line, ScreenDims, ScreenPt, ScreenRectangle,
Text,

View File

@ -1,7 +1,6 @@
use crate::widgets::PopupMenu;
use crate::{
hotkey, Btn, Color, Composite, EventCtx, GfxCtx, HorizontalAlignment, InputResult, Key, Line,
ManagedWidget, MultiKey, Outcome, Text, VerticalAlignment,
ManagedWidget, MultiKey, Outcome, PopupMenu, Text, VerticalAlignment,
};
use abstutil::Cloneable;
use std::collections::VecDeque;