Skip to content

UI: one After Effects-style colour picker with a hex field for every colour input - #638

Merged
bflatastic merged 1 commit into
storytold:mainfrom
FrederoxDev:feat/color-hex-input
Oct 10, 2026
Merged

bflatastic merged 1 commit into
storytold:mainfrom
FrederoxDev:feat/color-hex-input

Conversation

@FrederoxDev

@FrederoxDev FrederoxDev commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Every colour input now opens one colour picker, laid out like After Effects' Color Picker, and every one takes a hex code. Three dialogs stored picked colours too dark; they're fixed by the same change.

Before After
colorpicker_before colorpicker_after

Cause: there were two colour inputs. Effect Controls, the Timeline, Properties, Character, the toolbar's Fill / Stroke, Paint and the effect editors (8 sites) used header::color_popup, which wrapped egui's picker: no hex field, and egui's own R/G/B row with its U8 / linear toggle and copy button. Seven other places called egui's colour button directly. Three of them (the 3D light dialog, Essential Graphics and Layer Styles) passed the project's sRGB values to color_edit_button_rgb(a), which reads them as linear. Their swatch showed lighter, and a picked colour was stored darker: mid-grey #808080 became #373737. widgets::srgb_color_button already existed to avoid exactly this (its comment says so), but those three didn't use it.

Fix: a new color_picker.rs has the picker and the colour helpers; widgets re-exports them, so the 8 popup call sites are unchanged.

  • Layout (as in After Effects): a square and a vertical slider for the channel chosen with the H / S / B / R / G / B buttons. R puts blue across and green up the square, and so on; the choice is remembered between pickers. The new colour sits over the original, then the H° S% B% and R G B fields, the # hex field, and OK / Cancel under the square.
  • Hex: accepts #RRGGBB, RRGGBB, #RGB and RGB, and applies as soon as a valid code is typed. Focusing the field selects the code, so typing replaces it.
  • Revert: changes apply as they are made (After Effects with Preview on). Cancel, Escape and clicking the original swatch go back to the colour the picker opened with. Behaviour change: Escape used to close the popup and keep the change.
  • Hue: kept while the colour is grey or black, where RGB has none, so moving off black returns to the chosen hue.
  • Rounding: the fields round as the hex code does (178.5 shows as 179, matching B3), and 360° shows as 0°.
  • One sRGB button: srgb_color_button draws its own swatch and opens the same popup. The 3D light dialog, Essential Graphics, Layer Styles, Composition Settings, the Solid dialog and both Settings colour rows use it, so no egui colour button is left in the UI crate. It reports itself as a colour button to accessibility, as egui's did.
  • Cleanup: viewer::hex_rgb is now the shared parser (it also accepts #RGB). widgets.rs and color_picker.rs are in the i18n scan.

Test: tests/ui_color_hex.rs (8 tests):

  • hex_code_sets_an_effect_colour: types into CC Toner's Midtones in Effect Controls. A full code applies, a partial one doesn't, the short form does.
  • the_dialog_colour_button_stores_srgb: #808080 through the dialogs' button is stored as 128/255.
  • cancel_escape_and_the_original_swatch_restore_the_colour
  • the_hsb_square_slider_and_fields_set_the_colour: includes keeping the hue through black, and typing H/S/B/R values.
  • choosing_r_puts_red_on_the_slider_and_blue_green_on_the_square: checks the axes and that the choice is remembered.
  • the_fields_agree_with_the_hex_code, hex_codes_parse, hsv_round_trips

The layout was checked from headless renders in H and R modes.

Not checked:

  • The darkening bug was found by reading the code, not reproduced in the app. No test drives the 3D light / Essential Graphics / Layer Styles dialogs on main to show it. the_dialog_colour_button_stores_srgb covers the button they use now.
  • No side-by-side render against After Effects. The layout follows a screenshot of After Effects' Color Picker.
  • One untranslated string. The original swatch's tooltip ("Original color: click to go back to it") has no Japanese / Chinese / Ukrainian row yet and falls back to English.
  • Not in this PR: an eyedropper in the picker, the Preview checkbox, and 16 / 32 bpc value ranges (fields are always 0–255).

Gate (Windows, Rust 1.99):

  • cargo fmt --all --check passes.
  • cargo clippy -p effectcraft-ui-egui --all-targets --no-deps -- -D warnings passes.
  • cargo test -p effectcraft-ui-egui --no-fail-fast: 404 passed, 0 failed.
  • Workspace clippy without --no-deps fails in effectcraft-media (convert.rs:157, chunks_exact_to_as_chunks, new in Rust 1.99). That's untouched by this PR and also fails on main.

🤖 Generated with Claude Code

…colour input

Every colour input opens one picker laid out like After Effects' Color
Picker: a square and slider for the channel chosen with H / S / B /
R / G / B, the new colour over the original, HSB and RGB fields, a hex
field (#RRGGBB, RRGGBB, #RGB) and OK / Cancel. Changes apply live;
Cancel, Escape and the original swatch restore the starting colour.

The 3D light dialog, Essential Graphics and Layer Styles passed sRGB
values to egui's color_edit_button_rgb(a), which reads them as linear,
so picked colours were stored darker (#808080 became #373737). They and
the other dialogs now use the shared sRGB colour button.

The picker and colour helpers live in color_picker.rs; widgets
re-exports them.

Tests: ui_color_hex.

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

Copy link
Copy Markdown
Member

Thank you for the After Effects-style colour picker with a hex field, @FrederoxDev! It landed on main through #643, with your commits and authorship intact.

If you're not there yet, come hang out with us on Discord: https://discord.gg/artcraft


Generated by Claude Code

@FrederoxDev
FrederoxDev deleted the feat/color-hex-input branch October 10, 2026 21:03
tylerjenningsw added a commit to tylerjenningsw/effectcraft that referenced this pull request Oct 11, 2026
…ses only the picker (storytold#612)

The stop colour now uses widgets::srgb_color_button, the After Effects-style
picker every colour input opens (storytold#638): hex field, HSB/RGB fields, OK and
Cancel, sRGB as the project stores colours. The stop keeps its alpha.

The dialog Escape handler only stepped aside for egui popups, and this
picker isn't one, so in a modal dialog Escape with the picker open closed
the dialog too. The picker now marks the pass it was open in
(color_picker::open_recently), and the handler leaves Escape to it: Escape
restores the colour the picker opened with and closes only the picker.

Tests: ui_gradient_editor clicks inside the picker's colour field over the
modal editor, types a hex code, closes the picker by clicking outside it
and saves the stop; a new test checks that Escape and the picker's Cancel
restore the stop's colour and keep the editor and its other edits. That
test fails without the Escape change. ui_color_hex still passes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants