mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-26 16:02:23 +03:00
starting to move some text drawing code out of canvas
This commit is contained in:
parent
c4d09b6e4f
commit
5181a3db34
@ -87,7 +87,7 @@
|
||||
- probably use f32, not f64 everywhere... but after Pt2D becomes fixed size
|
||||
- undo the y inversion hacks at last!
|
||||
- ezgui passes EventCtx and DrawCtx with appropriate things exposed.
|
||||
- maybe move glyph ownership out of canvas entirely
|
||||
- maybe move glyph ownership out of canvas entirely. dont need RefCell.
|
||||
- canvas owning text-drawing is maybe a bit weird, at least API-wise
|
||||
- hide stuff inside the ctx's? canvas and prerender shouldnt even be known outside of crate
|
||||
- generic World with quadtree should have actions on objects
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::screen_geom::ScreenRectangle;
|
||||
use crate::{text, GfxCtx, ScreenPt, Text, UserInput};
|
||||
use crate::{ScreenPt, Text, UserInput};
|
||||
use geom::{Bounds, Pt2D};
|
||||
use glium_glyph::GlyphBrush;
|
||||
use std::cell::RefCell;
|
||||
@ -14,8 +14,8 @@ pub struct Canvas {
|
||||
pub cam_zoom: f64,
|
||||
|
||||
// TODO We probably shouldn't even track screen-space cursor when we don't have the cursor.
|
||||
cursor_x: f64,
|
||||
cursor_y: f64,
|
||||
pub(crate) cursor_x: f64,
|
||||
pub(crate) cursor_y: f64,
|
||||
window_has_cursor: bool,
|
||||
|
||||
left_mouse_drag_from: Option<ScreenPt>,
|
||||
@ -27,7 +27,7 @@ pub struct Canvas {
|
||||
pub(crate) line_height: f64,
|
||||
|
||||
// TODO Bit weird and hacky to mutate inside of draw() calls.
|
||||
covered_areas: RefCell<Vec<ScreenRectangle>>,
|
||||
pub(crate) covered_areas: RefCell<Vec<ScreenRectangle>>,
|
||||
}
|
||||
|
||||
impl Canvas {
|
||||
@ -99,72 +99,6 @@ impl Canvas {
|
||||
self.covered_areas.borrow_mut().push(rect);
|
||||
}
|
||||
|
||||
pub fn draw_mouse_tooltip(&self, g: &mut GfxCtx, txt: Text) {
|
||||
let (width, height) = self.text_dims(&txt);
|
||||
let x1 = self.cursor_x - (width / 2.0);
|
||||
let y1 = self.cursor_y - (height / 2.0);
|
||||
// No need to cover the tooltip; this tooltip follows the mouse anyway.
|
||||
text::draw_text_bubble(g, self, ScreenPt::new(x1, y1), txt, (width, height));
|
||||
}
|
||||
|
||||
// TODO Rename these draw_nonblocking_text_*
|
||||
pub fn draw_text_at(&self, g: &mut GfxCtx, txt: Text, map_pt: Pt2D) {
|
||||
let (width, height) = self.text_dims(&txt);
|
||||
let pt = self.map_to_screen(map_pt);
|
||||
text::draw_text_bubble(
|
||||
g,
|
||||
self,
|
||||
ScreenPt::new(pt.x - (width / 2.0), pt.y - (height / 2.0)),
|
||||
txt,
|
||||
(width, height),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn draw_text_at_topleft(&self, g: &mut GfxCtx, txt: Text, pt: Pt2D) {
|
||||
let dims = self.text_dims(&txt);
|
||||
text::draw_text_bubble(g, self, self.map_to_screen(pt), txt, dims);
|
||||
}
|
||||
|
||||
pub fn draw_text_at_screenspace_topleft(&self, g: &mut GfxCtx, txt: Text, pt: ScreenPt) {
|
||||
let dims = self.text_dims(&txt);
|
||||
text::draw_text_bubble(g, self, pt, txt, dims);
|
||||
}
|
||||
|
||||
// The text box covers up what's beneath and eats the cursor (for get_cursor_in_map_space).
|
||||
pub fn draw_blocking_text(
|
||||
&self,
|
||||
g: &mut GfxCtx,
|
||||
txt: Text,
|
||||
(horiz, vert): (HorizontalAlignment, VerticalAlignment),
|
||||
) {
|
||||
if txt.is_empty() {
|
||||
return;
|
||||
}
|
||||
let (width, height) = self.text_dims(&txt);
|
||||
let x1 = match horiz {
|
||||
HorizontalAlignment::Left => 0.0,
|
||||
HorizontalAlignment::Center => (self.window_width - width) / 2.0,
|
||||
HorizontalAlignment::Right => self.window_width - width,
|
||||
};
|
||||
let y1 = match vert {
|
||||
VerticalAlignment::Top => 0.0,
|
||||
VerticalAlignment::BelowTopMenu => self.line_height,
|
||||
VerticalAlignment::Center => (self.window_height - height) / 2.0,
|
||||
VerticalAlignment::Bottom => self.window_height - height,
|
||||
};
|
||||
self.covered_areas.borrow_mut().push(text::draw_text_bubble(
|
||||
g,
|
||||
self,
|
||||
ScreenPt::new(x1, y1),
|
||||
txt,
|
||||
(width, height),
|
||||
));
|
||||
}
|
||||
|
||||
pub fn text_dims(&self, txt: &Text) -> (f64, f64) {
|
||||
txt.dims(self)
|
||||
}
|
||||
|
||||
fn zoom_towards_mouse(&mut self, delta_zoom: f64) {
|
||||
let old_zoom = self.cam_zoom;
|
||||
self.cam_zoom += delta_zoom;
|
||||
@ -217,7 +151,7 @@ impl Canvas {
|
||||
self.cam_y = (pt.y() * self.cam_zoom) - (self.window_height / 2.0);
|
||||
}
|
||||
|
||||
fn map_to_screen(&self, pt: Pt2D) -> ScreenPt {
|
||||
pub(crate) fn map_to_screen(&self, pt: Pt2D) -> ScreenPt {
|
||||
ScreenPt::new(
|
||||
(pt.x() * self.cam_zoom) - self.cam_x,
|
||||
(pt.y() * self.cam_zoom) - self.cam_y,
|
||||
@ -236,6 +170,10 @@ impl Canvas {
|
||||
pub fn top_menu_height(&self) -> f64 {
|
||||
self.line_height
|
||||
}
|
||||
|
||||
pub fn text_dims(&self, txt: &Text) -> (f64, f64) {
|
||||
txt.dims(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub enum HorizontalAlignment {
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::{
|
||||
Canvas, Color, Drawable, HorizontalAlignment, Prerender, ScreenPt, Text, VerticalAlignment,
|
||||
text, Canvas, Color, Drawable, HorizontalAlignment, Prerender, ScreenPt, Text,
|
||||
VerticalAlignment,
|
||||
};
|
||||
use geom::{Bounds, Circle, Distance, Line, Polygon, Pt2D};
|
||||
use glium::{uniform, Surface};
|
||||
@ -149,32 +150,77 @@ impl<'a> GfxCtx<'a> {
|
||||
self.num_draw_calls += 1;
|
||||
}
|
||||
|
||||
// Forwarded canvas stuff.
|
||||
// Canvas stuff.
|
||||
|
||||
// The text box covers up what's beneath and eats the cursor (for get_cursor_in_map_space).
|
||||
pub fn draw_blocking_text(
|
||||
&mut self,
|
||||
txt: Text,
|
||||
(horiz, vert): (HorizontalAlignment, VerticalAlignment),
|
||||
) {
|
||||
self.canvas.draw_blocking_text(self, txt, (horiz, vert));
|
||||
if txt.is_empty() {
|
||||
return;
|
||||
}
|
||||
let (width, height) = self.text_dims(&txt);
|
||||
let x1 = match horiz {
|
||||
HorizontalAlignment::Left => 0.0,
|
||||
HorizontalAlignment::Center => (self.canvas.window_width - width) / 2.0,
|
||||
HorizontalAlignment::Right => self.canvas.window_width - width,
|
||||
};
|
||||
let y1 = match vert {
|
||||
VerticalAlignment::Top => 0.0,
|
||||
VerticalAlignment::BelowTopMenu => self.canvas.line_height,
|
||||
VerticalAlignment::Center => (self.canvas.window_height - height) / 2.0,
|
||||
VerticalAlignment::Bottom => self.canvas.window_height - height,
|
||||
};
|
||||
self.canvas
|
||||
.covered_areas
|
||||
.borrow_mut()
|
||||
.push(text::draw_text_bubble(
|
||||
self,
|
||||
ScreenPt::new(x1, y1),
|
||||
txt,
|
||||
(width, height),
|
||||
));
|
||||
}
|
||||
|
||||
pub fn get_screen_bounds(&self) -> Bounds {
|
||||
self.canvas.get_screen_bounds()
|
||||
}
|
||||
|
||||
// TODO Rename these draw_nonblocking_text_*
|
||||
pub fn draw_text_at(&mut self, txt: Text, map_pt: Pt2D) {
|
||||
self.canvas.draw_text_at(self, txt, map_pt);
|
||||
let (width, height) = self.text_dims(&txt);
|
||||
let pt = self.canvas.map_to_screen(map_pt);
|
||||
text::draw_text_bubble(
|
||||
self,
|
||||
ScreenPt::new(pt.x - (width / 2.0), pt.y - (height / 2.0)),
|
||||
txt,
|
||||
(width, height),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn text_dims(&self, txt: &Text) -> (f64, f64) {
|
||||
self.canvas.text_dims(txt)
|
||||
}
|
||||
|
||||
pub fn draw_text_at_screenspace_topleft(&mut self, txt: Text, pt: ScreenPt) {
|
||||
self.canvas.draw_text_at_screenspace_topleft(self, txt, pt);
|
||||
let dims = self.text_dims(&txt);
|
||||
text::draw_text_bubble(self, pt, txt, dims);
|
||||
}
|
||||
|
||||
pub fn draw_mouse_tooltip(&mut self, txt: Text) {
|
||||
self.canvas.draw_mouse_tooltip(self, txt);
|
||||
let (width, height) = self.text_dims(&txt);
|
||||
let x1 = self.canvas.cursor_x - (width / 2.0);
|
||||
let y1 = self.canvas.cursor_y - (height / 2.0);
|
||||
// No need to cover the tooltip; this tooltip follows the mouse anyway.
|
||||
text::draw_text_bubble(self, ScreenPt::new(x1, y1), txt, (width, height));
|
||||
}
|
||||
|
||||
pub fn screen_to_map(&self, pt: ScreenPt) -> Pt2D {
|
||||
self.canvas.screen_to_map(pt)
|
||||
}
|
||||
|
||||
pub fn get_cursor_in_map_space(&self) -> Option<Pt2D> {
|
||||
self.canvas.get_cursor_in_map_space()
|
||||
}
|
||||
|
@ -145,7 +145,6 @@ impl Text {
|
||||
|
||||
pub fn draw_text_bubble(
|
||||
g: &mut GfxCtx,
|
||||
canvas: &Canvas,
|
||||
top_left: ScreenPt,
|
||||
txt: Text,
|
||||
// Callers almost always calculate this anyway
|
||||
@ -165,7 +164,7 @@ pub fn draw_text_bubble(
|
||||
);
|
||||
}
|
||||
|
||||
let mut glyphs = canvas.glyphs.borrow_mut();
|
||||
let mut glyphs = g.canvas.glyphs.borrow_mut();
|
||||
let mut y = top_left.y;
|
||||
for (line_color, line) in &txt.lines {
|
||||
let section = VariedSection {
|
||||
@ -188,12 +187,12 @@ pub fn draw_text_bubble(
|
||||
&Polygon::rectangle_topleft(
|
||||
Pt2D::new(top_left.x, y),
|
||||
total_width,
|
||||
canvas.line_height,
|
||||
g.canvas.line_height,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
y += canvas.line_height;
|
||||
y += g.canvas.line_height;
|
||||
glyphs.queue(section);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user