diff --git a/apps/studio/src/orisys_studio/ui/force_plots.py b/apps/studio/src/orisys_studio/ui/force_plots.py index 2b4c7a7..ec8e651 100644 --- a/apps/studio/src/orisys_studio/ui/force_plots.py +++ b/apps/studio/src/orisys_studio/ui/force_plots.py @@ -1027,11 +1027,23 @@ class ForcePlotsPanel(QFrame): for cursor in self.cursors: cursor.setMovable(bool(browsing)) - def _on_cursor_dragged(self) -> None: - """The shared cursor is a timeline control while browsing.""" + def _on_cursor_dragged(self, cursor=None) -> None: + """The shared cursor is a timeline control while browsing. + + Each subplot carries its own copy of the same cursor and any of them can be + dragged, so the signal names the one that moved. Reading ``cursors[0]`` instead + made only the first subplot work: dragging FX or FY re-read FN's already-current + value, judged it unchanged and returned, leaving the other two subplots behind. + """ if self._syncing or self._mode != "browse": return - value = float(self.cursors[0].value()) + # ``sigPositionChanged`` emits the line that moved; ``sender()`` covers a + # pyqtgraph that emits no argument. A direct call with neither falls back to the + # first subplot, which is the only cursor a caller could mean. + line = cursor if cursor is not None else self.sender() + if line is None: + line = self.cursors[0] + value = float(line.value()) if value == self._cursor_t: return self.pause_playback() diff --git a/apps/studio/tests/test_ui_smoke.py b/apps/studio/tests/test_ui_smoke.py index b63aae4..6016f23 100644 --- a/apps/studio/tests/test_ui_smoke.py +++ b/apps/studio/tests/test_ui_smoke.py @@ -1452,6 +1452,21 @@ def test_the_charts_zoom_and_pan_in_every_view(make_window): QApplication.processEvents() assert [round(cursor.value(), 2) for cursor in panel.cursors] == [1.25] * 3 assert moved and moved[-1] == 1.25, "the cursor drag did not notify the replay" + + # Every subplot carries the same cursor, so every one of them is the control. + # Dragging FX or FY used to re-read FN's already-current value, judge it unchanged and + # return — only the first subplot moved the other two. + for index in (1, 2): + moved.clear() + target = round(1.5 + index * 0.1, 2) + panel.cursors[index].setValue(target) + QApplication.processEvents() + assert [round(cursor.value(), 2) for cursor in panel.cursors] == [target] * 3, ( + f"dragging subplot {index}'s cursor did not move the other two" + ) + assert moved and round(moved[-1], 2) == target, ( + f"dragging subplot {index}'s cursor did not notify the replay" + ) _finish(window, stuck)