Conversation
Most scientific multichannel viewers put channel index 0 at the top of the canvas; phosphor was bottom-up. Add a SweepConfig.channel_order field ("top_down" | "bottom_up") that flips the per-channel Z indices in SweepBuffer._build_multiline_array. Default is "top_down" because that's what users expect; existing callers can pass "bottom_up" to opt back in.
set_channel_order() lets the host swap orientation at runtime; marks the column range dirty so the next frame rebuilds with the new layout.
…lors The bright CHANNEL_COLORS palette is hard on the eyes when many channels are visible at once; the 1.5-thickness lines compound it. Switch the SweepWidget default to a lower-saturation palette (SOFT_CHANNEL_COLORS) and DEFAULT_LINE_THICKNESS = 0.8. SweepConfig grows a `colors` field (None → soft default; pass constants.CHANNEL_COLORS for the legacy bright look) and a `line_thickness` field. Both are configurable so callers who liked the old look can opt back in.
The previous _zoom_amplitude scaled the camera's Y axis, which also rescaled the channel-row offsets — channels visibly drifted apart or collapsed together as the user adjusted amplitude. Replace with a per-row amplitude multiplier baked into SweepBuffer's data construction: out_y = (data * y_scale - ch_mid) * amplitude_scale + ch_mid Where ch_mid is the per-channel midpoint of the visible window's range. Subtracting it before the multiply means each channel scales around its own visual center rather than around y=0, so DC bias doesn't translate the line as amplitude grows. ChannelPlotWidget._zoom_amplitude routes to buffer.set_amplitude_scale when the buffer exposes it; other buffers (scatter, spectrum) keep the legacy camera-scale path.
When a host app provides its own controls widget (incoming), the plot's own mouse handlers (wheel-scroll for channel/zoom, hover tooltip) become redundant and sometimes interfere. Expose set_mouse_enabled(False) so hosts can detach them while keeping keyboard shortcuts active.
… shortcuts Embeddable Qt toolbar exposing the keyboard shortcuts already defined on ChannelPlotWidget (channel scroll/page, n_visible halve/double + spinbox, amplitude zoom, time zoom for sweep/spectrum, autoscale toggle). Tight default styling so it doesn't dominate the canvas. Useful for hosts who prefer click-driven UI over memorized keys. Periodically re-syncs widget state from the buffer so external mutations (keyboard, programmatic) keep the toolbar accurate.
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
Five targeted improvements to
SweepWidget/ChannelPlotWidgetdriven by real usage in theintent-toolsviewer apps. Each is a small, opt-in change with sensible defaults; no breaking changes to existing callers beyond the default-look adjustments noted below.What changed
1. Top-down channel order (
SweepBuffer,SweepConfig)SweepConfig.channel_order: "top_down" | "bottom_up". Default flipped to"top_down"— channel 0 at the top of the canvas, growing downward, which matches what most scientific multichannel viewers do. Existing callers can opt back in withchannel_order="bottom_up".SweepBuffer.set_channel_order()lets the host swap orientation at runtime without rebuilding the widget.2. Softer default palette and thinner default line
SweepWidgetnow usesSOFT_CHANNEL_COLORS(lower-saturation 10-color palette) andDEFAULT_LINE_THICKNESS = 0.8(down from 1.5). Way easier on the eyes when many channels are on screen.SweepConfiggrows two configurable fields:colors: list | None— passphosphor.constants.CHANNEL_COLORSfor the legacy bright palette;None(default) uses the new soft palette.line_thickness: float— defaults toDEFAULT_LINE_THICKNESS.3. Per-row amplitude zoom (real fix for
_zoom_amplitude)The previous
_zoom_amplitudescaled the camera's Y axis, which also scaled the channel-row offsets — channels visibly drifted apart or collapsed together as the user adjusted amplitude. Confusing and wrong.Replaced with a per-row amplitude multiplier baked into
SweepBuffer's data construction:ch_midis the per-channel midpoint of the visible window's range, recomputed on every full rebuild. Subtracting it before the multiply means each channel scales around its own visual center, so DC bias doesn't translate the line as amplitude grows.SweepConfig.amplitude_scalesets the initial multiplier;SweepBuffer.set_amplitude_scale(scale)is the runtime knob.ChannelPlotWidget._zoom_amplitudenow routes to the buffer when it exposesset_amplitude_scale(sweep) and falls back to the legacy camera scaling for buffers that don't (scatter, spectrum).4.
ChannelPlotWidget.set_mouse_enabled(bool)Detaches/reattaches the wheel-scroll and pointer-move (hover-tooltip) handlers without affecting keyboard shortcuts. For hosts that provide their own controls UI and don't want the plot's own mouse handlers competing.
5. New
ChannelPlotControlsWidgetOptional Qt toolbar that mirrors the keyboard shortcuts already defined on
ChannelPlotWidget: channel scroll up/down, page up/down, n_visible halve/double + spinbox, amplitude zoom in/out, time zoom in/out (only when the underlying widget exposes_time_zoom), and an autoscale toggle.Tight default styling so it doesn't dominate the canvas. A 200 ms timer re-syncs widget state from the buffer so external mutations (keyboard, programmatic) keep the toolbar accurate.
Exported as
phosphor.ChannelPlotControlsWidget.Why this matters
Driven by
intent-tools'intent-timeseriesGUI feedback:Backward compatibility
SweepConfigfields are all keyword-with-default; positional callers unaffected._zoom_amplitudesemantics changed forSweepWidgetonly (now scales waveforms around channel midpoints instead of the camera).ScatterWidgetandSpectrumWidgetkeep the legacy camera-scale behavior because their buffers don't exposeset_amplitude_scale.ChannelPlotControlsWidgetis additive — opt-in.