Skip to content

feat: expand selection editing in the properties pane - #396

Merged
devmobasa merged 13 commits into
mainfrom
feat/properties-panel-actions
Sep 27, 2026
Merged

devmobasa merged 13 commits into
mainfrom
feat/properties-panel-actions

Conversation

@devmobasa

@devmobasa devmobasa commented Sep 27, 2026 •

Copy link
Copy Markdown
Owner

Expand the properties panel with controls for styling and managing selected shapes:

  • Add thickness and opacity sliders, with each drag recorded as one undo step.
  • Give rectangles, ellipses, and polygons separate fill colors and a “no fill” swatch.
  • Add ordering, Duplicate, and Delete buttons.
  • Apply tool presets to selections and save selected styles into preset slots.

Also fix Move to Front, add one-step ordering to the context menu, and hide the tool preview while a canvas click would only dismiss a popup.

Validation: full local CI passed, including all-feature and no-default-feature checks.

While the properties panel or the context menu is open, a press on the
canvas closes it and draws nothing, so the pen's cursor preview promised a
stroke that never came. The preview now waits until the popup is gone.
Frame::move_shape read its target as "insert before the shape at to",
which can never reach the top of the stack: Move to Front left a shape one
below it, and did nothing at all to the shape just beneath the top. The
target is now the index the shape ends at, in the move and in its undo.

The shape context menu gains Move Forward and Move Backward, which step
the selection past its nearest unselected neighbour and move a selected
run as one block. The four ordering entries dim when the selection is
already as far that way as it goes.
The panel gains an actions area under its rows: four ordering buttons
(to back, back one, forward one, to front) and Duplicate and Delete, run
through the same selection edits as the context menu. Buttons that would do
nothing dim: ordering at the end of the stack, Duplicate and Delete for a
locked selection. Duplicating keeps the panel open on the copies, and
deleting closes it with nothing left to show.

The area has a fixed height the layout fits around, so short screens still
fall back to columns or scrolling rows.
The panel gains an Opacity row for every colored shape, stepped in 5%
increments from 5% to 100%; a marker stays at or below 90%, as the marker
tool keeps it. Opacity has its own control now, so an opaque swatch or
color key changes the hue and keeps each shape's opacity, while a
translucent swatch still sets its own. The color picker's OK sets exactly
the color shown, opacity included.

Thickness and Opacity are sliders: pressing the track jumps to the
pointer, the shapes follow the drag live, and the whole drag lands as one
undo entry on release, or when the panel closes mid-drag. The keyboard and
the wheel still step them. The thickness stroke preview gives way to the
slider's filled track. Opacity stays off the toolbar's style pill.
Rectangles, ellipses, and polygons gain an optional fill color. Without
one a fill paints with the border color, as every fill did before, and the
field is written only when set, so sessions read the same either way.
Scaling, grid snapping, and copies carry it along.

The properties panel's Fill switch becomes a swatch row: a leading "no
fill" swatch, then the quick-color palette. A swatch fills the selection
with that color and leaves the border alone; no fill turns the fill off and
keeps its color, so turning it back on restores it. A shape has one
opacity: an opaque fill swatch takes the shape's, and the Opacity row moves
border and fill together. The keyboard and the toolbar pill still toggle
the fill on and off.
The panel's actions area gains a preset row: one chip per preset slot,
showing its color, and a Save button. A chip applies that preset's style to
the selection as one undo entry: its color (a marker keeps its own
translucency unless the preset sets one), its size as a stroke width, fill,
font size, text background, and arrow head. The tool in use stays as it
is; this restyles shapes rather than picking up the preset's tool.

Save arms saving: the next chip clicked stores the style of the first
editable selected shape a tool draws, with that tool, through the same
path as the Save Preset actions, so it is written to the config. Escape
disarms it before it closes the panel. Empty slots dim until saving is
armed, and Save dims for a selection no tool draws, such as text.
Whether the selection can step forward or back scanned the stack from every
selected shape and looked each neighbour up in the selection list, so with a
whole board selected it grew with the cube of the shape count: seconds on a
board of thousands. The properties panel asks twice on every refresh,
slider drags included. It now holds exactly when the lowest selected shape
sits below the highest unselected one (or, backward, the highest selected
above the lowest unselected), which one pass with a hash set finds. The
step itself uses a hash set for membership too.
A slider drag records nothing until its release, then commits one entry
measured from snapshots taken when it began. A keyboard step pressed
mid-drag recorded its own entry first, so the drag's landed on top of it
with a stale "before", and two undos from 3 to 50 to 49 ended at 50
instead of 3. The drag now commits first whenever another edit would
record history: any selection edit, a panel key, a panel click, or an
undo or redo.
Resolves the one conflict in the properties panel control tests: main's
whole-pixel thickness step was tested through the thickness stepper, which
this branch replaced with a slider. The same rounding is now tested through
the keyboard, which still steps thickness.
A preset saved from a rectangle, ellipse, or polygon filled with its own
color kept only whether it was filled and the border color, so applying it
filled the target with the border's color: a red rectangle with a green
fill came back filled red. Presets gain an optional fill_color, written
only when set. Saving from the panel captures it, applying restores it on
selected closed shapes (a preset without one resets a separate fill to
follow the border), and the configurator carries it through when it
rewrites a slot.
The five preset chips and Save shared the button column after the label,
leaving each chip about 38 px for a color dot and a number, which touched
its edges. The presets now take two lines: a label line with a wider Save
at its end, then the slot chips across the panel's full width, with more
space between dot and number.
The Fill row gets a + that opens the color picker for the fill alone.
OK fills the selection with exactly that color, opacity included, as
one undo entry; the border keeps its color.
The first-run quick-access card mentions that Alt+click selects a shape
without switching tools. The guided tour's menus step, now "Menus &
Selection", adds Alt+click, Alt+drag to move or box-select, and the
properties shortcut from the live keymap.
@devmobasa
devmobasa merged commit a43a8ac into main Sep 27, 2026
3 checks passed
@devmobasa
devmobasa deleted the feat/properties-panel-actions branch September 27, 2026 11:03
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.

1 participant