mirror of
https://github.com/storytold/photocraft.git
synced 2026-11-07 10:54:10 +00:00
fix(ui): address review notes on the shape Fill/Stroke popover
- The Stroke Color Picker on a shape whose stroke is off (none or 0 px) previews the stroke its OK turns on, at the enabled width, even for the colour it opened on (CodeRabbit). - No Color's diagonal uses the theme's danger token, not a fixed red. - docs/ui-parity.md: the history entry notes Recently Used Colors is a new preference, so 12 of 182 do nothing (matching the row). - The Fill/Stroke swatches clip their checker to the rounded corners, so dark themes no longer show white specks there (#8741). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TYsCL5E2GM6hUabP9dmYAv
This commit is contained in:
5 files changed
+35
-6
No files matched your search
@@ -208,7 +208,10 @@ pub(crate) fn display_doc(app: &mut PhotocraftApp, idx: usize) -> Option<(Arc<Do
|
||||
app.shape_fill_preview = None;
|
||||
return None;
|
||||
};
|
||||
if d.fields.get("color") == d.fields.get("__orig") {
|
||||
// OK on the opening colour changes a paint that isn't solid yet (No Color, a gradient), so
|
||||
// that one previews too.
|
||||
let solid = d.fields.get("__shapePaintSolid").and_then(Value::as_bool).unwrap_or(true);
|
||||
if solid && d.fields.get("color") == d.fields.get("__orig") {
|
||||
return None;
|
||||
}
|
||||
let layer = target(app, &d.fields, idx).ok()??;
|
||||
@@ -228,8 +231,13 @@ pub(crate) fn display_doc(app: &mut PhotocraftApp, idx: usize) -> Option<(Arc<Do
|
||||
if let LayerContent::Shape(sh) = &mut doc.layer_mut(layer)?.content {
|
||||
match which {
|
||||
Paint::Fill => sh.fill = Some(Fill::Solid(color)),
|
||||
// A stroke that is off (No Color) shows on OK, at its enabled width.
|
||||
Paint::Stroke => sh.stroke.as_mut().filter(|s| s.width > 0.0)?.paint = Fill::Solid(color),
|
||||
// A stroke that is off (none, or 0 px) previews as OK makes it: on, at its enabled
|
||||
// width, with `shape.edit`'s default style when the shape has none.
|
||||
Paint::Stroke => {
|
||||
let stroke = sh.stroke.get_or_insert_with(Default::default);
|
||||
stroke.width = crate::vector_ui::enabled_stroke_width(stroke.width);
|
||||
stroke.paint = Fill::Solid(color);
|
||||
}
|
||||
}
|
||||
photocraft_engine::vector_cmds::refresh_shape(&st.doc, sh);
|
||||
}
|
||||
|
||||
@@ -118,6 +118,26 @@ fn stroke_picker_previews_commits_and_rejects_stale_or_bad_targets() {
|
||||
assert!(display_doc(&mut app, 0).is_none());
|
||||
}
|
||||
|
||||
/// A shape without a stroke, or with a 0 px one, previews the stroke the picker's OK turns on:
|
||||
/// the picked colour at the enabled width, even for the colour it opened on.
|
||||
#[test]
|
||||
fn stroke_picker_previews_a_stroke_that_is_off_as_ok_turns_it_on() {
|
||||
for stroke in [json!(null), json!({"width": 0, "color": "#ff0000"})] {
|
||||
let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());
|
||||
app.run("file.new", json!({"width": 64, "height": 48})).unwrap();
|
||||
let id = LayerId(app.run("shape.create", json!({"rect": [8, 8, 40, 30], "fill": "#336699", "stroke": stroke})).unwrap()["layer"].as_u64().unwrap());
|
||||
let dialog = open_paint(&mut app, Paint::Stroke, Some(id), false, [0.0, 0.0, 0.0, 1.0]).unwrap();
|
||||
let (shown, _) = display_doc(&mut app, 0).expect("the unchanged colour still previews the stroke OK adds");
|
||||
let LayerContent::Shape(sh) = &shown.layer(id).unwrap().content else { panic!() };
|
||||
let previewed = sh.stroke.clone().expect("a previewed stroke");
|
||||
crate::dialogs::confirm(&mut app, dialog).unwrap();
|
||||
let LayerContent::Shape(sh) = &app.session.active().unwrap().doc.layer(id).unwrap().content else { panic!() };
|
||||
let committed = sh.stroke.clone().expect("OK turned the stroke on");
|
||||
assert_eq!((previewed.paint, previewed.width), (committed.paint, committed.width), "{stroke}: the preview is what OK commits");
|
||||
assert_eq!(committed.width, 3.0);
|
||||
}
|
||||
}
|
||||
|
||||
/// From the options bar without a selected shape, OK sets the next shape's colour and turns the
|
||||
/// paint on, and edits no document.
|
||||
#[test]
|
||||
|
||||
@@ -148,7 +148,7 @@ fn draw_no_color(ui: &egui::Ui, r: Rect, t: &Tokens) {
|
||||
let p = ui.painter();
|
||||
p.rect_filled(r, 0.0, Color32::WHITE);
|
||||
p.rect_stroke(r, 0.0, Stroke::new(1.0, t.field_border), StrokeKind::Inside);
|
||||
p.line_segment([r.left_bottom() + vec2(1.5, -1.5), r.right_top() + vec2(-1.5, 1.5)], Stroke::new(1.5, Color32::from_rgb(220, 40, 40)));
|
||||
p.line_segment([r.left_bottom() + vec2(1.5, -1.5), r.right_top() + vec2(-1.5, 1.5)], Stroke::new(1.5, t.danger));
|
||||
}
|
||||
|
||||
fn draw_gradient(ui: &egui::Ui, r: Rect, t: &Tokens) {
|
||||
|
||||
@@ -77,7 +77,8 @@ pub(crate) fn swatch(
|
||||
let (r, resp) = ui.allocate_exact_size(vec2(30.0, 22.0), Sense::click());
|
||||
resp.widget_info(|| egui::WidgetInfo::labeled(egui::Role::ColorWell, ui.is_enabled(), tip));
|
||||
let current = fill.and_then(color_of);
|
||||
crate::widgets::checker(ui.painter(), r.shrink(1.0), 4.0);
|
||||
// Clipped to the rounded corners: square checker cells showed white past them (#8741, #3208).
|
||||
crate::widgets::checker_rounded(ui.painter(), r.shrink(1.0), 4.0, t.radius_sm);
|
||||
match (current, fill) {
|
||||
(Some(c), _) => {
|
||||
ui.painter().rect_filled(r.shrink(1.0), t.radius_sm, rgba32(c));
|
||||
|
||||
+1
-1
@@ -254,7 +254,7 @@ Paragraph; the rest open as in-app floating windows.
|
||||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-10-27 | minor | Shape Fill/Stroke popover as Photoshop's (paint types, Color Picker button, Recently Used Colors, swatch folders, with the Gradient tab) and every colour swatch opens the full Color Picker; rows added (partial, done); no percentage changed |
|
||||
| 2026-10-27 | minor | Shape Fill/Stroke popover as Photoshop's (paint types, Color Picker button, Recently Used Colors, swatch folders, with the Gradient tab) and every colour swatch opens the full Color Picker; rows added (partial, done); Recently Used Colors is a new preference, so 12 of 182 do nothing; no percentage changed |
|
||||
| 2026-10-27 | minor | Every preference takes effect: 12 of 181 do nothing, the scorecard's count with integration batch 9 (#9775) on main; new layers go above a group whose lock would refuse them (#4329) |
|
||||
| 2026-10-25 | minor | Every preference takes effect: 12 of 178 do nothing, the scorecard's count (it still said 46 of 149) |
|
||||
| 2026-10-25 | minor | Art History Brush is in the History group of the Y flyout (partial, TOOL-213-20, #1610) |
|
||||
|
||||
Reference in new issue
Block a user