Skip to content

ESC Polar Display: Add Click-to-Adjust Interaction for Phase and Gain #3091

Description

@k9mq

Request preparation

  • I used an AI assistant to help structure this request
  • I checked for existing issues covering the same feature

What would you like?

ESC Polar Display: Add Click-to-Adjust Interaction for Phase and Gain
What
Add interactive click-to-adjust control within the ESC (Enhanced Signal Clarity) polar display circle, allowing users to set phase and gain by clicking anywhere inside the circular visualization — matching SmartSDR's UX pattern.
Why
Currently, AetherSDR's ESC implementation requires users to adjust phase and gain exclusively via sliders. SmartSDR provides a more intuitive interface where users can click directly on the polar display circle to immediately set both phase and gain coordinates in a single action. This creates a UX inconsistency between AetherSDR and SmartSDR that makes the ESC feature less ergonomic for operators who switch between clients or are familiar with SmartSDR's workflow.
The click-to-adjust pattern is particularly valuable during diversity beamforming operations because:

Faster nulling: Operators can rapidly explore different phase/gain combinations by clicking around the circle rather than dragging two separate sliders
Visual feedback loop: The polar display shows the combined signal's position; clicking on that position or nearby adjusts the settings immediately
Single-action tuning: One click sets both phase and gain simultaneously, reducing the number of UI interactions needed to optimize signal clarity

How Other Clients Do It
SmartSDR for Windows: The ESC polar display is an interactive circular control. Users can:

Click anywhere inside the circle to jump the phase/gain cursor to that position
Drag the cursor around the circle for continuous adjustment
Still use the phase and gain sliders for fine-tuning or numeric precision

The circle translates 2D click coordinates into polar coordinates (angle = phase, radius = gain).
GQRX, SDR++: These clients do not support FlexRadio diversity reception or ESC, so there's no equivalent feature.
Suggested Behavior
Interactive Polar Display Widget
The existing ESC polar display (currently read-only visualization) becomes an interactive QWidget with mouse event handling:
Mouse Click:

Convert click coordinates (x, y) relative to circle center into polar coordinates
Angle (0–360°) maps to phase
Radius (0–1 normalized) maps to gain (0–100%)
Send corresponding slice set diversity_phase= and slice set diversity_gain= commands

Mouse Drag:

Track mouse movement while button is pressed
Continuously update phase/gain as the cursor moves
Provide smooth visual feedback with the cursor following the mouse

Visual Feedback:

Draw a crosshair or dot at the current phase/gain position
Highlight the cursor during drag operations
Optional: show phase/gain values as tooltips during interaction

Slider Integration
The existing phase and gain sliders remain fully functional and bidirectionally synced:

Clicking the circle updates both sliders
Dragging either slider updates the circle cursor position
Use QSignalBlocker or an m_updatingFromCircle guard to prevent feedback loops

UI Location
The interactive polar display sits in the same location where the current ESC visualization appears (likely in a dedicated ESC or Diversity panel alongside the existing sliders).
Protocol Hints
FlexRadio diversity commands (SmartSDR protocol v1.4.0.0):
slice set diversity_phase=<0-360>
slice set diversity_gain=<0-100>
slice set diversity_parent=<parent_slice_id>
The polar display is client-side UI only — the radio doesn't have a concept of "click on circle." The client translates (x, y) → (phase, gain) and sends the appropriate slice set commands.
Status echo from radio:
S|slice diversity_phase= diversity_gain= ...
Coordinate conversion (pseudo-code):
cppQPoint clickPos = event->pos();
QPoint center = rect().center();
QPoint delta = clickPos - center;
double radius = std::sqrt(delta.x() * delta.x() + delta.y() * delta.y());
double maxRadius = rect().width() / 2.0;
double gain = std::clamp(radius / maxRadius, 0.0, 1.0) * 100.0;
double phase = std::atan2(delta.y(), delta.x()) * 180.0 / M_PI;
if (phase < 0) phase += 360.0;
Acceptance Criteria

Clicking anywhere inside the ESC polar display circle sets phase and gain based on click position (angle and radius)
Dragging the mouse inside the circle continuously updates phase and gain in real-time
The polar display cursor (crosshair/dot) visually tracks the current phase/gain setting
Phase and gain sliders remain bidirectionally synchronized with the polar display (no feedback loops)
Mouse events are bounded to the circle area (clicks outside the circle are ignored or clamped to the perimeter)

Suggested labels: enhancement, GUI, protocol

Metadata

Metadata

Assignees

No one assigned

    Labels

    GUIUser interfaceenhancementImprovement to existing featuremaintainer-reviewRequires maintainer review before any action is taken

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions