feat(processing): pick the Reference source position on the spectrum - #1
Closed
Limdongcheng wants to merge 9 commits into
Closed
feat(processing): pick the Reference source position on the spectrum#1Limdongcheng wants to merge 9 commits into
Limdongcheng wants to merge 9 commits into
Conversation
|
I have read the CLA Document and I hereby sign the CLA You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot. |
fit_layout translated a card rigidly with its anchored boundary's displacement, so hiding the secondary sidebar teleported every right-anchored card by the full sidebar width even when it was parked mid-board — the user then had to drag it all the way back. CardLayout now keeps the user-intended rectangle (`preferred`) separate from the fitted one: only an edge resting on a boundary follows that boundary (the default top-right docking), a parked card keeps its absolute position and is merely clamped inside the new bounds, and a card that a sidebar pushed aside returns to its place once the boundary recedes. Drag and resize gestures write both rectangles, so drag origins always match what is on screen. A full-render regression test drives sidebars, workspace geometry and the Processing card through a hide/drag sequence; fit-level tests pin the parked-stays-put and displaced-returns semantics.
…ist#72) Task-card rows that expand or reveal content on click (processing step rows, CRAFT signal groups, region rows) rendered as plain text until hovered, so users never discovered they were clickable. The Ribbon already has a clickable visual language — enabled button glyphs carry `Visuals::hyperlink_color` — so a new `ui::affordance` module exposes that colour (`clickable_tint`) plus a `selectable_row` helper that tints a row's leading glyph with it while the label keeps the theme text colour. The three click-to-enter rows now render through the helper; Statistics and Curve Fit cards expose their actions through framed buttons and combo boxes already, so they need no change.
`H` fits the y axis to the data visible in the current x window (the NMR vertical-fit convention — reset_y's window-scoped auto range, not full_y) and `F` fits both axes, both as single undoable viewport steps sharing the double-click reset path. Plain `F` was already bound to ZoomToSelection (board-level frame fit), so the chord is now context-split by a focused handler instead of the dispatch table: with the pointer on a plot's data area it runs the new FitPlotXY, anywhere else it keeps ZoomToSelection. Both fits are registered as CommandId (FitPlotY / FitPlotXY), gated in describe on an active plot, searchable in the palette, and listed in the View menu; invoked without a pointer target they fall back to the active plot. `H` was unbound before. The keyboard shortcut reference (English and Simplified Chinese) now documents the new keys; shortcuts.rs tests moved to a sibling shortcuts_tests.rs to stay under the source-size limit.
Manual picking snapped to the tallest local maximum inside a window fixed at 1.5% of the full x span, regardless of zoom — so next to a strong line, a weak line could never be picked: zooming in sharpened the click but not the window. The apex search window is now derived from a fixed screen radius (12 px) at the current zoom, so zooming in narrows it in step with the click precision; tallest-in-window is kept (over nearest-local-maximum) so zoomed-out clicks land on real peaks instead of the nearest noise wiggle. Shift+click skips the snap and places the mark on the nearest sample — the escape hatch for shoulders. The hover preview resolves through the same path, modifier included. `Trace1d::snap` becomes `snap_within(x, half_width)` + `nearest_sample`, unified under `pick(x, ManualPeakSnap)`; `add_manual_peak` takes the snap explicitly. Range drag-picking (`pick_in_range`) keeps its 3-sigma prominence floor: it is scoped to the dragged window with MAD-based noise, which peaks inflate very little, and the reported failure was click-snap, not range picking. New peaks_tests.rs pins the narrow-window weak-apex pick, the wide-window tallest pick, free placement, and the no-apex fallback. The peak-picking guide (EN + zh-CN) documents the zoom-scaled snap and Shift placement.
) PeakMark stored its x as a finished-spectrum snapshot, so editing a Reference step shifted the whole ppm axis while every existing mark stayed at the old coordinate — visibly detached from its peak. Marks now store the *uncalibrated* position (finished x minus the pipeline's reference offset at pick time) and every reader adds the current offset back through `PeakSet::resolve(offset)`, fed by the new `Dataset::peak_reference_offset_ppm()` (the pipeline's single semantic outlet `chemical_shift_reference_offset_ppm`, previously used only by CRAFT; tables calibrate by zero). This is the lifecycle-copy option: the calibration lives once, in the pipeline, and marks follow any Reference edit — including undo/redo of the processing step — without being rewritten, so no mark-translation action or migration exists. Both write paths (manual picks and detection on the finished trace) subtract the current offset symmetrically; de-duplication compares in uncalibrated space. Persisted mark coordinates change meaning; the format stays v1 with no compatibility reader, per repository policy. `y` deliberately remains a pick-time intensity snapshot: reference edits never change intensities, and refreshing y after re-phasing or normalization is an orthogonal concern. Regression tests: mark → reference edit → resolved ppm follows the shifted trace and its default label; picks on an already-referenced spectrum round-trip through the uncalibrated store.
The Reference step's source position could only be typed as a number, while the value the user wants is "the peak currently sitting there" — a position they can see on the plot but had to read off manually. The step editor gains a "Pick position on spectrum" row (styled with the shared clickable-affordance accent) that arms a one-shot on-plot pick. While armed, hovering the target plot previews the position with a dashed guide line, an apex dot and a ppm readout; the pick reuses the zoom-scaled apex snap manual peak picking uses (Shift = nearest sample), so weak lines are reachable by zooming in first. A click writes the step's at_ppm through the property catalog — one undo step, the same recompute as typing — and prompts for the target position. Esc, collapsing the editor, or switching datasets disarms; the arm state is revalidated per frame like the on-plot phase mode, so a collapsed card never leaves a live click trap. The picked coordinate lives on the finished axis while at_ppm lives on the axis entering the step, so the commit subtracts the calibration applied at or after the step — exposed as AxisPipeline::chemical_shift_offset_from_step_ppm beside the existing whole-pipeline reduction, keeping reference-step semantics in one place. After the edit the picked feature reads exactly target_ppm even when re-picking a step that already carries an offset. The pick handler runs after navigation (wheel/trackpad zoom keep working while aiming) and consumes the pointer over the plot so the click cannot fall through to layout or data gestures. An axis without a 1D trace (a 2D dimension) picks the raw coordinate without snapping. canvas/mod.rs's inline test modules move to a sibling mod_tests.rs, and ui_state.rs's dialog-state cluster to ui_state_dialogs.rs, to stay under the 800-line limit. The Processing manual page (EN + zh-CN) gains a Reference section documenting the workflow.
Limdongcheng
force-pushed
the
feat/reference-pick
branch
from
August 29, 2026 09:02
0f5b8ab to
56abd92
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The Reference step's source position (
at_ppm) could only be typed as a number, while the value the user actually wants is "the peak currently sitting there" — a position they can see on the plot but had to read off manually and re-type.What this adds
The Reference step editor gains a Pick position on spectrum row (rendered with the shared clickable-affordance accent). Clicking it arms a one-shot on-plot pick:
Trace1d::pick), so weak lines are reachable by zooming in first; Shift skips the snap and reads the exact cursor position.at_ppmthrough the property catalog — one undo step, the same recompute as typing — and the status bar prompts for the target position.Design
session.ui.reference_pick, typedDatasetId+StepId) is revalidated every frame and is only valid while the step editor that armed it stays expanded on the active dataset. A collapsed card can never leave a live click trap on the plot.at_ppmlives on the axis entering the step. The commit subtracts the calibration applied at or after the step, exposed asAxisPipeline::chemical_shift_offset_from_step_ppmbeside the existing whole-pipeline reduction so reference-step semantics stay in one place. Re-picking a step that already carries an offset still lands the picked feature exactly ontarget_ppm.CommandId: the row is a panel-local widget interaction parameterized by the step whose editor it sits in — the same catalog exemption the Add-step menu uses. A palette command would have no visible editor context and would arm an invisible mode.Tests
plotx-processing: the from-step offset reduction (enabled/disabled steps, unknown id).plotx-core: arm/resolve/sync lifecycle — expanded-editor gating, toggle disarm, non-Reference steps never resolve.plotx(app): end-to-end commit through the property catalog — offset-aware conversion, one undo step, undo restores the previous value.canvas/mod.rs's inline test modules moved to a siblingmod_tests.rs(unchanged) to keep the file under the 800-line limit.cargo pr-checkpasses. The Processing manual page (EN + zh-CN) gains a Reference section documenting the workflow;npm run buildindocs/passes.Part 6 of the stack, based on
fix/peaks-follow-reference(#6); full chain: #2 → #3 → #4 → #5 → #6 → this PR. Retarget tomainonce the predecessors merge.