system settings
git clone https://git.lucas.co/cce-system-interface.git
settings: re-emit bridged TextBox wells, not just Dropdown troughs
The page collected control carves as `(rect, radius, depth, face color)` —
a shape that could only describe an inset plate, because `inset_plate` was
the only relief hook a flat host had. With `RenderTarget::recess` added
upstream, a TextBox now offers its well here too, and a well is a different
carve, not the same one at another rect: collapsing them would give this app
text fields no other relief host has.
So the collected tuple carries a `ControlCarve` instead of a colour, and
`display_list` matches on it — inset plate for a Dropdown, recess (or
`recess_tinted` while the box is being edited) for a TextBox. Both the page
and the popover re-emit paths take the same match; the scroll shift and the
page-viewport clip are unchanged.
Verified live headless on the Browser page: Homepage and Download Directory
carve wells at (36,59) and (36,239) while the two dropdowns keep troughs at
(36,119) and (36,179) — confirmed in the plate tracer AND in the pixels, and
the dropdown's open popover plate still draws.
src/app.rs | 38 ++++++++++++++++++++++++++++++++------
src/main.rs | 36 +++++++++++++++++++-----------------
2 files changed, 51 insertions(+), 23 deletions(-)
diff --git a/src/app.rs b/src/app.rs
index 44bb171..9d89605 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -124,6 +124,20 @@ pub enum AppAction {
}
+/// A control carve bridged out of a widget's `paint` for the flat path: the
+/// two relief idioms the toolkit's controls draw for themselves, which the
+/// legacy `all_quads` stream cannot carry. The page collects them and
+/// `display_list` re-emits them as real prims into the window plate.
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub enum ControlCarve {
+ /// `PaintCtx::inset_plate` — a flush inset face over a boundary seam
+ /// (Dropdown). `color` fills the face; transparent leaves the plate below.
+ Plate { color: [f32; 4] },
+ /// `PaintCtx::recess` / `recess_tinted` — a sunken well (TextBox).
+ /// `tint` is the focus accent on the rim while the box is being edited.
+ Well { tint: Option<[f32; 3]> },
+}
+
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]>)>,
@@ -135,11 +149,12 @@ pub struct PageContent {
/// plus the title tab box, carved into the window plate by display_list as
/// recess prims (page coordinates, pre-scroll).
pub reliefs: Vec<((f32, f32, f32, f32), Option<(f32, f32, f32, f32)>)>,
- /// Control troughs claimed via `RenderTarget::inset_plate` (the flat-path
- /// bridge offers a Dropdown's flush inset chrome here) — (x, y, w, h,
- /// radius, depth, face color), page coordinates, pre-scroll; display_list
- /// carves them as real inset plates.
- pub control_reliefs: Vec<(f32, f32, f32, f32, f32, f32, [f32; 4])>,
+ /// Control carves claimed via the flat-path relief hooks
+ /// (`RenderTarget::inset_plate` for a Dropdown's flush inset chrome,
+ /// `RenderTarget::recess` for a TextBox's well) — (x, y, w, h, radius,
+ /// depth, carve), page coordinates, pre-scroll; display_list re-emits them
+ /// as real relief prims.
+ pub control_reliefs: Vec<(f32, f32, f32, f32, f32, f32, ControlCarve)>,
pub clip_stack: Vec<[f32; 4]>,
pub measure_only: bool,
}
@@ -310,7 +325,18 @@ impl RenderTarget for PageContent {
if self.measure_only {
return;
}
- self.control_reliefs.push((x, y, w, h, radius, depth, color));
+ self.control_reliefs.push((x, y, w, h, radius, depth, ControlCarve::Plate { color }));
+ }
+
+ /// The same bridge for a TextBox's well — a DIFFERENT carve, not the same
+ /// one at another rect: a trough is a seam about the boundary with the face
+ /// level, a well drops the whole interior. Collapsing them would give the
+ /// settings app text fields no other relief host has.
+ fn recess(&mut self, x: f32, y: f32, w: f32, h: f32, radius: f32, depth: f32, tint: Option<[f32; 3]>) {
+ if self.measure_only {
+ return;
+ }
+ self.control_reliefs.push((x, y, w, h, radius, depth, ControlCarve::Well { tint }));
}
fn section_relief(&mut self, f: &cce_ui::layout::SectionFrame) -> bool {
diff --git a/src/main.rs b/src/main.rs
index 7cb2b69..bec1283 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,7 +1,7 @@
use cce_ui::widget::hover_animation;
use cce_ui::cosmic_text::{Buffer, FontSystem};
-use cce_settings::app::{AppAction, AppState};
+use cce_settings::app::{AppAction, AppState, ControlCarve};
use cce_settings::pages::{self, Page};
mod input_handler;
mod renderer;
@@ -46,7 +46,7 @@ struct SystemInterface {
popover_texts: Vec<(String, f32, f32, f32, [f32; 4], Option<String>, Option<[f32; 4]>)>,
/// Popover-layer inset plates (window coords, scroll already applied) —
/// the dropdown's grown-trigger surface via the inset_plate hook.
- popover_control_reliefs: Vec<(f32, f32, f32, f32, f32, f32, [f32; 4])>,
+ popover_control_reliefs: Vec<(f32, f32, f32, f32, f32, f32, ControlCarve)>,
page_buttons: Vec<(cce_ui::widget::Adapted<cce_ui::widget::Button>, AppAction)>,
sidebar_width: f32,
@@ -108,7 +108,7 @@ struct SystemInterface {
page_reliefs: Vec<((f32, f32, f32, f32), Option<(f32, f32, f32, f32)>)>,
/// Control troughs from `PageContent::control_reliefs` (page coords,
/// pre-scroll) — each carved as a flush inset plate after the section wells.
- page_control_reliefs: Vec<(f32, f32, f32, f32, f32, f32, [f32; 4])>,
+ page_control_reliefs: Vec<(f32, f32, f32, f32, f32, f32, ControlCarve)>,
// Root Backplate + StatusBar DISSOLVED (Phase 6s): the window plate and the status
// bar are emitted as tuples in rebuild_layout.
sans_serif_family: String,
@@ -417,13 +417,14 @@ impl cce_ui::engine::Application for SystemInterface {
};
let scroll_y = self.scroll_y;
pc.clip(view, |pc| {
- for &(x, y, w, h, radius, depth, color) in &self.page_control_reliefs {
- pc.inset_plate(
- Rect { x, y: y - scroll_y, width: w, height: h },
- (radius, radius, radius, radius),
- color,
- depth,
- );
+ for &(x, y, w, h, radius, depth, carve) in &self.page_control_reliefs {
+ let rect = Rect { x, y: y - scroll_y, width: w, height: h };
+ let radii = (radius, radius, radius, radius);
+ match carve {
+ ControlCarve::Plate { color } => pc.inset_plate(rect, radii, color, depth),
+ ControlCarve::Well { tint: Some(t) } => pc.recess_tinted(rect, radii, depth, t),
+ ControlCarve::Well { tint: None } => pc.recess(rect, radii, depth),
+ }
}
});
}
@@ -443,13 +444,14 @@ impl cce_ui::engine::Application for SystemInterface {
// Popover surfaces claimed through the inset_plate hook (the dropdown's
// grown-trigger plate): real relief prims at the popover layer, over
// the page and its control troughs.
- for &(x, y, w, h, radius, depth, color) in &self.popover_control_reliefs {
- pc.inset_plate(
- Rect { x, y, width: w, height: h },
- (radius, radius, radius, radius),
- color,
- depth,
- );
+ for &(x, y, w, h, radius, depth, carve) in &self.popover_control_reliefs {
+ let rect = Rect { x, y, width: w, height: h };
+ let radii = (radius, radius, radius, radius);
+ match carve {
+ ControlCarve::Plate { color } => pc.inset_plate(rect, radii, color, depth),
+ ControlCarve::Well { tint: Some(t) } => pc.recess_tinted(rect, radii, depth, t),
+ ControlCarve::Well { tint: None } => pc.recess(rect, radii, depth),
+ }
}
for (text, font_size, x, y, col, font, bounds) in self.texts.iter().chain(self.popover_texts.iter()) {
pc.text_with(