GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
Fix remaining missing as_ptr/as_ptr_mut widget overrides and apply strict anchor rect bounds clamping
src/backend/window_runner.rs | 20 ++++++++++++++------
src/widget/display/graph.rs | 3 +++
src/widget/display/node.rs | 6 ++++++
src/widget/display/separator.rs | 6 ++++++
src/widget/display/sidebar.rs | 6 ++++++
src/widget/display/splitter.rs | 6 ++++++
src/widget/display/status_bar.rs | 6 ++++++
src/widget/display/svg.rs | 6 ++++++
src/widget/input/canvas.rs | 6 ++++++
9 files changed, 59 insertions(+), 6 deletions(-)
diff --git a/src/backend/window_runner.rs b/src/backend/window_runner.rs
index 38da5ec..6299ec6 100644
--- a/src/backend/window_runner.rs
+++ b/src/backend/window_runner.rs
@@ -2038,15 +2038,23 @@ pub fn run<A: Application>() {
let (rx, ry, rw, rh) = popover_widget.rect();
let scroll_y = crate::widget::hover_animation::get_scroll_offset();
let screen_ry = ry - scroll_y;
- let ax = (rx as i32).clamp(0, (engine_state.logical_width as i32 - 1).max(0));
- let ay = (screen_ry as i32).clamp(0, (engine_state.logical_height as i32 - 1).max(0));
- positioner.set_anchor_rect(ax, ay, rw as i32, rh as i32);
+ let lw = engine_state.logical_width as i32;
+ let lh = engine_state.logical_height as i32;
+ let ax = (rx as i32).clamp(0, (lw - 1).max(0));
+ let ay = (screen_ry as i32).clamp(0, (lh - 1).max(0));
+ let aw = (rw as i32).clamp(1, (lw - ax).max(1));
+ let ah = (rh as i32).clamp(1, (lh - ay).max(1));
+ positioner.set_anchor_rect(ax, ay, aw, ah);
positioner.set_anchor(Anchor::BottomLeft);
positioner.set_gravity(Gravity::BottomRight);
} else {
- let ax = (px as i32).clamp(0, (engine_state.logical_width as i32 - 1).max(0));
- let ay = (py as i32).clamp(0, (engine_state.logical_height as i32 - 1).max(0));
- positioner.set_anchor_rect(ax, ay, 1, 1);
+ let lw = engine_state.logical_width as i32;
+ let lh = engine_state.logical_height as i32;
+ let ax = (px as i32).clamp(0, (lw - 1).max(0));
+ let ay = (py as i32).clamp(0, (lh - 1).max(0));
+ let aw = 1.clamp(1, (lw - ax).max(1));
+ let ah = 1.clamp(1, (lh - ay).max(1));
+ positioner.set_anchor_rect(ax, ay, aw, ah);
positioner.set_anchor(Anchor::TopLeft);
positioner.set_gravity(Gravity::BottomRight);
}
diff --git a/src/widget/display/graph.rs b/src/widget/display/graph.rs
index ad58b85..d254a1e 100644
--- a/src/widget/display/graph.rs
+++ b/src/widget/display/graph.rs
@@ -245,6 +245,9 @@ impl Element for Graph {
fn as_ptr(&self) -> *mut (dyn Element + 'static) {
self as *const Self as *mut Self as *mut (dyn Element + 'static)
}
+ fn as_ptr_mut(&mut self) -> *mut (dyn Element + 'static) {
+ self as *mut Self as *mut (dyn Element + 'static)
+ }
fn rounded_corners(&self) -> (bool, bool, bool, bool) { (false, false, true, true) }
diff --git a/src/widget/display/node.rs b/src/widget/display/node.rs
index 6ba2e09..59fcdb9 100644
--- a/src/widget/display/node.rs
+++ b/src/widget/display/node.rs
@@ -59,6 +59,12 @@ impl Element for Node {
else if self.selected { colors::node_selected_color() }
else { colors::node_color() }
}
+ fn as_ptr(&self) -> *mut (dyn Element + 'static) {
+ self as *const Self as *mut Self as *mut (dyn Element + 'static)
+ }
+ fn as_ptr_mut(&mut self) -> *mut (dyn Element + 'static) {
+ self as *mut Self as *mut (dyn Element + 'static)
+ }
fn set_hovered(&mut self, v: bool) { self.hovered = v; }
fn hovered(&self) -> bool { self.hovered }
diff --git a/src/widget/display/separator.rs b/src/widget/display/separator.rs
index e223f5c..54ba050 100644
--- a/src/widget/display/separator.rs
+++ b/src/widget/display/separator.rs
@@ -19,6 +19,12 @@ impl Element for Separator {
fn rect(&self) -> (f32, f32, f32, f32) {
(self.x, self.y, self.w, self.h)
}
+ fn as_ptr(&self) -> *mut (dyn Element + 'static) {
+ self as *const Self as *mut Self as *mut (dyn Element + 'static)
+ }
+ fn as_ptr_mut(&mut self) -> *mut (dyn Element + 'static) {
+ self as *mut Self as *mut (dyn Element + 'static)
+ }
fn set_rect(&mut self, x: f32, y: f32, w: f32, h: f32) {
self.x = x;
diff --git a/src/widget/display/sidebar.rs b/src/widget/display/sidebar.rs
index 6877198..8a3651e 100644
--- a/src/widget/display/sidebar.rs
+++ b/src/widget/display/sidebar.rs
@@ -14,6 +14,12 @@ impl Element for Sidebar {
fn rect(&self) -> (f32, f32, f32, f32) { (self.x, self.y, self.w, self.h) }
fn set_rect(&mut self, x: f32, y: f32, w: f32, h: f32) { self.x = x; self.y = y; self.w = w; self.h = h; }
fn color(&self) -> [f32; 4] { colors::sidebar_bg_color() }
+ fn as_ptr(&self) -> *mut (dyn Element + 'static) {
+ self as *const Self as *mut Self as *mut (dyn Element + 'static)
+ }
+ fn as_ptr_mut(&mut self) -> *mut (dyn Element + 'static) {
+ self as *mut Self as *mut (dyn Element + 'static)
+ }
fn set_hovered(&mut self, v: bool) { self.hovered = v; }
fn hovered(&self) -> bool { self.hovered }
}
diff --git a/src/widget/display/splitter.rs b/src/widget/display/splitter.rs
index c773573..22a165b 100644
--- a/src/widget/display/splitter.rs
+++ b/src/widget/display/splitter.rs
@@ -17,6 +17,12 @@ impl Splitter {
impl Element for Splitter {
fn rect(&self) -> (f32, f32, f32, f32) { (self.x, self.y, self.w, self.h) }
fn set_rect(&mut self, x: f32, y: f32, w: f32, h: f32) { self.x = x; self.y = y; self.w = w; self.h = h; }
+ fn as_ptr(&self) -> *mut (dyn Element + 'static) {
+ self as *const Self as *mut Self as *mut (dyn Element + 'static)
+ }
+ fn as_ptr_mut(&mut self) -> *mut (dyn Element + 'static) {
+ self as *mut Self as *mut (dyn Element + 'static)
+ }
fn color(&self) -> [f32; 4] {
if self.dragging { colors::SPLITTER_DRAG }
else if self.hovered { colors::SPLITTER_HOVER }
diff --git a/src/widget/display/status_bar.rs b/src/widget/display/status_bar.rs
index 191b008..4f1ad19 100644
--- a/src/widget/display/status_bar.rs
+++ b/src/widget/display/status_bar.rs
@@ -57,6 +57,12 @@ impl StatusBar {
impl Element for StatusBar {
fn rect(&self) -> (f32, f32, f32, f32) { (self.x, self.y, self.w, self.h) }
fn set_rect(&mut self, x: f32, y: f32, w: f32, h: f32) { self.x = x; self.y = y; self.w = w; self.h = h; }
+ fn as_ptr(&self) -> *mut (dyn Element + 'static) {
+ self as *const Self as *mut Self as *mut (dyn Element + 'static)
+ }
+ fn as_ptr_mut(&mut self) -> *mut (dyn Element + 'static) {
+ self as *mut Self as *mut (dyn Element + 'static)
+ }
fn color(&self) -> [f32; 4] { self.bg_color.unwrap_or(colors::STATUS_BG) }
fn set_hovered(&mut self, v: bool) { self.hovered = v; }
fn hovered(&self) -> bool { self.hovered }
diff --git a/src/widget/display/svg.rs b/src/widget/display/svg.rs
index 7ef46d6..e8c26b6 100644
--- a/src/widget/display/svg.rs
+++ b/src/widget/display/svg.rs
@@ -68,6 +68,12 @@ impl Svg {
impl Element for Svg {
fn rect(&self) -> (f32, f32, f32, f32) { (self.x, self.y, self.w, self.h) }
+ fn as_ptr(&self) -> *mut (dyn Element + 'static) {
+ self as *const Self as *mut Self as *mut (dyn Element + 'static)
+ }
+ fn as_ptr_mut(&mut self) -> *mut (dyn Element + 'static) {
+ self as *mut Self as *mut (dyn Element + 'static)
+ }
fn set_rect(&mut self, x: f32, y: f32, w: f32, h: f32) {
let dx = x - self.x;
diff --git a/src/widget/input/canvas.rs b/src/widget/input/canvas.rs
index 1867305..f88b092 100644
--- a/src/widget/input/canvas.rs
+++ b/src/widget/input/canvas.rs
@@ -13,6 +13,12 @@ impl Element for Canvas {
fn rect(&self) -> (f32, f32, f32, f32) { (self.x, self.y, self.w, self.h) }
fn set_rect(&mut self, x: f32, y: f32, w: f32, h: f32) { self.x = x; self.y = y; self.w = w; self.h = h; }
fn color(&self) -> [f32; 4] { [0.0, 0.0, 0.0, 0.0] }
+ fn as_ptr(&self) -> *mut (dyn Element + 'static) {
+ self as *const Self as *mut Self as *mut (dyn Element + 'static)
+ }
+ fn as_ptr_mut(&mut self) -> *mut (dyn Element + 'static) {
+ self as *mut Self as *mut (dyn Element + 'static)
+ }
fn set_hovered(&mut self, v: bool) { self.hovered = v; }
fn hovered(&self) -> bool { self.hovered }
fn hit_test(&self, _px: f32, _py: f32, _ctx: &UiContext) -> bool { false }