scope windows: a right-click menu of their own

A scope window is a view with its own arrangement, but its plot had no menu: every right-click
went nowhere, because the main window's row menu acts on the main window's rows.

`on_scope_right_click()` wires each scope window's GL area (beside its drop target) to a menu
that acts on **that window's** row set: y axis auto scale, y axis fixed range (the main menu's
dialog, aimed at the window's rows through `FixedRangeContext::rows`), fit, and one
*Remove '<signal>'* per trace on the plot. A detached window's menu also carries **Attach back
to the main window**. What it deliberately does not carry is an x fit: the window follows the
main window's time span, so an x fit here would be undone by the next frame's mirror.

`remove_trace()` and `FixedRangeContext` are generalized to take the row set they act on (the
main window passes its own). Probe: `[scope-probe] rclick=1` asserts the click gesture is wired
per window; the menu build is exercised by the real right-clicks the smoke makes.
This commit is contained in:
Martino Ferrari committed 2026-11-06 08:55:29 +01:00
1 parent b90a99ec39
commit 2924f7627d
5 files changed
+205 -10

No files matched your search

+7
View File
@@ -1652,6 +1652,9 @@ struct ExportContext {
};
struct FixedRangeContext {
App* app;
/// The row set the range applies to: `nullptr` is the main window's. A scope window's own
/// dialog writes its window's rows.
RowSet* rows = nullptr;
int row;
GtkWidget* lo;
GtkWidget* hi;
@@ -2070,6 +2073,10 @@ gboolean on_scope_drop_channel(GtkDropTarget*, const GValue* value, double x, do
/// drop target both end here). False, with a notice, when the signal cannot be acquired or the plot
/// holds four signals already.
bool assign_signal_to_scope(App& app, App::ScopeWindow& scope, std::size_t signal, int row);
/// The scope window's own right-click menu: the same row menu's actions, aimed at **that
/// window's** row set.
void on_scope_right_click(GtkGestureClick* gesture, int n_press, double x, double y,
gpointer user);
/// Reads each pane's own switch back off the header bar's button, and the other way round: the two are
/// one control in two places, and `panel_switch_sync` keeps the write from looking like a click.
void sync_panel_switches(App& app);