git.lucas.co / cce-designer
graphic design tool
git clone https://git.lucas.co/cce-designer.git

commit5219e68bb12b786c51dc7261a34e71b9255d7130
parent5e4881dbf9
authorLucas Galante <lsgalante12@gmail.com>
date2026-10-06 08:57
feat(scrollbars): the params pane's bar fades rather than flips

The PARAM_IDX arm draws the idle copy of ParametersBg::scrollbar_quads
before the plate every frame and the fore copy after the rows at
scrollbar_fade(), where it drew one copy on either side of the plate by
the latch. The dialog's bar takes layout::centred_scrollbar_width, the
one width the centred bars share.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

 CLAUDE.md     |  7 +++++++
 src/dialog.rs |  2 +-
 src/render.rs | 18 +++++++++++-------
 3 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/CLAUDE.md b/CLAUDE.md
index 3150e47..268a967 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -2187,6 +2187,13 @@ the widget paints the fore copy itself. A press on a sunk bar's lane is a
 press on the row under it. Checked in a shadow session: sunk, raised by a
 scroll, held by hover past the hold, sunk again once the pointer left.
 
+**The params pane's bar fades too** (the same day; cce-ui's CLAUDE.md,
+"Every scrollbar rides a centre line, behind the plate", is the rule all
+of these follow). The PARAM_IDX arm draws the idle copy of
+`ParametersBg::scrollbar_quads` before the plate every frame and the fore
+copy after the rows at `scrollbar_fade()`, where it drew ONE copy on
+either side of the plate by the latch, so a raise and a sink were a flip.
+
 ### An edit is in from the next frame
 
 An edit inside a simnet's chain, or to its seed, does not restart the
diff --git a/src/dialog.rs b/src/dialog.rs
index 7c6bc8d..99b7908 100644
--- a/src/dialog.rs
+++ b/src/dialog.rs
@@ -471,7 +471,7 @@ impl Dialog {
             return None;
         }
         let list = list_rect(rect);
-        let sb_w = cce_ui::layout::scrollbar_width() * 1.6;
+        let sb_w = cce_ui::layout::centred_scrollbar_width();
         let sb_x = rect.x + (rect.width - sb_w) * 0.5;
         let track_y = list.y + 4.0;
         let track_h = (list.height - 8.0).max(0.0);
diff --git a/src/render.rs b/src/render.rs
index eae13e8..6287e31 100644
--- a/src/render.rs
+++ b/src/render.rs
@@ -649,8 +649,9 @@ impl State {
             // skips this slot. The pane keeps three designer-owned pieces:
             // the plate (span-widened radii + focus tint), the viewport clip
             // (a clip inside the widget would not survive paint_self's
-            // replay), and the scrollbar straddle — idle it sinks behind the
-            // translucent plate, active it rides above the content.
+            // replay), and the scrollbar straddle — its idle copy behind the
+            // translucent plate every frame, its fore copy over the content
+            // at the raise's fade, so a raise and a sink are a fade.
             let param_scrollbar = {
                 let pb = self
                     .slots
@@ -659,14 +660,14 @@ impl State {
                     .downcast_ref::<cce_ui::widget::ParametersBg>()
                     .expect("PARAM_IDX must be a ParametersBg");
                 if pb.scrollbar_visible() {
-                    Some((pb.scrollbar_quads(), pb.scrollbar_active()))
+                    Some((pb.scrollbar_quads(), pb.scrollbar_fade()))
                 } else {
                     None
                 }
             };
             // Track and thumb are pills — half-width radius on the DE corner
             // family (squircle when corner_shape > 2), like the nodes.
-            if let Some((quads, false)) = &param_scrollbar {
+            if let Some((quads, _)) = &param_scrollbar {
                 for &(qx, qy, qw, qh, qc) in quads {
                     pc.rounded_rect(rect(qx, qy, qw, qh), qw.min(qh) * 0.5, (true, true, true, true), qc);
                 }
@@ -705,9 +706,12 @@ impl State {
                 }
             }
 
-            if let Some((quads, true)) = &param_scrollbar {
-                for &(qx, qy, qw, qh, qc) in quads {
-                    pc.rounded_rect(rect(qx, qy, qw, qh), qw.min(qh) * 0.5, (true, true, true, true), qc);
+            if let Some((quads, fade)) = &param_scrollbar {
+                if *fade > 0.001 {
+                    for &(qx, qy, qw, qh, mut qc) in quads {
+                        qc[3] *= fade;
+                        pc.rounded_rect(rect(qx, qy, qw, qh), qw.min(qh) * 0.5, (true, true, true, true), qc);
+                    }
                 }
             }
         } else {