Skip to content

Redesign the View panel and restore drag speed's real meaning: pan sensitivity - #331

Merged
dovvnloading merged 1 commit into
mainfrom
feat/view-popover-redesign
Aug 15, 2026
Merged

Redesign the View panel and restore drag speed's real meaning: pan sensitivity#331
dovvnloading merged 1 commit into
mainfrom
feat/view-popover-redesign

Conversation

@dovvnloading

Copy link
Copy Markdown
Owner

Problem

The View popover was a prototype-level straight port of the three Qt settings islands. Sliders had no labels or value readouts. The font family used a bare operating-system select while the app's own styled dropdown existed for exactly that purpose. The connection toggles sat under GRID only because that is which Qt bridge owned their checkboxes. The colour palettes were frozen verbatim from the deleted Qt code - three of the grid swatches were nearly invisible against the canvas, and two of the four font grays were 19 units apart. Grid spacing had been reduced from the legacy spinbox to four fixed preset buttons, and the server-side handler accepted a spacing of zero, which would have blanked the canvas background.

Separately, the DRAG setting did nothing recognisable. In the legacy app the factor was commented "For controlling pan speed." and multiplied each mouse delta while panning the view - it controlled how fast you move around the graph. The port applied it to node movement instead, so the actual feature did not exist in this codebase.

Change

The panel. Every slider now has a label and a live value readout. Grid spacing has a real slider (4-120px), clamped server-side as well. Grid style and the preset rows are segmented controls. Connection toggles moved to their own CONNECTIONS section, and every toggle carries a one-line description. The font family uses the app's CustomSelect, with a live preview of the resulting node typography rendered on a real card background. Both colour rows gained a free-choice picker - the backend always accepted any colour; only the panel never offered one - plus upgraded palettes: three neutrals and five tuned hues for the grid, three neutrals and four readable tints for node text. The filter section gained "By kind" / "By status" labels, pill-shaped chips visually distinct from the segmented controls, and a Clear button that appears when any filter is active. A footer button resets every setting to its documented default. The Chat Library dialog's workspace tabs and tag chips shared the old chip styling and move to the new one with it.

The pan-speed restoration. React Flow's built-in canvas pan has no speed input, which is presumably why the port substituted node scaling. It is now disabled; the canvas owns the pan gesture and multiplies each pointer delta by the configured factor, exactly as the legacy view did. Node dragging is no longer affected by the setting, matching the original behaviour, and the section is relabelled Navigation / "Canvas pan speed". Box selection with Shift and viewport persistence are unchanged.

Test plan

  • Backend suite passes (2,873 tests), including the palette shape guard updated from an exact-count assertion to the shape contract
  • Full frontend check passes: schema, types, lint (0 errors), 1,928 tests, production build, bundle size
  • Measured: pan tracks the pointer 1:1 at 100% and moves exactly 5px per 100px of mouse travel at 5%; node dragging is unaffected by the setting
  • Confirmed working in the desktop app by the reporter, including slider, presets, and server round-trip of the value

…nsitivity

The View popover was a prototype-level straight port: unlabelled sliders
with no value readouts, a bare OS select for the font family while the
app's own styled dropdown existed for exactly that purpose, connection
toggles filed under GRID because that is which Qt bridge owned their
checkboxes, colour palettes frozen verbatim from the deleted Qt code
(three grid swatches nearly invisible against the canvas, two font grays
19 units apart), and a grid control reduced from the legacy spinbox to
four fixed presets.

The redesign, section by section: every slider now carries a label and a
live value readout; grid spacing gained a real slider (4-120px, clamped
server-side too, where the old handler accepted 0 and would have blanked
the canvas); grid style and the preset rows are segmented controls;
connection toggles moved to their own CONNECTIONS section; every toggle
explains itself with a one-line hint; the font family uses the app's
CustomSelect with a live preview of the resulting node typography on a
real card background; both colour rows gained a free-choice picker (the
backend always accepted any hex - only the UI didn't offer it) and
upgraded palettes; the filter section gained group labels, pill-shaped
chips distinct from the segmented controls, and a Clear button; and a
footer resets everything to the documented defaults. The Chat Library
dialog's workspace tabs and tag chips shared the old chip class and move
to the new one with it.

The panel's DRAG setting is also rewired to what it always meant. In the
legacy app the factor was commented "For controlling pan speed." and
multiplied each mouse delta while panning the view; the port applied it
to node movement instead, so the setting users knew - how fast you move
around the graph - did not exist in this codebase. React Flow's built-in
pan has no speed input, which is presumably why the substitution
happened; it is now disabled and the canvas owns the pan gesture,
applying the factor to every delta exactly as the legacy view did.
Verified: at 100% the viewport tracks the pointer 1:1, at 5% it moves
exactly 5px per 100px of mouse travel, and node dragging is unaffected.
Node-motion scaling is removed along with its now-dead helper; the
section is relabelled Navigation / "Canvas pan speed" so it says what it
does.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@dovvnloading
dovvnloading merged commit 504a8df into main Aug 15, 2026
dovvnloading added a commit that referenced this pull request Aug 15, 2026
…332)

Five issues found reviewing the View panel redesign:

The colour pickers and sliders committed on every change event. A native
colour picker emits changes continuously while the pointer moves inside
it, and each one fired an intent that triggered a full state republish -
so choosing a colour, or dragging any slider, put roughly a hundred round
trips on the wire. Continuous controls now show the in-flight value
immediately and commit the last one after a short pause, the same
debounce posture the canvas already uses for viewport reporting. Pending
state clears whenever a fresh value arrives with nothing in flight, so a
server-side clamp is always what ends up displayed. Discrete controls -
presets, grid style, toggles - stay immediate.

Panning was bound to mouse events only. React Flow's own pan, which #331
disabled so the speed factor could apply, was pointer-based, so touch and
pen users were left unable to pan at all. The handlers are pointer-based
now, including pointercancel, and the pane sets touch-action so the
browser cannot claim a touch drag for scrolling first.

dragStartRef was left as a Map whose values nothing read: it held start
positions only while the drag-speed factor scaled node motion from its
origin, and that factor now applies to panning. It is a Set of the ids
the gesture is carrying, which is all the drag-stop change needs to be
recognised.

ConnectionCanvas set a stroke width before its draw loop that every
iteration immediately overwrote.

The stylesheet described the chip class as the multi-select idiom, then
#331 applied it to the Chat Library's single-select workspace tabs. The
comment now describes what the class is actually for - selections from an
open-ended, data-driven set, carrying no single/multi-select meaning of
its own - as distinct from the segmented control used for short fixed
sets of mutually exclusive choices.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@dovvnloading
dovvnloading deleted the feat/view-popover-redesign branch August 15, 2026 14:41
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