Rename PaintCmd
to Shape
This commit is contained in:
parent
a0b0f36d29
commit
fb2317c993
33 changed files with 225 additions and 235 deletions
|
@ -17,6 +17,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
|
||||
* Center window titles.
|
||||
* Tweak size and alignment of some emojis to match other text.
|
||||
* Rename `PaintCmd` to `Shape`.
|
||||
* Rename feature "serde" to "persistence".
|
||||
|
||||
### Fixed 🐛
|
||||
|
@ -163,7 +164,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
* Refactored the interface for `egui::app::App`.
|
||||
* Windows are now constrained to the screen.
|
||||
* `Context::begin_frame()` no longer returns a `Ui`. Instead put your widgets into a `SidePanel`, `TopPanel`, `CentralPanel`, `Window` or `Area`.
|
||||
* `Context::end_frame()` now returns paint commands that need to be converted to triangles with `Context::tessellate()`.
|
||||
* `Context::end_frame()` now returns shapes that need to be converted to triangles with `Context::tessellate()`.
|
||||
* Anti-aliasing is now off by default in debug builds.
|
||||
|
||||
### Removed 🔥
|
||||
|
|
|
@ -173,8 +173,8 @@ loop {
|
|||
let raw_input: egui::RawInput = my_integration.gather_input();
|
||||
egui_ctx.begin_frame(raw_input);
|
||||
my_app.ui(&mut egui_ctx); // add panels, windows and widgets to `egui_ctx` here
|
||||
let (output, paint_commands) = egui_ctx.end_frame();
|
||||
let paint_jobs = egui_ctx.tessellate(paint_commands); // create triangles to paint
|
||||
let (output, shapes) = egui_ctx.end_frame();
|
||||
let paint_jobs = egui_ctx.tessellate(shapes); // create triangles to paint
|
||||
my_integration.paint(paint_jobs);
|
||||
my_integration.set_cursor_icon(output.cursor_icon);
|
||||
// Also see `egui::Output` for more
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::hash::Hash;
|
||||
|
||||
use crate::{
|
||||
paint::{PaintCmd, TextStyle},
|
||||
paint::{Shape, TextStyle},
|
||||
widgets::Label,
|
||||
*,
|
||||
};
|
||||
|
@ -119,7 +119,7 @@ pub(crate) fn paint_icon(ui: &mut Ui, openness: f32, response: &Response) {
|
|||
*p = rect.center() + rotation * (*p - rect.center());
|
||||
}
|
||||
|
||||
ui.painter().add(PaintCmd::closed_line(points, stroke));
|
||||
ui.painter().add(Shape::closed_line(points, stroke));
|
||||
}
|
||||
|
||||
/// A header which can be collapsed/expanded, revealing a contained [`Ui`] region.
|
||||
|
@ -203,7 +203,7 @@ impl CollapsingHeader {
|
|||
state.toggle(ui);
|
||||
}
|
||||
|
||||
let bg_index = ui.painter().add(PaintCmd::Noop);
|
||||
let bg_index = ui.painter().add(Shape::Noop);
|
||||
|
||||
{
|
||||
let (mut icon_rect, _) = ui.style().spacing.icon_rectangles(header_response.rect);
|
||||
|
@ -229,7 +229,7 @@ impl CollapsingHeader {
|
|||
|
||||
painter.set(
|
||||
bg_index,
|
||||
PaintCmd::Rect {
|
||||
Shape::Rect {
|
||||
rect: header_response.rect,
|
||||
corner_radius: ui.style().interact(&header_response).corner_radius,
|
||||
fill: ui.style().interact(&header_response).bg_fill,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{paint::PaintCmd, style::WidgetVisuals, *};
|
||||
use crate::{paint::Shape, style::WidgetVisuals, *};
|
||||
|
||||
/// A drop-down selection menu with a descriptive label.
|
||||
///
|
||||
|
@ -119,7 +119,7 @@ fn button_frame(
|
|||
let margin = ui.style().spacing.button_padding;
|
||||
let outer_rect_bounds = ui.available_rect_before_wrap();
|
||||
let inner_rect = outer_rect_bounds.shrink2(margin);
|
||||
let where_to_put_background = ui.painter().add(PaintCmd::Noop);
|
||||
let where_to_put_background = ui.painter().add(Shape::Noop);
|
||||
let mut content_ui = ui.child_ui(inner_rect, *ui.layout());
|
||||
add_contents(&mut content_ui);
|
||||
|
||||
|
@ -131,7 +131,7 @@ fn button_frame(
|
|||
|
||||
ui.painter().set(
|
||||
where_to_put_background,
|
||||
PaintCmd::Rect {
|
||||
Shape::Rect {
|
||||
rect: outer_rect,
|
||||
corner_radius: visuals.corner_radius,
|
||||
fill: visuals.bg_fill,
|
||||
|
@ -149,7 +149,7 @@ fn paint_icon(painter: &Painter, rect: Rect, visuals: &WidgetVisuals) {
|
|||
rect.center(),
|
||||
vec2(rect.width() * 0.7, rect.height() * 0.45),
|
||||
);
|
||||
painter.add(PaintCmd::closed_line(
|
||||
painter.add(Shape::closed_line(
|
||||
vec![rect.left_top(), rect.right_top(), rect.center_bottom()],
|
||||
visuals.fg_stroke,
|
||||
));
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Frame container
|
||||
|
||||
use crate::{layers::PaintCmdIdx, paint::*, *};
|
||||
use crate::{layers::ShapeIdx, paint::*, *};
|
||||
|
||||
/// Adds a rectangular frame and background to some [`Ui`].
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
||||
|
@ -95,13 +95,13 @@ impl Frame {
|
|||
pub struct Prepared {
|
||||
pub frame: Frame,
|
||||
outer_rect_bounds: Rect,
|
||||
where_to_put_background: PaintCmdIdx,
|
||||
where_to_put_background: ShapeIdx,
|
||||
pub content_ui: Ui,
|
||||
}
|
||||
|
||||
impl Frame {
|
||||
pub fn begin(self, ui: &mut Ui) -> Prepared {
|
||||
let where_to_put_background = ui.painter().add(PaintCmd::Noop);
|
||||
let where_to_put_background = ui.painter().add(Shape::Noop);
|
||||
let outer_rect_bounds = ui.available_rect_before_wrap();
|
||||
let inner_rect = outer_rect_bounds.shrink2(self.margin);
|
||||
let content_ui = ui.child_ui(inner_rect, *ui.layout());
|
||||
|
@ -141,7 +141,7 @@ impl Prepared {
|
|||
..
|
||||
} = self;
|
||||
|
||||
let frame_cmd = PaintCmd::Rect {
|
||||
let frame_shape = Shape::Rect {
|
||||
rect: outer_rect,
|
||||
corner_radius: frame.corner_radius,
|
||||
fill: frame.fill,
|
||||
|
@ -149,13 +149,13 @@ impl Prepared {
|
|||
};
|
||||
|
||||
if frame.shadow == Default::default() {
|
||||
ui.painter().set(where_to_put_background, frame_cmd);
|
||||
ui.painter().set(where_to_put_background, frame_shape);
|
||||
} else {
|
||||
let shadow = frame.shadow.tessellate(outer_rect, frame.corner_radius);
|
||||
let shadow = PaintCmd::Triangles(shadow);
|
||||
let shadow = Shape::Triangles(shadow);
|
||||
ui.painter().set(
|
||||
where_to_put_background,
|
||||
PaintCmd::Vec(vec![shadow, frame_cmd]),
|
||||
Shape::Vec(vec![shadow, frame_shape]),
|
||||
)
|
||||
};
|
||||
|
||||
|
|
|
@ -284,7 +284,7 @@ impl Resize {
|
|||
if self.with_stroke && corner_response.is_some() {
|
||||
let rect = Rect::from_min_size(content_ui.min_rect().left_top(), state.desired_size);
|
||||
let rect = rect.expand(2.0); // breathing room for content
|
||||
ui.painter().add(paint::PaintCmd::Rect {
|
||||
ui.painter().add(paint::Shape::Rect {
|
||||
rect,
|
||||
corner_radius: 3.0,
|
||||
fill: Default::default(),
|
||||
|
|
|
@ -325,7 +325,7 @@ impl Prepared {
|
|||
|
||||
let visuals = ui.style().interact(&response);
|
||||
|
||||
ui.painter().add(paint::PaintCmd::Rect {
|
||||
ui.painter().add(paint::Shape::Rect {
|
||||
rect: outer_scroll_rect,
|
||||
corner_radius,
|
||||
fill: ui.style().visuals.dark_bg_color,
|
||||
|
@ -334,7 +334,7 @@ impl Prepared {
|
|||
// stroke: visuals.bg_stroke,
|
||||
});
|
||||
|
||||
ui.painter().add(paint::PaintCmd::Rect {
|
||||
ui.painter().add(paint::Shape::Rect {
|
||||
rect: handle_rect.expand(-2.0),
|
||||
corner_radius,
|
||||
fill: visuals.fg_fill,
|
||||
|
|
|
@ -623,7 +623,7 @@ fn paint_frame_interaction(
|
|||
points.push(pos2(max.x, min.y + cr));
|
||||
points.push(pos2(max.x, max.y - cr));
|
||||
}
|
||||
ui.painter().add(PaintCmd::line(points, visuals.bg_stroke));
|
||||
ui.painter().add(Shape::line(points, visuals.bg_stroke));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
|
@ -592,10 +592,10 @@ impl Context {
|
|||
|
||||
/// Call at the end of each frame.
|
||||
/// Returns what has happened this frame (`Output`) as well as what you need to paint.
|
||||
/// You can transform the returned paint commands into triangles with a call to
|
||||
/// You can transform the returned shapes into triangles with a call to
|
||||
/// `Context::tessellate`.
|
||||
#[must_use]
|
||||
pub fn end_frame(&self) -> (Output, Vec<(Rect, PaintCmd)>) {
|
||||
pub fn end_frame(&self) -> (Output, Vec<(Rect, Shape)>) {
|
||||
if self.input.wants_repaint() {
|
||||
self.request_repaint();
|
||||
}
|
||||
|
@ -608,25 +608,21 @@ impl Context {
|
|||
output.needs_repaint = true;
|
||||
}
|
||||
|
||||
let paint_commands = self.drain_paint_lists();
|
||||
(output, paint_commands)
|
||||
let shapes = self.drain_paint_lists();
|
||||
(output, shapes)
|
||||
}
|
||||
|
||||
fn drain_paint_lists(&self) -> Vec<(Rect, PaintCmd)> {
|
||||
fn drain_paint_lists(&self) -> Vec<(Rect, Shape)> {
|
||||
let memory = self.memory();
|
||||
self.graphics().drain(memory.areas.order()).collect()
|
||||
}
|
||||
|
||||
/// Tessellate the given paint commands into triangle meshes.
|
||||
pub fn tessellate(&self, paint_commands: Vec<(Rect, PaintCmd)>) -> PaintJobs {
|
||||
/// Tessellate the given shapes into triangle meshes.
|
||||
pub fn tessellate(&self, shapes: Vec<(Rect, Shape)>) -> PaintJobs {
|
||||
let mut tessellation_options = self.memory().options.tessellation_options;
|
||||
tessellation_options.aa_size = 1.0 / self.pixels_per_point();
|
||||
let paint_stats = PaintStats::from_paint_commands(&paint_commands); // TODO: internal allocations
|
||||
let paint_jobs = tessellator::tessellate_paint_commands(
|
||||
paint_commands,
|
||||
tessellation_options,
|
||||
self.fonts(),
|
||||
);
|
||||
let paint_stats = PaintStats::from_shapes(&shapes); // TODO: internal allocations
|
||||
let paint_jobs = tessellator::tessellate_shapes(shapes, tessellation_options, self.fonts());
|
||||
*self.paint_stats.lock() = paint_stats.with_paint_jobs(&paint_jobs);
|
||||
paint_jobs
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! uis for egui types.
|
||||
use crate::{
|
||||
paint::{self, PaintCmd, Texture, Triangles},
|
||||
paint::{self, Shape, Texture, Triangles},
|
||||
*,
|
||||
};
|
||||
|
||||
|
@ -25,7 +25,7 @@ impl Texture {
|
|||
[pos2(0.0, 0.0), pos2(1.0, 1.0)].into(),
|
||||
Color32::WHITE,
|
||||
);
|
||||
ui.painter().add(PaintCmd::triangles(triangles));
|
||||
ui.painter().add(Shape::triangles(triangles));
|
||||
|
||||
let (tex_w, tex_h) = (self.width as f32, self.height as f32);
|
||||
|
||||
|
@ -49,7 +49,7 @@ impl Texture {
|
|||
);
|
||||
let mut triangles = Triangles::default();
|
||||
triangles.add_rect_with_uv(zoom_rect, uv_rect, Color32::WHITE);
|
||||
ui.painter().add(PaintCmd::triangles(triangles));
|
||||
ui.painter().add(Shape::triangles(triangles));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ahash::AHashMap;
|
||||
|
||||
use crate::{math::Rect, paint::PaintCmd, Id, *};
|
||||
use crate::{math::Rect, paint::Shape, Id, *};
|
||||
|
||||
/// Different layer categories
|
||||
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
|
||||
|
@ -70,47 +70,48 @@ impl LayerId {
|
|||
}
|
||||
}
|
||||
|
||||
/// A unique identifier of a specific [`PaintCmd`] in a [`PaintList`].
|
||||
/// A unique identifier of a specific [`Shape`] in a [`PaintList`].
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub struct PaintCmdIdx(usize);
|
||||
pub struct ShapeIdx(usize);
|
||||
|
||||
/// A list of [`PaintCmd`]s paired with a clip rectangle.
|
||||
/// A list of [`Shape`]s paired with a clip rectangle.
|
||||
#[derive(Clone, Default)]
|
||||
pub struct PaintList(Vec<(Rect, PaintCmd)>);
|
||||
pub struct PaintList(Vec<(Rect, Shape)>);
|
||||
|
||||
impl PaintList {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
|
||||
/// Returns the index of the new command that can be used with `PaintList::set`.
|
||||
pub fn add(&mut self, clip_rect: Rect, cmd: PaintCmd) -> PaintCmdIdx {
|
||||
let idx = PaintCmdIdx(self.0.len());
|
||||
self.0.push((clip_rect, cmd));
|
||||
/// Returns the index of the new [`Shape`] that can be used with `PaintList::set`.
|
||||
pub fn add(&mut self, clip_rect: Rect, shape: Shape) -> ShapeIdx {
|
||||
let idx = ShapeIdx(self.0.len());
|
||||
self.0.push((clip_rect, shape));
|
||||
idx
|
||||
}
|
||||
|
||||
pub fn extend(&mut self, clip_rect: Rect, mut cmds: Vec<PaintCmd>) {
|
||||
self.0.extend(cmds.drain(..).map(|cmd| (clip_rect, cmd)))
|
||||
pub fn extend(&mut self, clip_rect: Rect, mut shapes: Vec<Shape>) {
|
||||
self.0
|
||||
.extend(shapes.drain(..).map(|shape| (clip_rect, shape)))
|
||||
}
|
||||
|
||||
/// Modify an existing command.
|
||||
/// Modify an existing [`Shape`].
|
||||
///
|
||||
/// Sometimes you want to paint a frame behind some contents, but don't know how large the frame needs to be
|
||||
/// until the contents have been added, and therefor also painted to the `PaintList`.
|
||||
///
|
||||
/// The solution is to allocate a `PaintCmd` using `let idx = paint_list.add(cr, PaintCmd::Noop);`
|
||||
/// The solution is to allocate a `Shape` using `let idx = paint_list.add(cr, Shape::Noop);`
|
||||
/// and then later setting it using `paint_list.set(idx, cr, frame);`.
|
||||
pub fn set(&mut self, idx: PaintCmdIdx, clip_rect: Rect, cmd: PaintCmd) {
|
||||
pub fn set(&mut self, idx: ShapeIdx, clip_rect: Rect, shape: Shape) {
|
||||
assert!(idx.0 < self.0.len());
|
||||
self.0[idx.0] = (clip_rect, cmd);
|
||||
self.0[idx.0] = (clip_rect, shape);
|
||||
}
|
||||
|
||||
/// Translate each paint-command and clip rectangle by this much, in-place
|
||||
/// Translate each [`Shape`] and clip rectangle by this much, in-place
|
||||
pub fn translate(&mut self, delta: Vec2) {
|
||||
for (clip_rect, cmd) in &mut self.0 {
|
||||
for (clip_rect, shape) in &mut self.0 {
|
||||
*clip_rect = clip_rect.translate(delta);
|
||||
cmd.translate(delta);
|
||||
shape.translate(delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -128,8 +129,8 @@ impl GraphicLayers {
|
|||
pub fn drain(
|
||||
&mut self,
|
||||
area_order: &[LayerId],
|
||||
) -> impl ExactSizeIterator<Item = (Rect, PaintCmd)> {
|
||||
let mut all_commands: Vec<_> = Default::default();
|
||||
) -> impl ExactSizeIterator<Item = (Rect, Shape)> {
|
||||
let mut all_shapes: Vec<_> = Default::default();
|
||||
|
||||
for &order in &Order::ALL {
|
||||
let order_map = &mut self.0[order as usize];
|
||||
|
@ -142,18 +143,18 @@ impl GraphicLayers {
|
|||
// First do the layers part of area_order:
|
||||
for layer_id in area_order {
|
||||
if layer_id.order == order {
|
||||
if let Some(commands) = order_map.get_mut(&layer_id.id) {
|
||||
all_commands.extend(commands.0.drain(..));
|
||||
if let Some(shapes) = order_map.get_mut(&layer_id.id) {
|
||||
all_shapes.extend(shapes.0.drain(..));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Also draw areas that are missing in `area_order`:
|
||||
for commands in order_map.values_mut() {
|
||||
all_commands.extend(commands.0.drain(..));
|
||||
for shapes in order_map.values_mut() {
|
||||
all_shapes.extend(shapes.0.drain(..));
|
||||
}
|
||||
}
|
||||
|
||||
all_commands.into_iter()
|
||||
all_shapes.into_iter()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
//! let raw_input: egui::RawInput = my_integration.gather_input();
|
||||
//! egui_ctx.begin_frame(raw_input);
|
||||
//! my_app.ui(&egui_ctx); // add panels, windows and widgets to `egui_ctx` here
|
||||
//! let (output, paint_commands) = egui_ctx.end_frame();
|
||||
//! let paint_jobs = egui_ctx.tessellate(paint_commands); // create triangles to paint
|
||||
//! let (output, shapes) = egui_ctx.end_frame();
|
||||
//! let paint_jobs = egui_ctx.tessellate(shapes); // create triangles to paint
|
||||
//! my_integration.paint(paint_jobs);
|
||||
//! my_integration.set_cursor_icon(output.cursor_icon);
|
||||
//! // Also see `egui::Output` for more
|
||||
|
@ -108,7 +108,7 @@ pub use {
|
|||
math::{clamp, lerp, pos2, remap, remap_clamp, vec2, Align, Align2, NumExt, Pos2, Rect, Vec2},
|
||||
memory::Memory,
|
||||
paint::{
|
||||
color, Color32, FontDefinitions, FontFamily, PaintCmd, PaintJobs, Rgba, Stroke, TextStyle,
|
||||
color, Color32, FontDefinitions, FontFamily, PaintJobs, Rgba, Shape, Stroke, TextStyle,
|
||||
Texture, TextureId,
|
||||
},
|
||||
painter::Painter,
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
//! 2D graphics/rendering. Fonts, textures, color, geometry, tessellation etc.
|
||||
|
||||
pub mod color;
|
||||
pub mod command;
|
||||
pub mod font;
|
||||
pub mod fonts;
|
||||
mod galley;
|
||||
mod shadow;
|
||||
pub mod shape;
|
||||
pub mod stats;
|
||||
pub mod tessellator;
|
||||
mod texture_atlas;
|
||||
|
||||
pub use {
|
||||
color::{Color32, Rgba},
|
||||
command::{PaintCmd, Stroke},
|
||||
fonts::{FontDefinitions, FontFamily, Fonts, TextStyle},
|
||||
galley::*,
|
||||
shadow::Shadow,
|
||||
shape::{Shape, Stroke},
|
||||
stats::PaintStats,
|
||||
tessellator::{
|
||||
PaintJob, PaintJobs, TessellationOptions, TextureId, Triangles, Vertex, WHITE_UV,
|
||||
|
|
|
@ -6,12 +6,12 @@ use {
|
|||
/// A paint primitive such as a circle or a piece of text.
|
||||
/// Coordinates are all screen space points (not physical pixels).
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum PaintCmd {
|
||||
pub enum Shape {
|
||||
/// Paint nothing. This can be useful as a placeholder.
|
||||
Noop,
|
||||
/// Recursively nest more paint commands - sometimes a convenience to be able to do.
|
||||
/// Recursively nest more shapes - sometimes a convenience to be able to do.
|
||||
/// For performance reasons it is better to avoid it.
|
||||
Vec(Vec<PaintCmd>),
|
||||
Vec(Vec<Shape>),
|
||||
Circle {
|
||||
center: Pos2,
|
||||
radius: f32,
|
||||
|
@ -49,7 +49,7 @@ pub enum PaintCmd {
|
|||
}
|
||||
|
||||
/// ## Constructors
|
||||
impl PaintCmd {
|
||||
impl Shape {
|
||||
pub fn line_segment(points: [Pos2; 2], stroke: impl Into<Stroke>) -> Self {
|
||||
Self::LineSegment {
|
||||
points,
|
||||
|
@ -141,14 +141,14 @@ impl PaintCmd {
|
|||
}
|
||||
|
||||
/// ## Operations
|
||||
impl PaintCmd {
|
||||
impl Shape {
|
||||
pub fn triangles(triangles: Triangles) -> Self {
|
||||
debug_assert!(triangles.is_valid());
|
||||
Self::Triangles(triangles)
|
||||
}
|
||||
|
||||
pub fn texture_id(&self) -> super::TextureId {
|
||||
if let PaintCmd::Triangles(triangles) = self {
|
||||
if let Shape::Triangles(triangles) = self {
|
||||
triangles.texture_id
|
||||
} else {
|
||||
super::TextureId::Egui
|
||||
|
@ -158,32 +158,32 @@ impl PaintCmd {
|
|||
/// Translate location by this much, in-place
|
||||
pub fn translate(&mut self, delta: Vec2) {
|
||||
match self {
|
||||
PaintCmd::Noop => {}
|
||||
PaintCmd::Vec(commands) => {
|
||||
for command in commands {
|
||||
command.translate(delta);
|
||||
Shape::Noop => {}
|
||||
Shape::Vec(shapes) => {
|
||||
for shape in shapes {
|
||||
shape.translate(delta);
|
||||
}
|
||||
}
|
||||
PaintCmd::Circle { center, .. } => {
|
||||
Shape::Circle { center, .. } => {
|
||||
*center += delta;
|
||||
}
|
||||
PaintCmd::LineSegment { points, .. } => {
|
||||
Shape::LineSegment { points, .. } => {
|
||||
for p in points {
|
||||
*p += delta;
|
||||
}
|
||||
}
|
||||
PaintCmd::Path { points, .. } => {
|
||||
Shape::Path { points, .. } => {
|
||||
for p in points {
|
||||
*p += delta;
|
||||
}
|
||||
}
|
||||
PaintCmd::Rect { rect, .. } => {
|
||||
Shape::Rect { rect, .. } => {
|
||||
*rect = rect.translate(delta);
|
||||
}
|
||||
PaintCmd::Text { pos, .. } => {
|
||||
Shape::Text { pos, .. } => {
|
||||
*pos += delta;
|
||||
}
|
||||
PaintCmd::Triangles(triangles) => {
|
||||
Shape::Triangles(triangles) => {
|
||||
triangles.translate(delta);
|
||||
}
|
||||
}
|
|
@ -54,16 +54,16 @@ impl std::ops::AddAssign for AllocInfo {
|
|||
}
|
||||
|
||||
impl AllocInfo {
|
||||
// pub fn from_paint_cmd(cmd: &PaintCmd) -> Self {
|
||||
// match cmd {
|
||||
// PaintCmd::Noop
|
||||
// PaintCmd::Vec(commands) => Self::from_paint_commands(commands)
|
||||
// | PaintCmd::Circle { .. }
|
||||
// | PaintCmd::LineSegment { .. }
|
||||
// | PaintCmd::Rect { .. } => Self::default(),
|
||||
// PaintCmd::Path { points, .. } => Self::from_slice(points),
|
||||
// PaintCmd::Text { galley, .. } => Self::from_galley(galley),
|
||||
// PaintCmd::Triangles(triangles) => Self::from_triangles(triangles),
|
||||
// pub fn from_shape(shape: &Shape) -> Self {
|
||||
// match shape {
|
||||
// Shape::Noop
|
||||
// Shape::Vec(shapes) => Self::from_shapes(shapes)
|
||||
// | Shape::Circle { .. }
|
||||
// | Shape::LineSegment { .. }
|
||||
// | Shape::Rect { .. } => Self::default(),
|
||||
// Shape::Path { points, .. } => Self::from_slice(points),
|
||||
// Shape::Text { galley, .. } => Self::from_galley(galley),
|
||||
// Shape::Triangles(triangles) => Self::from_triangles(triangles),
|
||||
// }
|
||||
// }
|
||||
|
||||
|
@ -137,11 +137,11 @@ impl AllocInfo {
|
|||
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct PaintStats {
|
||||
primitives: AllocInfo,
|
||||
cmd_text: AllocInfo,
|
||||
cmd_path: AllocInfo,
|
||||
cmd_mesh: AllocInfo,
|
||||
cmd_vec: AllocInfo,
|
||||
shapes: AllocInfo,
|
||||
shape_text: AllocInfo,
|
||||
shape_path: AllocInfo,
|
||||
shape_mesh: AllocInfo,
|
||||
shape_vec: AllocInfo,
|
||||
|
||||
/// Number of separate clip rectangles
|
||||
jobs: AllocInfo,
|
||||
|
@ -150,40 +150,39 @@ pub struct PaintStats {
|
|||
}
|
||||
|
||||
impl PaintStats {
|
||||
pub fn from_paint_commands(paint_commands: &[(Rect, PaintCmd)]) -> Self {
|
||||
pub fn from_shapes(shapes: &[(Rect, Shape)]) -> Self {
|
||||
let mut stats = Self::default();
|
||||
stats.cmd_path.element_size = ElementSize::Heterogenous; // nicer display later
|
||||
stats.cmd_vec.element_size = ElementSize::Heterogenous; // nicer display later
|
||||
stats.shape_path.element_size = ElementSize::Heterogenous; // nicer display later
|
||||
stats.shape_vec.element_size = ElementSize::Heterogenous; // nicer display later
|
||||
|
||||
stats.primitives = AllocInfo::from_slice(paint_commands);
|
||||
for (_, cmd) in paint_commands {
|
||||
stats.add(cmd);
|
||||
stats.shapes = AllocInfo::from_slice(shapes);
|
||||
for (_, shape) in shapes {
|
||||
stats.add(shape);
|
||||
}
|
||||
stats
|
||||
}
|
||||
|
||||
fn add(&mut self, cmd: &PaintCmd) {
|
||||
match cmd {
|
||||
PaintCmd::Vec(paint_commands) => {
|
||||
// self += PaintStats::from_paint_commands(&paint_commands); // TODO
|
||||
self.primitives += AllocInfo::from_slice(paint_commands);
|
||||
self.cmd_vec += AllocInfo::from_slice(paint_commands);
|
||||
for cmd in paint_commands {
|
||||
self.add(cmd);
|
||||
fn add(&mut self, shape: &Shape) {
|
||||
match shape {
|
||||
Shape::Vec(shapes) => {
|
||||
// self += PaintStats::from_shapes(&shapes); // TODO
|
||||
self.shapes += AllocInfo::from_slice(shapes);
|
||||
self.shape_vec += AllocInfo::from_slice(shapes);
|
||||
for shape in shapes {
|
||||
self.add(shape);
|
||||
}
|
||||
}
|
||||
PaintCmd::Noop
|
||||
| PaintCmd::Circle { .. }
|
||||
| PaintCmd::LineSegment { .. }
|
||||
| PaintCmd::Rect { .. } => Default::default(),
|
||||
PaintCmd::Path { points, .. } => {
|
||||
self.cmd_path += AllocInfo::from_slice(points);
|
||||
Shape::Noop | Shape::Circle { .. } | Shape::LineSegment { .. } | Shape::Rect { .. } => {
|
||||
Default::default()
|
||||
}
|
||||
PaintCmd::Text { galley, .. } => {
|
||||
self.cmd_text += AllocInfo::from_galley(galley);
|
||||
Shape::Path { points, .. } => {
|
||||
self.shape_path += AllocInfo::from_slice(points);
|
||||
}
|
||||
PaintCmd::Triangles(triangles) => {
|
||||
self.cmd_mesh += AllocInfo::from_triangles(triangles);
|
||||
Shape::Text { galley, .. } => {
|
||||
self.shape_text += AllocInfo::from_galley(galley);
|
||||
}
|
||||
Shape::Triangles(triangles) => {
|
||||
self.shape_mesh += AllocInfo::from_triangles(triangles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -198,10 +197,10 @@ impl PaintStats {
|
|||
}
|
||||
|
||||
// pub fn total(&self) -> AllocInfo {
|
||||
// self.primitives
|
||||
// + self.cmd_text
|
||||
// + self.cmd_path
|
||||
// + self.cmd_mesh
|
||||
// self.shapes
|
||||
// + self.shape_text
|
||||
// + self.shape_path
|
||||
// + self.shape_mesh
|
||||
// + self.jobs
|
||||
// + self.vertices
|
||||
// + self.indices
|
||||
|
@ -211,7 +210,7 @@ impl PaintStats {
|
|||
impl PaintStats {
|
||||
pub fn ui(&self, ui: &mut crate::Ui) {
|
||||
ui.label(
|
||||
"Egui generates intermediate level primitives like circles and text. \
|
||||
"Egui generates intermediate level shapes like circles and text. \
|
||||
These are later tessellated into triangles.",
|
||||
);
|
||||
ui.advance_cursor(10.0);
|
||||
|
@ -219,24 +218,24 @@ impl PaintStats {
|
|||
ui.style_mut().body_text_style = TextStyle::Monospace;
|
||||
|
||||
let Self {
|
||||
primitives,
|
||||
cmd_text,
|
||||
cmd_path,
|
||||
cmd_mesh,
|
||||
cmd_vec,
|
||||
shapes,
|
||||
shape_text,
|
||||
shape_path,
|
||||
shape_mesh,
|
||||
shape_vec,
|
||||
jobs,
|
||||
vertices,
|
||||
indices,
|
||||
} = self;
|
||||
|
||||
ui.label("Intermediate:");
|
||||
primitives
|
||||
.label(ui, "primitives")
|
||||
shapes
|
||||
.label(ui, "shapes")
|
||||
.on_hover_text("Boxes, circles, etc");
|
||||
cmd_text.label(ui, "text");
|
||||
cmd_path.label(ui, "paths");
|
||||
cmd_mesh.label(ui, "meshes");
|
||||
cmd_vec.label(ui, "nested");
|
||||
shape_text.label(ui, "text");
|
||||
shape_path.label(ui, "paths");
|
||||
shape_mesh.label(ui, "meshes");
|
||||
shape_vec.label(ui, "nested");
|
||||
ui.advance_cursor(10.0);
|
||||
|
||||
ui.label("Tessellated:");
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Converts graphics primitives into textured triangles.
|
||||
//!
|
||||
//! This module converts lines, circles, text and more represented by [`PaintCmd`]
|
||||
//! This module converts lines, circles, text and more represented by [`Shape`]
|
||||
//! into textured triangles represented by [`Triangles`].
|
||||
|
||||
#![allow(clippy::identity_op)]
|
||||
|
@ -687,31 +687,26 @@ impl Tessellator {
|
|||
}
|
||||
}
|
||||
|
||||
/// Tessellate a single [`PaintCmd`] into a [`Triangles`].
|
||||
/// Tessellate a single [`Shape`] into a [`Triangles`].
|
||||
///
|
||||
/// * `command`: the command to tessellate
|
||||
/// * `shape`: the shape to tessellate
|
||||
/// * `options`: tessellation quality
|
||||
/// * `fonts`: font source when tessellating text
|
||||
/// * `out`: where the triangles are put
|
||||
/// * `scratchpad_path`: if you plan to run `tessellate_paint_command`
|
||||
/// * `scratchpad_path`: if you plan to run `tessellate_shape`
|
||||
/// many times, pass it a reference to the same `Path` to avoid excessive allocations.
|
||||
pub fn tessellate_paint_command(
|
||||
&mut self,
|
||||
fonts: &Fonts,
|
||||
command: PaintCmd,
|
||||
out: &mut Triangles,
|
||||
) {
|
||||
pub fn tessellate_shape(&mut self, fonts: &Fonts, shape: Shape, out: &mut Triangles) {
|
||||
let clip_rect = self.clip_rect;
|
||||
let options = self.options;
|
||||
|
||||
match command {
|
||||
PaintCmd::Noop => {}
|
||||
PaintCmd::Vec(vec) => {
|
||||
for command in vec {
|
||||
self.tessellate_paint_command(fonts, command, out)
|
||||
match shape {
|
||||
Shape::Noop => {}
|
||||
Shape::Vec(vec) => {
|
||||
for shape in vec {
|
||||
self.tessellate_shape(fonts, shape, out)
|
||||
}
|
||||
}
|
||||
PaintCmd::Circle {
|
||||
Shape::Circle {
|
||||
center,
|
||||
radius,
|
||||
fill,
|
||||
|
@ -733,20 +728,20 @@ impl Tessellator {
|
|||
fill_closed_path(&path.0, fill, options, out);
|
||||
stroke_path(&path.0, Closed, stroke, options, out);
|
||||
}
|
||||
PaintCmd::Triangles(triangles) => {
|
||||
Shape::Triangles(triangles) => {
|
||||
if triangles.is_valid() {
|
||||
out.append(triangles);
|
||||
} else {
|
||||
debug_assert!(false, "Invalid Triangles in PaintCmd::Triangles");
|
||||
debug_assert!(false, "Invalid Triangles in Shape::Triangles");
|
||||
}
|
||||
}
|
||||
PaintCmd::LineSegment { points, stroke } => {
|
||||
Shape::LineSegment { points, stroke } => {
|
||||
let path = &mut self.scratchpad_path;
|
||||
path.clear();
|
||||
path.add_line_segment(points);
|
||||
stroke_path(&path.0, Open, stroke, options, out);
|
||||
}
|
||||
PaintCmd::Path {
|
||||
Shape::Path {
|
||||
points,
|
||||
closed,
|
||||
fill,
|
||||
|
@ -772,7 +767,7 @@ impl Tessellator {
|
|||
stroke_path(&path.0, typ, stroke, options, out);
|
||||
}
|
||||
}
|
||||
PaintCmd::Rect {
|
||||
Shape::Rect {
|
||||
rect,
|
||||
corner_radius,
|
||||
fill,
|
||||
|
@ -786,7 +781,7 @@ impl Tessellator {
|
|||
};
|
||||
self.tessellate_rect(&rect, out);
|
||||
}
|
||||
PaintCmd::Text {
|
||||
Shape::Text {
|
||||
pos,
|
||||
galley,
|
||||
text_style,
|
||||
|
@ -872,7 +867,7 @@ impl Tessellator {
|
|||
let c = chars.next().unwrap();
|
||||
|
||||
if self.options.coarse_tessellation_culling && !is_line_visible {
|
||||
// culling individual lines of text is important, since a single `PaintCmd::Text`
|
||||
// culling individual lines of text is important, since a single `Shape::Text`
|
||||
// can span hundreds of lines.
|
||||
continue;
|
||||
}
|
||||
|
@ -899,29 +894,29 @@ impl Tessellator {
|
|||
}
|
||||
}
|
||||
|
||||
/// Turns [`PaintCmd`]:s into sets of triangles.
|
||||
/// Turns [`Shape`]:s into sets of triangles.
|
||||
///
|
||||
/// The given commands will be painted back-to-front (painters algorithm).
|
||||
/// The given shapes will be painted back-to-front (painters algorithm).
|
||||
/// They will be batched together by clip rectangle.
|
||||
///
|
||||
/// * `commands`: the command to tessellate
|
||||
/// * `shapes`: the shape to tessellate
|
||||
/// * `options`: tessellation quality
|
||||
/// * `fonts`: font source when tessellating text
|
||||
///
|
||||
/// ## Returns
|
||||
/// A list of clip rectangles with matching [`Triangles`].
|
||||
pub fn tessellate_paint_commands(
|
||||
commands: Vec<(Rect, PaintCmd)>,
|
||||
pub fn tessellate_shapes(
|
||||
shapes: Vec<(Rect, Shape)>,
|
||||
options: TessellationOptions,
|
||||
fonts: &Fonts,
|
||||
) -> Vec<(Rect, Triangles)> {
|
||||
let mut tessellator = Tessellator::from_options(options);
|
||||
|
||||
let mut jobs = PaintJobs::default();
|
||||
for (clip_rect, cmd) in commands {
|
||||
for (clip_rect, shape) in shapes {
|
||||
let start_new_job = match jobs.last() {
|
||||
None => true,
|
||||
Some(job) => job.0 != clip_rect || job.1.texture_id != cmd.texture_id(),
|
||||
Some(job) => job.0 != clip_rect || job.1.texture_id != shape.texture_id(),
|
||||
};
|
||||
|
||||
if start_new_job {
|
||||
|
@ -930,15 +925,15 @@ pub fn tessellate_paint_commands(
|
|||
|
||||
let out = &mut jobs.last_mut().unwrap().1;
|
||||
tessellator.clip_rect = clip_rect;
|
||||
tessellator.tessellate_paint_command(fonts, cmd, out);
|
||||
tessellator.tessellate_shape(fonts, shape, out);
|
||||
}
|
||||
|
||||
if options.debug_paint_clip_rects {
|
||||
for (clip_rect, triangles) in &mut jobs {
|
||||
tessellator.clip_rect = Rect::everything();
|
||||
tessellator.tessellate_paint_command(
|
||||
tessellator.tessellate_shape(
|
||||
fonts,
|
||||
PaintCmd::Rect {
|
||||
Shape::Rect {
|
||||
rect: *clip_rect,
|
||||
corner_radius: 0.0,
|
||||
fill: Default::default(),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::{
|
||||
layers::PaintCmdIdx,
|
||||
layers::ShapeIdx,
|
||||
math::{Align2, Pos2, Rect, Vec2},
|
||||
paint::{Fonts, Galley, PaintCmd, Stroke, TextStyle},
|
||||
paint::{Fonts, Galley, Shape, Stroke, TextStyle},
|
||||
Color32, CtxRef, LayerId,
|
||||
};
|
||||
|
||||
|
@ -10,7 +10,7 @@ use crate::{
|
|||
/// All coordinates are screen coordinates in the unit points (one point can consist of many physical pixels).
|
||||
#[derive(Clone)]
|
||||
pub struct Painter {
|
||||
/// Source of fonts and destination of paint commands
|
||||
/// Source of fonts and destination of shapes
|
||||
ctx: CtxRef,
|
||||
|
||||
/// Where we paint
|
||||
|
@ -106,26 +106,26 @@ impl Painter {
|
|||
/// It is up to the caller to make sure there is room for this.
|
||||
/// Can be used for free painting.
|
||||
/// NOTE: all coordinates are screen coordinates!
|
||||
pub fn add(&self, paint_cmd: PaintCmd) -> PaintCmdIdx {
|
||||
pub fn add(&self, shape: Shape) -> ShapeIdx {
|
||||
self.ctx
|
||||
.graphics()
|
||||
.list(self.layer_id)
|
||||
.add(self.clip_rect, paint_cmd)
|
||||
.add(self.clip_rect, shape)
|
||||
}
|
||||
|
||||
pub fn extend(&self, cmds: Vec<PaintCmd>) {
|
||||
pub fn extend(&self, shapes: Vec<Shape>) {
|
||||
self.ctx
|
||||
.graphics()
|
||||
.list(self.layer_id)
|
||||
.extend(self.clip_rect, cmds);
|
||||
.extend(self.clip_rect, shapes);
|
||||
}
|
||||
|
||||
/// Modify an existing command.
|
||||
pub fn set(&self, idx: PaintCmdIdx, cmd: PaintCmd) {
|
||||
/// Modify an existing [`Shape`].
|
||||
pub fn set(&self, idx: ShapeIdx, shape: Shape) {
|
||||
self.ctx
|
||||
.graphics()
|
||||
.list(self.layer_id)
|
||||
.set(idx, self.clip_rect, cmd)
|
||||
.set(idx, self.clip_rect, shape)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,7 @@ impl Painter {
|
|||
let galley = font.layout_multiline(format!("🔥 {}", text), f32::INFINITY);
|
||||
let rect = Align2::LEFT_TOP.anchor_rect(Rect::from_min_size(pos, galley.size));
|
||||
let frame_rect = rect.expand(2.0);
|
||||
self.add(PaintCmd::Rect {
|
||||
self.add(Shape::Rect {
|
||||
rect: frame_rect,
|
||||
corner_radius: 0.0,
|
||||
fill: Color32::from_black_alpha(240),
|
||||
|
@ -157,7 +157,7 @@ impl Painter {
|
|||
/// # Paint different primitives
|
||||
impl Painter {
|
||||
pub fn line_segment(&self, points: [Pos2; 2], stroke: impl Into<Stroke>) {
|
||||
self.add(PaintCmd::LineSegment {
|
||||
self.add(Shape::LineSegment {
|
||||
points,
|
||||
stroke: stroke.into(),
|
||||
});
|
||||
|
@ -170,7 +170,7 @@ impl Painter {
|
|||
fill_color: impl Into<Color32>,
|
||||
stroke: impl Into<Stroke>,
|
||||
) {
|
||||
self.add(PaintCmd::Circle {
|
||||
self.add(Shape::Circle {
|
||||
center,
|
||||
radius,
|
||||
fill: fill_color.into(),
|
||||
|
@ -179,7 +179,7 @@ impl Painter {
|
|||
}
|
||||
|
||||
pub fn circle_filled(&self, center: Pos2, radius: f32, fill_color: impl Into<Color32>) {
|
||||
self.add(PaintCmd::Circle {
|
||||
self.add(Shape::Circle {
|
||||
center,
|
||||
radius,
|
||||
fill: fill_color.into(),
|
||||
|
@ -188,7 +188,7 @@ impl Painter {
|
|||
}
|
||||
|
||||
pub fn circle_stroke(&self, center: Pos2, radius: f32, stroke: impl Into<Stroke>) {
|
||||
self.add(PaintCmd::Circle {
|
||||
self.add(Shape::Circle {
|
||||
center,
|
||||
radius,
|
||||
fill: Default::default(),
|
||||
|
@ -203,7 +203,7 @@ impl Painter {
|
|||
fill_color: impl Into<Color32>,
|
||||
stroke: impl Into<Stroke>,
|
||||
) {
|
||||
self.add(PaintCmd::Rect {
|
||||
self.add(Shape::Rect {
|
||||
rect,
|
||||
corner_radius,
|
||||
fill: fill_color.into(),
|
||||
|
@ -212,7 +212,7 @@ impl Painter {
|
|||
}
|
||||
|
||||
pub fn rect_filled(&self, rect: Rect, corner_radius: f32, fill_color: impl Into<Color32>) {
|
||||
self.add(PaintCmd::Rect {
|
||||
self.add(Shape::Rect {
|
||||
rect,
|
||||
corner_radius,
|
||||
fill: fill_color.into(),
|
||||
|
@ -221,7 +221,7 @@ impl Painter {
|
|||
}
|
||||
|
||||
pub fn rect_stroke(&self, rect: Rect, corner_radius: f32, stroke: impl Into<Stroke>) {
|
||||
self.add(PaintCmd::Rect {
|
||||
self.add(Shape::Rect {
|
||||
rect,
|
||||
corner_radius,
|
||||
fill: Default::default(),
|
||||
|
@ -266,7 +266,7 @@ impl Painter {
|
|||
|
||||
/// Paint text that has already been layed out in a `Galley`.
|
||||
pub fn galley(&self, pos: Pos2, galley: Galley, text_style: TextStyle, color: Color32) {
|
||||
self.add(PaintCmd::Text {
|
||||
self.add(Shape::Text {
|
||||
pos,
|
||||
galley,
|
||||
text_style,
|
||||
|
|
|
@ -923,7 +923,7 @@ impl Ui {
|
|||
(ret, response)
|
||||
}
|
||||
|
||||
/// Redirect paint commands to another paint layer.
|
||||
/// Redirect shapes to another paint layer.
|
||||
pub fn with_layer_id<R>(
|
||||
&mut self,
|
||||
layer_id: LayerId,
|
||||
|
|
|
@ -196,7 +196,7 @@ impl<'a> Widget for Checkbox<'a> {
|
|||
rect.center().y - 0.5 * galley.size.y,
|
||||
);
|
||||
let (small_icon_rect, big_icon_rect) = ui.style().spacing.icon_rectangles(rect);
|
||||
ui.painter().add(PaintCmd::Rect {
|
||||
ui.painter().add(Shape::Rect {
|
||||
rect: big_icon_rect,
|
||||
corner_radius: visuals.corner_radius,
|
||||
fill: visuals.bg_fill,
|
||||
|
@ -205,7 +205,7 @@ impl<'a> Widget for Checkbox<'a> {
|
|||
|
||||
if *checked {
|
||||
// Check mark:
|
||||
ui.painter().add(PaintCmd::line(
|
||||
ui.painter().add(Shape::line(
|
||||
vec![
|
||||
pos2(small_icon_rect.left(), small_icon_rect.center().y),
|
||||
pos2(small_icon_rect.center().x, small_icon_rect.bottom()),
|
||||
|
@ -289,7 +289,7 @@ impl Widget for RadioButton {
|
|||
|
||||
let painter = ui.painter();
|
||||
|
||||
painter.add(PaintCmd::Circle {
|
||||
painter.add(Shape::Circle {
|
||||
center: big_icon_rect.center(),
|
||||
radius: big_icon_rect.width() / 2.0,
|
||||
fill: visuals.bg_fill,
|
||||
|
@ -297,7 +297,7 @@ impl Widget for RadioButton {
|
|||
});
|
||||
|
||||
if checked {
|
||||
painter.add(PaintCmd::Circle {
|
||||
painter.add(Shape::Circle {
|
||||
center: small_icon_rect.center(),
|
||||
radius: small_icon_rect.width() / 3.0,
|
||||
fill: visuals.fg_stroke.color, // Intentional to use stroke and not fill
|
||||
|
|
|
@ -37,7 +37,7 @@ fn background_checkers(painter: &Painter, rect: Rect) {
|
|||
);
|
||||
std::mem::swap(&mut top_color, &mut bottom_color);
|
||||
}
|
||||
painter.add(PaintCmd::triangles(triangles));
|
||||
painter.add(Shape::triangles(triangles));
|
||||
}
|
||||
|
||||
pub fn show_color(ui: &mut Ui, color: impl Into<Color32>, desired_size: Vec2) -> Response {
|
||||
|
@ -47,7 +47,7 @@ pub fn show_color(ui: &mut Ui, color: impl Into<Color32>, desired_size: Vec2) ->
|
|||
fn show_srgba(ui: &mut Ui, srgba: Color32, desired_size: Vec2) -> Response {
|
||||
let (rect, response) = ui.allocate_at_least(desired_size, Sense::hover());
|
||||
background_checkers(ui.painter(), rect);
|
||||
ui.painter().add(PaintCmd::Rect {
|
||||
ui.painter().add(Shape::Rect {
|
||||
rect,
|
||||
corner_radius: 2.0,
|
||||
fill: srgba,
|
||||
|
@ -61,7 +61,7 @@ fn color_button(ui: &mut Ui, color: Color32) -> Response {
|
|||
let (rect, response) = ui.allocate_at_least(desired_size, Sense::click());
|
||||
let visuals = ui.style().interact(&response);
|
||||
background_checkers(ui.painter(), rect);
|
||||
ui.painter().add(PaintCmd::Rect {
|
||||
ui.painter().add(Shape::Rect {
|
||||
rect,
|
||||
corner_radius: visuals.corner_radius.at_most(2.0),
|
||||
fill: color,
|
||||
|
@ -103,7 +103,7 @@ fn color_slider_1d(ui: &mut Ui, value: &mut f32, color_at: impl Fn(f32) -> Color
|
|||
triangles.add_triangle(2 * i + 1, 2 * i + 2, 2 * i + 3);
|
||||
}
|
||||
}
|
||||
ui.painter().add(PaintCmd::triangles(triangles));
|
||||
ui.painter().add(Shape::triangles(triangles));
|
||||
}
|
||||
|
||||
ui.painter().rect_stroke(rect, 0.0, visuals.bg_stroke); // outline
|
||||
|
@ -113,7 +113,7 @@ fn color_slider_1d(ui: &mut Ui, value: &mut f32, color_at: impl Fn(f32) -> Color
|
|||
let x = lerp(rect.left()..=rect.right(), *value);
|
||||
let r = rect.height() / 4.0;
|
||||
let picked_color = color_at(*value);
|
||||
ui.painter().add(PaintCmd::polygon(
|
||||
ui.painter().add(Shape::polygon(
|
||||
vec![
|
||||
pos2(x - r, rect.bottom()),
|
||||
pos2(x + r, rect.bottom()),
|
||||
|
@ -164,7 +164,7 @@ fn color_slider_2d(
|
|||
}
|
||||
}
|
||||
}
|
||||
ui.painter().add(PaintCmd::triangles(triangles)); // fill
|
||||
ui.painter().add(Shape::triangles(triangles)); // fill
|
||||
|
||||
ui.painter().rect_stroke(rect, 0.0, visuals.bg_stroke); // outline
|
||||
|
||||
|
@ -172,7 +172,7 @@ fn color_slider_2d(
|
|||
let x = lerp(rect.left()..=rect.right(), *x_value);
|
||||
let y = lerp(rect.bottom()..=rect.top(), *y_value);
|
||||
let picked_color = color_at(*x_value, *y_value);
|
||||
ui.painter().add(PaintCmd::Circle {
|
||||
ui.painter().add(Shape::Circle {
|
||||
center: pos2(x, y),
|
||||
radius: rect.width() / 12.0,
|
||||
fill: picked_color,
|
||||
|
|
|
@ -59,14 +59,14 @@ impl Image {
|
|||
if *bg_fill != Default::default() {
|
||||
let mut triangles = Triangles::default();
|
||||
triangles.add_colored_rect(rect, *bg_fill);
|
||||
ui.painter().add(PaintCmd::triangles(triangles));
|
||||
ui.painter().add(Shape::triangles(triangles));
|
||||
}
|
||||
|
||||
{
|
||||
// TODO: builder pattern for Triangles
|
||||
let mut triangles = Triangles::with_texture(*texture_id);
|
||||
triangles.add_rect_with_uv(rect, *uv, *tint);
|
||||
ui.painter().add(PaintCmd::triangles(triangles));
|
||||
ui.painter().add(Shape::triangles(triangles));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -277,14 +277,14 @@ impl<'a> Slider<'a> {
|
|||
);
|
||||
let marker_center_x = self.x_from_value(value, x_range);
|
||||
|
||||
ui.painter().add(PaintCmd::Rect {
|
||||
ui.painter().add(Shape::Rect {
|
||||
rect: rail_rect,
|
||||
corner_radius: rail_radius,
|
||||
fill: ui.style().visuals.widgets.inactive.bg_fill,
|
||||
stroke: ui.style().visuals.widgets.inactive.bg_stroke,
|
||||
});
|
||||
|
||||
ui.painter().add(PaintCmd::Circle {
|
||||
ui.painter().add(Shape::Circle {
|
||||
center: pos2(marker_center_x, rail_rect.center().y),
|
||||
radius: handle_radius(rect),
|
||||
fill: ui.style().interact(response).fg_fill,
|
||||
|
|
|
@ -216,7 +216,7 @@ impl<'t> Widget for TextEdit<'t> {
|
|||
let margin = Vec2::splat(2.0);
|
||||
let frame_rect = ui.available_rect_before_wrap();
|
||||
let content_rect = frame_rect.shrink2(margin);
|
||||
let where_to_put_background = ui.painter().add(PaintCmd::Noop);
|
||||
let where_to_put_background = ui.painter().add(Shape::Noop);
|
||||
let mut content_ui = ui.child_ui(content_rect, *ui.layout());
|
||||
let response = self.content_ui(&mut content_ui);
|
||||
let frame_rect = Rect::from_min_max(frame_rect.min, content_ui.min_rect().max + margin);
|
||||
|
@ -226,7 +226,7 @@ impl<'t> Widget for TextEdit<'t> {
|
|||
let frame_rect = response.rect;
|
||||
ui.painter().set(
|
||||
where_to_put_background,
|
||||
PaintCmd::Rect {
|
||||
Shape::Rect {
|
||||
rect: frame_rect,
|
||||
corner_radius: visuals.corner_radius,
|
||||
fill: ui.style().visuals.dark_bg_color,
|
||||
|
|
|
@ -36,11 +36,9 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
|||
let mut demo_windows = egui_demo_lib::DemoWindows::default();
|
||||
ctx.begin_frame(raw_input.clone());
|
||||
demo_windows.ui(&ctx);
|
||||
let (_, paint_commands) = ctx.end_frame();
|
||||
let (_, shapes) = ctx.end_frame();
|
||||
|
||||
c.bench_function("tessellate", |b| {
|
||||
b.iter(|| ctx.tessellate(paint_commands.clone()))
|
||||
});
|
||||
c.bench_function("tessellate", |b| b.iter(|| ctx.tessellate(shapes.clone())));
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -300,7 +300,7 @@ fn vertex_gradient(ui: &mut Ui, bg_fill: Color32, gradient: &Gradient) -> Respon
|
|||
if bg_fill != Default::default() {
|
||||
let mut triangles = Triangles::default();
|
||||
triangles.add_colored_rect(rect, bg_fill);
|
||||
ui.painter().add(PaintCmd::triangles(triangles));
|
||||
ui.painter().add(Shape::triangles(triangles));
|
||||
}
|
||||
{
|
||||
let n = gradient.0.len();
|
||||
|
@ -317,7 +317,7 @@ fn vertex_gradient(ui: &mut Ui, bg_fill: Color32, gradient: &Gradient) -> Respon
|
|||
triangles.add_triangle(2 * i + 1, 2 * i + 2, 2 * i + 3);
|
||||
}
|
||||
}
|
||||
ui.painter().add(PaintCmd::triangles(triangles));
|
||||
ui.painter().add(Shape::triangles(triangles));
|
||||
}
|
||||
response
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ impl super::View for DancingStrings {
|
|||
let desired_size = ui.available_width() * vec2(1.0, 0.35);
|
||||
let (_id, rect) = ui.allocate_space(desired_size);
|
||||
|
||||
let mut cmds = vec![];
|
||||
let mut shapes = vec![];
|
||||
|
||||
for &mode in &[2, 3, 5] {
|
||||
let mode = mode as f32;
|
||||
|
@ -55,13 +55,13 @@ impl super::View for DancingStrings {
|
|||
.collect();
|
||||
|
||||
let thickness = 10.0 / mode;
|
||||
cmds.push(paint::PaintCmd::line(
|
||||
shapes.push(paint::Shape::line(
|
||||
points,
|
||||
Stroke::new(thickness, Color32::from_additive_luminance(196)),
|
||||
));
|
||||
}
|
||||
|
||||
ui.painter().extend(cmds);
|
||||
ui.painter().extend(shapes);
|
||||
});
|
||||
ui.add(crate::__egui_github_link_file!());
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ pub fn drop_target<R>(
|
|||
|
||||
let outer_rect_bounds = ui.available_rect_before_wrap();
|
||||
let inner_rect = outer_rect_bounds.shrink2(margin);
|
||||
let where_to_put_background = ui.painter().add(PaintCmd::Noop);
|
||||
let where_to_put_background = ui.painter().add(Shape::Noop);
|
||||
let mut content_ui = ui.child_ui(inner_rect, *ui.layout());
|
||||
let ret = body(&mut content_ui);
|
||||
let outer_rect = Rect::from_min_max(outer_rect_bounds.min, content_ui.min_rect().max + margin);
|
||||
|
@ -61,7 +61,7 @@ pub fn drop_target<R>(
|
|||
|
||||
ui.painter().set(
|
||||
where_to_put_background,
|
||||
PaintCmd::Rect {
|
||||
Shape::Rect {
|
||||
corner_radius: style.corner_radius,
|
||||
fill: style.bg_fill,
|
||||
stroke: style.bg_stroke,
|
||||
|
|
|
@ -52,7 +52,7 @@ impl Painting {
|
|||
for line in &self.lines {
|
||||
if line.len() >= 2 {
|
||||
let points: Vec<Pos2> = line.iter().map(|p| rect.min + *p).collect();
|
||||
painter.add(PaintCmd::line(points, self.stroke));
|
||||
painter.add(Shape::line(points, self.stroke));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ impl FrameHistory {
|
|||
let (rect, response) = ui.allocate_at_least(size, Sense::hover());
|
||||
let style = ui.style().noninteractive();
|
||||
|
||||
let mut cmds = vec![PaintCmd::Rect {
|
||||
let mut shapes = vec![Shape::Rect {
|
||||
rect,
|
||||
corner_radius: style.corner_radius,
|
||||
fill: ui.style().visuals.dark_bg_color,
|
||||
|
@ -82,13 +82,13 @@ impl FrameHistory {
|
|||
if let Some(mouse_pos) = ui.input().mouse.pos {
|
||||
if rect.contains(mouse_pos) {
|
||||
let y = mouse_pos.y;
|
||||
cmds.push(PaintCmd::line_segment(
|
||||
shapes.push(Shape::line_segment(
|
||||
[pos2(rect.left(), y), pos2(rect.right(), y)],
|
||||
line_stroke,
|
||||
));
|
||||
let cpu_usage = remap(y, rect.bottom_up_range(), 0.0..=graph_top_cpu_usage);
|
||||
let text = format!("{:.1} ms", 1e3 * cpu_usage);
|
||||
cmds.push(PaintCmd::text(
|
||||
shapes.push(Shape::text(
|
||||
ui.fonts(),
|
||||
pos2(rect.left(), y),
|
||||
egui::Align2::LEFT_BOTTOM,
|
||||
|
@ -108,17 +108,17 @@ impl FrameHistory {
|
|||
let x = remap(age, history.max_age()..=0.0, rect.x_range());
|
||||
let y = remap_clamp(cpu_usage, 0.0..=graph_top_cpu_usage, rect.bottom_up_range());
|
||||
|
||||
cmds.push(PaintCmd::line_segment(
|
||||
shapes.push(Shape::line_segment(
|
||||
[pos2(x, rect.bottom()), pos2(x, y)],
|
||||
line_stroke,
|
||||
));
|
||||
|
||||
if cpu_usage < graph_top_cpu_usage {
|
||||
cmds.push(PaintCmd::circle_filled(pos2(x, y), radius, circle_color));
|
||||
shapes.push(Shape::circle_filled(pos2(x, y), radius, circle_color));
|
||||
}
|
||||
}
|
||||
|
||||
ui.painter().extend(cmds);
|
||||
ui.painter().extend(shapes);
|
||||
|
||||
response
|
||||
}
|
||||
|
|
|
@ -98,8 +98,8 @@ fn test_egui_e2e() {
|
|||
for _ in 0..NUM_FRAMES {
|
||||
ctx.begin_frame(raw_input.clone());
|
||||
demo_windows.ui(&ctx);
|
||||
let (_output, paint_commands) = ctx.end_frame();
|
||||
let paint_jobs = ctx.tessellate(paint_commands);
|
||||
let (_output, shapes) = ctx.end_frame();
|
||||
let paint_jobs = ctx.tessellate(shapes);
|
||||
assert!(!paint_jobs.is_empty());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -184,7 +184,7 @@ pub fn run(mut app: Box<dyn epi::App>) -> ! {
|
|||
*ctx.memory() = saved_memory; // We don't want to remember that windows were huge.
|
||||
ctx.clear_animations();
|
||||
|
||||
let (egui_output, _paint_commands) = ctx.end_frame();
|
||||
let (egui_output, _shapes) = ctx.end_frame();
|
||||
handle_output(egui_output, &display, clipboard.as_mut());
|
||||
// TODO: handle app_output
|
||||
// eprintln!("Warmed up in {} ms", warm_up_start.elapsed().as_millis())
|
||||
|
@ -211,8 +211,8 @@ pub fn run(mut app: Box<dyn epi::App>) -> ! {
|
|||
}
|
||||
.build();
|
||||
app.update(&ctx, &mut frame);
|
||||
let (egui_output, paint_commands) = ctx.end_frame();
|
||||
let paint_jobs = ctx.tessellate(paint_commands);
|
||||
let (egui_output, shapes) = ctx.end_frame();
|
||||
let paint_jobs = ctx.tessellate(shapes);
|
||||
|
||||
let frame_time = (Instant::now() - frame_start).as_secs_f64() as f32;
|
||||
previous_frame_time = Some(frame_time);
|
||||
|
|
|
@ -38,8 +38,8 @@ impl WebBackend {
|
|||
.take()
|
||||
.expect("unmatched calls to begin_frame/end_frame");
|
||||
|
||||
let (output, paint_commands) = self.ctx.end_frame();
|
||||
let paint_jobs = self.ctx.tessellate(paint_commands);
|
||||
let (output, shapes) = self.ctx.end_frame();
|
||||
let paint_jobs = self.ctx.tessellate(shapes);
|
||||
|
||||
let now = now_sec();
|
||||
self.previous_frame_time = Some((now - frame_start) as f32);
|
||||
|
|
|
@ -67,7 +67,7 @@ pub trait App {
|
|||
/// If `true` a warm-up call to [`Self::update`] will be issued where
|
||||
/// `ctx.memory().everything_is_visible()` will be set to `true`.
|
||||
///
|
||||
/// In this warm-up call, all paint commands will be ignored.
|
||||
/// In this warm-up call, all painted shapes will be ignored.
|
||||
fn warm_up_enabled(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue