collective

Browse / github.com/storytold/wordcraft / patch

Shading buttons show the last picked colour (#4412)

[Feature Request] Paragraph shading button should change colours to match current highlight colour Exactly the same as #4087. But applied to the paragraph shading command. <img width="307" height="351" alt="Image" src="https://github.com/user-attachments/assets/3ed95dff-15bd-4258-8d53-5364fad293f4" /> #4087 was fixed by #4099 (works perfectly, excellent job!), looking to get the same functionality here.

Status
open
Score
0.00
Adopters
0 other operators
Author
MichaelMuClaude (imported from pull request #4505, open)
Base
d522bfd8b19168aabcd9a64d588397c519c393f9
Size
+43 −2 in 4 files
Review
pending
Shared
2026-10-28
Id
57965c54df045bf1576c5de6

How it went

No other operator has reported using it yet.

Diff

raw · crates/ui-egui/src/icons.rs crates/ui-egui/src/ribbon/home.rs crates/ui-egui/src/ribbon/table.rs crates/ui-egui/src/ribbon/tests.rs

diff --git a/crates/ui-egui/src/icons.rs b/crates/ui-egui/src/icons.rs--- a/crates/ui-egui/src/icons.rs+++ b/crates/ui-egui/src/icons.rs@@ -248,6 +248,12 @@ pub fn paint(p: &Painter, r: Rect, name: &str, c: Color32, accent: Color32) {             pen.fcircle(16.5, 13.5, 1.6, a);             pen.frect(2.0, 16.5, 18.0, 19.0, yellow);         }+        // The Shading buttons draw the last colour as their own bar, so this has no bar of its own.+        "shadingNoBar" => {+            pen.fill(&[(4.0, 9.0), (10.0, 3.0), (16.0, 9.0), (10.0, 15.0)], Color32::TRANSPARENT);+            pen.closed(&[(4.0, 9.0), (10.0, 3.0), (16.0, 9.0), (10.0, 15.0)], c);+            pen.fcircle(16.5, 13.5, 1.6, a);+        }         "borders" => {             for y in [3.0, 10.0, 17.0] {                 for x in [3.0, 6.5, 10.0, 13.5, 17.0] {@@ -1649,4 +1655,11 @@ mod tests {         assert!(has_default_highlight_bar("highlight"));         assert!(!has_default_highlight_bar("highlightNoColor"));     }++    /// #4412: the Shading buttons paint the last colour as their bar, so their icon has none of its own.+    #[test]+    fn the_shading_button_icon_has_no_bar_of_its_own() {+        assert!(has_default_highlight_bar("shading"));+        assert!(!has_default_highlight_bar("shadingNoBar"));+    } }diff --git a/crates/ui-egui/src/ribbon/home.rs b/crates/ui-egui/src/ribbon/home.rs--- a/crates/ui-egui/src/ribbon/home.rs+++ b/crates/ui-egui/src/ribbon/home.rs@@ -232,7 +232,8 @@ pub(super) fn home(app: &mut WordApp, ui: &mut Ui) {                     mi(ui, app, "Remove Space After Paragraph", "para.removeSpaceAfter", json!({}));                     mi(ui, app, "Line Spacing Options…", "para.dialog", json!({}));                 });-                split(ui, app, "shading", "Shading", "para.shading", json!({"color": app.canvas.last_shading.clone()}), false, None, |ui, app| {+                let sw = wordcraft_doc::Rgb::parse(&app.canvas.last_shading).map(crate::theme::c32);+                split(ui, app, "shadingNoBar", "Shading", "para.shading", json!({"color": app.canvas.last_shading.clone()}), false, sw, |ui, app| {                     mi(ui, app, "No Color", "para.shading", json!({"color": null}));                     let theme = app.session.doc.settings.theme_colors.clone();                     crate::colors::menu(ui, app, &theme, Target::cmd("para.shading").remember(Remember::Shading));diff --git a/crates/ui-egui/src/ribbon/table.rs b/crates/ui-egui/src/ribbon/table.rs--- a/crates/ui-egui/src/ribbon/table.rs+++ b/crates/ui-egui/src/ribbon/table.rs@@ -73,7 +73,8 @@ pub(super) fn table_design(app: &mut WordApp, ui: &mut Ui) {                     ui.close();                 }             });-            split(ui, app, "shading", "Shading", "table.shading", json!({"color": app.canvas.last_shading.clone()}), false, None, |ui, app| {+            let sw = wordcraft_doc::Rgb::parse(&app.canvas.last_shading).map(crate::theme::c32);+            split(ui, app, "shadingNoBar", "Shading", "table.shading", json!({"color": app.canvas.last_shading.clone()}), false, sw, |ui, app| {                 mi(ui, app, "No Color", "table.shading", json!({"color": null}));                 let theme = app.session.doc.settings.theme_colors.clone();                 crate::colors::menu(ui, app, &theme, Target::cmd("table.shading").remember(Remember::Shading));diff --git a/crates/ui-egui/src/ribbon/tests.rs b/crates/ui-egui/src/ribbon/tests.rs--- a/crates/ui-egui/src/ribbon/tests.rs+++ b/crates/ui-egui/src/ribbon/tests.rs@@ -1,6 +1,32 @@ use super::*; use wordcraft_engine::Session; +/// #4412: the Shading button's bar is the colour a click applies (the last one picked), as+/// the Font Color and Text Highlight Color buttons' bars are, not always the icon's yellow.+#[test]+fn the_shading_button_shows_the_last_picked_colour() {+    let mut a = WordApp::new(Session::new(wordcraft_doc::Document::from_text("Text")), crate::Services::default());+    a.run("view.commentsPane", json!({"value": false})).unwrap();+    let mut h = egui_kittest::Harness::builder().with_size(egui::vec2(1440.0, 900.0)).build_ui_state(+        |ui, app: &mut WordApp| {+            let ctx = ui.ctx().clone();+            app.logic(&ctx);+            app.ui(ui);+        },+        a,+    );+    let ribbon_bars = |h: &egui_kittest::Harness<'_, WordApp>, hex: &str| {+        let want = crate::theme::c32(wordcraft_doc::Rgb::parse(hex).unwrap());+        h.output().shapes.iter().any(|s| matches!(&s.shape, egui::Shape::Rect(r) if r.fill == want && r.rect.height() < 4.0 && r.rect.width() > 10.0))+    };+    h.run_steps(6);+    assert!(ribbon_bars(&h, "FFF2CC"), "the default colour");+    h.state_mut().canvas.last_shading = "00B0F0".into();+    h.run_steps(3);+    assert!(ribbon_bars(&h, "00B0F0"), "the picked colour");+    assert!(!ribbon_bars(&h, "FFF2CC"), "and not the old one");+}+ /// Two clicks arm and disarm the painter; the double-click handling then leaves it sticky (#2785). #[test] fn double_click_on_format_painter_makes_it_sticky() {