diff --git a/egui/src/context.rs b/egui/src/context.rs index 482363ad..e8d9a400 100644 --- a/egui/src/context.rs +++ b/egui/src/context.rs @@ -685,7 +685,9 @@ impl Context { /// Move all the graphics at the given layer. /// Can be used to implement drag-and-drop (see relevant demo). pub fn translate_layer(&self, layer_id: LayerId, delta: Vec2) { - self.graphics().list(layer_id).translate(delta); + if delta != Vec2::ZERO { + self.graphics().list(layer_id).lock().translate(delta); + } } pub fn layer_id_at(&self, pos: Pos2) -> Option { diff --git a/egui/src/layers.rs b/egui/src/layers.rs index 6d56f85d..6e2b7bae 100644 --- a/egui/src/layers.rs +++ b/egui/src/layers.rs @@ -3,7 +3,9 @@ use crate::{Id, *}; use epaint::ahash::AHashMap; +use epaint::mutex::Mutex; use epaint::{ClippedShape, Shape}; +use std::sync::Arc; /// Different layer categories #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)] @@ -120,10 +122,10 @@ impl PaintList { } #[derive(Clone, Default)] -pub(crate) struct GraphicLayers([AHashMap; Order::COUNT]); +pub(crate) struct GraphicLayers([AHashMap>>; Order::COUNT]); impl GraphicLayers { - pub fn list(&mut self, layer_id: LayerId) -> &mut PaintList { + pub fn list(&mut self, layer_id: LayerId) -> &Arc> { self.0[layer_id.order as usize] .entry(layer_id.id) .or_default() @@ -138,20 +140,20 @@ impl GraphicLayers { // If a layer is empty at the start of the frame // the nobody has added to it, and it is old and defunct. // Free it to save memory: - order_map.retain(|_, list| !list.is_empty()); + order_map.retain(|_, list| !list.lock().is_empty()); // First do the layers part of area_order: for layer_id in area_order { if layer_id.order == order { - if let Some(shapes) = order_map.get_mut(&layer_id.id) { - all_shapes.extend(shapes.0.drain(..)); + if let Some(list) = order_map.get_mut(&layer_id.id) { + all_shapes.extend(list.lock().0.drain(..)); } } } // Also draw areas that are missing in `area_order`: for shapes in order_map.values_mut() { - all_shapes.extend(shapes.0.drain(..)); + all_shapes.extend(shapes.lock().0.drain(..)); } } diff --git a/egui/src/painter.rs b/egui/src/painter.rs index 27f2ec8a..e4e9c2e6 100644 --- a/egui/src/painter.rs +++ b/egui/src/painter.rs @@ -1,9 +1,10 @@ use crate::{ emath::{Align2, Pos2, Rect, Vec2}, - layers::{LayerId, ShapeIdx}, + layers::{LayerId, PaintList, ShapeIdx}, Color32, CtxRef, }; use epaint::{ + mutex::Mutex, text::{Fonts, Galley, TextStyle}, Shape, Stroke, }; @@ -19,6 +20,8 @@ pub struct Painter { /// Where we paint layer_id: LayerId, + paint_list: std::sync::Arc>, + /// Everything painted in this `Painter` will be clipped against this. /// This means nothing outside of this rectangle will be visible on screen. clip_rect: Rect, @@ -30,9 +33,11 @@ pub struct Painter { impl Painter { pub fn new(ctx: CtxRef, layer_id: LayerId, clip_rect: Rect) -> Self { + let paint_list = ctx.graphics().list(layer_id).clone(); Self { ctx, layer_id, + paint_list, clip_rect, fade_to_color: None, } @@ -40,8 +45,10 @@ impl Painter { #[must_use] pub fn with_layer_id(self, layer_id: LayerId) -> Self { + let paint_list = self.ctx.graphics().list(layer_id).clone(); Self { ctx: self.ctx, + paint_list, layer_id, clip_rect: self.clip_rect, fade_to_color: None, @@ -51,6 +58,7 @@ impl Painter { /// redirect pub fn set_layer_id(&mut self, layer_id: LayerId) { self.layer_id = layer_id; + self.paint_list = self.ctx.graphics().list(self.layer_id).clone(); } /// If set, colors will be modified to look like this @@ -66,6 +74,7 @@ impl Painter { Self { ctx: self.ctx.clone(), layer_id: self.layer_id, + paint_list: self.paint_list.clone(), clip_rect: rect.intersect(self.clip_rect), fade_to_color: self.fade_to_color, } @@ -129,10 +138,7 @@ impl Painter { /// NOTE: all coordinates are screen coordinates! pub fn add(&self, mut shape: Shape) -> ShapeIdx { self.transform_shape(&mut shape); - self.ctx - .graphics() - .list(self.layer_id) - .add(self.clip_rect, shape) + self.paint_list.lock().add(self.clip_rect, shape) } /// Add many shapes at once. @@ -146,20 +152,14 @@ impl Painter { } } - self.ctx - .graphics() - .list(self.layer_id) - .extend(self.clip_rect, shapes); + self.paint_list.lock().extend(self.clip_rect, shapes); } } /// Modify an existing [`Shape`]. pub fn set(&self, idx: ShapeIdx, mut shape: Shape) { self.transform_shape(&mut shape); - self.ctx - .graphics() - .list(self.layer_id) - .set(idx, self.clip_rect, shape) + self.paint_list.lock().set(idx, self.clip_rect, shape) } }