Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion bec_widgets/utils/compact_popup.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import time
from types import SimpleNamespace
from typing import Literal

from bec_qthemes import material_icon
from qtpy.QtCore import Property, Qt, Signal
Expand Down Expand Up @@ -39,7 +40,7 @@ def __init__(self, parent=None):
self.setState("default")
self.setFixedSize(20, 20)

def setState(self, state: str):
def setState(self, state: Literal["success", "default", "warning", "emergency"]):
match state:
case "success":
r, g, b, a = self.palette.success.getRgb()
Expand Down
10 changes: 10 additions & 0 deletions bec_widgets/widgets/containers/dock/dock_area.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
from bec_widgets.widgets.progress.ring_progress_bar.ring_progress_bar import RingProgressBar
from bec_widgets.widgets.services.bec_queue.bec_queue import BECQueue
from bec_widgets.widgets.services.bec_status_box.bec_status_box import BECStatusBox
from bec_widgets.widgets.services.device_browser.device_browser import DeviceBrowser
from bec_widgets.widgets.utility.logpanel.logpanel import LogPanel
from bec_widgets.widgets.utility.visual.dark_mode_button.dark_mode_button import DarkModeButton

Expand Down Expand Up @@ -185,6 +186,12 @@ def _setup_toolbar(self):
filled=True,
parent=self,
),
"device_browser": MaterialIconAction(
icon_name=DeviceBrowser.ICON_NAME,
tooltip="Add Device Browser",
filled=True,
parent=self,
),
},
),
)
Expand Down Expand Up @@ -312,6 +319,9 @@ def _hook_toolbar(self):
menu_devices.actions["positioner_box"].action.triggered.connect(
lambda: self._create_widget_from_toolbar(widget_name="PositionerBox")
)
menu_devices.actions["device_browser"].action.triggered.connect(
lambda: self._create_widget_from_toolbar(widget_name="DeviceBrowser")
)

# Menu Utils
menu_utils.actions["queue"].action.triggered.connect(
Expand Down
6 changes: 2 additions & 4 deletions bec_widgets/widgets/services/device_browser/device_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,8 @@ def on_device_update(self, action: ConfigAction, content: dict) -> None:
action (str): The action that triggered the event.
content (dict): The content of the config update.
"""
if action in ["add", "remove", "reload"]:
self.devices_changed.emit()
if action in ["update", "reload"]:
self.device_update.emit(action, content)
self.devices_changed.emit()
self.device_update.emit(action, content)

def init_device_list(self):
self.dev_list.clear()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,17 @@
from bec_qthemes import material_icon
from qtpy.QtCore import QMimeData, QSize, Qt, QThreadPool, Signal
from qtpy.QtGui import QDrag
from qtpy.QtWidgets import QApplication, QHBoxLayout, QTabWidget, QToolButton, QVBoxLayout, QWidget
from qtpy.QtWidgets import (
QApplication,
QHBoxLayout,
QLabel,
QTabWidget,
QToolButton,
QVBoxLayout,
QWidget,
)

from bec_widgets.utils.compact_popup import LedLabel
from bec_widgets.utils.error_popups import SafeSlot
from bec_widgets.utils.expandable_frame import ExpandableGroupFrame
from bec_widgets.widgets.services.device_browser.device_item.config_communicator import (
Expand Down Expand Up @@ -56,6 +65,10 @@ def __init__(
self._expanded_first_time = False
self._data = None
self.device = device
self._deleting = False

self._ro_pixmap = material_icon(icon_name="keyboard_off", size=(15, 15))
self._we_pixmap = material_icon(icon_name="keyboard", size=(15, 15))

self._layout = QHBoxLayout()
self._layout.setContentsMargins(0, 0, 0, 0)
Expand All @@ -78,6 +91,7 @@ def __init__(

self.set_layout(self._layout)
self.adjustSize()
self._reload_config()

def _create_title_layout(self, title: str, icon: str):
super()._create_title_layout(title, icon)
Expand All @@ -92,6 +106,11 @@ def _create_title_layout(self, title: str, icon: str):
self._title_layout.insertWidget(self._title_layout.count() - 1, self.delete_button)
self.delete_button.clicked.connect(self._delete_device)

self.enabled_led = LedLabel()
self._title_layout.insertWidget(1, self.enabled_led)
self.readonly_label = QLabel()
self._title_layout.insertWidget(2, self.readonly_label)

@SafeSlot()
def _create_edit_dialog(self):
dialog = DeviceConfigDialog(
Expand All @@ -106,6 +125,7 @@ def _create_edit_dialog(self):

@SafeSlot()
def _delete_device(self):
self._deleting = True
self.expanded = False
deleter = CommunicateConfigAction(self._config_helper, self.device, None, "remove")
deleter.signals.error.connect(self._deletion_error)
Expand Down Expand Up @@ -147,17 +167,23 @@ def set_editable(self, enabled: bool):

@SafeSlot(str, dict)
def config_update(self, action: ConfigAction, content: dict) -> None:
if self.device in content:
if (self.device in content or action == "reload") and not self._deleting:
self._reload_config()

@SafeSlot(popup_error=True)
def _reload_config(self, *_):
self.set_display_config(self.dev[self.device]._config)
# Guard in case we attempt to reload config while a device is being removed/readded
if (dev := self.dev.get(self.device)) is not None:
self.set_display_config(dev._config)

def set_display_config(self, config_dict: dict):
"""Set the displayed information from a device config dict, which must conform to the
bec_lib.atlas_models.Device config model."""
self._data = DeviceConfigModel.model_validate(config_dict)
self.enabled_led.setState("success" if self._data.enabled else "emergency")
self.enabled_led.setToolTip("enabled" if self._data.enabled else "disabled")
self.readonly_label.setPixmap(self._ro_pixmap if self._data.readOnly else self._we_pixmap)
self.readonly_label.setToolTip("read only" if self._data.readOnly else "writing enabled")
if self._expanded_first_time:
self.form.set_data(self._data)

Expand Down
Loading