Addresses a batch of issues found during a painting test.
Tools
- Paint bucket used the background color unconditionally. It now picks
FG/BG like the brush does, via a shared Color: [FG][BG] row that every
color-using tool renders (brush, bucket, eyedropper).
- The eyedropper previously inferred its target swatch from
active_color_mode, which was only ever set as a side effect of opening
a color picker — so where a sample landed depended on invisible state.
It now has an explicit toggle, and active_color_mode is gone.
- Effect brushes (dodge/burn, sponge, blur, smudge, clone, heal, pattern)
were stuck on a hardcoded Gaussian dab. Replaced ~20 flat per-tool
fields with a BrushKind -> BrushSlot model: every dab-painting tool now
owns its size/strength/hardness/spacing, its .myb preset, and its FG/BG
choice, and gets the full brush library. base_settings already flowed
into the dab engine independently of blend_mode, so this needed no core
or WGSL changes.
Cursors
- Rebuilt around three kinds instead of "icon = cursor": System (real OS
cursor for Select/Transform), Precise (glyph with a real tip, e.g.
pencil/pipette), and Badge (crosshair marks the click point, glyph sits
to its bottom-right) for icons with no focus point.
- Cursors are now OS-composited via egui::CursorImage rather than painted
into the scene, so they no longer lag the pointer. Glyphs are rasterized
from egui's font atlas using epaint's own placement maths, so they land
where painter.text put them. Drops the SVG cursor rasterization path.
Tablet
- The Wayland backend never handled zwp_tablet_tool_v2 Button events, so
stylus barrel buttons were silently dropped. Both Wayland and X11 now
emit them, with actions bound in Preferences (Pan/Eyedropper/Eraser).
A pan-bound button suppresses the tool the way Alt+drag does, since the
pen tip is still down while panning. Also adds middle-mouse panning.
Timeline
- Raster layers had no opacity control; the slider always drove volume,
which is meaningless on them. The layer row is now three tiers, and each
layer only shows controls that apply to it: Vector/Video get both volume
and opacity (they can hold movie clips with audio), Raster/Text get
opacity, Audio gets volume. Mute/solo are hidden where there's no audio.
- Layer toggles use Lucide icons with tooltips, and gain a visibility
(eye) toggle. LayerProperty::Visible already existed but was only
reachable from the info panel.
- Below 1.5x the layer-header width, the track area is dropped and the
headers take the full pane.
Panes
- Color picker popups closed on any click (including on their own hue
slider) and would not close on a drag — so drawing on the stage left one
open. Shared color_swatch widget closes on a press outside instead.
- Stage header gains undo/redo buttons for tablet use, and taller targets.
- Toolbar is real egui layout (horizontal_wrapped) instead of absolute
rect math, so it scrolls when the pane is too short.
- Tools with no SVG icon use Lucide glyphs instead of a TODO placeholder.