GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
feat: demo + cce-bevel popovers on the direct PaintCtx path
PaintCtx is a RenderTarget — render_popover draws the real expanded
inset-plate surface; the collector flatten-and-rebound replay is gone.
Both apps expose ui_context_mut so the engine drives animation frames.
Co-Authored-By: Claude Fable 5 <[email protected]>
src/bin/cce-bevel.rs | 24 +++++++++---------------
src/main.rs | 24 +++++++++---------------
2 files changed, 18 insertions(+), 30 deletions(-)
diff --git a/src/bin/cce-bevel.rs b/src/bin/cce-bevel.rs
index b40d797..b029070 100644
--- a/src/bin/cce-bevel.rs
+++ b/src/bin/cce-bevel.rs
@@ -735,21 +735,10 @@ impl Application for BevelPopup {
// The selector's popover, drawn into the frame on top of everything
// below it (its labels carry the popover rect as bounds).
- if let Some((px, py, pw, ph)) = self.profile_dropdown.popover_rect() {
- let mut coll = cce_ui::layout::PopoverCollector::new();
- self.profile_dropdown.render_popover(&mut coll);
- for &(c, x, y, qw, qh) in &coll.rects {
- pc.quad(Rect { x, y, width: qw, height: qh }, c);
- }
- let bounds = Some([px, py, px + pw, py + ph]);
- for (content, size, tx, ty, color, font, _b) in coll.texts {
- let color_u8 = [
- (color[0] * 255.0).clamp(0.0, 255.0) as u8,
- (color[1] * 255.0).clamp(0.0, 255.0) as u8,
- (color[2] * 255.0).clamp(0.0, 255.0) as u8,
- ];
- pc.text_with(content, tx, ty, size, color_u8, font, bounds);
- }
+ if self.profile_dropdown.popover_rect().is_some() {
+ // PaintCtx is a RenderTarget: the popover draws its real prims (the
+ // dropdown's expanded inset-plate surface) with its own bounds.
+ self.profile_dropdown.render_popover(&mut pc);
}
// The shared context menu (slider Copy/Paste), last, on top.
@@ -780,6 +769,11 @@ impl Application for BevelPopup {
Some(&self.ui_context)
}
+ // Engine-driven animation frames for the dropdown expand/contract.
+ fn ui_context_mut(&mut self) -> Option<&mut cce_ui::context::UiContext> {
+ Some(&mut self.ui_context)
+ }
+
fn is_movable_backplate_at(&self, px: f32, py: f32) -> bool {
self.ui_context.drag_allowed_at(px, py)
}
diff --git a/src/main.rs b/src/main.rs
index d1e87da..f0fd643 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -433,21 +433,10 @@ impl Application for DemoApp {
// where it hit-tests. Labels carry bounds equal to the popover rect: that clips
// them to the plate AND exempts them from the occlusion clamp (text whose bounds
// equal an overlay rect is treated as the overlay's own).
- if let Some((px, py, pw, ph)) = self.theme_dropdown.popover_rect() {
- let mut coll = cce_ui::layout::PopoverCollector::new();
- self.theme_dropdown.render_popover(&mut coll);
- for &(c, x, y, qw, qh) in &coll.rects {
- pc.quad(Rect { x, y, width: qw, height: qh }, c);
- }
- let bounds = Some([px, py, px + pw, py + ph]);
- for (content, size, tx, ty, color, font, _b) in coll.texts {
- let color_u8 = [
- (color[0] * 255.0).clamp(0.0, 255.0) as u8,
- (color[1] * 255.0).clamp(0.0, 255.0) as u8,
- (color[2] * 255.0).clamp(0.0, 255.0) as u8,
- ];
- pc.text_with(content, tx, ty, size, color_u8, font, bounds);
- }
+ if self.theme_dropdown.popover_rect().is_some() {
+ // PaintCtx is a RenderTarget: the popover draws its real prims (the
+ // dropdown's expanded inset-plate surface) with its own bounds.
+ self.theme_dropdown.render_popover(&mut pc);
}
Some(pc.finish())
@@ -462,6 +451,11 @@ impl Application for DemoApp {
Some(&self.ui_context)
}
+ // Engine-driven animation frames for the dropdown expand/contract.
+ fn ui_context_mut(&mut self) -> Option<&mut cce_ui::context::UiContext> {
+ Some(&mut self.ui_context)
+ }
+
/// Window dragging for a dissolved root: the surface is the movable plate; drag
/// anywhere a drag-blocking registered widget isn't.
fn is_movable_backplate_at(&self, px: f32, py: f32) -> bool {