1313from bec_widgets .utils .bec_connector import ConnectionConfig
1414from bec_widgets .utils .colors import Colors
1515from bec_widgets .utils .error_popups import SafeProperty , SafeSlot
16+ from bec_widgets .widgets .progress .progress_backend import (
17+ BECProgressTracker ,
18+ ProgressSnapshot ,
19+ ProgressSource ,
20+ )
1621
1722logger = bec_logger .logger
1823if TYPE_CHECKING :
@@ -81,6 +86,8 @@ def __init__(self, parent: RingProgressContainerWidget | None = None, client=Non
8186 self ._color : QColor = self .convert_color (self .config .color )
8287 self ._background_color : QColor = self .convert_color (self .config .background_color )
8388 self .registered_slot : tuple [Callable , str | EndpointInfo ] | None = None
89+ self .progress_tracker = BECProgressTracker (self .bec_dispatcher , parent = self )
90+ self .progress_tracker .progress_updated .connect (self ._on_progress_snapshot )
8491 self .RID = None
8592 self ._gap = 5
8693 self ._hovered = False
@@ -219,26 +226,18 @@ def set_update(
219226 case "manual" :
220227 if self .config .mode == "manual" :
221228 return
222- if self .registered_slot is not None :
223- self .bec_dispatcher .disconnect_slot (* self .registered_slot )
229+ self ._disconnect_registered_update ()
224230 self .config .mode = "manual"
225- self .registered_slot = None
226231 case "scan" :
227232 if self .config .mode == "scan" :
228233 return
229- if self .registered_slot is not None :
230- self .bec_dispatcher .disconnect_slot (* self .registered_slot )
234+ self ._disconnect_registered_update ()
231235 self .config .mode = "scan"
232- self .bec_dispatcher .connect_slot (
233- self .on_scan_progress , MessageEndpoints .scan_progress ()
234- )
235- self .registered_slot = (self .on_scan_progress , MessageEndpoints .scan_progress ())
236+ self .progress_tracker .start (source = ProgressSource .SCAN_PROGRESS )
236237 case "device" :
237- if self .registered_slot is not None :
238- self .bec_dispatcher .disconnect_slot (* self .registered_slot )
238+ self ._disconnect_registered_update ()
239239 self .config .mode = "device"
240240 if device == "" :
241- self .registered_slot = None
242241 return
243242 self .config .device = device
244243 # self.config.signal = self._get_signal_from_device(device, signal)
@@ -248,6 +247,12 @@ def set_update(
248247 case _:
249248 raise ValueError (f"Unsupported mode: { mode } " )
250249
250+ def _disconnect_registered_update (self ):
251+ if self .registered_slot is not None :
252+ self .bec_dispatcher .disconnect_slot (* self .registered_slot )
253+ self .registered_slot = None
254+ self .progress_tracker .cleanup ()
255+
251256 def set_precision (self , precision : int ):
252257 """
253258 Set the precision for the ring widget.
@@ -362,15 +367,14 @@ def _update_device_connection(self, device: str, signal: str | None) -> str:
362367 return ""
363368
364369 if signal in progress_signals :
365- endpoint = MessageEndpoints .device_progress (device )
366- self .bec_dispatcher .connect_slot (self .on_device_progress , endpoint )
367- self .registered_slot = (self .on_device_progress , endpoint )
370+ self .progress_tracker .start (source = ProgressSource .DEVICE_PROGRESS , device = device )
368371 return signal
369372 if signal in hinted_signals or signal in normal_signals :
370373 endpoint = MessageEndpoints .device_readback (device )
371374 self .bec_dispatcher .connect_slot (self .on_device_readback , endpoint )
372375 self .registered_slot = (self .on_device_readback , endpoint )
373376 return signal
377+ return ""
374378
375379 @SafeSlot (dict , dict )
376380 def on_scan_progress (self , msg , meta ):
@@ -381,11 +385,10 @@ def on_scan_progress(self, msg, meta):
381385 msg(dict): Message with the scan progress
382386 meta(dict): Metadata for the message
383387 """
384- current_RID = meta .get ("RID" , None )
385- if current_RID != self .RID :
386- self .set_min_max_values (0 , msg .get ("max_value" , 100 ))
387- self .set_value (msg .get ("value" , 0 ))
388- self .update ()
388+ if self .progress_tracker .active_rid is None and self .RID is not None :
389+ self .progress_tracker ._active_rid = self .RID
390+ self .progress_tracker ._active_scan_id = self .RID
391+ self .progress_tracker .process_progress_message (ProgressSource .SCAN_PROGRESS , msg , meta )
389392
390393 @SafeSlot (dict , dict )
391394 def on_device_readback (self , msg , meta ):
@@ -418,12 +421,20 @@ def on_device_progress(self, msg, meta):
418421 device = self .config .device
419422 if device is None :
420423 return
421- max_val = msg .get ("max_value" , 100 )
422- self .set_min_max_values (0 , max_val )
423- value = msg .get ("value" , 0 )
424- if msg .get ("done" ):
425- value = max_val
426- self .set_value (value )
424+ self .progress_tracker .process_progress_message (
425+ ProgressSource .DEVICE_PROGRESS , msg , meta , device = device
426+ )
427+
428+ def _on_progress_snapshot (self , snapshot : ProgressSnapshot ):
429+ if snapshot .source == ProgressSource .SCAN_PROGRESS :
430+ if snapshot .is_new_scan :
431+ self .set_min_max_values (0 , snapshot .max_value )
432+ self .RID = snapshot .rid
433+ else :
434+ if self .config .device is None :
435+ return
436+ self .set_min_max_values (0 , snapshot .max_value )
437+ self .set_value (snapshot .value )
427438 self .update ()
428439
429440 def paintEvent (self , event ):
@@ -517,6 +528,7 @@ def cleanup(self):
517528 if self .registered_slot is not None :
518529 self .bec_dispatcher .disconnect_slot (* self .registered_slot )
519530 self .registered_slot = None
531+ self .progress_tracker .cleanup ()
520532
521533 ###############################################
522534 ####### QProperties ###########################
0 commit comments