git.lucas.co / cce-ui
GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git

commita65cabc6c5297b85a102ad5f738d4133acd57d28
parent28fb9da768
authorLucas Galante <[email protected]>
date2026-07-21 10:43
feat: corner_frame concentric adjustment applies to the inset relief

The relief branch no longer bails when a corner_frame is set (which fell
back to the legacy flat path and force-opaqued a transparent fill to
black). The per-corner concentric radii (frame radius - gap at corners
with equal gaps) now feed inset_plate directly, so a dropdown nested
into a window corner keeps the flush inset look while following the
plate's curve.

Co-Authored-By: Claude Fable 5 <[email protected]>

 src/widget/input/dropdown.rs | 32 +++++++++++++++++++++++++++++---
 1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/src/widget/input/dropdown.rs b/src/widget/input/dropdown.rs
index 7424b28..81b709c 100644
--- a/src/widget/input/dropdown.rs
+++ b/src/widget/input/dropdown.rs
@@ -294,13 +294,39 @@ impl Dropdown {
         // flat outlines, which a rolled edge replaces). A transparent
         // configured fill degrades to a Boss: edges only, plate as the face —
         // judged on the RAW alpha, before the opacity force above.
-        if self.raised && self.corner_frame.is_none() {
+        if self.raised {
             let depth = crate::layout::bevel_width().min(visual_h * 0.2);
-            let r4 = (radius, radius, radius, radius);
+            // Concentric corner_frame adjustment applies to the relief too:
+            // a corner nested at equal gaps into the frame follows its curve
+            // (radius = frame radius - gap), per corner.
+            let mut r4 = [radius; 4];
+            if let Some(((px, py, pw, ph), pr, (pr1, pr2, pr3, pr4))) = self.corner_frame {
+                let g_left = x - px;
+                let g_top = y - py;
+                let g_right = (px + pw) - (x + w);
+                let g_bottom = (py + ph) - (y + visual_h);
+                if pr1 && (g_left - g_top).abs() < 1.0 && g_left >= 0.0 {
+                    r4[0] = (pr - g_left).max(0.0);
+                }
+                if pr2 && (g_right - g_top).abs() < 1.0 && g_right >= 0.0 {
+                    r4[1] = (pr - g_right).max(0.0);
+                }
+                if pr3 && (g_right - g_bottom).abs() < 1.0 && g_right >= 0.0 {
+                    r4[2] = (pr - g_right).max(0.0);
+                }
+                if pr4 && (g_left - g_bottom).abs() < 1.0 && g_left >= 0.0 {
+                    r4[3] = (pr - g_left).max(0.0);
+                }
+            }
             // Flush inset plate: groove ring down, beveled lip back up, face
             // level with the surface (transparent raw fill = edges only).
             let face = if raw_bg[3] > 0.001 { bg_color } else { [0.0; 4] };
-            ctx.inset_plate(Rect { x, y, width: w, height: visual_h }, r4, face, depth);
+            ctx.inset_plate(
+                Rect { x, y, width: w, height: visual_h },
+                (r4[0], r4[1], r4[2], r4[3]),
+                face,
+                depth,
+            );
             return;
         }
         if radius <= 0.0 {