bec-widgets 2.8.3__py3-none-any.whl → 2.8.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
CHANGELOG.md CHANGED
@@ -1,6 +1,15 @@
1
1
  # CHANGELOG
2
2
 
3
3
 
4
+ ## v2.8.4 (2025-05-30)
5
+
6
+ ### Bug Fixes
7
+
8
+ - **crosshair**: Label decimal precision is dynamically scaled with the plot zoom; API of all
9
+ affected widgets adjusted; option added to PlotBase; closes #637
10
+ ([`c8128fa`](https://github.com/bec-project/bec_widgets/commit/c8128faf79c43487921aada9dbf1869ef5bda93c))
11
+
12
+
4
13
  ## v2.8.3 (2025-05-30)
5
14
 
6
15
  ### Bug Fixes
PKG-INFO CHANGED
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bec_widgets
3
- Version: 2.8.3
3
+ Version: 2.8.4
4
4
  Summary: BEC Widgets
5
5
  Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec_widgets/issues
6
6
  Project-URL: Homepage, https://gitlab.psi.ch/bec/bec_widgets
bec_widgets/cli/client.py CHANGED
@@ -1221,6 +1221,20 @@ class Image(RPCBase):
1221
1221
  Set auto range for the y-axis.
1222
1222
  """
1223
1223
 
1224
+ @property
1225
+ @rpc_call
1226
+ def minimal_crosshair_precision(self) -> "int":
1227
+ """
1228
+ Minimum decimal places for crosshair when dynamic precision is enabled.
1229
+ """
1230
+
1231
+ @minimal_crosshair_precision.setter
1232
+ @rpc_call
1233
+ def minimal_crosshair_precision(self) -> "int":
1234
+ """
1235
+ Minimum decimal places for crosshair when dynamic precision is enabled.
1236
+ """
1237
+
1224
1238
  @property
1225
1239
  @rpc_call
1226
1240
  def color_map(self) -> "str":
@@ -2350,6 +2364,20 @@ class MultiWaveform(RPCBase):
2350
2364
  The font size of the legend font.
2351
2365
  """
2352
2366
 
2367
+ @property
2368
+ @rpc_call
2369
+ def minimal_crosshair_precision(self) -> "int":
2370
+ """
2371
+ Minimum decimal places for crosshair when dynamic precision is enabled.
2372
+ """
2373
+
2374
+ @minimal_crosshair_precision.setter
2375
+ @rpc_call
2376
+ def minimal_crosshair_precision(self) -> "int":
2377
+ """
2378
+ Minimum decimal places for crosshair when dynamic precision is enabled.
2379
+ """
2380
+
2353
2381
  @property
2354
2382
  @rpc_call
2355
2383
  def highlighted_index(self):
@@ -3315,6 +3343,20 @@ class ScatterWaveform(RPCBase):
3315
3343
  The font size of the legend font.
3316
3344
  """
3317
3345
 
3346
+ @property
3347
+ @rpc_call
3348
+ def minimal_crosshair_precision(self) -> "int":
3349
+ """
3350
+ Minimum decimal places for crosshair when dynamic precision is enabled.
3351
+ """
3352
+
3353
+ @minimal_crosshair_precision.setter
3354
+ @rpc_call
3355
+ def minimal_crosshair_precision(self) -> "int":
3356
+ """
3357
+ Minimum decimal places for crosshair when dynamic precision is enabled.
3358
+ """
3359
+
3318
3360
  @property
3319
3361
  @rpc_call
3320
3362
  def main_curve(self) -> "ScatterCurve":
@@ -3789,6 +3831,20 @@ class Waveform(RPCBase):
3789
3831
  The font size of the legend font.
3790
3832
  """
3791
3833
 
3834
+ @property
3835
+ @rpc_call
3836
+ def minimal_crosshair_precision(self) -> "int":
3837
+ """
3838
+ Minimum decimal places for crosshair when dynamic precision is enabled.
3839
+ """
3840
+
3841
+ @minimal_crosshair_precision.setter
3842
+ @rpc_call
3843
+ def minimal_crosshair_precision(self) -> "int":
3844
+ """
3845
+ Minimum decimal places for crosshair when dynamic precision is enabled.
3846
+ """
3847
+
3792
3848
  @property
3793
3849
  @rpc_call
3794
3850
  def curves(self) -> "list[Curve]":
@@ -34,13 +34,21 @@ class Crosshair(QObject):
34
34
  coordinatesChanged2D = Signal(tuple)
35
35
  coordinatesClicked2D = Signal(tuple)
36
36
 
37
- def __init__(self, plot_item: pg.PlotItem, precision: int = 3, parent=None):
37
+ def __init__(
38
+ self,
39
+ plot_item: pg.PlotItem,
40
+ precision: int | None = None,
41
+ *,
42
+ min_precision: int = 2,
43
+ parent=None,
44
+ ):
38
45
  """
39
46
  Crosshair for 1D and 2D plots.
40
47
 
41
48
  Args:
42
49
  plot_item (pyqtgraph.PlotItem): The plot item to which the crosshair will be attached.
43
- precision (int, optional): Number of decimal places to round the coordinates to. Defaults to None.
50
+ precision (int | None, optional): Fixed number of decimal places to display. If *None*, precision is chosen dynamically from the current view range.
51
+ min_precision (int, optional): The lower bound (in decimal places) used when dynamic precision is enabled. Defaults to 2.
44
52
  parent (QObject, optional): Parent object for the QObject. Defaults to None.
45
53
  """
46
54
  super().__init__(parent)
@@ -48,7 +56,9 @@ class Crosshair(QObject):
48
56
  self.is_log_x = None
49
57
  self.is_derivative = None
50
58
  self.plot_item = plot_item
51
- self.precision = precision
59
+ self._precision = precision
60
+ self._min_precision = max(0, int(min_precision)) # ensure non‑negative
61
+
52
62
  self.v_line = pg.InfiniteLine(angle=90, movable=False)
53
63
  self.v_line.skip_auto_range = True
54
64
  self.h_line = pg.InfiniteLine(angle=0, movable=False)
@@ -93,6 +103,56 @@ class Crosshair(QObject):
93
103
 
94
104
  self._connect_to_theme_change()
95
105
 
106
+ @property
107
+ def precision(self) -> int | None:
108
+ """Fixed number of decimals; ``None`` enables dynamic mode."""
109
+ return self._precision
110
+
111
+ @precision.setter
112
+ def precision(self, value: int | None):
113
+ """
114
+ Set the fixed number of decimals to display.
115
+
116
+ Args:
117
+ value(int | None): The number of decimals to display. If `None`, dynamic precision is used based on the view range.
118
+ """
119
+ self._precision = value
120
+
121
+ @property
122
+ def min_precision(self) -> int:
123
+ """Lower bound on decimals when dynamic precision is used."""
124
+ return self._min_precision
125
+
126
+ @min_precision.setter
127
+ def min_precision(self, value: int):
128
+ """
129
+ Set the lower bound on decimals when dynamic precision is used.
130
+
131
+ Args:
132
+ value(int): The minimum number of decimals to display. Must be non-negative.
133
+ """
134
+ self._min_precision = max(0, int(value))
135
+
136
+ def _current_precision(self) -> int:
137
+ """
138
+ Get the current precision based on the view range or fixed precision.
139
+ """
140
+ if self._precision is not None:
141
+ return self._precision
142
+
143
+ # Dynamically choose precision from the smaller visible span
144
+ view_range = self.plot_item.vb.viewRange()
145
+ x_span = abs(view_range[0][1] - view_range[0][0])
146
+ y_span = abs(view_range[1][1] - view_range[1][0])
147
+
148
+ # Ignore zero spans that can appear during initialisation
149
+ spans = [s for s in (x_span, y_span) if s > 0]
150
+ span = min(spans) if spans else 1.0
151
+
152
+ exponent = np.floor(np.log10(span)) # order of magnitude
153
+ decimals = max(0, int(-exponent) + 1)
154
+ return max(self._min_precision, decimals)
155
+
96
156
  def _connect_to_theme_change(self):
97
157
  """Connect to the theme change signal."""
98
158
  qapp = QApplication.instance()
@@ -324,6 +384,7 @@ class Crosshair(QObject):
324
384
  # not sure how we got here, but just to be safe...
325
385
  return
326
386
 
387
+ precision = self._current_precision()
327
388
  for item in self.items:
328
389
  if isinstance(item, pg.PlotDataItem):
329
390
  name = item.name() or str(id(item))
@@ -334,8 +395,8 @@ class Crosshair(QObject):
334
395
  x_snapped_scaled, y_snapped_scaled = self.scale_emitted_coordinates(x, y)
335
396
  coordinate_to_emit = (
336
397
  name,
337
- round(x_snapped_scaled, self.precision),
338
- round(y_snapped_scaled, self.precision),
398
+ round(x_snapped_scaled, precision),
399
+ round(y_snapped_scaled, precision),
339
400
  )
340
401
  self.coordinatesChanged1D.emit(coordinate_to_emit)
341
402
  elif isinstance(item, pg.ImageItem):
@@ -380,6 +441,7 @@ class Crosshair(QObject):
380
441
  # not sure how we got here, but just to be safe...
381
442
  return
382
443
 
444
+ precision = self._current_precision()
383
445
  for item in self.items:
384
446
  if isinstance(item, pg.PlotDataItem):
385
447
  name = item.name() or str(id(item))
@@ -391,8 +453,8 @@ class Crosshair(QObject):
391
453
  x_snapped_scaled, y_snapped_scaled = self.scale_emitted_coordinates(x, y)
392
454
  coordinate_to_emit = (
393
455
  name,
394
- round(x_snapped_scaled, self.precision),
395
- round(y_snapped_scaled, self.precision),
456
+ round(x_snapped_scaled, precision),
457
+ round(y_snapped_scaled, precision),
396
458
  )
397
459
  self.coordinatesClicked1D.emit(coordinate_to_emit)
398
460
  elif isinstance(item, pg.ImageItem):
@@ -443,7 +505,8 @@ class Crosshair(QObject):
443
505
  """
444
506
  x, y = pos
445
507
  x_scaled, y_scaled = self.scale_emitted_coordinates(x, y)
446
- text = f"({x_scaled:.{self.precision}g}, {y_scaled:.{self.precision}g})"
508
+ precision = self._current_precision()
509
+ text = f"({x_scaled:.{precision}f}, {y_scaled:.{precision}f})"
447
510
  for item in self.items:
448
511
  if isinstance(item, pg.ImageItem):
449
512
  image = item.image
@@ -452,7 +515,7 @@ class Crosshair(QObject):
452
515
  ix = int(np.clip(x, 0, image.shape[0] - 1))
453
516
  iy = int(np.clip(y, 0, image.shape[1] - 1))
454
517
  intensity = image[ix, iy]
455
- text += f"\nIntensity: {intensity:.{self.precision}g}"
518
+ text += f"\nIntensity: {intensity:.{precision}f}"
456
519
  break
457
520
  # Update coordinate label
458
521
  self.coord_label.setText(text)
@@ -88,6 +88,8 @@ class Image(PlotBase):
88
88
  "auto_range_x.setter",
89
89
  "auto_range_y",
90
90
  "auto_range_y.setter",
91
+ "minimal_crosshair_precision",
92
+ "minimal_crosshair_precision.setter",
91
93
  # ImageView Specific Settings
92
94
  "color_map",
93
95
  "color_map.setter",
@@ -91,6 +91,8 @@ class MultiWaveform(PlotBase):
91
91
  "y_log.setter",
92
92
  "legend_label_size",
93
93
  "legend_label_size.setter",
94
+ "minimal_crosshair_precision",
95
+ "minimal_crosshair_precision.setter",
94
96
  # MultiWaveform Specific RPC Access
95
97
  "highlighted_index",
96
98
  "highlighted_index.setter",
@@ -116,6 +116,7 @@ class PlotBase(BECWidget, QWidget):
116
116
  self._user_y_label = ""
117
117
  self._y_label_suffix = ""
118
118
  self._y_axis_units = ""
119
+ self._minimal_crosshair_precision = 3
119
120
 
120
121
  # Plot Indicator Items
121
122
  self.tick_item = BECTickItem(parent=self, plot_item=self.plot_item)
@@ -978,7 +979,9 @@ class PlotBase(BECWidget, QWidget):
978
979
  def hook_crosshair(self) -> None:
979
980
  """Hook the crosshair to all plots."""
980
981
  if self.crosshair is None:
981
- self.crosshair = Crosshair(self.plot_item, precision=3)
982
+ self.crosshair = Crosshair(
983
+ self.plot_item, min_precision=self._minimal_crosshair_precision
984
+ )
982
985
  self.crosshair.crosshairChanged.connect(self.crosshair_position_changed)
983
986
  self.crosshair.crosshairClicked.connect(self.crosshair_position_clicked)
984
987
  self.crosshair.coordinatesChanged1D.connect(self.crosshair_coordinates_changed)
@@ -1006,6 +1009,29 @@ class PlotBase(BECWidget, QWidget):
1006
1009
 
1007
1010
  self.unhook_crosshair()
1008
1011
 
1012
+ @SafeProperty(
1013
+ int, doc="Minimum decimal places for crosshair when dynamic precision is enabled."
1014
+ )
1015
+ def minimal_crosshair_precision(self) -> int:
1016
+ """
1017
+ Minimum decimal places for crosshair when dynamic precision is enabled.
1018
+ """
1019
+ return self._minimal_crosshair_precision
1020
+
1021
+ @minimal_crosshair_precision.setter
1022
+ def minimal_crosshair_precision(self, value: int):
1023
+ """
1024
+ Set the minimum decimal places for crosshair when dynamic precision is enabled.
1025
+
1026
+ Args:
1027
+ value(int): The minimum decimal places to set.
1028
+ """
1029
+ value_int = max(0, int(value))
1030
+ self._minimal_crosshair_precision = value_int
1031
+ if self.crosshair is not None:
1032
+ self.crosshair.min_precision = value_int
1033
+ self.property_changed.emit("minimal_crosshair_precision", value_int)
1034
+
1009
1035
  @SafeSlot()
1010
1036
  def reset(self) -> None:
1011
1037
  """Reset the plot widget."""
@@ -82,6 +82,8 @@ class ScatterWaveform(PlotBase):
82
82
  "y_log.setter",
83
83
  "legend_label_size",
84
84
  "legend_label_size.setter",
85
+ "minimal_crosshair_precision",
86
+ "minimal_crosshair_precision.setter",
85
87
  # Scatter Waveform Specific RPC Access
86
88
  "main_curve",
87
89
  "color_map",
@@ -60,6 +60,7 @@ class AxisSettings(SettingWidget):
60
60
  self.ui.y_grid,
61
61
  self.ui.inner_axes,
62
62
  self.ui.outer_axes,
63
+ self.ui.minimal_crosshair_precision,
63
64
  ]:
64
65
  WidgetIO.connect_widget_change_signal(widget, self.set_property)
65
66
 
@@ -121,6 +122,7 @@ class AxisSettings(SettingWidget):
121
122
  self.ui.y_max,
122
123
  self.ui.y_log,
123
124
  self.ui.y_grid,
125
+ self.ui.minimal_crosshair_precision,
124
126
  ]:
125
127
  property_name = widget.objectName()
126
128
  value = getattr(self.target_widget, property_name)
@@ -144,6 +146,7 @@ class AxisSettings(SettingWidget):
144
146
  self.ui.y_grid,
145
147
  self.ui.outer_axes,
146
148
  self.ui.inner_axes,
149
+ self.ui.minimal_crosshair_precision,
147
150
  ]:
148
151
  property_name = widget.objectName()
149
152
  value = WidgetIO.get_value(widget)
@@ -14,21 +14,78 @@
14
14
  <string>Form</string>
15
15
  </property>
16
16
  <layout class="QGridLayout" name="gridLayout">
17
- <item row="1" column="0">
18
- <widget class="QLabel" name="label">
19
- <property name="text">
20
- <string>Inner Axes</string>
21
- </property>
22
- </widget>
23
- </item>
24
- <item row="1" column="1">
25
- <widget class="ToggleSwitch" name="inner_axes"/>
26
- </item>
27
- <item row="1" column="2">
28
- <widget class="QLabel" name="label_outer_axes">
29
- <property name="text">
30
- <string>Outer Axes</string>
17
+ <item row="2" column="2" colspan="2">
18
+ <widget class="QGroupBox" name="y_axis_box">
19
+ <property name="title">
20
+ <string>Y Axis</string>
31
21
  </property>
22
+ <layout class="QGridLayout" name="gridLayout_5">
23
+ <item row="1" column="0" colspan="2">
24
+ <widget class="QLabel" name="y_min_label">
25
+ <property name="text">
26
+ <string>Min</string>
27
+ </property>
28
+ </widget>
29
+ </item>
30
+ <item row="0" column="2">
31
+ <widget class="QLineEdit" name="y_label"/>
32
+ </item>
33
+ <item row="3" column="0">
34
+ <widget class="QLabel" name="y_scale_label">
35
+ <property name="text">
36
+ <string>Log</string>
37
+ </property>
38
+ </widget>
39
+ </item>
40
+ <item row="0" column="0">
41
+ <widget class="QLabel" name="y_label_label">
42
+ <property name="text">
43
+ <string>Label</string>
44
+ </property>
45
+ </widget>
46
+ </item>
47
+ <item row="2" column="0">
48
+ <widget class="QLabel" name="y_max_label">
49
+ <property name="text">
50
+ <string>Max</string>
51
+ </property>
52
+ </widget>
53
+ </item>
54
+ <item row="4" column="0">
55
+ <widget class="QLabel" name="y_grid_label">
56
+ <property name="text">
57
+ <string>Grid</string>
58
+ </property>
59
+ </widget>
60
+ </item>
61
+ <item row="3" column="2">
62
+ <widget class="ToggleSwitch" name="y_log">
63
+ <property name="checked" stdset="0">
64
+ <bool>false</bool>
65
+ </property>
66
+ </widget>
67
+ </item>
68
+ <item row="4" column="2">
69
+ <widget class="ToggleSwitch" name="y_grid">
70
+ <property name="checked" stdset="0">
71
+ <bool>false</bool>
72
+ </property>
73
+ </widget>
74
+ </item>
75
+ <item row="1" column="2">
76
+ <widget class="BECSpinBox" name="y_min">
77
+ <property name="alignment">
78
+ <set>Qt::AlignmentFlag::AlignCenter</set>
79
+ </property>
80
+ <property name="buttonSymbols">
81
+ <enum>QAbstractSpinBox::ButtonSymbols::UpDownArrows</enum>
82
+ </property>
83
+ </widget>
84
+ </item>
85
+ <item row="2" column="2">
86
+ <widget class="BECSpinBox" name="y_max"/>
87
+ </item>
88
+ </layout>
32
89
  </widget>
33
90
  </item>
34
91
  <item row="1" column="3">
@@ -38,6 +95,13 @@
38
95
  </property>
39
96
  </widget>
40
97
  </item>
98
+ <item row="1" column="0">
99
+ <widget class="QLabel" name="label">
100
+ <property name="text">
101
+ <string>Inner Axes</string>
102
+ </property>
103
+ </widget>
104
+ </item>
41
105
  <item row="2" column="0" colspan="2">
42
106
  <widget class="QGroupBox" name="x_axis_box">
43
107
  <property name="title">
@@ -105,80 +169,6 @@
105
169
  </layout>
106
170
  </widget>
107
171
  </item>
108
- <item row="2" column="2" colspan="2">
109
- <widget class="QGroupBox" name="y_axis_box">
110
- <property name="title">
111
- <string>Y Axis</string>
112
- </property>
113
- <layout class="QGridLayout" name="gridLayout_5">
114
- <item row="1" column="0" colspan="2">
115
- <widget class="QLabel" name="y_min_label">
116
- <property name="text">
117
- <string>Min</string>
118
- </property>
119
- </widget>
120
- </item>
121
- <item row="0" column="2">
122
- <widget class="QLineEdit" name="y_label"/>
123
- </item>
124
- <item row="3" column="0">
125
- <widget class="QLabel" name="y_scale_label">
126
- <property name="text">
127
- <string>Log</string>
128
- </property>
129
- </widget>
130
- </item>
131
- <item row="0" column="0">
132
- <widget class="QLabel" name="y_label_label">
133
- <property name="text">
134
- <string>Label</string>
135
- </property>
136
- </widget>
137
- </item>
138
- <item row="2" column="0">
139
- <widget class="QLabel" name="y_max_label">
140
- <property name="text">
141
- <string>Max</string>
142
- </property>
143
- </widget>
144
- </item>
145
- <item row="4" column="0">
146
- <widget class="QLabel" name="y_grid_label">
147
- <property name="text">
148
- <string>Grid</string>
149
- </property>
150
- </widget>
151
- </item>
152
- <item row="3" column="2">
153
- <widget class="ToggleSwitch" name="y_log">
154
- <property name="checked" stdset="0">
155
- <bool>false</bool>
156
- </property>
157
- </widget>
158
- </item>
159
- <item row="4" column="2">
160
- <widget class="ToggleSwitch" name="y_grid">
161
- <property name="checked" stdset="0">
162
- <bool>false</bool>
163
- </property>
164
- </widget>
165
- </item>
166
- <item row="1" column="2">
167
- <widget class="BECSpinBox" name="y_min">
168
- <property name="alignment">
169
- <set>Qt::AlignmentFlag::AlignCenter</set>
170
- </property>
171
- <property name="buttonSymbols">
172
- <enum>QAbstractSpinBox::ButtonSymbols::UpDownArrows</enum>
173
- </property>
174
- </widget>
175
- </item>
176
- <item row="2" column="2">
177
- <widget class="BECSpinBox" name="y_max"/>
178
- </item>
179
- </layout>
180
- </widget>
181
- </item>
182
172
  <item row="0" column="0" colspan="4">
183
173
  <layout class="QHBoxLayout" name="horizontalLayout">
184
174
  <item>
@@ -191,8 +181,41 @@
191
181
  <item>
192
182
  <widget class="QLineEdit" name="title"/>
193
183
  </item>
184
+ <item>
185
+ <widget class="QLabel" name="label_2">
186
+ <property name="text">
187
+ <string>Precision</string>
188
+ </property>
189
+ </widget>
190
+ </item>
191
+ <item>
192
+ <widget class="QSpinBox" name="minimal_crosshair_precision">
193
+ <property name="toolTip">
194
+ <string>Minimal Crosshair Precision</string>
195
+ </property>
196
+ <property name="alignment">
197
+ <set>Qt::AlignmentFlag::AlignCenter</set>
198
+ </property>
199
+ <property name="maximum">
200
+ <number>20</number>
201
+ </property>
202
+ <property name="value">
203
+ <number>3</number>
204
+ </property>
205
+ </widget>
206
+ </item>
194
207
  </layout>
195
208
  </item>
209
+ <item row="1" column="2">
210
+ <widget class="QLabel" name="label_outer_axes">
211
+ <property name="text">
212
+ <string>Outer Axes</string>
213
+ </property>
214
+ </widget>
215
+ </item>
216
+ <item row="1" column="1">
217
+ <widget class="ToggleSwitch" name="inner_axes"/>
218
+ </item>
196
219
  </layout>
197
220
  </widget>
198
221
  <customwidgets>
@@ -6,15 +6,84 @@
6
6
  <rect>
7
7
  <x>0</x>
8
8
  <y>0</y>
9
- <width>241</width>
10
- <height>526</height>
9
+ <width>250</width>
10
+ <height>612</height>
11
11
  </rect>
12
12
  </property>
13
13
  <property name="windowTitle">
14
14
  <string>Form</string>
15
15
  </property>
16
- <layout class="QGridLayout" name="gridLayout">
17
- <item row="4" column="0" colspan="2">
16
+ <layout class="QVBoxLayout" name="verticalLayout">
17
+ <item>
18
+ <widget class="QGroupBox" name="general_box">
19
+ <property name="title">
20
+ <string>General</string>
21
+ </property>
22
+ <layout class="QGridLayout" name="gridLayout_2">
23
+ <item row="4" column="0">
24
+ <widget class="QLabel" name="label_outer_axes">
25
+ <property name="text">
26
+ <string>Outer Axes</string>
27
+ </property>
28
+ </widget>
29
+ </item>
30
+ <item row="4" column="1">
31
+ <widget class="ToggleSwitch" name="outer_axes">
32
+ <property name="checked" stdset="0">
33
+ <bool>false</bool>
34
+ </property>
35
+ </widget>
36
+ </item>
37
+ <item row="1" column="1">
38
+ <widget class="QLineEdit" name="title"/>
39
+ </item>
40
+ <item row="3" column="0">
41
+ <widget class="QLabel" name="label">
42
+ <property name="text">
43
+ <string>Inner Axes</string>
44
+ </property>
45
+ </widget>
46
+ </item>
47
+ <item row="1" column="0">
48
+ <widget class="QLabel" name="plot_title_label">
49
+ <property name="text">
50
+ <string>Plot Title</string>
51
+ </property>
52
+ </widget>
53
+ </item>
54
+ <item row="3" column="1">
55
+ <widget class="ToggleSwitch" name="inner_axes"/>
56
+ </item>
57
+ <item row="2" column="0">
58
+ <widget class="QLabel" name="label_2">
59
+ <property name="toolTip">
60
+ <string>Minimal Crosshair Precision</string>
61
+ </property>
62
+ <property name="text">
63
+ <string>Precision</string>
64
+ </property>
65
+ </widget>
66
+ </item>
67
+ <item row="2" column="1">
68
+ <widget class="QSpinBox" name="minimal_crosshair_precision">
69
+ <property name="toolTip">
70
+ <string>Minimal Crosshair Precision</string>
71
+ </property>
72
+ <property name="alignment">
73
+ <set>Qt::AlignmentFlag::AlignCenter</set>
74
+ </property>
75
+ <property name="maximum">
76
+ <number>20</number>
77
+ </property>
78
+ <property name="value">
79
+ <number>3</number>
80
+ </property>
81
+ </widget>
82
+ </item>
83
+ </layout>
84
+ </widget>
85
+ </item>
86
+ <item>
18
87
  <widget class="QGroupBox" name="x_axis_box">
19
88
  <property name="title">
20
89
  <string>X Axis</string>
@@ -81,28 +150,7 @@
81
150
  </layout>
82
151
  </widget>
83
152
  </item>
84
- <item row="0" column="0" colspan="2">
85
- <layout class="QHBoxLayout" name="horizontalLayout">
86
- <item>
87
- <widget class="QLabel" name="plot_title_label">
88
- <property name="text">
89
- <string>Plot Title</string>
90
- </property>
91
- </widget>
92
- </item>
93
- <item>
94
- <widget class="QLineEdit" name="title"/>
95
- </item>
96
- </layout>
97
- </item>
98
- <item row="2" column="0">
99
- <widget class="QLabel" name="label_outer_axes">
100
- <property name="text">
101
- <string>Outer Axes</string>
102
- </property>
103
- </widget>
104
- </item>
105
- <item row="5" column="0" colspan="2">
153
+ <item>
106
154
  <widget class="QGroupBox" name="y_axis_box">
107
155
  <property name="title">
108
156
  <string>Y Axis</string>
@@ -169,23 +217,6 @@
169
217
  </layout>
170
218
  </widget>
171
219
  </item>
172
- <item row="2" column="1">
173
- <widget class="ToggleSwitch" name="outer_axes">
174
- <property name="checked" stdset="0">
175
- <bool>false</bool>
176
- </property>
177
- </widget>
178
- </item>
179
- <item row="1" column="0">
180
- <widget class="QLabel" name="label">
181
- <property name="text">
182
- <string>Inner Axes</string>
183
- </property>
184
- </widget>
185
- </item>
186
- <item row="1" column="1">
187
- <widget class="ToggleSwitch" name="inner_axes"/>
188
- </item>
189
220
  </layout>
190
221
  </widget>
191
222
  <customwidgets>
@@ -86,6 +86,8 @@ class Waveform(PlotBase):
86
86
  "y_log.setter",
87
87
  "legend_label_size",
88
88
  "legend_label_size.setter",
89
+ "minimal_crosshair_precision",
90
+ "minimal_crosshair_precision.setter",
89
91
  # Waveform Specific RPC Access
90
92
  "curves",
91
93
  "x_mode",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bec_widgets
3
- Version: 2.8.3
3
+ Version: 2.8.4
4
4
  Summary: BEC Widgets
5
5
  Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec_widgets/issues
6
6
  Project-URL: Homepage, https://gitlab.psi.ch/bec/bec_widgets
@@ -2,11 +2,11 @@
2
2
  .gitlab-ci.yml,sha256=1nMYldzVk0tFkBWYTcUjumOrdSADASheWOAc0kOFDYs,9509
3
3
  .pylintrc,sha256=eeY8YwSI74oFfq6IYIbCqnx3Vk8ZncKaatv96n_Y8Rs,18544
4
4
  .readthedocs.yaml,sha256=ivqg3HTaOxNbEW3bzWh9MXAkrekuGoNdj0Mj3SdRYuw,639
5
- CHANGELOG.md,sha256=0WBTTBgn-v4VUYX03djHKwV47IUSHRDcrZreVEpXtxo,289561
5
+ CHANGELOG.md,sha256=zrzPgv4SdkfI87Bynz1AKCww3iy1vOyt7iaEzOy2M4Q,289871
6
6
  LICENSE,sha256=Daeiu871NcAp8uYi4eB_qHgvypG-HX0ioRQyQxFwjeg,1531
7
- PKG-INFO,sha256=m4bfcr8jJsEua1MIwebS06gdMZN4x8PzQ5cRHeWZo7I,1273
7
+ PKG-INFO,sha256=i_3fowZja6vwAtG6rabvccdxkcoUynup_6DHrxGLYuw,1273
8
8
  README.md,sha256=oY5Jc1uXehRASuwUJ0umin2vfkFh7tHF-LLruHTaQx0,3560
9
- pyproject.toml,sha256=K4xA4pMZN1a6gYuOc9qCKFhNfFAROEwAAorG1PDHvPE,2902
9
+ pyproject.toml,sha256=s2v1q74HdC09fmE082F9bwYEDALJFrH_W0PPKu7Ykgo,2902
10
10
  .git_hooks/pre-commit,sha256=n3RofIZHJl8zfJJIUomcMyYGFi_rwq4CC19z0snz3FI,286
11
11
  .github/pull_request_template.md,sha256=F_cJXzooWMFgMGtLK-7KeGcQt0B4AYFse5oN0zQ9p6g,801
12
12
  .github/ISSUE_TEMPLATE/bug_report.yml,sha256=WdRnt7HGxvsIBLzhkaOWNfg8IJQYa_oV9_F08Ym6znQ,1081
@@ -35,7 +35,7 @@ bec_widgets/assets/app_icons/bec_widgets_icon.png,sha256=K8dgGwIjalDh9PRHUsSQBqg
35
35
  bec_widgets/assets/app_icons/ui_loader_tile.png,sha256=qSK3XHqvnAVGV9Q0ulORcGFbXJ9LDq2uz8l9uTtMsNk,1812476
36
36
  bec_widgets/assets/app_icons/widget_launch_tile.png,sha256=bWsICHFfSe9-ESUj3AwlE95dDOea-f6M-s9fBapsxB4,2252911
37
37
  bec_widgets/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
- bec_widgets/cli/client.py,sha256=xbftm0CWcw5EgKlQg1f4jJ5BznXsXh34u-54sjBXW3M,93493
38
+ bec_widgets/cli/client.py,sha256=qtAdEDsNub66VLi0uInX4RUQnSaFW86a-I_0bj4um_A,95077
39
39
  bec_widgets/cli/client_utils.py,sha256=F2hyt--jL53bN8NoWifNUMqwwx5FbpS6I1apERdTRzM,18114
40
40
  bec_widgets/cli/generate_cli.py,sha256=K_wMxo2XBUn92SnY3dSrlyUn8ax6Y20QBGCuP284DsQ,10986
41
41
  bec_widgets/cli/server.py,sha256=h7QyBOOGjyrP_fxJIIOSEMc4E06cLG0JyaofjNV6oCA,5671
@@ -71,7 +71,7 @@ bec_widgets/utils/collapsible_panel_manager.py,sha256=tvv77-9YTfYpsU6M_Le3bHR6wt
71
71
  bec_widgets/utils/colors.py,sha256=4Oms3kcstf7-WddGMB2TZXPqJwFMGVjFyBO8tHZHnxk,18308
72
72
  bec_widgets/utils/compact_popup.py,sha256=xVK_lQqL5Hy1ZnUzHXB8GU-Ru-mXevKcdM8ync3ssiA,10269
73
73
  bec_widgets/utils/container_utils.py,sha256=J8YXombOlAPa3M8NGZdhntp2NirBu4raDEQZOgP4elM,3791
74
- bec_widgets/utils/crosshair.py,sha256=zWz4rkVD_HQYWhYzX8asjjb1z_G0V3QqyrOXx6f4xXI,20106
74
+ bec_widgets/utils/crosshair.py,sha256=UZNM4GQnpYD6arN6CAgM9CTQ4LX6t24NoHozPU244Fc,22310
75
75
  bec_widgets/utils/entry_validator.py,sha256=lwT8HP0RDG1FXENIeZ3IDEF2DQmD8KXGkRxPoMXbryk,1817
76
76
  bec_widgets/utils/error_popups.py,sha256=UBAmD1YlAgKodpihudyf0VWtI59KGFiLgnjiKmKGjgk,13254
77
77
  bec_widgets/utils/expandable_frame.py,sha256=VV4mgwz4lXbO3r-dNCX2QFUguwWCCXSUkXyjDSTJHbU,2345
@@ -257,9 +257,9 @@ bec_widgets/widgets/games/minesweeper.pyproject,sha256=wHrLKY3H8uNiVgb9BIrj4S0Je
257
257
  bec_widgets/widgets/games/minesweeper_plugin.py,sha256=oPEjSTpdIIkvuGThHxhVS8Rp47DWiaXHROtm8NJWYwo,1255
258
258
  bec_widgets/widgets/games/register_minesweeper.py,sha256=8fgMBD3yB-5_eGqhG_qxpj3igXDK9WZfHrdYcA1aqz8,467
259
259
  bec_widgets/widgets/plots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
260
- bec_widgets/widgets/plots/plot_base.py,sha256=l8qzLybw6PEBZI5gRXaLY0AX_v81e50TFxOO1Muh774,34872
260
+ bec_widgets/widgets/plots/plot_base.py,sha256=GETUsx51BE_Tuop8bC-KiFVrkR82TJ5S0cr7siouSWM,35848
261
261
  bec_widgets/widgets/plots/image/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
262
- bec_widgets/widgets/plots/image/image.py,sha256=FA2a583iWkDi_zydw_OYi4NEiGHXtM_O0PxxSmdgUiY,42042
262
+ bec_widgets/widgets/plots/image/image.py,sha256=4PamL6EqwpmLMpSagYsBS7ZpU0fXVlzMg7518Tqo5EI,42127
263
263
  bec_widgets/widgets/plots/image/image.pyproject,sha256=_sRCIu4MNgToaB4D7tUMWq3xKX6T2VoRS3UzGNIseHQ,23
264
264
  bec_widgets/widgets/plots/image/image_item.py,sha256=2bn9H5YLmo7ohQnnf1mLlL24TASnlZNzMvF7buMutmI,8728
265
265
  bec_widgets/widgets/plots/image/image_plugin.py,sha256=R0Hzh2GgYlfZLPZwOMgqLKKIA5DxEnTcSrbI7zTe-tI,1204
@@ -282,7 +282,7 @@ bec_widgets/widgets/plots/motor_map/settings/motor_map_settings.ui,sha256=lEKjDU
282
282
  bec_widgets/widgets/plots/motor_map/toolbar_bundles/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
283
283
  bec_widgets/widgets/plots/motor_map/toolbar_bundles/motor_selection.py,sha256=rho8gUGs7cL0YkVYwFFy2FzquB81g5PljpDizfkDTKI,2714
284
284
  bec_widgets/widgets/plots/multi_waveform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
285
- bec_widgets/widgets/plots/multi_waveform/multi_waveform.py,sha256=vSjjE5TOfvVAIG7qpPr2vBzvvyT9Nr14CvOA6ULN-dI,17536
285
+ bec_widgets/widgets/plots/multi_waveform/multi_waveform.py,sha256=Zwtbv1rgDAbZNtwMM76_KLr0Sy4CyaCegRIsdKWqnHM,17621
286
286
  bec_widgets/widgets/plots/multi_waveform/multi_waveform.pyproject,sha256=DnGmG0HymVvUPLFlOYleIW_pJpDrLIbSne5jrI1Gdfk,32
287
287
  bec_widgets/widgets/plots/multi_waveform/multi_waveform_plugin.py,sha256=pSds2QM6VI5BuCNUIZTzFUd0B0beHBe1dcdBgb1AoGY,1296
288
288
  bec_widgets/widgets/plots/multi_waveform/register_multi_waveform.py,sha256=rP9SfyTwmrX-UXcr6Mk73r8jf8s75-1GX2sNh04QHvU,489
@@ -296,7 +296,7 @@ bec_widgets/widgets/plots/roi/image_roi.py,sha256=HIDlsRJtsZf2Iu09tHQuRXI0jFUiBJ
296
296
  bec_widgets/widgets/plots/scatter_waveform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
297
297
  bec_widgets/widgets/plots/scatter_waveform/register_scatter_waveform.py,sha256=KttVjlAK3PfP9tyMfLnqEm6kphap8NZyqyaRry8oebY,514
298
298
  bec_widgets/widgets/plots/scatter_waveform/scatter_curve.py,sha256=nCyZ_6EunS1m5XkLB-CwfBV9L4IX04D9SpHlHc8zG_I,6763
299
- bec_widgets/widgets/plots/scatter_waveform/scatter_waveform.py,sha256=8d6MF5ud8HzqPGQmYNhWpEp8ac9eDRRM5Z4T5Zq77Fk,19794
299
+ bec_widgets/widgets/plots/scatter_waveform/scatter_waveform.py,sha256=kan90pUjfEeJ4z85ZBWnUfEM9XwV6Ehk4XgSD1jMgD0,19879
300
300
  bec_widgets/widgets/plots/scatter_waveform/scatter_waveform.pyproject,sha256=Z_bnXkjDCBJPBCh1_wX3TyCn75aNBYU8SXxxu6DAj0Q,34
301
301
  bec_widgets/widgets/plots/scatter_waveform/scatter_waveform_plugin.py,sha256=3hpAk08kWSi6eE8NB-_vpHbYjBjGOHiCd42MJzmvFw0,1318
302
302
  bec_widgets/widgets/plots/scatter_waveform/settings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -304,9 +304,9 @@ bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_setting.py,sha
304
304
  bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_settings_horizontal.ui,sha256=UdUbOWRMonvsfXSH-NQenDGh3Of4xcirU4kXMniENgY,5013
305
305
  bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_settings_vertical.ui,sha256=68BUUYkMd6fBQlAcV1Co1FRCSDrJ0m8OAsUj_qxoZqU,7814
306
306
  bec_widgets/widgets/plots/setting_menus/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
307
- bec_widgets/widgets/plots/setting_menus/axis_settings.py,sha256=v-esAvJG8SeVv3hWf5L8jyF03jRjd0WvJ9fzbffHY7s,5233
308
- bec_widgets/widgets/plots/setting_menus/axis_settings_horizontal.ui,sha256=v8jJfPLnhORVfJukhRmygrPobMmJLufA4e3C08QeO-o,9526
309
- bec_widgets/widgets/plots/setting_menus/axis_settings_vertical.ui,sha256=k4vsQgZyKZkK3JiOXaQmvgR3IHy90mb4upGAtIwBOsA,9104
307
+ bec_widgets/widgets/plots/setting_menus/axis_settings.py,sha256=REGperW9vSS_ZtZH_zXhId_t4-qax0dFFbHgK84HX88,5380
308
+ bec_widgets/widgets/plots/setting_menus/axis_settings_horizontal.ui,sha256=rXUyB6ciPtYRWBk9-SJpiBl80akCst3U3Nly3_TZiEg,10632
309
+ bec_widgets/widgets/plots/setting_menus/axis_settings_vertical.ui,sha256=-5SYn_o4-EuhG2zaBFVbB5lWs2CpWzB2cYaWXuw-rns,11017
310
310
  bec_widgets/widgets/plots/toolbar_bundles/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
311
311
  bec_widgets/widgets/plots/toolbar_bundles/mouse_interactions.py,sha256=gdQ6Ggdq0rhELncCCUBXwi_k16xXWAgHOtgNmND58cA,4169
312
312
  bec_widgets/widgets/plots/toolbar_bundles/plot_export.py,sha256=43JnNwmp0lAVvSArZ0qa8SWwEAHwrZWBUse0nhlqMkA,3049
@@ -315,7 +315,7 @@ bec_widgets/widgets/plots/toolbar_bundles/save_state.py,sha256=H3fu-bRzNIycCUFb2
315
315
  bec_widgets/widgets/plots/waveform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
316
316
  bec_widgets/widgets/plots/waveform/curve.py,sha256=KlcGbd60lPO9BYcca08fMhWkfx5qu4O9IbSNTwvajGM,10401
317
317
  bec_widgets/widgets/plots/waveform/register_waveform.py,sha256=pdcLCYKkLkSb-5DqbJdC6M3JyoXQBRVAKf7BZVCto80,467
318
- bec_widgets/widgets/plots/waveform/waveform.py,sha256=tNoeqcPPv0nsJT87qSwJFv2jGATvRayxQQjAoaaLKmQ,68552
318
+ bec_widgets/widgets/plots/waveform/waveform.py,sha256=g4aAaeRgvOrwMW6Ju1cx-OKc0lXqN21Xo0rxbAcGBgk,68637
319
319
  bec_widgets/widgets/plots/waveform/waveform.pyproject,sha256=X2T6d4JGt9YSI28e-myjXh1YkUM4Yr3kNb0-F84KvUA,26
320
320
  bec_widgets/widgets/plots/waveform/waveform_plugin.py,sha256=2AZPtBHs75l9cdhwQnY3jpIMRPUUqK3RNvQbTvrFyvg,1237
321
321
  bec_widgets/widgets/plots/waveform/settings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -404,8 +404,8 @@ bec_widgets/widgets/utility/visual/dark_mode_button/dark_mode_button.py,sha256=O
404
404
  bec_widgets/widgets/utility/visual/dark_mode_button/dark_mode_button.pyproject,sha256=Lbi9zb6HNlIq14k6hlzR-oz6PIFShBuF7QxE6d87d64,34
405
405
  bec_widgets/widgets/utility/visual/dark_mode_button/dark_mode_button_plugin.py,sha256=CzChz2SSETYsR8-36meqWnsXCT-FIy_J_xeU5coWDY8,1350
406
406
  bec_widgets/widgets/utility/visual/dark_mode_button/register_dark_mode_button.py,sha256=rMpZ1CaoucwobgPj1FuKTnt07W82bV1GaSYdoqcdMb8,521
407
- bec_widgets-2.8.3.dist-info/METADATA,sha256=m4bfcr8jJsEua1MIwebS06gdMZN4x8PzQ5cRHeWZo7I,1273
408
- bec_widgets-2.8.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
409
- bec_widgets-2.8.3.dist-info/entry_points.txt,sha256=dItMzmwA1wizJ1Itx15qnfJ0ZzKVYFLVJ1voxT7K7D4,214
410
- bec_widgets-2.8.3.dist-info/licenses/LICENSE,sha256=Daeiu871NcAp8uYi4eB_qHgvypG-HX0ioRQyQxFwjeg,1531
411
- bec_widgets-2.8.3.dist-info/RECORD,,
407
+ bec_widgets-2.8.4.dist-info/METADATA,sha256=i_3fowZja6vwAtG6rabvccdxkcoUynup_6DHrxGLYuw,1273
408
+ bec_widgets-2.8.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
409
+ bec_widgets-2.8.4.dist-info/entry_points.txt,sha256=dItMzmwA1wizJ1Itx15qnfJ0ZzKVYFLVJ1voxT7K7D4,214
410
+ bec_widgets-2.8.4.dist-info/licenses/LICENSE,sha256=Daeiu871NcAp8uYi4eB_qHgvypG-HX0ioRQyQxFwjeg,1531
411
+ bec_widgets-2.8.4.dist-info/RECORD,,
pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "bec_widgets"
7
- version = "2.8.3"
7
+ version = "2.8.4"
8
8
  description = "BEC Widgets"
9
9
  requires-python = ">=3.10"
10
10
  classifiers = [