file manager
git clone https://git.lucas.co/cce-files.git
feat: mirror the breadcrumb's per-segment button plates in the flat view
PageContent reliefs carry a kind (recessed/raised/inset) instead of a
bool; relief_inset maps to the flush inset button treatment
(WidgetFx::Inset). Browse and Network carve one inset per segment from
Breadcrumb::segment_boxes, replacing the single recessed well.
Co-Authored-By: Claude Fable 5 <[email protected]>
src/main.rs | 8 ++++++--
src/pages/browse.rs | 13 ++++++++++---
src/pages/mod.rs | 25 ++++++++++++++++++++-----
src/pages/network.rs | 13 ++++++++++---
4 files changed, 46 insertions(+), 13 deletions(-)
diff --git a/src/main.rs b/src/main.rs
index 065918e..7c62260 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -715,7 +715,7 @@ impl FilesystemApp {
fx: WidgetFx::Image { id: *id, alpha: *alpha },
});
}
- for (rx, ry, rw, rh, rr, rd, raised) in &pc_part.reliefs {
+ for (rx, ry, rw, rh, rr, rd, kind) in &pc_part.reliefs {
let (mut wy, mut wh) = (*ry, *rh);
if is_page_content {
match clip_to_viewport(wy, wh, content_y, content_y + content_h) {
@@ -731,7 +731,11 @@ impl FilesystemApp {
color: [0.0; 4],
radius: *rr,
corners: (true, true, true, true),
- fx: if *raised { WidgetFx::Boss(*rd) } else { WidgetFx::Recess(*rd) },
+ fx: match *kind {
+ pages::RELIEF_RAISED => WidgetFx::Boss(*rd),
+ pages::RELIEF_INSET => WidgetFx::Inset(*rd),
+ _ => WidgetFx::Recess(*rd),
+ },
});
}
for (btn, action) in &pc_part.buttons {
diff --git a/src/pages/browse.rs b/src/pages/browse.rs
index 7677982..974b788 100644
--- a/src/pages/browse.rs
+++ b/src/pages/browse.rs
@@ -198,9 +198,16 @@ pub fn view(state: &mut BrowseState, view_dropdown: &mut cce_ui::widget::Adapted
let breadcrumb_w = client_w - dropdown_w - gap;
let (bx, by, bw, bh) = layout.allocate(breadcrumb_w, breadcrumb_h);
cce_ui::layout::render_widget(&mut pc, &mut state.breadcrumb, bx, by, bw, bh, ctx);
- // The breadcrumb's recessed well lives in its modern paint(); the flat view
- // this host renders through loses it, so carve it here.
- pc.relief_recessed(bx, by, bw, bh, cce_ui::layout::breadcrumb_corner_radius());
+ // The breadcrumb's per-segment button plates live in its modern paint();
+ // the flat view this host renders through loses them, so carve each
+ // segment's flush inset here (the dropdown-mirror idiom).
+ {
+ let r = cce_ui::layout::breadcrumb_corner_radius().min(bh * 0.5);
+ let rect = cce_ui::scene::layout::Rect { x: bx, y: by, width: bw, height: bh };
+ for (sx, sy, sw, sh) in state.breadcrumb.segment_boxes(rect) {
+ pc.relief_inset(sx, sy, sw, sh, r);
+ }
+ }
cce_ui::layout::render_widget(&mut pc, view_dropdown, bx + bw + gap, by, dropdown_w, breadcrumb_h, ctx);
// 2. Allocate and render List (ScrollBox)
diff --git a/src/pages/mod.rs b/src/pages/mod.rs
index feb45cc..b65ccdc 100644
--- a/src/pages/mod.rs
+++ b/src/pages/mod.rs
@@ -31,14 +31,19 @@ impl Page {
}
}
+pub const RELIEF_RECESSED: u8 = 0;
+pub const RELIEF_RAISED: u8 = 1;
+pub const RELIEF_INSET: u8 = 2;
+
pub struct PageContent {
pub rects: Vec<([f32; 4], f32, f32, f32, f32, f32, (bool, bool, bool, bool))>,
pub texts: Vec<(String, f32, f32, f32, [f32; 4], Option<String>, Option<[f32; 4]>)>,
pub buttons: Vec<(cce_ui::widget::Adapted<cce_ui::widget::Button>, crate::Message)>,
/// Relief steps for the control_relief styling — (x, y, w, h, radius, depth,
- /// raised). The flat rects own the faces; these are the edges-only boss/recess
- /// walls emitted over them (the ParametersBg::reliefs idiom for flat-view hosts).
- pub reliefs: Vec<(f32, f32, f32, f32, f32, f32, bool)>,
+ /// kind: [`RELIEF_RECESSED`]/[`RELIEF_RAISED`]/[`RELIEF_INSET`]). The flat rects
+ /// own the faces; these are the edges-only walls emitted over them (the
+ /// ParametersBg::reliefs idiom for flat-view hosts).
+ pub reliefs: Vec<(f32, f32, f32, f32, f32, f32, u8)>,
/// GPU-textured quads — (image id from `cce_ui::vk::upload_rgba`, x, y, w, h,
/// alpha). Drawn after the part's rects, so a fill emitted earlier is the floor
/// beneath the image and overlay parts still cover it.
@@ -70,7 +75,7 @@ impl PageContent {
pub fn relief_recessed(&mut self, x: f32, y: f32, w: f32, h: f32, radius: f32) {
if cce_ui::layout::control_relief() {
let depth = cce_ui::layout::bevel_width().min(h * 0.2);
- self.reliefs.push((x, y, w, h, radius, depth, false));
+ self.reliefs.push((x, y, w, h, radius, depth, RELIEF_RECESSED));
}
}
@@ -79,7 +84,17 @@ impl PageContent {
pub fn relief_raised(&mut self, x: f32, y: f32, w: f32, h: f32, radius: f32) {
if cce_ui::layout::control_relief() {
let depth = cce_ui::layout::bevel_width().min(h * 0.2);
- self.reliefs.push((x, y, w, h, radius, depth, true));
+ self.reliefs.push((x, y, w, h, radius, depth, RELIEF_RAISED));
+ }
+ }
+
+ /// A flush inset button plate (groove ring + beveled lip, face level with the
+ /// surface — the Button treatment) over the control at (x, y, w, h) — no-op
+ /// when the DE's control_relief styling is off.
+ pub fn relief_inset(&mut self, x: f32, y: f32, w: f32, h: f32, radius: f32) {
+ if cce_ui::layout::control_relief() {
+ let depth = cce_ui::layout::bevel_width().min(h * 0.2);
+ self.reliefs.push((x, y, w, h, radius, depth, RELIEF_INSET));
}
}
diff --git a/src/pages/network.rs b/src/pages/network.rs
index 20bd733..e94eabd 100644
--- a/src/pages/network.rs
+++ b/src/pages/network.rs
@@ -115,9 +115,16 @@ pub fn view(state: &mut NetworkState, browse: &BrowseState, view_dropdown: &mut
let dropdown_w = 120.0;
let breadcrumb_w = cw - 16.0 - dropdown_w - 12.0;
cce_ui::layout::render_widget(&mut pc, &mut state.breadcrumb, cx + 4.0, cy + 6.0, breadcrumb_w, 24.0, ctx);
- // The breadcrumb's recessed well lives in its modern paint(); the flat view
- // this host renders through loses it, so carve it here.
- pc.relief_recessed(cx + 4.0, cy + 6.0, breadcrumb_w, 24.0, cce_ui::layout::breadcrumb_corner_radius());
+ // The breadcrumb's per-segment button plates live in its modern paint();
+ // the flat view this host renders through loses them, so carve each
+ // segment's flush inset here (the dropdown-mirror idiom).
+ {
+ let r = cce_ui::layout::breadcrumb_corner_radius().min(12.0);
+ let rect = cce_ui::scene::layout::Rect { x: cx + 4.0, y: cy + 6.0, width: breadcrumb_w, height: 24.0 };
+ for (sx, sy, sw, sh) in state.breadcrumb.segment_boxes(rect) {
+ pc.relief_inset(sx, sy, sw, sh, r);
+ }
+ }
cce_ui::layout::render_widget(&mut pc, view_dropdown, cx + 4.0 + breadcrumb_w + 12.0, cy + 6.0, dropdown_w, 24.0, ctx);
// Check if directory changed, or if last_dir is empty, and repopulate