mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-31 13:17:19 -06:00
Merge pull request #4673 from storytold/fix/mixer-color-mode-menu
Color Mixer popover: the Color panel's menu, with its color modes (#4249)
This commit is contained in:
@@ -236,13 +236,18 @@ pub fn panel_menu_items(app: &mut VectorcraftApp, ui: &mut Ui, id: &str) -> bool
|
||||
true
|
||||
}
|
||||
|
||||
/// The ≡ panel-menu button drawn into `rect` (the right end of a panel's title/tab strip).
|
||||
pub fn panel_menu(app: &mut VectorcraftApp, ui: &mut Ui, id: &str, rect: Rect) {
|
||||
/// The ≡ button drawn into `rect` that opens a panel menu.
|
||||
fn menu_button(ui: &mut Ui, id: &str, rect: Rect) -> egui::Response {
|
||||
let t = Tokens::get(ui.ctx());
|
||||
let resp = ui.interact(rect, ui.scope_id().with(("panel-menu", id)), Sense::click());
|
||||
icons::paint(ui, "menu", rect.shrink(1.0), if resp.hovered() { t.text_strong } else { t.text_dim });
|
||||
resp.widget_info(|| egui::WidgetInfo::labeled(egui::Role::Button, ui.is_enabled(), tl!("Panel menu")));
|
||||
let resp = resp.on_hover_text(tl!("Panel menu"));
|
||||
resp.on_hover_text(tl!("Panel menu"))
|
||||
}
|
||||
|
||||
/// The ≡ panel-menu button drawn into `rect` (the right end of a panel's title/tab strip).
|
||||
pub fn panel_menu(app: &mut VectorcraftApp, ui: &mut Ui, id: &str, rect: Rect) {
|
||||
let resp = menu_button(ui, id, rect);
|
||||
egui::Popup::menu(&resp).show(|ui| {
|
||||
crate::widgets::menu_scroll(ui, |ui| {
|
||||
ui.set_min_width(220.0);
|
||||
@@ -431,6 +436,18 @@ fn paint_popover(app: &mut VectorcraftApp, ui: &mut Ui) {
|
||||
set_pstate(ui.ctx(), MIXER, m);
|
||||
}
|
||||
}
|
||||
// The mixer is the Color panel, so its menu comes along: the color modes (Grayscale,
|
||||
// RGB, HSB, CMYK, Web Safe RGB), Invert, Complement and the rest (#4249).
|
||||
if mixer {
|
||||
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
|
||||
let (rect, _) = ui.allocate_exact_size(vec2(18.0, 18.0), Sense::hover());
|
||||
let resp = menu_button(ui, "color-mixer", rect);
|
||||
egui::Popup::menu(&resp).show(|ui| {
|
||||
ui.set_min_width(200.0);
|
||||
color::menu(app, ui);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
crate::widgets::divider(ui);
|
||||
if mixer {
|
||||
|
||||
@@ -322,3 +322,36 @@ fn the_popover_swatch_libraries_button_opens_the_libraries_menu() {
|
||||
let open = crate::panels::library_panel::last_open(&app.ui).map(|o| (o.kind.clone(), o.id.clone()));
|
||||
assert_eq!(open, Some(("swatches".into(), "earth-tones".into())));
|
||||
}
|
||||
|
||||
/// #4249: the Color Mixer a Shift-click on a Fill chip opens has the Color panel's menu, whose
|
||||
/// color modes (Grayscale, RGB, HSB, CMYK, Web Safe RGB) switch the color it shows and edits.
|
||||
#[test]
|
||||
fn the_mixer_popover_has_the_color_panels_menu() {
|
||||
let mut app = app();
|
||||
app.run("shape.rectangle", json!({"x": 10, "y": 10, "width": 50, "height": 50})).unwrap();
|
||||
app.run("paint.setFill", json!({"color": "#ff0000"})).unwrap();
|
||||
let ctx = context();
|
||||
frame(&mut app, &ctx, vec![], Modifiers::NONE, control_bar);
|
||||
let (fill, _) = chips(&ctx);
|
||||
click(&mut app, &ctx, fill.center(), Modifiers::SHIFT, control_bar);
|
||||
let menu = ctx.viewport(|vp| {
|
||||
vp.prev_pass
|
||||
.widgets
|
||||
.layers()
|
||||
.filter(|(l, _)| l.order != egui::Order::Background)
|
||||
.flat_map(|(_, w)| w.iter())
|
||||
.find_map(|w| (w.rect.size() == vec2(18.0, 18.0)).then_some(w.rect))
|
||||
});
|
||||
let menu = menu.expect("the mixer has a panel menu button");
|
||||
click(&mut app, &ctx, menu.center(), Modifiers::NONE, control_bar);
|
||||
let shapes = frame(&mut app, &ctx, vec![], Modifiers::NONE, control_bar);
|
||||
// The fill is RGB, so RGB is checked.
|
||||
assert!(menu_item_rect(&shapes, "✓ RGB").is_some(), "RGB is the checked mode");
|
||||
for mode in ["Grayscale", "HSB", "Web Safe RGB", "Invert", "Complement"] {
|
||||
assert!(menu_item_rect(&shapes, mode).is_some(), "{mode} in the mixer's menu");
|
||||
}
|
||||
let cmyk = menu_item_rect(&shapes, "CMYK").expect("CMYK in the mixer's menu");
|
||||
click(&mut app, &ctx, cmyk.center(), Modifiers::NONE, control_bar);
|
||||
let fill = panels::current_paints(&app).0.color();
|
||||
assert!(matches!(fill, Some(vectorcraft_color::Color::Cmyk { .. })), "the fill is CMYK now: {fill:?}");
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
# UI and interaction parity
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-30 · **Change:** minor (Average & Join with a corner or smooth choice, Cmd+Alt+Shift+J; one row done; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-30 · **Change:** minor (Color Mixer popover: the Color panel's menu with its color modes (#4249); scores unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
|
||||
## Feature submission evidence
|
||||
|
||||
@@ -361,6 +361,7 @@ separate. Scores and hours unchanged. [Behavior and command details](development
|
||||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-10-30 | minor | Color Mixer popover: the Color panel's menu with its color modes (#4249); scores and estimates unchanged |
|
||||
| 2026-10-30 | minor | Object › Path › Average & Join… (`path.averageJoin`, Cmd+Alt+Shift+J) moves two open path ends to their midpoint and joins them there, the joined anchor a corner or a smooth point as its dialog's Points choice asks, in one undo step; one row done; scores and estimates unchanged. |
|
||||
| 2026-10-30 | minor | G12: Preferences audit (#394): 5 options are stored but not acted on (Open Documents As Tabs, Units › East Asian Type, Hyphenation › Default Language, Scratch Disks, Legacy vector clipboard), each waiting on a subsystem; Highlight Alternate Glyphs, Real-time Drawing and the Devices options act; scores and estimates unchanged |
|
||||
| 2026-10-30 | minor | Preferences: the workspace, panels, toolbars and other UI settings are saved within 2 seconds of a change instead of only on quitting, and a window saves only what it changed, merged into the file as another VectorCraft window left it, so a second window closing last no longer puts back the settings it started with (#4625). Tests `prefs::tests` in `apps/vectorcraft`; scores and estimates unchanged |
|
||||
|
||||
Reference in New Issue
Block a user