whittle away weird geombatch APIs. more left

This commit is contained in:
Dustin Carlino 2020-06-05 11:14:17 -07:00
parent 0b1760cbce
commit 63067656b8
17 changed files with 123 additions and 163 deletions

View File

@ -10,7 +10,7 @@
use ezgui::{
hotkey, lctrl, Btn, Checkbox, Color, Composite, Drawable, EventCtx, EventLoopMode, GeomBatch,
GfxCtx, HorizontalAlignment, Key, Line, Outcome, Plot, PlotOptions, Series, Text, TextExt,
GfxCtx, HorizontalAlignment, Key, Line, LinePlot, Outcome, PlotOptions, Series, Text, TextExt,
VerticalAlignment, Widget, GUI,
};
use geom::{Angle, Duration, Polygon, Pt2D, Time};
@ -77,7 +77,7 @@ impl App {
Widget::col(col2).outline(3.0, Color::BLACK).margin(5),
Widget::col(col3).outline(3.0, Color::BLACK).margin(5),
]),
Plot::new(
LinePlot::new(
ctx,
"timeseries",
vec![
@ -103,6 +103,7 @@ impl App {
// Without this, the plot doesn't stretch to cover times in between whole
// seconds.
max_x: Some(Time::START_OF_DAY + self.elapsed),
max_y: None,
},
),
])
@ -230,19 +231,17 @@ fn setup_scrollable_canvas(ctx: &mut EventCtx) -> Drawable {
1.0,
// Rotate
Angle::ZERO,
ezgui::RewriteColor::NoOp,
// Map-space (don't scale for high DPI monitors)
true,
);
// Text rendering also goes through lyon and usvg.
batch.add_transformed(
batch.append(
Text::from(Line("Awesome vector text thanks to usvg and lyon").fg(Color::hex("#DF8C3D")))
.render_to_batch(&ctx.prerender),
// Translate
Pt2D::new(600.0, 500.0),
// Scale
2.0,
// Rotate
Angle::new_degs(30.0),
.render_to_batch(&ctx.prerender)
.scale(2.0)
.centered_on(Pt2D::new(600.0, 500.0))
.rotate(Angle::new_degs(30.0)),
);
// This is a bit of a hack; it's needed so that zooming in/out has reasonable limits.
ctx.canvas.map_dims = (5000.0, 5000.0);

View File

@ -205,7 +205,7 @@ impl<'a> GfxCtx<'a> {
Color::BLACK,
Polygon::rectangle(dims.width, dims.height).translate(pt.x, pt.y),
);
batch.add_translated(txt_batch, pt.x + pad, pt.y + pad);
batch.append(txt_batch.translate(pt.x + pad, pt.y + pad));
// fork_screenspace, but with an even more prominent Z
self.uniforms.transform = [0.0, 0.0, 1.0];

View File

@ -180,11 +180,7 @@ impl<'a> LoadingScreen<'a> {
text::BG_COLOR,
Polygon::rectangle(0.8 * g.canvas.window_width, 0.8 * g.canvas.window_height),
)]);
batch.add_translated(
txt.inner_render(&g.prerender.assets, svg::LOW_QUALITY),
0.0,
0.0,
);
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),

View File

@ -32,6 +32,7 @@ impl GeomBatch {
pub fn push(&mut self, color: Color, p: Polygon) {
self.list.push((FancyColor::RGBA(color), p));
}
// TODO Weird API too
pub fn fancy_push(&mut self, color: FancyColor, p: Polygon) {
self.list.push((color, p));
}
@ -117,15 +118,6 @@ impl GeomBatch {
}
}
/// Transforms all colors in a batch.
pub fn rewrite_color(&mut self, transformation: RewriteColor) {
for (fancy, _) in self.list.iter_mut() {
if let FancyColor::RGBA(ref mut c) = fancy {
*c = transformation.apply(*c);
}
}
}
// TODO Weird API.
/// Adds an SVG image to the current batch, applying the transformations first.
pub fn add_svg(
@ -138,7 +130,7 @@ impl GeomBatch {
rewrite: RewriteColor,
map_space: bool,
) {
self.add_transformed(
self.append(
svg::load_svg(
prerender,
filename,
@ -148,61 +140,60 @@ impl GeomBatch {
*prerender.assets.scale_factor.borrow()
},
)
.0,
center,
scale,
rotate,
rewrite,
.0
.scale(scale)
.centered_on(center)
.rotate(rotate)
.color(rewrite),
);
}
// TODO Weird API
/// Parse an SVG string and add it to the batch.
pub fn add_svg_contents(&mut self, raw: Vec<u8>) {
let svg_tree = usvg::Tree::from_data(&raw, &usvg::Options::default()).unwrap();
svg::add_svg_inner(self, svg_tree, svg::HIGH_QUALITY, 1.0).unwrap();
}
// TODO Weird API
/// Adds geometry from another batch to the current batch, first centering it on the given
/// point.
pub fn add_centered(&mut self, other: GeomBatch, center: Pt2D) {
self.add_transformed(other, center, 1.0, Angle::ZERO, RewriteColor::NoOp);
self.append(other.centered_on(center));
}
/// 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,
rewrite: RewriteColor,
) {
let dims = other.get_dims();
let dx = center.x() - dims.width * scale / 2.0;
let dy = center.y() - dims.height * scale / 2.0;
for (mut fancy_color, mut poly) in other.consume() {
// Avoid unnecessary transformations for slight perf boost
if scale != 1.0 {
poly = poly.scale(scale);
/// Transforms all colors in a batch.
pub fn color(mut self, transformation: RewriteColor) -> GeomBatch {
for (fancy, _) in &mut self.list {
if let FancyColor::RGBA(ref mut c) = fancy {
*c = transformation.apply(*c);
}
poly = poly.translate(dx, dy);
if rotate != Angle::ZERO {
poly = poly.rotate(rotate);
}
if let FancyColor::RGBA(ref mut c) = fancy_color {
*c = rewrite.apply(*c);
}
self.fancy_push(fancy_color, poly);
}
self
}
// 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.fancy_push(color, poly.translate(dx, dy));
/// Translates the batch to be centered on some point.
pub fn centered_on(self, center: Pt2D) -> GeomBatch {
let dims = self.get_dims();
let dx = center.x() - dims.width / 2.0;
let dy = center.y() - dims.height / 2.0;
self.translate(dx, dy)
}
/// Translates the batch by some offset.
pub fn translate(mut self, dx: f64, dy: f64) -> GeomBatch {
for (_, poly) in &mut self.list {
*poly = poly.translate(dx, dy);
}
self
}
/// Rotates each polygon in the batch relative to the center of that polygon.
pub fn rotate(mut self, angle: Angle) -> GeomBatch {
for (_, poly) in &mut self.list {
*poly = poly.rotate(angle);
}
self
}
/// Scales the batch by some factor.

View File

@ -291,13 +291,8 @@ impl BtnBuilder {
let geom =
Polygon::rectangle(bounds.width() + 2.0 * pad, bounds.height() + 2.0 * pad);
let mut normal = GeomBatch::new();
normal.add_translated(orig.clone(), pad, pad);
normal.rewrite_color(rewrite_normal);
let mut hovered = GeomBatch::new();
hovered.add_translated(orig, pad, pad);
hovered.rewrite_color(rewrite_hover);
let normal = orig.clone().translate(pad, pad).color(rewrite_normal);
let hovered = orig.translate(pad, pad).color(rewrite_hover);
Button::new(
ctx,
@ -325,9 +320,9 @@ impl BtnBuilder {
);
let mut normal = GeomBatch::new();
normal.add_translated(unselected_batch, horiz_padding, vert_padding);
normal.append(unselected_batch.translate(horiz_padding, vert_padding));
let mut hovered = GeomBatch::new();
hovered.add_translated(selected_batch, horiz_padding, vert_padding);
hovered.append(selected_batch.translate(horiz_padding, vert_padding));
Button::new(
ctx,
@ -357,9 +352,9 @@ impl BtnBuilder {
);
let mut normal = GeomBatch::new();
normal.add_translated(unselected_batch, horiz_padding, vert_padding);
normal.append(unselected_batch.translate(horiz_padding, vert_padding));
let mut hovered = GeomBatch::new();
hovered.add_translated(selected_batch, horiz_padding, vert_padding);
hovered.append(selected_batch.translate(horiz_padding, vert_padding));
Button::new(
ctx,
@ -390,10 +385,10 @@ impl BtnBuilder {
);
let mut normal = GeomBatch::from(vec![(unselected_bg_color, geom.clone())]);
normal.add_translated(txt_batch.clone(), HORIZ_PADDING, VERT_PADDING);
normal.append(txt_batch.clone().translate(HORIZ_PADDING, VERT_PADDING));
let mut hovered = GeomBatch::from(vec![(selected_bg_color, geom.clone())]);
hovered.add_translated(txt_batch.clone(), HORIZ_PADDING, VERT_PADDING);
hovered.append(txt_batch.translate(HORIZ_PADDING, VERT_PADDING));
Button::new(
ctx,

View File

@ -35,12 +35,12 @@ impl JustDraw {
}))
}
pub(crate) fn svg_transform(ctx: &EventCtx, filename: &str, rewrite: RewriteColor) -> Widget {
let (mut batch, bounds) = svg::load_svg(
let (batch, bounds) = svg::load_svg(
ctx.prerender,
filename,
*ctx.prerender.assets.scale_factor.borrow(),
);
batch.rewrite_color(rewrite);
let batch = batch.color(rewrite);
// TODO The dims will be wrong; it'll only look at geometry, not the padding in the image.
Widget::new(Box::new(JustDraw {
dims: ScreenDims::new(bounds.width(), bounds.height()),

View File

@ -250,16 +250,18 @@ impl CommonState {
app.cs.panel_bg,
Polygon::rectangle(g.canvas.window_width, 1.5 * g.default_line_height()),
)]);
batch.add_translated(osd.render_g(g), 10.0, 0.25 * g.default_line_height());
batch.append(
osd.render_g(g)
.translate(10.0, 0.25 * g.default_line_height()),
);
if app.opts.dev && !g.is_screencap() {
let dev_batch = Text::from(Line("DEV")).bg(Color::RED).render_g(g);
let dims = dev_batch.get_dims();
batch.add_translated(
dev_batch,
batch.append(dev_batch.translate(
g.canvas.window_width - dims.width - 10.0,
0.25 * g.default_line_height(),
);
));
}
let draw = g.upload(batch);
let top_left = ScreenPt::new(0.0, g.canvas.window_height - 1.5 * g.default_line_height());

View File

@ -485,14 +485,12 @@ impl Marker {
RewriteColor::Change(Color::hex("#5B5B5B"), Color::hex("#FE3D00")),
false,
);
batch.add_transformed(
batch.append(
Text::from(Line(&event))
.with_bg()
.render_to_batch(ctx.prerender),
pts[0],
0.5,
Angle::ZERO,
RewriteColor::NoOp,
.render_to_batch(ctx.prerender)
.scale(0.5)
.centered_on(pts[0]),
);
batch.unioned_polygon()
} else {
@ -502,14 +500,12 @@ impl Marker {
batch.push(Color::RED, o);
}
// TODO Refactor
batch.add_transformed(
batch.append(
Text::from(Line(&event))
.with_bg()
.render_to_batch(ctx.prerender),
poly.polylabel(),
0.5,
Angle::ZERO,
RewriteColor::NoOp,
.render_to_batch(ctx.prerender)
.scale(0.5)
.centered_on(poly.polylabel()),
);
poly
};
@ -533,26 +529,22 @@ impl Marker {
RewriteColor::Change(Color::hex("#5B5B5B"), app.cs.hovering),
false,
);
batch.add_transformed(
batch.append(
Text::from(Line(&self.event))
.with_bg()
.render_to_batch(g.prerender),
self.pts[0],
0.75,
Angle::ZERO,
RewriteColor::NoOp,
.render_to_batch(g.prerender)
.scale(0.75)
.centered_on(self.pts[0]),
);
} else {
batch.push(app.cs.hovering, Polygon::new(&self.pts));
// TODO Refactor plz
batch.add_transformed(
batch.append(
Text::from(Line(&self.event))
.with_bg()
.render_to_batch(g.prerender),
self.hitbox.polylabel(),
0.75,
Angle::ZERO,
RewriteColor::NoOp,
.render_to_batch(g.prerender)
.scale(0.75)
.centered_on(self.hitbox.polylabel()),
);
}
batch.draw(g);

View File

@ -1,11 +1,8 @@
use crate::app::App;
use crate::info::{header_btns, make_tabs, throughput, DataOptions, Details, Tab};
use abstutil::prettyprint_usize;
use ezgui::{
Color, EventCtx, GeomBatch, Line, PlotOptions, RewriteColor, ScatterPlotV2, Series, Text,
Widget,
};
use geom::{Angle, ArrowCap, Distance, PolyLine};
use ezgui::{Color, EventCtx, GeomBatch, Line, PlotOptions, ScatterPlotV2, Series, Text, Widget};
use geom::{ArrowCap, Distance, PolyLine};
use map_model::{IntersectionID, IntersectionType};
use std::collections::BTreeSet;
@ -138,12 +135,11 @@ pub fn current_demand(
pl.make_arrow(percent * Distance::meters(3.0), ArrowCap::Triangle)
.unwrap(),
);
txt_batch.add_transformed(
Text::from(Line(prettyprint_usize(demand))).render_ctx(ctx),
pl.middle(),
0.15 / ctx.get_scale_factor(),
Angle::ZERO,
RewriteColor::NoOp,
txt_batch.append(
Text::from(Line(prettyprint_usize(demand)))
.render_ctx(ctx)
.scale(0.15 / ctx.get_scale_factor())
.centered_on(pl.middle()),
);
}
batch.append(txt_batch);

View File

@ -85,12 +85,10 @@ impl Renderable for DrawBuilding {
if b.amenities.len() > 1 {
txt.append(Line(format!(" (+{})", b.amenities.len() - 1)).fg(Color::BLACK));
}
batch.add_transformed(
txt.render_to_batch(g.prerender),
b.label_center,
0.1,
Angle::ZERO,
RewriteColor::NoOp,
batch.append(
txt.render_to_batch(g.prerender)
.scale(0.1)
.centered_on(b.label_center),
);
}
*label = Some(g.prerender.upload(batch));

View File

@ -135,12 +135,11 @@ impl DrawCar {
if let Some(line) = input.label {
// TODO Would rotation make any sense? Or at least adjust position/size while turning.
// Buses are a constant length, so hardcoding this is fine.
draw_default.add_transformed(
Text::from(Line(line).fg(cs.bus_label)).render_to_batch(prerender),
input.body.dist_along(Distance::meters(9.0)).0,
0.07,
Angle::ZERO,
RewriteColor::NoOp,
draw_default.append(
Text::from(Line(line).fg(cs.bus_label))
.render_to_batch(prerender)
.scale(0.07)
.centered_on(input.body.dist_along(Distance::meters(9.0)).0),
);
}

View File

@ -77,7 +77,7 @@ impl DrawIntersection {
let zorder = i.get_zorder(map);
if zorder < 0 {
default_geom.rewrite_color(RewriteColor::ChangeAlpha(0.5));
default_geom = default_geom.color(RewriteColor::ChangeAlpha(0.5));
}
DrawIntersection {
@ -152,12 +152,11 @@ impl Renderable for DrawIntersection {
app.opts.traffic_signal_style.clone(),
);
if app.opts.traffic_signal_style != TrafficSignalStyle::BAP {
batch.add_transformed(
Text::from(Line(format!("{}", idx + 1))).render_to_batch(g.prerender),
app.primary.map.get_i(self.id).polygon.center(),
0.1,
Angle::ZERO,
RewriteColor::NoOp,
batch.append(
Text::from(Line(format!("{}", idx + 1)))
.render_to_batch(g.prerender)
.scale(0.1)
.centered_on(app.primary.map.get_i(self.id).polygon.center()),
);
}
*maybe_redraw = Some((app.primary.sim.time(), g.prerender.upload(batch)));

View File

@ -64,8 +64,7 @@ impl AlmostDrawLane {
}
if self.zorder < 0 {
self.draw_default
.rewrite_color(RewriteColor::ChangeAlpha(0.5));
self.draw_default = self.draw_default.color(RewriteColor::ChangeAlpha(0.5));
}
DrawLane {

View File

@ -2,8 +2,8 @@ use crate::app::App;
use crate::colors::ColorScheme;
use crate::helpers::ID;
use crate::render::{DrawOptions, Renderable, OUTLINE_THICKNESS};
use ezgui::{Color, Drawable, GeomBatch, GfxCtx, Line, Prerender, RewriteColor, Text};
use geom::{Angle, ArrowCap, Circle, Distance, PolyLine, Polygon};
use ezgui::{Color, Drawable, GeomBatch, GfxCtx, Line, Prerender, Text};
use geom::{ArrowCap, Circle, Distance, PolyLine, Polygon};
use map_model::{Map, SIDEWALK_THICKNESS};
use sim::{DrawPedCrowdInput, DrawPedestrianInput, PedCrowdLocation, PedestrianID};
@ -222,13 +222,11 @@ impl DrawPedCrowd {
let blob = pl_shifted.make_polygons(SIDEWALK_THICKNESS / 2.0);
let mut batch = GeomBatch::new();
batch.push(cs.ped_crowd, blob.clone());
batch.add_transformed(
batch.append(
Text::from(Line(format!("{}", input.members.len())).fg(Color::BLACK))
.render_to_batch(prerender),
blob.center(),
0.02,
Angle::ZERO,
RewriteColor::NoOp,
.render_to_batch(prerender)
.scale(0.02)
.centered_on(blob.center()),
);
DrawPedCrowd {

View File

@ -2,8 +2,8 @@ use crate::app::App;
use crate::colors::ColorScheme;
use crate::helpers::ID;
use crate::render::{DrawOptions, Renderable};
use ezgui::{Drawable, GeomBatch, GfxCtx, Line, Prerender, RewriteColor, Text};
use geom::{Angle, Distance, Polygon, Pt2D};
use ezgui::{Drawable, GeomBatch, GfxCtx, Line, Prerender, Text};
use geom::{Distance, Polygon, Pt2D};
use map_model::{LaneType, Map, Road, RoadID};
use std::cell::RefCell;
@ -62,12 +62,10 @@ impl Renderable for DrawRoad {
let mut txt = Text::new().with_bg();
txt.add(Line(r.get_name()));
batch.add_transformed(
txt.render_to_batch(g.prerender),
r.center_pts.middle(),
0.1,
Angle::ZERO,
RewriteColor::NoOp,
batch.append(
txt.render_to_batch(g.prerender)
.scale(0.1)
.centered_on(r.center_pts.middle()),
);
*label = Some(g.prerender.upload(batch));
}

View File

@ -437,7 +437,7 @@ pub fn make_table(
batch.autocrop_dims = false;
let mut x1 = 0.0;
for (col, width) in row.into_iter().zip(width_per_col.iter()) {
batch.add_translated(col.scale(1.0 / ctx.get_scale_factor()), x1, 0.0);
batch.append(col.scale(1.0 / ctx.get_scale_factor()).translate(x1, 0.0));
x1 += *width + extra_margin;
}

View File

@ -4,10 +4,10 @@ mod world;
use abstutil::{CmdArgs, Timer};
use ezgui::{
hotkey, Btn, Canvas, Choice, Color, Composite, Drawable, EventCtx, EventLoopMode, GeomBatch,
GfxCtx, HorizontalAlignment, Key, Line, Outcome, RewriteColor, ScreenPt, Text,
VerticalAlignment, Widget, Wizard, GUI,
GfxCtx, HorizontalAlignment, Key, Line, Outcome, ScreenPt, Text, VerticalAlignment, Widget,
Wizard, GUI,
};
use geom::{Angle, Distance, Line, Polygon, Pt2D};
use geom::{Distance, Line, Polygon, Pt2D};
use map_model::raw::{OriginalBuilding, OriginalIntersection, OriginalRoad, RestrictionType};
use map_model::{osm, NORMAL_LANE_THICKNESS};
use model::{Model, ID};
@ -657,14 +657,12 @@ fn preview_intersection(i: OriginalIntersection, model: &Model, ctx: &EventCtx)
for (label, poly) in debug {
let center = poly.center();
batch.push(Color::RED.alpha(0.5), poly);
batch.add_transformed(
batch.append(
Text::from(Line(label))
.with_bg()
.render_to_batch(ctx.prerender),
center,
0.1,
Angle::ZERO,
RewriteColor::NoOp,
.render_to_batch(ctx.prerender)
.scale(0.1)
.centered_on(center),
);
}
batch.upload(ctx)