Skip to content

Commit 8cf1020

Browse files
committed
fyne-ui: waterfall on/off toggle with CGo direct call and config persistence
- C side: - New ui_comm_set_waterfall() in ui_communication.c; set_waterfall command handler delegates to it. Persists enabled state to mercury.ini so the choice survives restarts. - New mercury_ui_set_waterfall() bridge function, exposed to Go via CGo for direct access without the generic command dispatch. - Fixed the set_waterfall handler nesting (was inside the radio config block). - Go side: - engineLink.SetWaterfall() calls the bridge directly (no websocket, no strcmp dispatch). Stub (non-embedded) has a no-op fallback. - Waterfall toggle checkbox in Settings > Waterfall uses the direct CGo path when the embedded engine is active; remote links still fall back to sendWSCommand. - waterfallCard visibility bound to telemetry.Waterfall: when the engine reports waterfall disabled, the spectrum/waterfall card vanishes from the layout; toggling on brings it back.
1 parent 6305461 commit 8cf1020

7 files changed

Lines changed: 65 additions & 0 deletions

File tree

gui_interface/fyne-ui/engine/mercury_bridge.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,8 @@ int mercury_ui_get_input_channel(void)
172172
{
173173
return ui_comm_get_input_channel();
174174
}
175+
176+
void mercury_ui_set_waterfall(bool enabled)
177+
{
178+
ui_comm_set_waterfall(enabled);
179+
}

gui_interface/fyne-ui/engine/mercury_bridge.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ int mercury_ui_get_radio_list(ui_device_t *out, int max,
7676
int *serial_speed);
7777
int mercury_ui_get_input_channel(void);
7878

79+
/* Enable / disable waterfall/spectrum at runtime. Saves to mercury.ini. */
80+
void mercury_ui_set_waterfall(bool enabled);
81+
7982
#ifdef __cplusplus
8083
}
8184
#endif

gui_interface/fyne-ui/link_engine.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,11 @@ func readRadioList() (RadioListEvent, bool) {
255255
}, true
256256
}
257257

258+
func (l *engineLink) SetWaterfall(enabled bool) {
259+
cEn := C.bool(enabled)
260+
C.mercury_ui_set_waterfall(cEn)
261+
}
262+
258263
func (l *engineLink) Close() {}
259264

260265
// statusFromC converts the engine's status struct into the UI's own type. This

gui_interface/fyne-ui/link_engine_stub.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,5 @@ func (l *engineLink) Send(cmd Command) error {
2929
}
3030

3131
func (l *engineLink) Close() {}
32+
33+
func (l *engineLink) SetWaterfall(enabled bool) {}

gui_interface/fyne-ui/main.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ type uiBindings struct {
110110
rxBytesText *canvas.Text
111111
spectrumCanvas *canvas.Raster
112112
waterfallCanvas *canvas.Raster
113+
waterfallCard *widget.Card
113114
}
114115

115116
func parseStatusMessage(payload []byte) (telemetryState, error) {
@@ -565,6 +566,13 @@ func main() {
565566
}
566567
bindings.txGainLabel.SetText(fmt.Sprintf("TX gain: %.1f dB", telemetry.TXGainDB))
567568
bindings.txPeakLabel.SetText(fmt.Sprintf("TX peak: %.1f dBFS", telemetry.TXPeakDBFS))
569+
if bindings.waterfallCard != nil {
570+
if telemetry.Waterfall {
571+
bindings.waterfallCard.Show()
572+
} else {
573+
bindings.waterfallCard.Hide()
574+
}
575+
}
568576
})
569577
}
570578

@@ -907,6 +915,7 @@ func main() {
907915
nil,
908916
waterfallContent,
909917
))
918+
bindings.waterfallCard = spectrumCard
910919

911920
topPanel := container.NewVBox(
912921
container.NewVBox(txCard, telemetryCard),
@@ -1002,6 +1011,24 @@ func main() {
10021011
}
10031012
paletteSelect.SetSelected(lowerToUpper[state.waterfallPalette])
10041013

1014+
enabledCheck := widget.NewCheck("Waterfall enabled", func(on bool) {
1015+
val := "on"
1016+
if !on {
1017+
val = "off"
1018+
}
1019+
if engLink, ok := state.link.(*engineLink); ok {
1020+
engLink.SetWaterfall(on)
1021+
appendLog(fmt.Sprintf("Waterfall turned %s.\n", val))
1022+
return
1023+
}
1024+
if err := sendWSCommand("set_waterfall", val, "", ""); err != nil {
1025+
appendLog(fmt.Sprintf("Failed to toggle waterfall: %v\n", err))
1026+
}
1027+
})
1028+
state.mu.RLock()
1029+
enabledCheck.SetChecked(state.telemetry.Waterfall)
1030+
state.mu.RUnlock()
1031+
10051032
applyBtn := widget.NewButton("Apply", func() {
10061033
sel := paletteSelect.Selected
10071034
if sel == "" {
@@ -1016,6 +1043,8 @@ func main() {
10161043
})
10171044

10181045
content := container.NewVBox(
1046+
enabledCheck,
1047+
widget.NewSeparator(),
10191048
container.NewGridWithColumns(2,
10201049
widget.NewLabel("Color Palette"), paletteSelect,
10211050
),

gui_interface/ui_communication.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,11 @@ int ui_comm_handle_command(ui_ctx_t *ctx, const ws_command_t *cmd)
182182
if (ctx->cfg_path[0] && cfg_write(&ctx->cfg, ctx->cfg_path))
183183
HLOGI(UI_LOG_TAG, "Config saved to %s", ctx->cfg_path);
184184

185+
} else if (strcmp(cmd->command, "set_waterfall") == 0) {
186+
bool enable = (strcmp(cmd->value, "off") != 0);
187+
ui_comm_set_waterfall(enable);
188+
HLOGI(UI_LOG_TAG, "Waterfall %s by UI command", enable ? "enabled" : "disabled");
189+
185190
} else if (strcmp(cmd->command, "set_tx_gain") == 0) {
186191
/* value carries the dB string; clamp to plan range and convert to
187192
* linear before pushing to the modulator. Persist to INI so the
@@ -205,6 +210,18 @@ int ui_comm_handle_command(ui_ctx_t *ctx, const ws_command_t *cmd)
205210
return 0;
206211
}
207212

213+
void ui_comm_set_waterfall(bool enabled)
214+
{
215+
ui_ctx_t *ctx = g_ui_ctx;
216+
if (!ctx)
217+
return;
218+
modem_set_spectrum_enabled(enabled);
219+
ctx->waterfall_enabled = enabled;
220+
ctx->cfg.waterfall_enabled = enabled;
221+
if (ctx->cfg_path[0] && cfg_write(&ctx->cfg, ctx->cfg_path))
222+
HLOGI(UI_LOG_TAG, "Config saved to %s", ctx->cfg_path);
223+
}
224+
208225
// ---------------- UI PUBLISHER THREAD ----------------
209226
// Periodically gathers modem/ARQ/network status and sends it to the UI.
210227

gui_interface/ui_communication.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@ int ui_comm_handle_command(ui_ctx_t *ctx, const ws_command_t *cmd);
127127
int ui_comm_command(const char *command, const char *value,
128128
const char *value2, const char *value3);
129129

130+
/* Enable / disable the waterfall/spectrum FFT pipeline at runtime. Saves the
131+
* choice to mercury.ini so it survives restarts. */
132+
void ui_comm_set_waterfall(bool enabled);
133+
130134
/* Copy the most recent status snapshot. False until the first publish. */
131135
bool ui_comm_get_status(ui_status_t *out);
132136

0 commit comments

Comments
 (0)