From 74af6b8b53199034c6feb00dfe28c9f0644c34fd Mon Sep 17 00:00:00 2001 From: Robert0Mart Date: Mon, 7 Sep 2026 14:09:59 +0100 Subject: [PATCH] feat: separated utilities ui into pages --- BlocksScreen/lib/panels/mainWindow.py | 2 +- BlocksScreen/lib/panels/utilitiesTab.py | 1062 ++---- .../widgets/UtilitiesTab/InputShaPage.py | 567 +++ .../widgets/UtilitiesTab/axisMaintPage.py | 215 ++ .../panels/widgets/UtilitiesTab/infoPage.py | 123 + .../widgets/UtilitiesTab/inputshaperPage.py | 450 --- .../panels/widgets/UtilitiesTab/ledsPage.py | 364 ++ .../widgets/UtilitiesTab/routinePage.py | 494 +++ .../widgets/UtilitiesTab/troubleshootPage.py | 70 +- BlocksScreen/lib/ui/utilitiesStackedWidget.ui | 3072 ----------------- .../lib/ui/utilitiesStackedWidget_ui.py | 1282 ------- 11 files changed, 2135 insertions(+), 5566 deletions(-) create mode 100644 BlocksScreen/lib/panels/widgets/UtilitiesTab/InputShaPage.py create mode 100644 BlocksScreen/lib/panels/widgets/UtilitiesTab/axisMaintPage.py create mode 100644 BlocksScreen/lib/panels/widgets/UtilitiesTab/infoPage.py delete mode 100644 BlocksScreen/lib/panels/widgets/UtilitiesTab/inputshaperPage.py create mode 100644 BlocksScreen/lib/panels/widgets/UtilitiesTab/ledsPage.py create mode 100644 BlocksScreen/lib/panels/widgets/UtilitiesTab/routinePage.py delete mode 100644 BlocksScreen/lib/ui/utilitiesStackedWidget.ui delete mode 100644 BlocksScreen/lib/ui/utilitiesStackedWidget_ui.py diff --git a/BlocksScreen/lib/panels/mainWindow.py b/BlocksScreen/lib/panels/mainWindow.py index 636b52c8..962ab0b9 100644 --- a/BlocksScreen/lib/panels/mainWindow.py +++ b/BlocksScreen/lib/panels/mainWindow.py @@ -587,7 +587,7 @@ def _on_moonraker_connected_post_update(self) -> None: def on_update_available(self, state: bool = False): """Signal render for red dot on utilities tab icon and Update button""" self.main_content_widget.setNotification(3, state) - self.utilitiesPanel.panel.update_btn.setShowNotification(state) + self.utilitiesPanel.up_update_btn.setShowNotification(state) self.repaint() def enable_tab_bar(self) -> bool: diff --git a/BlocksScreen/lib/panels/utilitiesTab.py b/BlocksScreen/lib/panels/utilitiesTab.py index f2c74be4..3b5e9176 100644 --- a/BlocksScreen/lib/panels/utilitiesTab.py +++ b/BlocksScreen/lib/panels/utilitiesTab.py @@ -1,724 +1,338 @@ -import re -import typing -from dataclasses import dataclass -from enum import Enum, auto -from functools import partial - -from lib.moonrakerComm import MoonWebSocket -from lib.panels.widgets.Common.basePopup import BasePopup -from lib.panels.widgets.UtilitiesTab.inputshaperPage import InputShaperPage -from lib.panels.widgets.Common.optionCardWidget import OptionCard -from lib.panels.widgets.UtilitiesTab.troubleshootPage import TroubleshootPage -from lib.printer import Printer -from lib.ui.utilitiesStackedWidget_ui import Ui_utilitiesStackedWidget -from lib.utils.blocks_button import BlocksCustomButton -from lib.utils.toggleAnimatedButton import ToggleAnimatedButton -from PyQt6 import QtCore, QtGui, QtWidgets - - -@dataclass -class LedState: - """Represents the state of an LED light.""" - - led_type: str - red: int = 0 - green: int = 0 - blue: int = 0 - white: int = 255 - state: str = "on" - - def get_gcode(self, name: str) -> str: - """Generates the G-code command for the current state.""" - if self.state == "off": - return f"SET_LED LED={name} RED=0 GREEN=0 BLUE=0 WHITE=0" - if self.led_type == "white": - return f"SET_LED LED={name} WHITE={self.white / 255:.2f}" - # Default to RGB - return ( - f"SET_LED LED={name} RED={self.red / 255:.2f} " - f"GREEN={self.green / 255:.2f} BLUE={self.blue / 255:.2f} " - f"WHITE={self.white / 255:.2f}" - ) - - -class Process(Enum): - FAN = auto() - AXIS = auto() - BED_HEATER = auto() - EXTRUDER = auto() - AXIS_MAINTENANCE = auto() - - -class UtilitiesTab(QtWidgets.QStackedWidget): - _LED_TYPES: frozenset[str] = frozenset({"led", "neopixel", "dotstar"}) - - request_back: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( - name="request-back" - ) - request_change_page: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( - int, int, name="request-change-page" - ) - request_available_objects_signal: typing.ClassVar[QtCore.pyqtSignal] = ( - QtCore.pyqtSignal(name="get-available-objects") - ) - run_gcode_signal: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( - str, name="run-gcode" - ) - request_numpad_signal: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( - int, - str, - str, - "PyQt_PyObject", - QtWidgets.QStackedWidget, - name="request-numpad", - ) - subscribe_config: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( - [list, "PyQt_PyObject"], - [str, "PyQt_PyObject"], - name="on-subscribe-config", - ) - on_update_message: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( - dict, name="handle-update-message" - ) - - update_available: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( - bool, name="update-available" - ) - - show_update_page: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( - bool, name="show-update-page" - ) - call_load_panel = QtCore.pyqtSignal(bool, str, bool, name="call-load-panel") - - def __init__( - self, parent: QtWidgets.QWidget, ws: MoonWebSocket, printer: Printer - ) -> None: - super().__init__(parent) - - self.panel = Ui_utilitiesStackedWidget() - self.panel.setupUi(self) - - self.ws = ws - self.printer: Printer = printer - self.troubleshoot_page: TroubleshootPage = TroubleshootPage(self) - - # --- State Variables --- - self.objects: dict = { - "fans": {}, - "axis": {"x": "indf", "y": "indf", "z": "indf"}, - "bheat": {"Bed_Heater": "indf"}, - "extrude": {"extruder": "indf"}, - "leds": {}, - } - self.x_inputshaper: dict = {} - self.stepper_limits: dict = {} - - self.current_object: typing.Optional[str] = None - self.current_process: typing.Optional[Process] = None - self.axis_in: str = "x" - self.amount: int = 1 - self.tb: bool = False - self.cg = None - self.aut: bool = False - - self._is_timeout_timer: QtCore.QTimer = QtCore.QTimer(self) - self._is_timeout_timer.setSingleShot(True) - self._is_timeout_timer.setInterval(300_000) # 5 min: longest plausible IS run - self._is_timeout_timer.timeout.connect(self._on_is_timeout) - - # --- PixMap --- - self._led_pixmap = QtGui.QPixmap(":/ui/media/btn_icons/LEDs.svg") - # --- UI Setup --- - self.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.panel.update_btn.clicked.connect( - lambda: self.show_update_page[bool].emit(False) - ) - - self.is_page = InputShaperPage(self) - self.is_page.call_load_panel.connect(self.call_load_panel) - self.addWidget(self.is_page) - - self.dialog_page = BasePopup(self, dialog=True, floating=True) - self.addWidget(self.dialog_page) - - # --- Back Buttons --- - for button in ( - self.panel.leds_back_btn, - self.panel.info_back_btn, - self.panel.leds_slider_back_btn, - self.panel.input_shaper_back_btn, - self.panel.routine_check_back_btn, - self.is_page.update_back_btn, - ): - button.clicked.connect(self.back_button) - - # --- Page Navigation --- - self._connect_page_change(self.panel.utilities_axes_btn, self.panel.axes_page) - self._connect_page_change( - self.panel.utilities_input_shaper_btn, self.panel.input_shaper_page - ) - self._connect_page_change(self.panel.utilities_info_btn, self.panel.info_page) - self._connect_page_change( - self.panel.utilities_routine_check_btn, self.panel.routines_page - ) - self._connect_page_change(self.panel.am_cancel, self.panel.utilities_page) - - self._connect_page_change(self.panel.axes_back_btn, self.panel.utilities_page) - self._connect_page_change( - self.troubleshoot_page.tb_back_btn, self.panel.utilities_page - ) - - # --- Routines --- - self.panel.rc_fans.clicked.connect(partial(self.run_routine, Process.FAN)) - self.panel.rc_bheat.clicked.connect( - partial(self.run_routine, Process.BED_HEATER) - ) - self.panel.rc_ext.clicked.connect(partial(self.run_routine, Process.EXTRUDER)) - self.panel.rc_axis.clicked.connect(partial(self.run_routine, Process.AXIS)) - self.panel.rc_no.clicked.connect(self.on_routine_answer) - self.panel.rc_yes.clicked.connect(self.on_routine_answer) - - # --- Axis Maintenance --- - self.panel.am_execute.clicked.connect(self.axis_maintenance) - self.panel.toggle_led_button.state = ToggleAnimatedButton.State.ON - - # --- LEDs --- - # self.panel.leds_r_slider.sliderReleased.connect(self.update_led_values) - # self.panel.leds_g_slider.sliderReleased.connect(self.update_led_values) - # self.panel.leds_b_slider.sliderReleased.connect(self.update_led_values) - self.panel.leds_w_slider.sliderReleased.connect(self.update_led_values) - self.panel.toggle_led_button.clicked.connect(self.toggle_led_state) - - # --- Websocket/Printer Signals --- - self.run_gcode_signal.connect(self.ws.api.run_gcode) - self.is_page.run_gcode_signal.connect(self.ws.api.run_gcode) - self.subscribe_config[str, "PyQt_PyObject"].connect( - self.printer.on_subscribe_config - ) - self.subscribe_config[list, "PyQt_PyObject"].connect( - self.printer.on_subscribe_config - ) - self.printer.gcode_response.connect(self.handle_gcode_response) - - # --- Initialize Printer Communication --- - self.printer.printer_config.connect(self.on_printer_config_received) - self.printer.gcode_move_update.connect(self.on_gcode_move_update) - - self.panel.update_btn.setPixmap( - QtGui.QPixmap(":/system/media/btn_icons/update-software-icon.svg") - ) - - # ---- Input Shaper ---- - self.automatic_is = OptionCard( - self, - "Automatic\nInput Shaper", - "Automatic Input Shaper", - QtGui.QPixmap(":/input_shaper/media/btn_icons/input_shaper_auto.svg"), - ) # type: ignore - self.automatic_is.setObjectName("Automatic_IS_Card") - self.panel.is_content_layout.addWidget( - self.automatic_is, alignment=QtCore.Qt.AlignmentFlag.AlignHCenter - ) - self.automatic_is.continue_clicked.connect( - lambda: self.handle_is("SHAPER_CALIBRATE") - ) - - self.manual_is = OptionCard( - self, - "Manual\nInput Shaper", - "Manual Input Shaper", - QtGui.QPixmap(":/input_shaper/media/btn_icons/input_shaper_manual.svg"), - ) # type: ignore - self.manual_is.setObjectName("Manual_IS_Card") - self.panel.is_content_layout.addWidget( - self.manual_is, alignment=QtCore.Qt.AlignmentFlag.AlignHCenter - ) - self.manual_is.continue_clicked.connect(lambda: self.handle_is("")) - - self.is_types: dict = {} - self.is_aut_types: dict = {} - self.dialog_page.accepted.connect( - lambda: self.handle_is("SHAPER_CALIBRATE AXIS=Y") - ) - self.dialog_page.rejected.connect( - lambda: self.handle_is("SHAPER_CALIBRATE AXIS=X") - ) - - self.is_page.action_btn.clicked.connect( - lambda: self.change_page(self.indexOf(self.panel.input_shaper_page)) - ) - - def handle_gcode_response(self, data: list[str]) -> None: - """ - Parses a Klipper Input Shaper console message and updates self.is_types. - """ - - if not isinstance(data, list) or len(data) != 1 or not isinstance(data[0], str): - print( - f"WARNING: Invalid input format. Expected a list with one string. Received: {data}" - ) - return - - message = data[0] - - pattern_fitted = re.compile( - r"Fitted shaper '(?P\w+)' frequency = (?P[\d\.]+) Hz \(vibrations = (?P[\d\.]+)%" - ) - match_fitted = pattern_fitted.search(message) - - if match_fitted: - name = match_fitted.group("name") - freq = float(match_fitted.group("freq")) - vib = float(match_fitted.group("vib")) - current_data = self.is_types.get(name, {}) - current_data.update( - { - "frequency": freq, - "vibration": vib, - "max_accel": current_data.get("max_accel", 0.0), - } - ) - self.is_types[name] = current_data - - return - pattern_accel = re.compile( - r"To avoid too much smoothing with '(?P\w+)', suggested max_accel <= (?P[\d\.]+) mm/sec\^2" - ) - match_accel = pattern_accel.search(message) - - if match_accel: - name = match_accel.group("name") - accel = float(match_accel.group("accel")) - - if name in self.is_types and isinstance(self.is_types[name], dict): - self.is_types[name]["max_accel"] = accel - else: - self.is_types[name] = self.is_types.get(name, {}) - self.is_types[name]["max_accel"] = accel - return - - pattern_recommended = re.compile( - r"Recommended shaper_type_(?P[xy]) = (?P\w+), shaper_freq_(?P=axis) = (?P[\d\.]+) Hz" - ) - match_recommended = pattern_recommended.search(message) - if match_recommended: - axis = match_recommended.group("axis") - recommended_type = match_recommended.group("type") - self.is_types["Axis"] = axis - if self.aut: - self.is_aut_types[axis] = recommended_type - if len(self.is_aut_types) == 2: - self.run_gcode_signal.emit("SAVE_CONFIG") - self._is_timeout_timer.stop() - self.call_load_panel.emit(False, "", False) - self.aut = False - return - return - - reordered = {recommended_type: self.is_types[recommended_type]} - for key, value in self.is_types.items(): - if key not in ("suggested_type", recommended_type, "Axis"): - reordered[key] = value - - self.is_page.set_type_dictionary(self.is_types) - first_key = next(iter(reordered.keys()), None) - for key in reordered.keys(): - if key == first_key: - self.is_page.add_type_entry(key, "Recommended type") - else: - self.is_page.add_type_entry(key) - - self.is_page.build_model_list() - self._is_timeout_timer.stop() - self.call_load_panel.emit(False, "", False) - return - - def handle_is(self, gcode: str) -> None: - if gcode == "SHAPER_CALIBRATE": - self.run_gcode_signal.emit("G28\nM400") - self.aut = True - self.run_gcode_signal.emit(gcode) - elif gcode == "": - self.dialog_page.confirm_background_color("#dfdfdf") - self.dialog_page.cancel_background_color("#dfdfdf") - self.dialog_page.cancel_font_color("#000000") - self.dialog_page.confirm_font_color("#000000") - self.dialog_page.cancel_button_text("X axis") - self.dialog_page.confirm_button_text("Y axis") - self.dialog_page.set_message( - "Select the axis you want to execute the input shaper on:" - ) - self.dialog_page.show() - return - else: - self.run_gcode_signal.emit("G28\nM400") - self.run_gcode_signal.emit(gcode) - self.change_page(self.indexOf(self.is_page)) - - self._is_timeout_timer.start() - self.call_load_panel.emit(True, "Running Input Shaper...", False) - - def _on_is_timeout(self) -> None: - self.call_load_panel.emit(False, "", False) - - @QtCore.pyqtSlot(list, name="on_object_list") - def on_object_list(self, object_list: list) -> None: - """Handle receiving printer object list""" - self.cg = object_list - for obj in self.cg: - base_name = obj.split()[0] - - # Only accept 'fan_generic' or 'fan' - if base_name == "fan_generic" or base_name == "fan": - self.objects["fans"][obj.removeprefix(base_name + " ")] = "indef" - self._update_leds_from_config() - - @QtCore.pyqtSlot(dict, name="on_object_config") - @QtCore.pyqtSlot(list, name="on_object_config") - def on_object_config(self, config: typing.Union[dict, list]) -> None: - """Handle receiving printer object configurations""" - if not config: - return - config_items = [config] if isinstance(config, dict) else config - for item in config_items: - for key, value in item.items(): - if ( - key.startswith("stepper_") - and isinstance(value, dict) - and key not in self.stepper_limits - ): - pos_min = value.get("position_min") - pos_max = value.get("position_max") - if pos_min is not None or pos_max is not None: - min_val = ( - float(pos_min) if pos_min is not None else -float("inf") - ) - max_val = ( - float(pos_max) if pos_max is not None else float("inf") - ) - endstop_raw = value.get("position_endstop") - endstop = float(endstop_raw) if endstop_raw is not None else 0.0 - homes_at_min = abs(endstop - min_val) <= abs(endstop - max_val) - self.stepper_limits[key] = { - "min": min_val, - "max": max_val, - "homes_at_min": homes_at_min, - } - - def on_printer_config_received(self, config: dict) -> None: - """Handle printer configuration""" - for axis in ("x", "y", "z"): - self.subscribe_config[str, "PyQt_PyObject"].emit( - f"stepper_{axis}", self.on_object_config - ) - - @QtCore.pyqtSlot(str, list, name="on_gcode_move_update") - def on_gcode_move_update(self, name: str, value: list) -> None: - """Handle gcode move""" - if not value: - return - if name == "gcode_position": - ... - - def run_routine(self, process: Process): - """Run check routine for available processes""" - self.current_process = process - routine_configs = { - Process.FAN: ("fans", "fan is spinning"), - Process.AXIS: ("axis", "axis is moving"), - Process.BED_HEATER: ("bheat", "bed is heating"), - Process.EXTRUDER: ("extrude", "extruder is being tested"), - } - if process not in routine_configs: - return - obj_key, message = routine_configs[process] - obj_list = list(self.objects.get(obj_key, {}).keys()) - if not self._advance_routine_object(obj_list): - if self.tb: - self.troubleshoot_request() - self.tb = False - else: - self.change_page(self.indexOf(self.panel.utilities_page)) - - return - if self.tb: - self.troubleshoot_request() - self.tb = False - self.current_object = None - self.current_process = None - return - message = ( - f"Please check if the {self.current_object}\nis functioning correctly." - ) - if process == Process.AXIS: - message = f"Please ensure the {self.current_object} axis moves correctly." - elif process in [Process.BED_HEATER, Process.EXTRUDER]: - message = "Please check if the temperature reaches 60°C. \n it may take a few moments." - - self.set_routine_check_page( - f"Running routine for: {self.current_object}", message - ) - self.show_waiting_page( - self.indexOf(self.panel.rc_page), - message, - 20000 if process == Process.AXIS else 0, - ) - self._send_routine_gcode() - - def _advance_routine_object(self, obj_list: list) -> bool: - if not obj_list: - is_first_run = self.current_object is None - self.current_object = obj_list[0] if is_first_run and obj_list else "done" - return is_first_run - if self.current_object not in obj_list: - if self.current_process == Process.AXIS: - self.run_gcode_signal.emit("G28") - self.current_object = obj_list[0] - return True - try: - current_index = obj_list.index(self.current_object) - if current_index + 1 < len(obj_list): - self.current_object = obj_list[current_index + 1] - return True - else: - self.current_object = None - return False - except ValueError: - self.current_object = obj_list[0] - return True - - def on_routine_answer(self) -> None: - """Handle routine ongoing process""" - if self.current_process is None or self.current_object is None: - return - if self.sender() == self.panel.rc_yes: - answer = "yes" - else: - answer = "no" - self.tb = True - process_map = { - Process.FAN: ("fans", self.current_object), - Process.AXIS: ("axis", self.current_object), - Process.BED_HEATER: ("bheat", "Bed_Heater"), - Process.EXTRUDER: ("extrude", "extruder"), - } - if self.current_process in process_map: - obj_key, item_key = process_map[self.current_process] - self.objects[obj_key][item_key] = answer - if self.current_process in [Process.BED_HEATER, Process.EXTRUDER]: - self.run_gcode_signal.emit("TURN_OFF_HEATERS") - - if self.current_process == Process.FAN: - self.run_gcode_signal.emit("M107") - for i in self.objects["fans"]: - self.run_gcode_signal.emit( - f"SET_FAN_SPEED FAN={i.removeprefix('fan_generic ')} SPEED=0\nM400" - ) - - self.run_routine(self.current_process) - elif self.current_process == Process.AXIS_MAINTENANCE: - if answer == "yes": - self._run_AXIS_MAINTENANCE_gcode(self.current_object) - else: - self.change_page(self.indexOf(self.panel.axes_page)) - - def _send_routine_gcode(self): - """Send the correct G-code for the current process and object.""" - if self.current_process == Process.FAN: - fan_name = self.current_object or next(iter(self.objects["fans"]), None) - if fan_name: - if fan_name == "fan": - self.run_gcode_signal.emit("M106 S255\nM400") - else: - self.run_gcode_signal.emit( - f"SET_FAN_SPEED FAN={fan_name.removeprefix('fan_generic ')} SPEED=0.8\nM400" - ) - - return - - if self.current_process == Process.AXIS: - if gcode := self._routine_check_axis_gcode(self.current_object): - self.run_gcode_signal.emit(f"{gcode}\nM400") - return - - gcode_map = { - Process.BED_HEATER: "SET_HEATER_TEMPERATURE HEATER=heater_bed TARGET=60", - Process.EXTRUDER: "SET_HEATER_TEMPERATURE HEATER=extruder TARGET=60", - } - - if gcode := gcode_map.get(self.current_process): - self.run_gcode_signal.emit(f"{gcode}\nM400") - - def _routine_check_axis_gcode(self, axis: str, margin: float = 70.0) -> str: - limits = self.stepper_limits.get(f"stepper_{axis}") - if not limits: - return "" - - span = limits["max"] - limits["min"] - if span <= 0: - return "" - - effective_margin = margin - if span - (2 * margin) <= 0: - effective_margin = span * 0.1 - - distance = span - (2 * effective_margin) - if distance <= 0: - return "" - - sign = 1 if limits.get("homes_at_min", True) else -1 - axis_upper = axis.upper() - - out = f"G1 {axis_upper}{sign * distance:.2f} F6000" - back = f"G1 {axis_upper}{-sign * (distance - 10):.2f} F6000" - moves = f"{out}\n{back}" - if axis == "x": - moves += "\nG90\nG1 X250 F6000" - - return f"G91\n{moves}" - - def set_routine_check_page(self, title: str, label: str): - """Set text on routine page""" - self.panel.rc_tittle.setText(title) - self.panel.rc_label.setText(label) - - def update_led_values(self) -> None: - """Update led state and color values""" - if self.current_object not in self.objects["leds"]: - return - led_state: LedState = self.objects["leds"][self.current_object] - led_state.white = int(self.panel.leds_w_slider.value() * 255 / 100) - self.save_led_state() - - def _update_leds_from_config(self): - layout = self.panel.leds_content_layout - - while layout.count(): - if (child := layout.takeAt(0)) and child.widget(): - child.widget().deleteLater() # type: ignore - - led_names = [] - if not self.cg: - return - - # Collect LED names - match Klipper LED hardware types only - for obj in self.cg: - parts = obj.split() - if len(parts) >= 2 and parts[0] in self._LED_TYPES: - name = parts[1] - led_names.append(name) - self.objects["leds"][name] = LedState(led_type="white") - - max_columns = 3 - buttons = [] # store references to created buttons - - # Create LED buttons - for i, name in enumerate(led_names): - if self.panel.leds_widget: - button = BlocksCustomButton() - button.setFixedSize(200, 70) - button.setText(name) - button.setProperty("class", "menu_btn") - button.setPixmap(self._led_pixmap) - row, col = divmod(i, max_columns) - layout.addWidget(button, row, col) - button.clicked.connect(partial(self.handle_led_button, name)) - buttons.append(button) - - try: - self.panel.utilities_leds_btn.clicked.disconnect() - except (RuntimeError, TypeError): - pass - if len(buttons) == 1: - self.panel.utilities_leds_btn.clicked.connect( - partial(self.handle_led_button, led_names[0]) - ) - elif len(buttons) > 1: - self._connect_page_change( - self.panel.utilities_leds_btn, self.panel.leds_page - ) - - def toggle_led_state(self) -> None: - """Toggle leds""" - if self.current_object not in self.objects["leds"]: - return - led_state: LedState = self.objects["leds"][self.current_object] - if led_state.state == "off": - led_state.state = "on" - self.panel.toggle_led_button.state = ToggleAnimatedButton.State.ON - else: - led_state.state = "off" - self.panel.toggle_led_button.state = ToggleAnimatedButton.State.OFF - self.save_led_state() - - def handle_led_button(self, name: str) -> None: - """Handle led button clicked""" - self.current_object = name - led_state: LedState = self.objects["leds"].get(name) - if not led_state: - return - is_rgb = led_state.led_type == "rgb" - self.panel.leds_w_slider.setVisible(not is_rgb) - self.panel.leds_w_slider.setValue(led_state.white) - self.change_page(self.indexOf(self.panel.leds_slider_page)) - - def save_led_state(self): - """Save led state""" - if self.current_object: - if self.current_object in self.objects["leds"]: - led_state: LedState = self.objects["leds"][self.current_object] - self.run_gcode_signal.emit(led_state.get_gcode(self.current_object)) - - def axis_maintenance(self) -> None: - """Routine, checks axis movement for printer debugging""" - self.current_process = Process.AXIS_MAINTENANCE - self.current_object = ( - self.panel.axis_maintenance_gb.checkedButton().text().lower() - ) - self.run_gcode_signal.emit(f"AXIS_MAINTENANCE_{self.current_object}\nM400") - self.set_routine_check_page( - "Axis Maintenance", - f"Insert oil on the {self.current_object.upper()} axis before confirming.", - ) - self.show_waiting_page( - self.indexOf(self.panel.rc_page), - f"Homing {self.current_object.upper()} axis...", - 20000, - ) - - def _run_AXIS_MAINTENANCE_gcode(self, axis: str): - stepper_key = f"stepper_{axis}" - if stepper_key in self.stepper_limits: - self.run_gcode_signal.emit(f"AXIS_MAINTENANCE_FINISH_{axis}\nM400") - self.show_waiting_page( - self.indexOf(self.panel.axes_page), - f"Running maintenance cycle on {axis.upper()} axis...", - 5000, - ) - else: - self.change_page(self.indexOf(self.panel.axes_page)) - - def troubleshoot_request(self) -> None: - """Show troubleshoot page""" - self.troubleshoot_page.show() - - def show_waiting_page(self, page_to_go_to: int, label: str, time_ms: int): - """Show placeholder page""" - self.call_load_panel.emit(True, label, False) - QtCore.QTimer.singleShot(time_ms, lambda: self.change_page(page_to_go_to)) - - def _connect_page_change(self, button: QtWidgets.QWidget, page: QtWidgets.QWidget): - if isinstance(button, QtWidgets.QAbstractButton): - button.clicked.connect(lambda: self.change_page(self.indexOf(page))) - - def change_page(self, index: int): - """Request change page by index""" - self.call_load_panel.emit(False, "", False) - self.troubleshoot_page.hide() - if index < self.count(): - self.request_change_page.emit(3, index) - - @QtCore.pyqtSlot(name="request-back") - def back_button(self) -> None: - """Request back""" - self.request_back.emit() +import typing +from enum import Enum, auto + +from lib.moonrakerComm import MoonWebSocket +from lib.panels.widgets.Common.basePopup import BasePopup +from lib.panels.widgets.UtilitiesTab.axisMaintPage import AxisMaintPage +from lib.panels.widgets.UtilitiesTab.infoPage import InfoPage +from lib.panels.widgets.UtilitiesTab.InputShaPage import InputShaperPage +from lib.panels.widgets.UtilitiesTab.ledsPage import LedsPage +from lib.panels.widgets.UtilitiesTab.routinePage import RoutineCheckPage +from lib.panels.widgets.UtilitiesTab.troubleshootPage import TroubleshootPage +from lib.printer import Printer +from lib.utils.blocks_button import BlocksCustomButton +from PyQt6 import QtCore, QtGui, QtWidgets + + +class Process(Enum): + AXIS = auto() + + +class UtilitiesTab(QtWidgets.QStackedWidget): + request_back: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( + name="request-back" + ) + request_change_page: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( + int, int, name="request-change-page" + ) + request_available_objects_signal: typing.ClassVar[QtCore.pyqtSignal] = ( + QtCore.pyqtSignal(name="get-available-objects") + ) + run_gcode_signal: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( + str, name="run-gcode" + ) + request_numpad_signal: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( + int, + str, + str, + "PyQt_PyObject", + QtWidgets.QStackedWidget, + name="request-numpad", + ) + subscribe_config: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( + [list, "PyQt_PyObject"], + [str, "PyQt_PyObject"], + name="on-subscribe-config", + ) + on_update_message: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( + dict, name="handle-update-message" + ) + + update_available: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( + bool, name="update-available" + ) + + show_update_page: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( + bool, name="show-update-page" + ) + call_load_panel = QtCore.pyqtSignal(bool, str, bool, name="call-load-panel") + + on_object_list = QtCore.pyqtSignal(list, name="on-object-list") + + def __init__( + self, parent: QtWidgets.QWidget, ws: MoonWebSocket, printer: Printer + ) -> None: + super().__init__(parent) + + self.info_page: InfoPage = InfoPage(self) + self.leds_page: LedsPage = LedsPage(self) + self.axes_page: AxisMaintPage = AxisMaintPage(self) + self.routines_page: RoutineCheckPage = RoutineCheckPage(self) + self.troubleshoot_page: TroubleshootPage = TroubleshootPage(self) + + # currently using the logic only so theres no duplicate (logic flag disables render/update Ui) + self.is_page: InputShaperPage = InputShaperPage(self, logic=True) + self.is_page.hide() + + self.setupUi() + + self.ws = ws + self.printer: Printer = printer + + # --- UI Setup --- + self.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) + self.up_update_btn.clicked.connect( + lambda: self.show_update_page[bool].emit(False) + ) + + # --- Page Navigation --- + self.up_input_shaper_btn.clicked.connect(self.ask_input_shaper) + + self.up_leds_btn.clicked.connect( + lambda: self.change_page(self.indexOf(self.leds_page)) + ) + self.up_axes_btn.clicked.connect( + lambda: self.change_page(self.indexOf(self.axes_page)) + ) + self.up_info_btn.clicked.connect( + lambda: self.change_page(self.indexOf(self.info_page)) + ) + self.up_routine_check_btn.clicked.connect( + lambda: self.change_page(self.indexOf(self.routines_page)) + ) + self.axes_page.axes_back_btn.clicked.connect( + lambda: self.change_page(self.indexOf(self.utilitiesPage)) + ) + self.troubleshoot_page.tb_back_btn.clicked.connect( + lambda: self.change_page(self.indexOf(self.utilitiesPage)) + ) + + # --- Info --- + self.info_page.request_back_button.connect(self.request_back) + + # --- LEDs --- + self.leds_page.request_back_button.connect(self.request_back) + self.leds_page.run_gcode_signal.connect(self.run_gcode_signal) + self.on_object_list.connect(self.leds_page.on_object_list) + + # --- Routines --- + self.routines_page.run_gcode_signal.connect(self.run_gcode_signal) + self.routines_page.request_back.connect(self.request_back) + self.routines_page.call_load_panel.connect(self.call_load_panel) + self.routines_page.request_tb_page.connect(self.troubleshoot_request) + self.printer.toolhead_update[str, str].connect( + self.routines_page.on_toolhead_update + ) + self.printer.printer_config.connect( + self.routines_page.on_printer_config_received + ) + self.routines_page.subscribe_config.connect(self.subscribe_config) + self.on_object_list.connect(self.routines_page.on_object_list) + + # --- Axis Maintenance --- + self.axes_page.run_gcode_signal.connect(self.run_gcode_signal) + self.axes_page.call_load_panel.connect(self.call_load_panel) + self.axes_page.request_back.connect(self.request_back) + + # ---- Input Shaper ---- + self.is_popup: BasePopup = BasePopup(self, dialog=True, floating=True) + self.is_popup.set_message( + "Run the automatic input shaper?\n\nThe printer will calibrate both axes." + ) + self.is_popup.confirm_button_text("Yes") + self.is_popup.cancel_button_text("No") + self.is_popup.confirm_button.clicked.connect(self.run_input_shaper) + self.is_page.run_gcode_signal.connect(self.run_gcode_signal) + self.is_page.call_load_panel.connect(self.call_load_panel) + self.printer.gcode_response.connect(self.is_page.handle_gcode_response) + + # --- Websocket/Printer Signals --- + self.run_gcode_signal.connect(self.ws.api.run_gcode) + + self.subscribe_config[str, "PyQt_PyObject"].connect( + self.printer.on_subscribe_config + ) + self.subscribe_config[list, "PyQt_PyObject"].connect( + self.printer.on_subscribe_config + ) + + def ask_input_shaper(self) -> None: + """Ask whether to run the automatic input shaper.""" + self.is_popup.show() + + def run_input_shaper(self) -> None: + """Start the automatic input shaper calibration.""" + self.is_popup.hide() + self.is_page.handle_is("SHAPER_CALIBRATE") + + def troubleshoot_request(self) -> None: + """Show troubleshoot page""" + self.troubleshoot_page.show() + + def change_page(self, index: int): + """Request change page by index""" + self.call_load_panel.emit(False, "", False) + self.troubleshoot_page.hide() + if index < self.count(): + self.request_change_page.emit(3, index) + + @QtCore.pyqtSlot(name="request-back") + def back_button(self) -> None: + """Request back""" + self.request_back.emit() + + def setupUi(self): + + self.setObjectName("utilitiesTab") + + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum + ) + + self.resize(710, 410) + self.setSizePolicy(sizePolicy) + self.setMinimumSize(QtCore.QSize(710, 410)) + self.setMaximumSize(QtCore.QSize(710, 410)) + self.utilitiesPage = QtWidgets.QWidget() + self.utilitiesPage.setObjectName("utilitiesPage") + + self.verticalLayout = QtWidgets.QVBoxLayout(self.utilitiesPage) + self.verticalLayout.setObjectName("verticalLayout") + + self.up_header_layout = QtWidgets.QHBoxLayout() + self.up_header_layout.setObjectName("up_header_layout") + + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum + ) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + + font = QtGui.QFont() + font.setFamily("Momcake") + font.setPointSize(24) + + self.up_title_label = QtWidgets.QLabel(parent=self.utilitiesPage) + self.up_title_label.setSizePolicy(sizePolicy) + self.up_title_label.setMinimumSize(QtCore.QSize(0, 60)) + self.up_title_label.setMaximumSize(QtCore.QSize(16777215, 60)) + self.up_title_label.setFont(font) + self.up_title_label.setStyleSheet("background: transparent; color: white;") + self.up_title_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + self.up_title_label.setObjectName("up_title_label") + self.up_header_layout.addWidget(self.up_title_label) + self.verticalLayout.addLayout(self.up_header_layout) + + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.Expanding, + QtWidgets.QSizePolicy.Policy.Expanding, + ) + + font = QtGui.QFont() + font.setFamily("Momcake") + font.setPointSize(19) + + self.up_content_layout = QtWidgets.QGridLayout() + self.up_content_layout.setObjectName("up_content_layout") + + self.up_info_btn = BlocksCustomButton(parent=self.utilitiesPage) + self.up_info_btn.setSizePolicy(sizePolicy) + self.up_info_btn.setMinimumSize(QtCore.QSize(250, 80)) + self.up_info_btn.setMaximumSize(QtCore.QSize(250, 80)) + self.up_info_btn.setFont(font) + self.up_info_btn.setProperty( + "icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/info.svg") + ) + self.up_info_btn.setObjectName("up_info_btn") + self.up_content_layout.addWidget(self.up_info_btn, 0, 0, 1, 1) + + self.up_leds_btn = BlocksCustomButton(parent=self.utilitiesPage) + self.up_leds_btn.setSizePolicy(sizePolicy) + self.up_leds_btn.setMinimumSize(QtCore.QSize(250, 80)) + self.up_leds_btn.setMaximumSize(QtCore.QSize(250, 80)) + self.up_leds_btn.setFont(font) + self.up_leds_btn.setProperty( + "icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/LEDs.svg") + ) + self.up_leds_btn.setObjectName("up_leds_btn") + self.up_content_layout.addWidget(self.up_leds_btn, 0, 1, 1, 1) + + self.up_routine_check_btn = BlocksCustomButton(parent=self.utilitiesPage) + self.up_routine_check_btn.setSizePolicy(sizePolicy) + self.up_routine_check_btn.setMinimumSize(QtCore.QSize(250, 80)) + self.up_routine_check_btn.setMaximumSize(QtCore.QSize(250, 80)) + self.up_routine_check_btn.setFont(font) + self.up_routine_check_btn.setProperty( + "icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/routine.svg") + ) + self.up_routine_check_btn.setObjectName("up_routine_check_btn") + self.up_content_layout.addWidget(self.up_routine_check_btn, 1, 0, 1, 1) + + self.up_axes_btn = BlocksCustomButton(parent=self.utilitiesPage) + self.up_axes_btn.setSizePolicy(sizePolicy) + self.up_axes_btn.setMinimumSize(QtCore.QSize(250, 80)) + self.up_axes_btn.setMaximumSize(QtCore.QSize(250, 80)) + self.up_axes_btn.setFont(font) + self.up_axes_btn.setProperty( + "icon_pixmap", + QtGui.QPixmap(":/motion/media/btn_icons/axis_maintenance.svg"), + ) + self.up_content_layout.addWidget(self.up_axes_btn, 1, 1, 1, 1) + + self.up_update_btn = BlocksCustomButton(parent=self.utilitiesPage) + self.up_update_btn.setSizePolicy(sizePolicy) + self.up_update_btn.setMinimumSize(QtCore.QSize(250, 80)) + self.up_update_btn.setMaximumSize(QtCore.QSize(250, 80)) + self.up_update_btn.setFont(font) + self.up_update_btn.setPixmap( + QtGui.QPixmap(":/system/media/btn_icons/update-software-icon.svg") + ) + + self.up_update_btn.setObjectName("up_update_btn") + self.up_content_layout.addWidget(self.up_update_btn, 2, 0, 1, 1) + + self.up_input_shaper_btn = BlocksCustomButton(parent=self.utilitiesPage) + self.up_input_shaper_btn.setSizePolicy(sizePolicy) + self.up_input_shaper_btn.setMinimumSize(QtCore.QSize(250, 80)) + self.up_input_shaper_btn.setMaximumSize(QtCore.QSize(250, 80)) + self.up_input_shaper_btn.setFont(font) + self.up_input_shaper_btn.setProperty( + "icon_pixmap", + QtGui.QPixmap(":/input_shaper/media/btn_icons/input_shaper.svg"), + ) + self.up_content_layout.addWidget(self.up_input_shaper_btn, 2, 1, 1, 1) + + self.verticalLayout.addLayout(self.up_content_layout) + self.addWidget(self.utilitiesPage) + + # Info + + self.addWidget(self.info_page) + + # Leds Page + + self.addWidget(self.leds_page) + + # Routine Page + + self.addWidget(self.routines_page) + + # Axis maintenance Page + + self.addWidget(self.axes_page) + + # Input Shaper Page + + # self.addWidget(self.is_page) + + self.setCurrentIndex(0) + + _translate = QtCore.QCoreApplication.translate + + self.up_title_label.setText(_translate("self", "Utilities")) + self.up_info_btn.setText(_translate("self", "Info")) + self.up_leds_btn.setText(_translate("self", "LED's")) + self.up_routine_check_btn.setText(_translate("self", "Routine\nCheck")) + self.up_axes_btn.setText(_translate("self", "Axis\nMaint.")) + self.up_update_btn.setText(_translate("self", "Update")) + self.up_input_shaper_btn.setText(_translate("self", "Input\nShaper")) diff --git a/BlocksScreen/lib/panels/widgets/UtilitiesTab/InputShaPage.py b/BlocksScreen/lib/panels/widgets/UtilitiesTab/InputShaPage.py new file mode 100644 index 00000000..876b4d4e --- /dev/null +++ b/BlocksScreen/lib/panels/widgets/UtilitiesTab/InputShaPage.py @@ -0,0 +1,567 @@ +import re +import typing + +from lib.panels.widgets.Common.basePopup import BasePopup +from lib.panels.widgets.Common.optionCardWidget import OptionCard +from lib.utils.blocks_button import BlocksCustomButton +from lib.utils.blocks_frame import BlocksCustomFrame +from lib.utils.icon_button import IconButton +from lib.utils.list_model import EntryDelegate, EntryListModel, ListItem +from PyQt6 import QtCore, QtGui, QtWidgets + + +class InputShaperPage(QtWidgets.QStackedWidget): + run_gcode_signal: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( + str, name="run-gcode" + ) + call_load_panel = QtCore.pyqtSignal(bool, str, bool, name="call-load-panel") + request_back_button = QtCore.pyqtSignal(name="request-back-button") + + def __init__(self, parent=None, logic: bool = False) -> None: + if parent: + super().__init__(parent) + else: + super().__init__() + + # flag that disable all UI usage (headless per say) <- current use on utilities tab + self.logic: bool = logic + + self.currentItem: ListItem | None = None + self.type_dict: dict = {} + self.is_types: dict = {} + self.is_aut_types: dict = {} + self.aut: bool = False + + self._is_timeout_timer: QtCore.QTimer = QtCore.QTimer(self) + self._is_timeout_timer.setSingleShot(True) + self._is_timeout_timer.setInterval(300_000) # 5 min: longest plausible IS run + self._is_timeout_timer.timeout.connect(self._on_is_timeout) + + if self.logic: + return + + self._setup_ui() + + self.model = EntryListModel() + self.model.setParent(self.update_buttons_list_widget) + self.entry_delegate = EntryDelegate() + self.update_buttons_list_widget.setModel(self.model) + self.update_buttons_list_widget.setItemDelegate(self.entry_delegate) + self.entry_delegate.item_selected.connect(self.on_item_clicked) + self.update_back_btn.clicked.connect(self.reset_view_model) + + self.is_back_btn.clicked.connect(self.request_back_button) + + self.dialog_page = BasePopup(self, dialog=True, floating=True) + self.addWidget(self.dialog_page) + self.dialog_page.confirm_button.clicked.connect( + lambda: self.handle_is("SHAPER_CALIBRATE AXIS=Y") + ) + self.dialog_page.cancel_button.clicked.connect( + lambda: self.handle_is("SHAPER_CALIBRATE AXIS=X") + ) + + self.action_btn.clicked.connect(self.handle_ism_confirm) + + self.automatic_card_is = OptionCard( + self, + "Automatic\nInput Shaper", + "Automatic Input Shaper", + QtGui.QPixmap(":/input_shaper/media/btn_icons/input_shaper_auto.svg"), + ) # type: ignore + self.automatic_card_is.setObjectName("Automatic_IS_Card") + self.is_content_layout.addWidget( + self.automatic_card_is, alignment=QtCore.Qt.AlignmentFlag.AlignHCenter + ) + self.automatic_card_is.clicked.connect( + lambda: self.handle_is("SHAPER_CALIBRATE") + ) + + self.manual__card_is = OptionCard( + self, + "Manual\nInput Shaper", + "Manual Input Shaper", + QtGui.QPixmap(":/input_shaper/media/btn_icons/input_shaper_manual.svg"), + ) # type: ignore + self.manual__card_is.setObjectName("Manual_IS_Card") + self.is_content_layout.addWidget( + self.manual__card_is, alignment=QtCore.Qt.AlignmentFlag.AlignHCenter + ) + self.manual__card_is.clicked.connect(lambda: self.handle_is("")) + + self.setCurrentIndex(self.indexOf(self.manual_is)) + + def handle_gcode_response(self, data: list[str]) -> None: + """ + Parses a Klipper Input Shaper console message and updates self.is_types. + """ + + if not isinstance(data, list) or len(data) != 1 or not isinstance(data[0], str): + print( + f"WARNING: Invalid input format. Expected a list with one string. Received: {data}" + ) + return + + message = data[0] + + pattern_fitted = re.compile( + r"Fitted shaper '(?P\w+)' frequency = (?P[\d\.]+) Hz \(vibrations = (?P[\d\.]+)%" + ) + match_fitted = pattern_fitted.search(message) + + if match_fitted: + name = match_fitted.group("name") + freq = float(match_fitted.group("freq")) + vib = float(match_fitted.group("vib")) + current_data = self.is_types.get(name, {}) + current_data.update( + { + "frequency": freq, + "vibration": vib, + "max_accel": current_data.get("max_accel", 0.0), + } + ) + self.is_types[name] = current_data + + return + pattern_accel = re.compile( + r"To avoid too much smoothing with '(?P\w+)', suggested max_accel <= (?P[\d\.]+) mm/sec\^2" + ) + match_accel = pattern_accel.search(message) + + if match_accel: + name = match_accel.group("name") + accel = float(match_accel.group("accel")) + + if name in self.is_types and isinstance(self.is_types[name], dict): + self.is_types[name]["max_accel"] = accel + else: + self.is_types[name] = self.is_types.get(name, {}) + self.is_types[name]["max_accel"] = accel + return + + pattern_recommended = re.compile( + r"Recommended shaper_type_(?P[xy]) = (?P\w+), shaper_freq_(?P=axis) = (?P[\d\.]+) Hz" + ) + match_recommended = pattern_recommended.search(message) + if match_recommended: + axis = match_recommended.group("axis") + recommended_type = match_recommended.group("type") + self.is_types["Axis"] = axis + if self.aut: + self.is_aut_types[axis] = recommended_type + if len(self.is_aut_types) == 2: + self.run_gcode_signal.emit("SAVE_CONFIG") + self._is_timeout_timer.stop() + self.call_load_panel.emit(False, "", False) + self.aut = False + return + return + + reordered = {} + if recommended_type in self.is_types: + reordered[recommended_type] = self.is_types[recommended_type] + for key, value in self.is_types.items(): + if key not in ("suggested_type", recommended_type, "Axis"): + reordered[key] = value + + self.set_type_dictionary(self.is_types) + first_key = next(iter(reordered.keys()), None) + for key in reordered: + if key == first_key: + self.add_type_entry(key, "Recommended type") + else: + self.add_type_entry(key) + + self.build_model_list() + self._is_timeout_timer.stop() + self.call_load_panel.emit(False, "", False) + return + + def set_type_dictionary(self, types: dict) -> None: + """Receives the dictionary of input shaper types from the utilities tab""" + self.type_dict = types + + def _on_is_timeout(self) -> None: + self.call_load_panel.emit(False, "", False) + + def handle_is(self, gcode: str) -> None: + if gcode == "SHAPER_CALIBRATE": + self.run_gcode_signal.emit("G28\nM400") + self.aut = True + self.run_gcode_signal.emit(gcode) + elif gcode == "": + # Picking an axis needs the dialog, which logic-only mode never built. + if self.logic: + return + self.dialog_page.confirm_background_color("#dfdfdf") + self.dialog_page.cancel_background_color("#dfdfdf") + self.dialog_page.cancel_font_color("#000000") + self.dialog_page.confirm_font_color("#000000") + self.dialog_page.cancel_button_text("X axis") + self.dialog_page.confirm_button_text("Y axis") + self.dialog_page.set_message( + "Select the axis you want to execute the input shaper on:" + ) + self.dialog_page.show() + return + else: + self.run_gcode_signal.emit("G28\nM400") + self.run_gcode_signal.emit(gcode) + if not self.logic: + self.setCurrentIndex(self.indexOf(self.manual_is)) + + self._is_timeout_timer.start() + self.call_load_panel.emit(True, "Running Input Shaper...", False) + + def reset_view_model(self) -> None: + """Clears items from ListView + (Resets `QAbstractListModel` by clearing entries) + """ + if self.logic: + return + self.model.clear() + self.entry_delegate.clear() + + def deleteLater(self) -> None: + """Schedule the object for deletion, resets the list model first""" + self.reset_view_model() + return super().deleteLater() + + def showEvent(self, a0: QtGui.QShowEvent | None) -> None: + """Re-add clients to update list""" + return super().showEvent(a0) + + def build_model_list(self) -> None: + """Builds the model list (`self.model`) containing updatable clients""" + if self.logic: + return + self.update_buttons_list_widget.blockSignals(True) + self.model.setData(self.model.index(0), True, EntryListModel.EnableRole) + self.on_item_clicked( + self.model.data(self.model.index(0), QtCore.Qt.ItemDataRole.UserRole) + ) + self.update_buttons_list_widget.blockSignals(False) + + @QtCore.pyqtSlot(ListItem, name="on-item-clicked") + def on_item_clicked(self, item: ListItem) -> None: + """Setup information for the currently clicked list item on the info box. + Keeps track of the list item + """ + if self.logic: + return + self.currentItem = item + if not item: + return + current_info = self.type_dict.get(item.text, {}) + if not current_info: + return + + self.vib_label.setText(self._measurement(current_info.get("vibration"), "%")) + self.sug_accel_label.setText( + self._measurement(current_info.get("max_accel"), "mm/s²") + ) + + self.action_btn.show() + + @staticmethod + def _measurement(value: object, unit: str) -> str: + if not isinstance(value, (int, float)) or isinstance(value, bool): + return "N/A" + return f"{value:.0f}{unit}" + + def handle_ism_confirm(self) -> None: + """Apply the selected shaper to the axis that was calibrated, and save.""" + if self.logic: + return + axis = self.type_dict.get("Axis") + if self.currentItem is None or axis not in ("x", "y"): + return + + current_info = self.type_dict.get(self.currentItem.text, {}) + frequency = current_info.get("frequency", "N/A") + self.run_gcode_signal.emit( + f"SET_INPUT_SHAPER SHAPER_TYPE_{axis.upper()}={self.currentItem.text} " + f"SHAPER_FREQ_{axis.upper()}={frequency}" + ) + + self.run_gcode_signal.emit("SAVE_CONFIG") + self.reset_view_model() + self.setCurrentIndex(self.indexOf(self.is_page)) + + def add_type_entry(self, cli_name: str, recommended: str = "") -> None: + """Adds a new item to the list model""" + if self.logic: + return + item = ListItem( + text=cli_name, + right_text=recommended, + right_icon=QtGui.QPixmap(":/arrow_icons/media/btn_icons/right_arrow.svg"), + selected=False, + _lfontsize=17, + _rfontsize=9, + height=60, + allow_check=True, + notificate=False, + ) + self.model.add_item(item) + + def _setup_ui(self) -> None: + """Setup UI for updatePage""" + + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.MinimumExpanding, + QtWidgets.QSizePolicy.Policy.MinimumExpanding, + ) + + self.setSizePolicy(sizePolicy) + self.setMinimumSize(QtCore.QSize(710, 400)) + self.setMaximumSize(QtCore.QSize(720, 420)) + + self.is_page = QtWidgets.QWidget() + self.is_page.setObjectName("is_page") + self.verticalLayout_13 = QtWidgets.QVBoxLayout(self.is_page) + self.verticalLayout_13.setObjectName("verticalLayout_13") + + spacerItem14 = QtWidgets.QSpacerItem( + 20, + 24, + QtWidgets.QSizePolicy.Policy.Minimum, + QtWidgets.QSizePolicy.Policy.Minimum, + ) + self.verticalLayout_13.addItem(spacerItem14) + self.is_header_layout = QtWidgets.QHBoxLayout() + self.is_header_layout.setObjectName("is_header_layout") + spacerItem15 = QtWidgets.QSpacerItem( + 60, + 0, + QtWidgets.QSizePolicy.Policy.Minimum, + QtWidgets.QSizePolicy.Policy.Minimum, + ) + self.is_header_layout.addItem(spacerItem15) + + font = QtGui.QFont() + font.setFamily("Momcake") + font.setPointSize(24) + + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Fixed + ) + + self.is_header_title = QtWidgets.QLabel(parent=self.is_page) + self.is_header_title.setSizePolicy(sizePolicy) + self.is_header_title.setMaximumSize(QtCore.QSize(16777215, 60)) + self.is_header_title.setFont(font) + self.is_header_title.setStyleSheet("background: transparent; color: white;") + self.is_header_title.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + self.is_header_layout.addWidget(self.is_header_title) + + self.is_back_btn = IconButton(parent=self.is_page) + self.is_back_btn.setMinimumSize(QtCore.QSize(60, 60)) + self.is_back_btn.setMaximumSize(QtCore.QSize(60, 60)) + self.is_back_btn.setStyleSheet("") + self.is_back_btn.setProperty( + "icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/back.svg") + ) + self.is_header_layout.addWidget(self.is_back_btn) + + self.verticalLayout_13.addLayout(self.is_header_layout) + + self.is_content_layout = QtWidgets.QHBoxLayout() + self.is_content_layout.setObjectName("is_content_layout") + self.verticalLayout_13.addLayout(self.is_content_layout) + + self.addWidget(self.is_page) + + self.is_header_title.setText("Input Shaper") + self.is_back_btn.setText("Back") + + # MANUAL INPUT SHAPPER PAGE DOWN HERE DONT TOUCH . thx :D + + self.manual_is = QtWidgets.QWidget(self) + self.manual_is.setSizePolicy(sizePolicy) + self.manual_is.setMinimumSize(QtCore.QSize(710, 400)) + self.manual_is.setMaximumSize(QtCore.QSize(720, 420)) + + self.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) + self.update_page_content_layout = QtWidgets.QVBoxLayout(self.manual_is) + self.update_page_content_layout.setContentsMargins(15, 15, 2, 2) + + self.header_content_layout = QtWidgets.QHBoxLayout(self.manual_is) + self.header_content_layout.setAlignment(QtCore.Qt.AlignmentFlag.AlignTop) + + self.spacer_left = QtWidgets.QLabel(self.manual_is) + self.spacer_left.setMinimumSize(QtCore.QSize(60, 60)) + self.spacer_left.setMaximumSize(QtCore.QSize(60, 60)) + self.header_content_layout.addWidget(self.spacer_left, 0) + + font = QtGui.QFont() + font.setPointSize(24) + + self.header_title = QtWidgets.QLabel(self.manual_is) + self.header_title.setMinimumSize(QtCore.QSize(100, 60)) + self.header_title.setMaximumSize(QtCore.QSize(16777215, 60)) + self.header_title.setFont(font) + self.header_title.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + self.header_title.setStyleSheet("color:white") + self.header_title.setText("Input Shaper") + self.header_content_layout.addWidget(self.header_title, 0) + + self.update_back_btn = IconButton(self.manual_is) + self.update_back_btn.setMinimumSize(QtCore.QSize(60, 60)) + self.update_back_btn.setMaximumSize(QtCore.QSize(60, 60)) + self.update_back_btn.setFlat(True) + self.update_back_btn.setPixmap(QtGui.QPixmap(":/ui/media/btn_icons/back.svg")) + + self.header_content_layout.addWidget(self.update_back_btn, 0) + self.update_page_content_layout.addLayout(self.header_content_layout, 0) + + self.main_content_layout = QtWidgets.QHBoxLayout(self.manual_is) + self.main_content_layout.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + + self.update_buttons_frame = BlocksCustomFrame(self.manual_is) + + self.update_buttons_list_widget = QtWidgets.QListView(self.update_buttons_frame) + self.update_buttons_list_widget.setMouseTracking(True) + self.update_buttons_list_widget.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.update_buttons_list_widget.setStyleSheet("background-color:transparent") + self.update_buttons_list_widget.setMinimumSize(self.update_buttons_frame.size()) + self.update_buttons_list_widget.setFrameShape(QtWidgets.QFrame.Shape.NoFrame) + self.update_buttons_list_widget.setVerticalScrollBarPolicy( + QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOff + ) + self.update_buttons_list_widget.setHorizontalScrollBarPolicy( + QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOff + ) + self.update_buttons_list_widget.setSizeAdjustPolicy( + QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustToContents + ) + self.update_buttons_list_widget.setAutoScroll(False) + self.update_buttons_list_widget.setProperty("showDropIndicator", False) + self.update_buttons_list_widget.setDefaultDropAction( + QtCore.Qt.DropAction.IgnoreAction + ) + self.update_buttons_list_widget.setAlternatingRowColors(False) + self.update_buttons_list_widget.setSelectionMode( + QtWidgets.QAbstractItemView.SelectionMode.NoSelection + ) + self.update_buttons_list_widget.setSelectionBehavior( + QtWidgets.QAbstractItemView.SelectionBehavior.SelectItems + ) + self.update_buttons_list_widget.setVerticalScrollMode( + QtWidgets.QAbstractItemView.ScrollMode.ScrollPerPixel + ) + self.update_buttons_list_widget.setHorizontalScrollMode( + QtWidgets.QAbstractItemView.ScrollMode.ScrollPerPixel + ) + QtWidgets.QScroller.grabGesture( + self.update_buttons_list_widget, + QtWidgets.QScroller.ScrollerGestureType.TouchGesture, + ) + QtWidgets.QScroller.grabGesture( + self.update_buttons_list_widget, + QtWidgets.QScroller.ScrollerGestureType.LeftMouseButtonGesture, + ) + + self.update_buttons_layout = QtWidgets.QVBoxLayout(self.manual_is) + # self.update_buttons_layout.setContentsMargins(15, 20, 20, 5) + self.update_buttons_layout.addWidget(self.update_buttons_list_widget, 0) + + self.update_buttons_frame.setLayout(self.update_buttons_layout) + + self.main_content_layout.addWidget(self.update_buttons_frame, 0) + + self.infobox_frame = BlocksCustomFrame(self.manual_is) + self.infobox_frame.setMaximumWidth(250) + + self.info_box_layout = QtWidgets.QVBoxLayout() + self.info_box_layout.setContentsMargins(10, 10, 10, 10) + + font = QtGui.QFont() + font.setPointSize(20) + + self.info_box = QtWidgets.QGridLayout(self.manual_is) + self.info_box.setContentsMargins(0, 0, 0, 0) + + font.setPointSize(12) + + self.vib_title_label = QtWidgets.QLabel(self.manual_is) + self.vib_title_label.setText("Vibrations: ") + self.vib_title_label.setMinimumSize(QtCore.QSize(60, 60)) + self.vib_title_label.setMaximumSize( + QtCore.QSize(int(self.infobox_frame.size().width() * 0.40), 9999) + ) + self.vib_title_label.setStyleSheet("color:white") + self.vib_title_label.setAlignment( + QtCore.Qt.AlignmentFlag.AlignLeft | QtCore.Qt.AlignmentFlag.AlignVCenter + ) + self.vib_title_label.setFont(font) + self.vib_title_label.setLayoutDirection(QtCore.Qt.LayoutDirection.RightToLeft) + + self.vib_label = QtWidgets.QLabel(self.manual_is) + self.vib_label.setMinimumSize(QtCore.QSize(100, 60)) + self.vib_label.setFont(font) + self.vib_label.setStyleSheet("color:white") + + self.vib_label.setLayoutDirection(QtCore.Qt.LayoutDirection.RightToLeft) + self.vib_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + + self.info_box.addWidget(self.vib_title_label, 0, 0) + self.info_box.addWidget(self.vib_label, 0, 1) + + self.sug_accel_title_label = QtWidgets.QLabel(self.manual_is) + self.sug_accel_title_label.setText("Sugested Max\nAcceleration:") + self.sug_accel_title_label.setMinimumSize(QtCore.QSize(60, 60)) + self.sug_accel_title_label.setMaximumSize( + QtCore.QSize(int(self.infobox_frame.size().width() * 0.40), 9999) + ) + self.sug_accel_title_label.setAlignment( + QtCore.Qt.AlignmentFlag.AlignLeft | QtCore.Qt.AlignmentFlag.AlignVCenter + ) + self.sug_accel_title_label.setFont(font) + self.sug_accel_title_label.setStyleSheet("color:white") + + self.sug_accel_label = QtWidgets.QLabel(self.manual_is) + self.sug_accel_label.setMinimumSize(QtCore.QSize(100, 60)) + self.sug_accel_label.setMaximumSize( + QtCore.QSize(int(self.infobox_frame.size().width() * 0.60), 9999) + ) + self.sug_accel_label.setStyleSheet("color:white") + + self.sug_accel_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + self.sug_accel_label.setFont(font) + + self.info_box.addWidget(self.sug_accel_title_label, 1, 0) + self.info_box.addWidget(self.sug_accel_label, 1, 1) + + self.info_box_layout.addLayout(self.info_box, 1) + + self.button_box = QtWidgets.QVBoxLayout(self.manual_is) + self.button_box.setContentsMargins(0, 0, 0, 0) + self.button_box.addSpacing(-1) + + self.action_btn = BlocksCustomButton(self.manual_is) + self.action_btn.setMinimumSize(QtCore.QSize(200, 60)) + self.action_btn.setMaximumSize(QtCore.QSize(250, 60)) + self.action_btn.setFont(font) + self.action_btn.setSizePolicy(sizePolicy) + self.action_btn.setText("Confirm") + self.action_btn.setPixmap(QtGui.QPixmap(":/dialog/media/btn_icons/yes.svg")) + self.action_btn.hide() + self.button_box.addWidget( + self.action_btn, + 0, + QtCore.Qt.AlignmentFlag.AlignRight | QtCore.Qt.AlignmentFlag.AlignBottom, + ) + + self.info_box_layout.addLayout( + self.button_box, + 0, + ) + self.infobox_frame.setLayout(self.info_box_layout) + self.main_content_layout.addWidget(self.infobox_frame, 1) + + self.update_page_content_layout.addLayout(self.main_content_layout, 1) + self.setLayout(self.update_page_content_layout) + + self.addWidget(self.manual_is) diff --git a/BlocksScreen/lib/panels/widgets/UtilitiesTab/axisMaintPage.py b/BlocksScreen/lib/panels/widgets/UtilitiesTab/axisMaintPage.py new file mode 100644 index 00000000..db4666bb --- /dev/null +++ b/BlocksScreen/lib/panels/widgets/UtilitiesTab/axisMaintPage.py @@ -0,0 +1,215 @@ +import typing + +from lib.panels.widgets.Common.basePopup import BasePopup +from lib.utils.blocks_button import BlocksCustomButton +from lib.utils.blocks_frame import BlocksCustomFrame +from lib.utils.check_button import BlocksCustomCheckButton +from lib.utils.icon_button import IconButton +from PyQt6 import QtCore, QtGui, QtWidgets + + +class AxisMaintPage(QtWidgets.QWidget): + """Axis Maintenance page of the utilities tab.""" + + request_back = QtCore.pyqtSignal(name="request-back-button") + + run_gcode_signal: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( + str, name="run-gcode" + ) + call_load_panel = QtCore.pyqtSignal(bool, str, bool, name="call-load-panel") + + def __init__( + self, + parent: typing.Optional["QtWidgets.QWidget"], + ) -> None: + super().__init__(parent) + + self.answerPage = BasePopup(self, False, True) + self.answerPage.accepted.connect(self._run_AXIS_MAINTENANCE_gcode) + + self._setup_ui() + self.axes_back_btn.clicked.connect(self.request_back.emit) + self.am_execute.clicked.connect(self.axis_maintenance) + + def _run_AXIS_MAINTENANCE_gcode(self): + if self.current_object: + self.run_gcode_signal.emit( + f"AXIS_MAINTENANCE_FINISH_{self.current_object}\nM400" + ) + + self.call_load_panel.emit( + True, + f"Running maintenance cycle on {self.current_object.upper()} axis...", + False, + ) + + QtCore.QTimer.singleShot( + 50000, lambda: self.call_load_panel.emit(False, "", False) + ) + + else: + self.answerPage.hide() + + def axis_maintenance(self) -> None: + """Routine, checks axis movement for printer debugging""" + self.current_object = self.axis_maintenance_gb.checkedButton().text().lower() + self.run_gcode_signal.emit(f"AXIS_MAINTENANCE_{self.current_object}\nM400") + + self.answerPage.set_message( + f"Apply oil to the {self.current_object.upper()} axis, then press Confirm.", + ) + + self.answerPage.show() + self.call_load_panel.emit( + True, f"Homing {self.current_object.upper()} axis...", False + ) + + QtCore.QTimer.singleShot( + 10000, + lambda: { + self.call_load_panel.emit(False, "", False), + self.answerPage.show(), + }, + ) + + def _setup_ui(self) -> None: + self.setObjectName("axes_page") + + self.verticalLayout_7 = QtWidgets.QVBoxLayout(self) + self.verticalLayout_7.setObjectName("verticalLayout_7") + spacerItem12 = QtWidgets.QSpacerItem( + 20, + 24, + QtWidgets.QSizePolicy.Policy.Minimum, + QtWidgets.QSizePolicy.Policy.Minimum, + ) + self.verticalLayout_7.addItem(spacerItem12) + self.lcd_settings_header_layout = QtWidgets.QHBoxLayout() + self.lcd_settings_header_layout.setObjectName("lcd_settings_header_layout") + spacerItem13 = QtWidgets.QSpacerItem( + 60, + 20, + QtWidgets.QSizePolicy.Policy.Minimum, + QtWidgets.QSizePolicy.Policy.Minimum, + ) + self.lcd_settings_header_layout.addItem(spacerItem13) + + font = QtGui.QFont() + font.setFamily("Momcake") + font.setPointSize(24) + + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum + ) + + self.lcd_settings_title_label = QtWidgets.QLabel(parent=self) + self.lcd_settings_title_label.setSizePolicy(sizePolicy) + self.lcd_settings_title_label.setMaximumSize(QtCore.QSize(16777215, 60)) + self.lcd_settings_title_label.setFont(font) + self.lcd_settings_title_label.setStyleSheet( + "background: transparent; color: white;" + ) + self.lcd_settings_title_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + self.lcd_settings_header_layout.addWidget(self.lcd_settings_title_label) + + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.MinimumExpanding, + QtWidgets.QSizePolicy.Policy.Minimum, + ) + + self.axes_back_btn = IconButton(parent=self) + self.axes_back_btn.setSizePolicy(sizePolicy) + self.axes_back_btn.setMinimumSize(QtCore.QSize(60, 60)) + self.axes_back_btn.setMaximumSize(QtCore.QSize(60, 60)) + self.axes_back_btn.setFont(font) + self.axes_back_btn.setProperty( + "icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/back.svg") + ) + self.axes_back_btn.setObjectName("axes_back_btn") + + self.lcd_settings_header_layout.addWidget(self.axes_back_btn) + self.verticalLayout_7.addLayout(self.lcd_settings_header_layout) + + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.Expanding, + QtWidgets.QSizePolicy.Policy.Expanding, + ) + + self.frame_2 = BlocksCustomFrame(parent=self) + self.frame_2.setSizePolicy(sizePolicy) + self.frame_2.setMinimumSize(QtCore.QSize(650, 0)) + self.frame_2.setObjectName("frame_2") + + self.gridLayout = QtWidgets.QGridLayout(self.frame_2) + self.gridLayout.setObjectName("gridLayout") + + self.axis_maintenance_gb = QtWidgets.QButtonGroup(self) + self.axis_maintenance_gb.setObjectName("axis_maintenance_gb") + + self.am_execute = BlocksCustomButton(parent=self.frame_2) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding + ) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + + font = QtGui.QFont() + font.setFamily("Momcake") + font.setPointSize(19) + + self.am_execute.setSizePolicy(sizePolicy) + self.am_execute.setMinimumSize(QtCore.QSize(250, 80)) + self.am_execute.setMaximumSize(QtCore.QSize(250, 80)) + self.am_execute.setFont(font) + self.am_execute.setProperty( + "icon_pixmap", QtGui.QPixmap(":/dialog/media/btn_icons/yes.svg") + ) + self.am_execute.setObjectName("am_execute") + self.gridLayout.addWidget(self.am_execute, 2, 1, 1, 1) + + font = QtGui.QFont() + font.setPointSize(20) + + self.am_y = BlocksCustomCheckButton(parent=self.frame_2) + self.am_y.setMinimumSize(QtCore.QSize(60, 80)) + self.am_y.setMaximumSize(QtCore.QSize(250, 80)) + self.am_y.setFont(font) + self.am_y.setCheckable(True) + self.am_y.setChecked(True) + self.am_y.setAutoExclusive(True) + self.am_y.setFlat(True) + self.am_y.setObjectName("am_y") + self.axis_maintenance_gb.addButton(self.am_y) + + self.gridLayout.addWidget(self.am_y, 1, 0, 1, 1) + + self.am_z = BlocksCustomCheckButton(parent=self.frame_2) + self.am_z.setMinimumSize(QtCore.QSize(60, 80)) + self.am_z.setMaximumSize(QtCore.QSize(250, 80)) + self.am_z.setFont(font) + self.am_z.setCheckable(True) + self.am_z.setAutoExclusive(True) + self.axis_maintenance_gb.addButton(self.am_z) + self.gridLayout.addWidget(self.am_z, 2, 0, 1, 1) + + self.am_x = BlocksCustomCheckButton(parent=self.frame_2) + self.am_x.setMinimumSize(QtCore.QSize(250, 80)) + self.am_x.setMaximumSize(QtCore.QSize(250, 80)) + self.am_x.setFont(font) + self.am_x.setCheckable(True) + self.am_x.setAutoExclusive(True) + self.axis_maintenance_gb.addButton(self.am_x) + self.gridLayout.addWidget(self.am_x, 0, 0, 1, 1) + + self.verticalLayout_7.addWidget( + self.frame_2, 0, QtCore.Qt.AlignmentFlag.AlignHCenter + ) + + self.lcd_settings_title_label.setText("Axis Maintenance") + + self.axes_back_btn.setText("Back") + self.am_execute.setText("Execute") + + self.am_z.setText("Z") + self.am_x.setText("X") + self.am_y.setText("Y") diff --git a/BlocksScreen/lib/panels/widgets/UtilitiesTab/infoPage.py b/BlocksScreen/lib/panels/widgets/UtilitiesTab/infoPage.py new file mode 100644 index 00000000..0f4ef130 --- /dev/null +++ b/BlocksScreen/lib/panels/widgets/UtilitiesTab/infoPage.py @@ -0,0 +1,123 @@ +import typing + +from lib.utils.blocks_frame import BlocksCustomFrame +from lib.utils.icon_button import IconButton +from PyQt6 import QtCore, QtGui, QtWidgets + + +class InfoPage(QtWidgets.QWidget): + """Info page of the utilities tab.""" + + request_back_button = QtCore.pyqtSignal(name="request-back-button") + + def __init__( + self, + parent: typing.Optional["QtWidgets.QWidget"], + ) -> None: + super().__init__(parent) + + self._setup_ui() + self.info_back_btn.clicked.connect(self.request_back_button.emit) + + def _setup_ui(self) -> None: + self.setObjectName("info_page") + + spacerItem = QtWidgets.QSpacerItem( + 20, + 24, + QtWidgets.QSizePolicy.Policy.Minimum, + QtWidgets.QSizePolicy.Policy.Minimum, + ) + + spacerItem1 = QtWidgets.QSpacerItem( + 60, + 60, + QtWidgets.QSizePolicy.Policy.Minimum, + QtWidgets.QSizePolicy.Policy.Minimum, + ) + + self.verticalLayout_2 = QtWidgets.QVBoxLayout(self) + self.verticalLayout_2.setObjectName("verticalLayout_2") + self.verticalLayout_2.addItem(spacerItem) + + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum + ) + + font = QtGui.QFont() + font.setFamily("Momcake") + font.setPointSize(24) + + self.info_header_layout = QtWidgets.QHBoxLayout() + self.info_header_layout.setObjectName("info_header_layout") + self.info_header_layout.addItem(spacerItem1) + + self.info_title_label = QtWidgets.QLabel(parent=self) + self.info_title_label.setSizePolicy(sizePolicy) + self.info_title_label.setMaximumSize(QtCore.QSize(16777215, 60)) + self.info_title_label.setFont(font) + self.info_title_label.setStyleSheet("background: transparent; color: white;") + self.info_title_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + self.info_header_layout.addWidget(self.info_title_label) + + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.MinimumExpanding, + QtWidgets.QSizePolicy.Policy.MinimumExpanding, + ) + + self.info_back_btn = IconButton(parent=self) + self.info_back_btn.setSizePolicy(sizePolicy) + self.info_back_btn.setMinimumSize(QtCore.QSize(60, 60)) + self.info_back_btn.setMaximumSize(QtCore.QSize(60, 60)) + self.info_back_btn.setProperty( + "icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/back.svg") + ) + self.info_header_layout.addWidget(self.info_back_btn) + self.verticalLayout_2.addLayout(self.info_header_layout) + + self.info_content_layout = QtWidgets.QVBoxLayout() + self.info_content_layout.setObjectName("info_content_layout") + + self.frame = BlocksCustomFrame(parent=self) + self.frame.setMinimumSize(QtCore.QSize(350, 260)) + self.frame.setMaximumSize(QtCore.QSize(350, 290)) + + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.Preferred, + QtWidgets.QSizePolicy.Policy.Expanding, + ) + + font = QtGui.QFont() + font.setPointSize(20) + + self.kv_label = QtWidgets.QLabel(parent=self.frame) + self.kv_label.setGeometry(QtCore.QRect(0, 10, 351, 81)) + self.kv_label.setSizePolicy(sizePolicy) + self.kv_label.setFont(font) + self.kv_label.setStyleSheet("color:white") + self.kv_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + self.kv_label.setObjectName("kv_label") + + font = QtGui.QFont() + font.setPointSize(20) + + self.smth_label = QtWidgets.QLabel(parent=self.frame) + self.smth_label.setGeometry(QtCore.QRect(0, 110, 351, 81)) + self.smth_label.setSizePolicy(sizePolicy) + self.smth_label.setFont(font) + self.smth_label.setStyleSheet("color:white") + self.smth_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + self.info_content_layout.addWidget( + self.frame, 0, QtCore.Qt.AlignmentFlag.AlignHCenter + ) + self.verticalLayout_2.addLayout(self.info_content_layout) + + _translate = QtCore.QCoreApplication.translate + + self.info_title_label.setText(_translate("self", "Info")) + self.info_title_label.setProperty("class", _translate("self", "title_text")) + self.info_back_btn.setText(_translate("self", "Back")) + self.info_back_btn.setProperty("class", _translate("self", "menu_btn")) + self.info_back_btn.setProperty("button_type", _translate("self", "icon")) + self.kv_label.setText(_translate("self", "Model: Blocks RF50")) + self.smth_label.setText(_translate("self", "www.blockstec.com ")) diff --git a/BlocksScreen/lib/panels/widgets/UtilitiesTab/inputshaperPage.py b/BlocksScreen/lib/panels/widgets/UtilitiesTab/inputshaperPage.py deleted file mode 100644 index 61bc7e87..00000000 --- a/BlocksScreen/lib/panels/widgets/UtilitiesTab/inputshaperPage.py +++ /dev/null @@ -1,450 +0,0 @@ -import typing - -from lib.utils.blocks_button import BlocksCustomButton -from lib.utils.blocks_frame import BlocksCustomFrame -from lib.utils.icon_button import IconButton -from lib.utils.list_model import EntryDelegate, EntryListModel, ListItem -from PyQt6 import QtCore, QtGui, QtWidgets - - -class InputShaperPage(QtWidgets.QWidget): - """Update GUI Page, - retrieves from moonraker available clients and adds functionality - for updating or recovering them - """ - - run_gcode_signal: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( - str, name="run-gcode" - ) - call_load_panel = QtCore.pyqtSignal(bool, str, bool, name="call-load-panel") - - def __init__(self, parent=None) -> None: - if parent: - super().__init__(parent) - else: - super().__init__() - self._setup_ui() - self.selected_item: ListItem | None = None - self.ongoing_update: bool = False - self.type_dict: dict = {} - self.repeated_request_status = QtCore.QTimer() - self.repeated_request_status.setInterval(2000) # every 2 seconds - self.model = EntryListModel() - self.model.setParent(self.update_buttons_list_widget) - self.entry_delegate = EntryDelegate() - self.update_buttons_list_widget.setModel(self.model) - self.update_buttons_list_widget.setItemDelegate(self.entry_delegate) - self.entry_delegate.item_selected.connect(self.on_item_clicked) - self.update_back_btn.clicked.connect(self.reset_view_model) - - self.action_btn.clicked.connect(self.handle_ism_confirm) - - def handle_update_end(self) -> None: - """Handles update end signal - (closes loading page, returns to normal operation) - """ - self.call_load_panel.emit(False, "Updating...", False) - self.repeated_request_status.stop() - self.build_model_list() - - def handle_ongoing_update(self) -> None: - """Handled ongoing update signal, - calls loading page (blocks user interaction) - """ - self.call_load_panel.emit(True, "Updating...", False) - self.repeated_request_status.start(2000) - - def reset_view_model(self) -> None: - """Clears items from ListView - (Resets `QAbstractListModel` by clearing entries) - """ - self.model.clear() - self.entry_delegate.clear() - - def deleteLater(self) -> None: - """Schedule the object for deletion, resets the list model first""" - self.reset_view_model() - return super().deleteLater() - - def showEvent(self, a0: QtGui.QShowEvent | None) -> None: - """Re-add clients to update list""" - return super().showEvent(a0) - - def build_model_list(self) -> None: - """Builds the model list (`self.model`) containing updatable clients""" - self.update_buttons_list_widget.blockSignals(True) - self.model.setData(self.model.index(0), True, EntryListModel.EnableRole) - self.on_item_clicked( - self.model.data(self.model.index(0), QtCore.Qt.ItemDataRole.UserRole) - ) - self.update_buttons_list_widget.blockSignals(False) - - def set_type_dictionary(self, dict) -> None: - """Receives the dictionary of input shaper types from the utilities tab""" - self.type_dict = dict - return - - @QtCore.pyqtSlot(ListItem, name="on-item-clicked") - def on_item_clicked(self, item: ListItem) -> None: - """Setup information for the currently clicked list item on the info box. - Keeps track of the list item - """ - self.currentItem: ListItem = item - if not item: - return - current_info = self.type_dict.get(self.currentItem.text, {}) - if not current_info: - return - - self.vib_label.setText(str("%.0f" % current_info.get("vibration", "N/A")) + "%") - self.sug_accel_label.setText( - str("%.0f" % current_info.get("max_accel", "N/A")) + "mm/s²" - ) - - self.action_btn.show() - - def handle_ism_confirm(self) -> None: - current_info = self.type_dict.get(self.currentItem.text, {}) - frequency = current_info.get("frequency", "N/A") - if self.type_dict["Axis"] == "x": - self.run_gcode_signal.emit( - f"SET_INPUT_SHAPER SHAPER_TYPE_X={self.currentItem.text} SHAPER_FREQ_X={frequency}" - ) - elif self.type_dict["Axis"] == "y": - self.run_gcode_signal.emit( - f"SET_INPUT_SHAPER SHAPER_TYPE_Y={self.currentItem.text} SHAPER_FREQ_Y={frequency}" - ) - - self.run_gcode_signal.emit("SAVE_CONFIG") - self.reset_view_model() - - def add_type_entry(self, cli_name: str, recommended: str = "") -> None: - """Adds a new item to the list model""" - item = ListItem( - text=cli_name, - right_text=recommended, - right_icon=QtGui.QPixmap(":/arrow_icons/media/btn_icons/right_arrow.svg"), - selected=False, - _lfontsize=17, - _rfontsize=9, - height=60, - allow_check=True, - notificate=False, - ) - self.model.add_item(item) - - def _setup_ui(self) -> None: - """Setup UI for updatePage""" - font_id = QtGui.QFontDatabase.addApplicationFont( - ":/font/media/fonts for text/Momcake-Bold.ttf" - ) - font_family = QtGui.QFontDatabase.applicationFontFamilies(font_id)[0] - sizePolicy = QtWidgets.QSizePolicy( - QtWidgets.QSizePolicy.Policy.MinimumExpanding, - QtWidgets.QSizePolicy.Policy.MinimumExpanding, - ) - sizePolicy.setHorizontalStretch(1) - sizePolicy.setVerticalStretch(1) - self.setSizePolicy(sizePolicy) - self.setMinimumSize(QtCore.QSize(710, 400)) - self.setMaximumSize(QtCore.QSize(720, 420)) - self.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.update_page_content_layout = QtWidgets.QVBoxLayout() - self.update_page_content_layout.setContentsMargins(15, 15, 2, 2) - - self.header_content_layout = QtWidgets.QHBoxLayout() - self.header_content_layout.setAlignment(QtCore.Qt.AlignmentFlag.AlignTop) - - self.spacer_left = QtWidgets.QLabel(self) - self.spacer_left.setMinimumSize(QtCore.QSize(60, 60)) - self.spacer_left.setMaximumSize(QtCore.QSize(60, 60)) - self.header_content_layout.addWidget(self.spacer_left, 0) - self.header_title = QtWidgets.QLabel(self) - self.header_title.setMinimumSize(QtCore.QSize(100, 60)) - self.header_title.setMaximumSize(QtCore.QSize(16777215, 60)) - font = QtGui.QFont() - font.setFamily(font_family) - font.setPointSize(24) - palette = self.header_title.palette() - palette.setColor(palette.ColorRole.WindowText, QtGui.QColor("#FFFFFF")) - self.header_title.setFont(font) - self.header_title.setPalette(palette) - self.header_title.setLayoutDirection(QtCore.Qt.LayoutDirection.RightToLeft) - self.header_title.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - self.header_title.setObjectName("header-title") - self.header_title.setText("Input Shaper") - self.header_content_layout.addWidget(self.header_title, 0) - self.update_back_btn = IconButton(self) - self.update_back_btn.setMinimumSize(QtCore.QSize(60, 60)) - self.update_back_btn.setMaximumSize(QtCore.QSize(60, 60)) - self.update_back_btn.setFlat(True) - self.update_back_btn.setPixmap(QtGui.QPixmap(":/ui/media/btn_icons/back.svg")) - self.header_content_layout.addWidget(self.update_back_btn, 0) - self.update_page_content_layout.addLayout(self.header_content_layout, 0) - - self.main_content_layout = QtWidgets.QHBoxLayout() - self.main_content_layout.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - - self.update_buttons_frame = BlocksCustomFrame(self) - - self.update_buttons_frame.setMinimumSize(QtCore.QSize(300, 300)) - self.update_buttons_frame.setMaximumSize(QtCore.QSize(350, 500)) - - palette = QtGui.QPalette() - brush = QtGui.QBrush(QtGui.QColor(0, 0, 0, 0)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush( - QtGui.QPalette.ColorGroup.Active, - QtGui.QPalette.ColorRole.Button, - brush, - ) - brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) - brush.setStyle(QtCore.Qt.BrushStyle.NoBrush) - palette.setBrush( - QtGui.QPalette.ColorGroup.Active, - QtGui.QPalette.ColorRole.Base, - brush, - ) - brush = QtGui.QBrush(QtGui.QColor(0, 0, 0, 0)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush( - QtGui.QPalette.ColorGroup.Active, - QtGui.QPalette.ColorRole.Window, - brush, - ) - brush = QtGui.QBrush(QtGui.QColor(0, 120, 215, 0)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush( - QtGui.QPalette.ColorGroup.Active, - QtGui.QPalette.ColorRole.Highlight, - brush, - ) - brush = QtGui.QBrush(QtGui.QColor(0, 0, 255, 0)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush( - QtGui.QPalette.ColorGroup.Active, - QtGui.QPalette.ColorRole.Link, - brush, - ) - brush = QtGui.QBrush(QtGui.QColor(0, 0, 0, 0)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush( - QtGui.QPalette.ColorGroup.Inactive, - QtGui.QPalette.ColorRole.Button, - brush, - ) - brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) - brush.setStyle(QtCore.Qt.BrushStyle.NoBrush) - palette.setBrush( - QtGui.QPalette.ColorGroup.Inactive, - QtGui.QPalette.ColorRole.Base, - brush, - ) - brush = QtGui.QBrush(QtGui.QColor(0, 0, 0, 0)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush( - QtGui.QPalette.ColorGroup.Inactive, - QtGui.QPalette.ColorRole.Window, - brush, - ) - brush = QtGui.QBrush(QtGui.QColor(0, 120, 215, 0)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush( - QtGui.QPalette.ColorGroup.Inactive, - QtGui.QPalette.ColorRole.Highlight, - brush, - ) - brush = QtGui.QBrush(QtGui.QColor(0, 0, 255, 0)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush( - QtGui.QPalette.ColorGroup.Inactive, - QtGui.QPalette.ColorRole.Link, - brush, - ) - brush = QtGui.QBrush(QtGui.QColor(0, 0, 0, 0)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush( - QtGui.QPalette.ColorGroup.Disabled, - QtGui.QPalette.ColorRole.Button, - brush, - ) - brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) - brush.setStyle(QtCore.Qt.BrushStyle.NoBrush) - palette.setBrush( - QtGui.QPalette.ColorGroup.Disabled, - QtGui.QPalette.ColorRole.Base, - brush, - ) - brush = QtGui.QBrush(QtGui.QColor(0, 0, 0, 0)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush( - QtGui.QPalette.ColorGroup.Disabled, - QtGui.QPalette.ColorRole.Window, - brush, - ) - brush = QtGui.QBrush(QtGui.QColor(0, 120, 215, 0)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush( - QtGui.QPalette.ColorGroup.Disabled, - QtGui.QPalette.ColorRole.Highlight, - brush, - ) - brush = QtGui.QBrush(QtGui.QColor(0, 0, 255, 0)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush( - QtGui.QPalette.ColorGroup.Disabled, - QtGui.QPalette.ColorRole.Link, - brush, - ) - self.update_buttons_list_widget = QtWidgets.QListView(self.update_buttons_frame) - self.update_buttons_list_widget.setMouseTracking(True) - self.update_buttons_list_widget.setTabletTracking(True) - - self.update_buttons_list_widget.setPalette(palette) - self.update_buttons_list_widget.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) - self.update_buttons_list_widget.setStyleSheet("background-color:transparent") - self.update_buttons_list_widget.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) - self.update_buttons_list_widget.setMinimumSize(self.update_buttons_frame.size()) - self.update_buttons_list_widget.setFrameShape(QtWidgets.QFrame.Shape.NoFrame) - self.update_buttons_list_widget.setVerticalScrollBarPolicy( - QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOff - ) - self.update_buttons_list_widget.setHorizontalScrollBarPolicy( - QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOff - ) - self.update_buttons_list_widget.setSizeAdjustPolicy( - QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustToContents - ) - self.update_buttons_list_widget.setAutoScroll(False) - self.update_buttons_list_widget.setProperty("showDropIndicator", False) - self.update_buttons_list_widget.setDefaultDropAction( - QtCore.Qt.DropAction.IgnoreAction - ) - self.update_buttons_list_widget.setAlternatingRowColors(False) - self.update_buttons_list_widget.setSelectionMode( - QtWidgets.QAbstractItemView.SelectionMode.NoSelection - ) - self.update_buttons_list_widget.setSelectionBehavior( - QtWidgets.QAbstractItemView.SelectionBehavior.SelectItems - ) - self.update_buttons_list_widget.setVerticalScrollMode( - QtWidgets.QAbstractItemView.ScrollMode.ScrollPerPixel - ) - self.update_buttons_list_widget.setHorizontalScrollMode( - QtWidgets.QAbstractItemView.ScrollMode.ScrollPerPixel - ) - QtWidgets.QScroller.grabGesture( - self.update_buttons_list_widget, - QtWidgets.QScroller.ScrollerGestureType.TouchGesture, - ) - QtWidgets.QScroller.grabGesture( - self.update_buttons_list_widget, - QtWidgets.QScroller.ScrollerGestureType.LeftMouseButtonGesture, - ) - self.update_buttons_layout = QtWidgets.QVBoxLayout() - self.update_buttons_layout.setContentsMargins(15, 20, 20, 5) - self.update_buttons_layout.addWidget(self.update_buttons_list_widget, 0) - self.update_buttons_frame.setLayout(self.update_buttons_layout) - - self.main_content_layout.addWidget(self.update_buttons_frame, 0) - - self.infobox_frame = BlocksCustomFrame() - self.infobox_frame.setMinimumSize(QtCore.QSize(250, 300)) - - self.info_box_layout = QtWidgets.QVBoxLayout() - self.info_box_layout.setContentsMargins(10, 10, 10, 10) - - font = QtGui.QFont() - font.setFamily(font_family) - font.setPointSize(20) - self.info_box = QtWidgets.QGridLayout() - self.info_box.setContentsMargins(0, 0, 0, 0) - - self.vib_title_label = QtWidgets.QLabel(self) - self.vib_title_label.setText("Vibrations: ") - self.vib_title_label.setMinimumSize(QtCore.QSize(60, 60)) - self.vib_title_label.setMaximumSize( - QtCore.QSize(int(self.infobox_frame.size().width() * 0.40), 9999) - ) - palette = self.vib_title_label.palette() - palette.setColor(palette.ColorRole.WindowText, QtGui.QColor("#FFFFFF")) - self.vib_title_label.setAlignment( - QtCore.Qt.AlignmentFlag.AlignLeft | QtCore.Qt.AlignmentFlag.AlignVCenter - ) - self.vib_title_label.setFont(font) - self.vib_title_label.setPalette(palette) - self.vib_title_label.setLayoutDirection(QtCore.Qt.LayoutDirection.RightToLeft) - self.vib_label = QtWidgets.QLabel(self) - self.vib_label.setMinimumSize(QtCore.QSize(100, 60)) - self.vib_label.setMaximumSize(QtCore.QSize(16777215, 9999)) - palette = self.vib_label.palette() - palette.setColor(palette.ColorRole.WindowText, QtGui.QColor("#FFFFFF")) - self.vib_label.setFont(font) - self.vib_label.setPalette(palette) - self.vib_label.setLayoutDirection(QtCore.Qt.LayoutDirection.RightToLeft) - self.vib_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - self.vib_label.setObjectName("version-tracking") - - self.info_box.addWidget(self.vib_title_label, 0, 0) - self.info_box.addWidget(self.vib_label, 0, 1) - - self.sug_accel_title_label = QtWidgets.QLabel(self) - self.sug_accel_title_label.setText("Sugested Max\nAcceleration:") - self.sug_accel_title_label.setMinimumSize(QtCore.QSize(60, 60)) - self.sug_accel_title_label.setMaximumSize( - QtCore.QSize(int(self.infobox_frame.size().width() * 0.40), 9999) - ) - palette = self.sug_accel_title_label.palette() - palette.setColor(palette.ColorRole.WindowText, QtGui.QColor("#FFFFFF")) - self.sug_accel_title_label.setAlignment( - QtCore.Qt.AlignmentFlag.AlignLeft | QtCore.Qt.AlignmentFlag.AlignVCenter - ) - self.sug_accel_title_label.setFont(font) - self.sug_accel_title_label.setPalette(palette) - self.sug_accel_title_label.setLayoutDirection( - QtCore.Qt.LayoutDirection.RightToLeft - ) - - self.sug_accel_label = QtWidgets.QLabel(self) - self.sug_accel_label.setMinimumSize(QtCore.QSize(100, 60)) - self.sug_accel_label.setMaximumSize( - QtCore.QSize(int(self.infobox_frame.size().width() * 0.60), 9999) - ) - palette = self.sug_accel_label.palette() - palette.setColor(palette.ColorRole.WindowText, QtGui.QColor("#FFFFFF")) - self.sug_accel_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - self.sug_accel_label.setFont(font) - self.sug_accel_label.setPalette(palette) - - self.info_box.addWidget(self.sug_accel_title_label, 1, 0) - self.info_box.addWidget(self.sug_accel_label, 1, 1) - - self.info_box_layout.addLayout(self.info_box, 1) - - self.button_box = QtWidgets.QVBoxLayout() - self.button_box.setContentsMargins(0, 0, 0, 0) - self.button_box.addSpacing(-1) - - self.action_btn = BlocksCustomButton() - self.action_btn.setMinimumSize(QtCore.QSize(200, 60)) - self.action_btn.setMaximumSize(QtCore.QSize(250, 60)) - font.setPointSize(20) - self.action_btn.setFont(font) - self.action_btn.setPalette(palette) - self.action_btn.setSizePolicy(sizePolicy) - self.action_btn.setText("Confirm") - self.action_btn.setPixmap(QtGui.QPixmap(":/dialog/media/btn_icons/yes.svg")) - self.button_box.addWidget( - self.action_btn, - 0, - QtCore.Qt.AlignmentFlag.AlignRight | QtCore.Qt.AlignmentFlag.AlignBottom, - ) - - self.info_box_layout.addLayout( - self.button_box, - 0, - ) - self.infobox_frame.setLayout(self.info_box_layout) - self.main_content_layout.addWidget(self.infobox_frame, 1) - self.update_page_content_layout.addLayout(self.main_content_layout, 1) - self.setLayout(self.update_page_content_layout) diff --git a/BlocksScreen/lib/panels/widgets/UtilitiesTab/ledsPage.py b/BlocksScreen/lib/panels/widgets/UtilitiesTab/ledsPage.py new file mode 100644 index 00000000..08a80020 --- /dev/null +++ b/BlocksScreen/lib/panels/widgets/UtilitiesTab/ledsPage.py @@ -0,0 +1,364 @@ +import typing +from dataclasses import dataclass +from functools import partial + +from lib.utils.blocks_button import BlocksCustomButton +from lib.utils.blocks_slider import BlocksSlider +from lib.utils.icon_button import IconButton +from PyQt6 import QtCore, QtGui, QtWidgets + + +@dataclass +class LedState: + """Represents the state of an LED light.""" + + led_type: str + red: int = 0 + green: int = 0 + blue: int = 0 + white: int = 255 + state: bool = True + + def get_gcode(self, name: str) -> str: + """Generates the G-code command for the current state.""" + if not self.state: + return f"SET_LED LED={name} RED=0 GREEN=0 BLUE=0 WHITE=0" + if self.led_type == "white": + return f"SET_LED LED={name} WHITE={self.white / 255:.2f}" + return ( + f"SET_LED LED={name} RED={self.red / 255:.2f} " + f"GREEN={self.green / 255:.2f} BLUE={self.blue / 255:.2f} " + f"WHITE={self.white / 255:.2f}" + ) + + +class LedsPage(QtWidgets.QStackedWidget): + """Leds page of the utilities tab.""" + + _LED_TYPES: frozenset[str] = frozenset({"led", "neopixel", "dotstar"}) + + request_back_button = QtCore.pyqtSignal(name="request-back-button") + run_gcode_signal: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( + str, name="run-gcode" + ) + + def __init__( + self, + parent: typing.Optional["QtWidgets.QWidget"], + ) -> None: + super().__init__(parent) + + self.singleled: bool = False + self.leds: dict[str, LedState] = {} + self.current_led: str | None = None + + self._led_pixmap = QtGui.QPixmap(":/ui/media/btn_icons/LEDs.svg") + + self._setup_ui() + self.leds_back_btn.clicked.connect(self.request_back_button.emit) + + self.leds_w_slider.sliderReleased.connect(self.update_led_values) + self.leds_slider_back_btn.clicked.connect(self._slider_back) + self.leds_on_btn.clicked.connect(partial(self.set_led_state, True)) + self.leds_off_btn.clicked.connect(partial(self.set_led_state, False)) + + def showEvent(self, a0: QtGui.QShowEvent | None) -> None: + if self.singleled and self.leds: + self.handle_led_button(next(iter(self.leds))) + else: + self.setCurrentIndex(self.indexOf(self.main_page)) + + return super().showEvent(a0) + + def _slider_back(self) -> None: + if self.singleled: + self.request_back_button.emit() + else: + self.setCurrentIndex(self.indexOf(self.main_page)) + + def update_led_values(self) -> None: + """Update led state and color values""" + led_state: LedState = self.leds[str(self.current_led)] + led_state.white = int(self.leds_w_slider.value() * 255 / 100) + self.save_led_state() + + def on_object_list(self, config_file) -> bool: + layout = self.leds_content_layout + cg = config_file + + while layout.count(): + if (child := layout.takeAt(0)) and child.widget(): + child.widget().deleteLater() # type: ignore + + led_names = [] + self.leds.clear() + + for obj in cg: + parts = obj.split() + if len(parts) >= 2 and parts[0] in self._LED_TYPES: + name = parts[1] + led_names.append(name) + self.leds[name] = LedState(led_type="white") + + max_columns = 3 + self.singleled = len(led_names) == 1 + + for i, name in enumerate(led_names): + button = BlocksCustomButton() + button.setFixedSize(250, 80) + button.setText(name) + button.setProperty("class", "menu_btn") + button.setPixmap(self._led_pixmap) + row, col = divmod(i, max_columns) + layout.addWidget(button, row, col, QtCore.Qt.AlignmentFlag.AlignCenter) + button.clicked.connect(partial(self.handle_led_button, name)) + + return True + + def handle_led_button(self, name: str): + self.current_led = name + led_state = self.leds.get(name) + if not led_state: + return + is_rgb = led_state.led_type == "rgb" + self.leds_w_slider.setVisible(not is_rgb) + self.leds_w_slider.setValue(round(led_state.white * 100 / 255)) + self._sync_state_buttons(led_state.state) + self.leds_slider_tittle_label.setText(name.replace("_", " ")) + self.setCurrentIndex(self.indexOf(self.leds_slider_page)) + + def set_led_state(self, state: bool) -> None: + """Turn the current led on or off""" + led_state = self.leds.get(str(self.current_led)) + if not led_state or led_state.state == state: + return + led_state.state = state + self._sync_state_buttons(state) + self.save_led_state() + + def _sync_state_buttons(self, state: bool) -> None: + # Whichever button matches the state the led is already in has nothing + # left to do, so it is the one that greys out. + self.leds_on_btn.setEnabled(not state) + self.leds_off_btn.setEnabled(state) + + def save_led_state(self): + """Save led state""" + if self.current_led and self.current_led in self.leds: + led_state: LedState = self.leds[self.current_led] + self.run_gcode_signal.emit(led_state.get_gcode(self.current_led)) + + def _setup_ui(self) -> None: + self.setObjectName("leds_page") + + self.main_page = QtWidgets.QWidget() + self.main_page.setObjectName("leds_main_page") + spacerItem3 = QtWidgets.QSpacerItem( + 60, + 20, + QtWidgets.QSizePolicy.Policy.Minimum, + QtWidgets.QSizePolicy.Policy.Minimum, + ) + + spacerItem2 = QtWidgets.QSpacerItem( + 20, + 24, + QtWidgets.QSizePolicy.Policy.Minimum, + QtWidgets.QSizePolicy.Policy.Minimum, + ) + + spacerItem4 = QtWidgets.QSpacerItem( + 20, + 40, + QtWidgets.QSizePolicy.Policy.Minimum, + QtWidgets.QSizePolicy.Policy.Expanding, + ) + + spacerItem5 = QtWidgets.QSpacerItem( + 20, + 40, + QtWidgets.QSizePolicy.Policy.Minimum, + QtWidgets.QSizePolicy.Policy.Expanding, + ) + + self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.main_page) + self.verticalLayout_4.addItem(spacerItem2) + + self.leds_header_layout = QtWidgets.QHBoxLayout() + self.leds_header_layout.setContentsMargins(0, 0, 0, 0) + self.leds_header_layout.setObjectName("leds_header_layout") + self.leds_header_layout.addItem(spacerItem3) + + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Fixed + ) + + font = QtGui.QFont() + font.setFamily("Momcake") + font.setPointSize(24) + + self.leds_title_label = QtWidgets.QLabel(parent=self.main_page) + self.leds_title_label.setSizePolicy(sizePolicy) + self.leds_title_label.setFont(font) + self.leds_title_label.setStyleSheet("background: transparent; color: white;") + self.leds_title_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + self.leds_title_label.setFixedHeight(60) + self.leds_header_layout.addWidget(self.leds_title_label) + + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.MinimumExpanding, + QtWidgets.QSizePolicy.Policy.MinimumExpanding, + ) + + self.leds_back_btn = IconButton(parent=self.main_page) + self.leds_back_btn.setSizePolicy(sizePolicy) + self.leds_back_btn.setMinimumSize(QtCore.QSize(60, 60)) + self.leds_back_btn.setMaximumSize(QtCore.QSize(60, 60)) + self.leds_back_btn.setProperty( + "icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/back.svg") + ) + self.leds_header_layout.addWidget(self.leds_back_btn) + + self.verticalLayout_4.addLayout(self.leds_header_layout) + self.verticalLayout_4.addItem(spacerItem4) + + self.leds_content_layout = QtWidgets.QGridLayout() + self.leds_content_layout.setObjectName("leds_content_layout") + + self.verticalLayout_4.addLayout(self.leds_content_layout) + self.verticalLayout_4.addItem(spacerItem5) + + self.addWidget(self.main_page) + + # --- LED slider page ------------------------------------------------- + + self.leds_slider_page = QtWidgets.QWidget() + self.leds_slider_page.setObjectName("leds_slider_page") + + self.verticalLayout_12 = QtWidgets.QVBoxLayout(self.leds_slider_page) + self.verticalLayout_12.setObjectName("verticalLayout_12") + self.verticalLayout_12.setContentsMargins(10, 30, 9, 9) + self.verticalLayout_12.setSpacing(0) + + self.leds_slider_header_layout = QtWidgets.QHBoxLayout() + self.leds_slider_header_layout.setObjectName("leds_slider_header_layout") + self.leds_slider_header_layout.setContentsMargins(0, 10, 0, 11) + self.leds_slider_header_layout.setSpacing(6) + self.leds_slider_header_layout.addItem( + QtWidgets.QSpacerItem( + 60, + 20, + QtWidgets.QSizePolicy.Policy.Minimum, + QtWidgets.QSizePolicy.Policy.Minimum, + ) + ) + + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.Expanding, + QtWidgets.QSizePolicy.Policy.Preferred, + ) + + font = QtGui.QFont() + font.setFamily("Momcake") + font.setPointSize(24) + + self.leds_slider_tittle_label = QtWidgets.QLabel(parent=self.leds_slider_page) + self.leds_slider_tittle_label.setSizePolicy(sizePolicy) + self.leds_slider_tittle_label.setMinimumSize(QtCore.QSize(0, 60)) + self.leds_slider_tittle_label.setMaximumSize(QtCore.QSize(16777215, 60)) + self.leds_slider_tittle_label.setFont(font) + self.leds_slider_tittle_label.setStyleSheet( + "background: transparent; color: white;" + ) + self.leds_slider_tittle_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + self.leds_slider_tittle_label.setObjectName("leds_slider_tittle_label") + self.leds_slider_header_layout.addWidget(self.leds_slider_tittle_label) + + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.MinimumExpanding, + QtWidgets.QSizePolicy.Policy.MinimumExpanding, + ) + + self.leds_slider_back_btn = IconButton(parent=self.leds_slider_page) + self.leds_slider_back_btn.setSizePolicy(sizePolicy) + self.leds_slider_back_btn.setMinimumSize(QtCore.QSize(60, 60)) + self.leds_slider_back_btn.setMaximumSize(QtCore.QSize(60, 60)) + self.leds_slider_back_btn.setProperty( + "icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/back.svg") + ) + self.leds_slider_back_btn.setObjectName("leds_slider_back_btn") + self.leds_slider_header_layout.addWidget(self.leds_slider_back_btn) + + self.verticalLayout_12.addLayout(self.leds_slider_header_layout) + + self.verticalLayout_12.addSpacing(50) + + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Fixed + ) + + self.leds_slider_content_layout = QtWidgets.QVBoxLayout() + self.leds_slider_content_layout.setObjectName("leds_slider_content_layout") + self.leds_slider_content_layout.setContentsMargins(0, 5, 0, 30) + + self.leds_w_slider = BlocksSlider(parent=self.leds_slider_page) + self.leds_w_slider.setSizePolicy(sizePolicy) + self.leds_w_slider.setMinimumSize(QtCore.QSize(600, 90)) + self.leds_w_slider.setMaximumSize(QtCore.QSize(600, 90)) + self.leds_w_slider.setMaximum(100) + self.leds_w_slider.setProperty("value", 100) + self.leds_w_slider.setOrientation(QtCore.Qt.Orientation.Horizontal) + self.leds_slider_content_layout.addWidget( + self.leds_w_slider, 0, QtCore.Qt.AlignmentFlag.AlignHCenter + ) + + self.verticalLayout_12.addLayout(self.leds_slider_content_layout) + self.verticalLayout_12.addSpacing(20) + + # The on/off pair that replaced the toggle. Only one of them is ever + # enabled -- see _sync_state_buttons. + self.leds_buttons_layout = QtWidgets.QHBoxLayout() + self.leds_buttons_layout.setObjectName("leds_buttons_layout") + self.leds_buttons_layout.setContentsMargins(0, 0, 0, 0) + self.leds_buttons_layout.setSpacing(50) + self.leds_buttons_layout.addStretch(1) + + font = QtGui.QFont() + font.setFamily("Momcake") + font.setPointSize(19) + + self.leds_on_btn = BlocksCustomButton(parent=self.leds_slider_page) + self.leds_on_btn.setFixedSize(QtCore.QSize(250, 80)) + self.leds_on_btn.setFont(font) + self.leds_on_btn.setProperty("class", "menu_btn") + self.leds_on_btn.setPixmap(self._led_pixmap) + self.leds_on_btn.setObjectName("leds_on_btn") + self.leds_on_btn.setText("ON") + self.leds_buttons_layout.addWidget(self.leds_on_btn) + + self.leds_off_btn = BlocksCustomButton(parent=self.leds_slider_page) + self.leds_off_btn.setFixedSize(QtCore.QSize(250, 80)) + self.leds_off_btn.setFont(font) + self.leds_off_btn.setProperty("class", "menu_btn") + self.leds_off_btn.setPixmap(QtGui.QPixmap(":/ui/media/btn_icons/LEDs_off.svg")) + self.leds_off_btn.setObjectName("leds_off_btn") + self.leds_off_btn.setText("OFF") + self.leds_buttons_layout.addWidget(self.leds_off_btn) + + self.leds_buttons_layout.addStretch(1) + + # LedState defaults to on, and so does the pair until a led is opened. + self._sync_state_buttons(True) + + self.verticalLayout_12.addLayout(self.leds_buttons_layout) + self.verticalLayout_12.addStretch(1) + + self.addWidget(self.leds_slider_page) + self.setAttribute(QtCore.Qt.WidgetAttribute.WA_StyledBackground, True) + + _translate = QtCore.QCoreApplication.translate + + self.leds_title_label.setText(_translate("self", "LED's")) + self.leds_back_btn.setText(_translate("self", "Back")) + self.leds_slider_back_btn.setText(_translate("self", "Back")) + self.leds_slider_tittle_label.setText(_translate("self", "LED's")) diff --git a/BlocksScreen/lib/panels/widgets/UtilitiesTab/routinePage.py b/BlocksScreen/lib/panels/widgets/UtilitiesTab/routinePage.py new file mode 100644 index 00000000..a3b81682 --- /dev/null +++ b/BlocksScreen/lib/panels/widgets/UtilitiesTab/routinePage.py @@ -0,0 +1,494 @@ +import math +import typing +from dataclasses import dataclass, replace + +from lib.panels.widgets.Common.basePopup import BasePopup +from lib.utils.blocks_button import BlocksCustomButton +from lib.utils.icon_button import IconButton +from PyQt6 import QtCore, QtGui, QtWidgets + + +class RoutineCheckPage(QtWidgets.QWidget): + """Routine check page of the utilities tab.""" + + request_back: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( + name="request-back" + ) + run_gcode_signal: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( + str, name="run-gcode" + ) + call_load_panel: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( + bool, str, bool, name="call-load-panel" + ) + request_tb_page: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( + name="request-tb-page" + ) + subscribe_config: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( + [list, "PyQt_PyObject"], + [str, "PyQt_PyObject"], + name="on-subscribe-config", + ) + + HOMED_AXES = frozenset("xyz") + + @dataclass(frozen=True) + class Step: + label: str + prompt: str + gcode: str + cleanup: str = "" + + @dataclass(frozen=True) + class AxisLimits: + """Travel range of one stepper, as reported by the printer config.""" + + min: float + max: float + homes_at_min: bool + + @property + def span(self) -> float: + """How far the axis can travel end to end.""" + return self.max - self.min + + def __init__( + self, + parent: typing.Optional["QtWidgets.QWidget"], + ) -> None: + super().__init__(parent) + self._setup_ui() + + self.fans: list[str] = [] + self.axis_limits: dict[str, RoutineCheckPage.AxisLimits] = {} + + self._steps: list[RoutineCheckPage.Step] = [] + self._index: int = -1 + self._awaiting: bool = False + + self._homing: bool = False + self._home_dropped: bool = False + self._pending: RoutineCheckPage.Step | None = None + + self._home_settle: QtCore.QTimer = QtCore.QTimer(self) + self._home_settle.setSingleShot(True) + self._home_settle.setInterval(10_000) + self._home_settle.timeout.connect(self._home_finished) + + self._home_guard: QtCore.QTimer = QtCore.QTimer(self) + self._home_guard.setSingleShot(True) + self._home_guard.setInterval(180_000) + self._home_guard.timeout.connect(self._home_finished) + + self.answerPopup: BasePopup = BasePopup(self) + self.answerPopup.accepted.connect(lambda: self.on_answer(True)) + self.answerPopup.rejected.connect(lambda: self.on_answer(False)) + + self.rp_button_1.clicked.connect(self.start_fan) + self.rp_button_2.clicked.connect(self.start_axis) + self.rp_button_3.clicked.connect(self.start_extruder) + self.rp_button_4.clicked.connect(self.start_bed) + self.back_button.clicked.connect(self.abort) + self.back_button.clicked.connect(self.request_back) + + def on_object_list(self, object_list: list): + """Collect the fans this printer reports, dropping any earlier list.""" + self.fans = [] + for obj in object_list: + base_name = obj.split()[0] + + if base_name == "fan_generic" or base_name == "fan": + self.fans.append(obj.removeprefix(base_name + " ")) + + @QtCore.pyqtSlot(dict, name="on_object_config") + @QtCore.pyqtSlot(list, name="on_object_config") + def on_object_config(self, config: dict | list) -> None: + """Handle receiving printer object configurations""" + if not config: + return + self.axis_limits.update(self.parse_axis_limits(config)) + + def on_printer_config_received(self, config: dict) -> None: + """Handle printer configuration""" + for axis in ("x", "y", "z"): + self.subscribe_config[str, "PyQt_PyObject"].emit( + f"stepper_{axis}", self.on_object_config + ) + + @QtCore.pyqtSlot(str, str, name="on_toolhead_update") + def on_toolhead_update(self, field: str, value: str) -> None: + """Watch homed_axes so the homing screen knows when to come down.""" + if field != "homed_axes" or not self._homing: + return + + if not self.HOMED_AXES <= set(str(value).lower()): + self._home_dropped = True + return + + if self._home_dropped and not self._home_settle.isActive(): + self._home_settle.start() + + def start_fan(self) -> None: + """Check every fan this printer reports, one at a time.""" + self.start_routine(self.fan_steps(self.fans)) + + def start_axis(self) -> None: + """Home, then move each axis out and back so the user can watch it.""" + self.start_routine(self.axis_steps(self.axis_limits)) + + def start_extruder(self) -> None: + """Check the extruder heater.""" + self.start_routine(self.heater_steps(["extruder"])) + + def start_bed(self) -> None: + """Check the bed heater.""" + self.start_routine(self.heater_steps(["heater_bed"])) + + def start_routine(self, steps: list[Step]) -> None: + """Begin a routine, asking about each step in turn.""" + self.abort() + self._steps = steps + self._index = -1 + self.next_step() + + def next_step(self) -> None: + """Advance to the next step, or finish when they have all been checked.""" + self._index += 1 + if self._index >= len(self._steps): + self._reset() + return + self._awaiting = True + step = self._steps[self._index] + self.send_gcode(step.gcode) + if self._homing: + self._pending = step + else: + self._ask(step) + + def on_answer(self, ok: bool) -> None: + """Continue to the next step, or hand over to troubleshoot on a no.""" + if not self._awaiting: + return + self._awaiting = False + cleanup = self._steps[self._index].cleanup + if cleanup: + self.send_gcode(cleanup) + if ok: + self.next_step() + return + self._reset() + self.request_tb_page.emit() + + def abort(self) -> None: + """Cancel a running routine and undo anything it left running.""" + if not self._steps: + return + self.answerPopup.hide() + + seen: set[str] = set() + for step in self._steps: + if step.cleanup and step.cleanup not in seen: + seen.add(step.cleanup) + self.send_gcode(step.cleanup) + + self._reset() + + def _reset(self) -> None: + self._steps = [] + self._index = -1 + self._awaiting = False + self._pending = None + + def send_gcode(self, gcode: str) -> None: + """Run a g-code block, raising the homing screen if it homes.""" + if "G28" in gcode: + self._await_home() + self.run_gcode_signal.emit(gcode) + + def _await_home(self) -> None: + self._homing = True + self._home_dropped = False + self._home_settle.stop() + self._home_guard.start() + self.answerPopup.hide() + self.call_load_panel.emit(True, "Homing...\nPlease wait", False) + + def _home_finished(self) -> None: + self._home_settle.stop() + self._home_guard.stop() + self._homing = False + self._home_dropped = False + self.call_load_panel.emit(False, "", False) + + step, self._pending = self._pending, None + if step is not None: + self._ask(step) + + def _ask(self, step: Step) -> None: + self.answerPopup.set_message(step.prompt) + self.answerPopup.show() + + @classmethod + def fan_steps(cls, fans: list[str]) -> list[Step]: + steps = [] + for fan in fans: + if fan == "fan": + label = "part cooling fan" + on, off = "M106 S255", "M107" + else: + label = fan + on = f"SET_FAN_SPEED FAN={fan} SPEED=0.8" + off = f"SET_FAN_SPEED FAN={fan} SPEED=0" + steps.append( + cls.Step( + label=label, + prompt=f"Please check if the {label} is spinning.", + gcode=f"{on}\nM400", + cleanup=off, + ) + ) + return steps + + @classmethod + def heater_steps(cls, heaters: list[str]) -> list[Step]: + """Build one check step per heater, warming each to 60 degrees.""" + steps = [] + for heater in heaters: + label = "bed heater" if heater == "heater_bed" else heater + steps.append( + cls.Step( + label=label, + prompt=( + f"Please check if the {label} reaches 60ºC.\n" + "It may take a few moments." + ), + gcode=f"SET_HEATER_TEMPERATURE HEATER={heater} TARGET=60\nM400", + cleanup="TURN_OFF_HEATERS", + ) + ) + return steps + + @classmethod + def parse_axis_limits( + cls, + config: dict | list | None, + ) -> dict[str, AxisLimits]: + """Pull the travel range of every stepper out of a printer config reply.""" + if not config: + return {} + + limits = {} + for item in [config] if isinstance(config, dict) else config: + for key, value in item.items(): + if not key.startswith("stepper_") or not isinstance(value, dict): + continue + + pos_min = value.get("position_min") + pos_max = value.get("position_max") + if pos_min is None and pos_max is None: + continue + + low = float(pos_min) if pos_min is not None else -math.inf + high = float(pos_max) if pos_max is not None else math.inf + + endstop_raw = value.get("position_endstop") + endstop = float(endstop_raw) if endstop_raw is not None else 0.0 + homes_at_min = abs(endstop - low) <= abs(endstop - high) + + limits[key.removeprefix("stepper_")] = cls.AxisLimits( + min=low, max=high, homes_at_min=homes_at_min + ) + return limits + + @staticmethod + def axis_move_gcode( + axis: str, + limits: AxisLimits, + margin: float = 70.0, + park: float | None = None, + ) -> str: + """Move the axis most of the way out and back, in absolute coordinates.""" + span = limits.span + if not math.isfinite(span) or span <= 0: + return "" + + if span - (2 * margin) <= 0: + margin = span * 0.1 + + far = limits.max - margin if limits.homes_at_min else limits.min + margin + middle = (limits.min + limits.max) / 2 + + name = axis.upper() + moves = [ + "G90", + f"G1 {name}{far:.2f} F{6000}", + f"G1 {name}{middle:.2f} F{6000}", + ] + if park is not None: + parked = min(max(park, limits.min), limits.max) + if abs(parked - middle) >= 0.01: + moves.append(f"G1 {name}{parked:.2f} F{6000}") + + return "\n".join(moves) + + @classmethod + def axis_steps( + cls, + limits: dict[str, AxisLimits], + axes: typing.Sequence[str] = ("x", "y", "z"), + ) -> list[Step]: + """Build one check step per axis, homing once before the first of them.""" + y = limits.get("y") + park_x = ( + (y.min + y.max) / 2 if y is not None and math.isfinite(y.span) else None + ) + + steps = [] + for axis in ["x", "y", "z"]: + limit = limits.get(axis) + if limit is None: + continue + + moves = cls.axis_move_gcode( + axis, limit, park=park_x if axis == "x" else None + ) + if not moves: + continue + + prologue = "" if steps else "G28\nM400\n" + steps.append( + cls.Step( + label=f"{axis.upper()} axis", + prompt=f"Please ensure the {axis.upper()} axis moves correctly.", + gcode=f"{prologue}{moves}\nM400", + ) + ) + + if steps: + steps[-1] = replace(steps[-1], cleanup="G28") + return steps + + def _setup_ui(self) -> None: + + self.blank = QtWidgets.QWidget() + self.blank.setMinimumSize(QtCore.QSize(250, 80)) + self.blank.setMaximumSize(QtCore.QSize(250, 80)) + + self.Hblank = QtWidgets.QWidget() + self.Hblank.setMinimumSize(QtCore.QSize(60, 60)) + self.Hblank.setMaximumSize(QtCore.QSize(60, 60)) + + self.verticalLayout = QtWidgets.QVBoxLayout(self) + self.verticalLayout.setObjectName("verticalLayout") + + self.rp_header_layout = QtWidgets.QHBoxLayout() + self.rp_header_layout.setObjectName("rp_header_layout") + + self.rp_header_layout.addWidget(self.Hblank) + + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum + ) + font = QtGui.QFont() + font.setFamily("Momcake") + font.setPointSize(24) + self.rp_header_title = QtWidgets.QLabel(parent=self) + self.rp_header_title.setSizePolicy(sizePolicy) + self.rp_header_title.setMinimumSize(QtCore.QSize(0, 60)) + self.rp_header_title.setMaximumSize(QtCore.QSize(16777215, 60)) + self.rp_header_title.setFont(font) + self.rp_header_title.setStyleSheet("background: transparent; color: white;") + self.rp_header_title.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + self.rp_header_layout.addWidget(self.rp_header_title) + + self.back_button = IconButton(parent=self) + self.back_button.setPixmap(QtGui.QPixmap(":/ui/media/btn_icons/back.svg")) + self.back_button.setMinimumSize(QtCore.QSize(60, 60)) + self.back_button.setMaximumSize(QtCore.QSize(60, 60)) + self.rp_header_layout.addWidget(self.back_button) + + self.verticalLayout.addLayout(self.rp_header_layout) + + self.rp_content_layout = QtWidgets.QGridLayout() + self.rp_content_layout.setObjectName("rp_content_layout") + + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.Expanding, + QtWidgets.QSizePolicy.Policy.Expanding, + ) + + font = QtGui.QFont() + font.setFamily("Momcake") + font.setPointSize(19) + + self.rp_button_1 = BlocksCustomButton(parent=self) + self.rp_button_1.setSizePolicy(sizePolicy) + self.rp_button_1.setMinimumSize(QtCore.QSize(250, 80)) + self.rp_button_1.setMaximumSize(QtCore.QSize(250, 80)) + self.rp_button_1.setFont(font) + self.rp_button_1.setProperty( + "icon_pixmap", + QtGui.QPixmap(":/fan_related/media/btn_icons/fan_cage.svg"), + ) + self.rp_content_layout.addWidget(self.rp_button_1, 0, 0, 1, 1) + + self.rp_button_2 = BlocksCustomButton(parent=self) + self.rp_button_2.setSizePolicy(sizePolicy) + self.rp_button_2.setMinimumSize(QtCore.QSize(250, 80)) + self.rp_button_2.setMaximumSize(QtCore.QSize(250, 80)) + self.rp_button_2.setFont(font) + self.rp_button_2.setProperty( + "icon_pixmap", + QtGui.QPixmap(":/motion/media/btn_icons/axis_maintenance.svg"), + ) + self.rp_content_layout.addWidget(self.rp_button_2, 0, 1, 1, 1) + + self.rp_button_3 = BlocksCustomButton(parent=self) + self.rp_button_3.setSizePolicy(sizePolicy) + self.rp_button_3.setMinimumSize(QtCore.QSize(250, 80)) + self.rp_button_3.setMaximumSize(QtCore.QSize(250, 80)) + self.rp_button_3.setFont(font) + self.rp_button_3.setProperty( + "icon_pixmap", + QtGui.QPixmap(":/extruder_related/media/btn_icons/nozzle.svg"), + ) + self.rp_content_layout.addWidget(self.rp_button_3, 1, 0, 1, 1) + + self.rp_button_4 = BlocksCustomButton(parent=self) + self.rp_button_4.setSizePolicy(sizePolicy) + self.rp_button_4.setMinimumSize(QtCore.QSize(250, 80)) + self.rp_button_4.setMaximumSize(QtCore.QSize(250, 80)) + self.rp_button_4.setFont(font) + self.rp_button_4.setProperty( + "icon_pixmap", + QtGui.QPixmap( + ":/temperature_related/media/btn_icons/temperature_plate.svg" + ), + ) + self.rp_content_layout.addWidget(self.rp_button_4, 1, 1, 1, 1) + + self.rp_content_layout.addWidget(self.blank, 2, 0, 1, 1) + + self.rp_content_layout.setRowMinimumHeight(0, 80) + self.rp_content_layout.setRowMinimumHeight(1, 80) + self.rp_content_layout.setRowMinimumHeight(2, 80) + + content_widget = QtWidgets.QWidget(parent=self) + content_widget.setLayout(self.rp_content_layout) + content_widget.setSizePolicy( + QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Fixed + ) + self.rp_content_layout.setContentsMargins(0, 0, 0, 0) + content_widget.setFixedHeight(80 * 3 + self.rp_content_layout.spacing() * 2) + + self.verticalLayout.addWidget(content_widget) + + _translate = QtCore.QCoreApplication.translate + self.setWindowTitle(_translate("controlStackedWidget", "StackedWidget")) + self.rp_header_title.setText( + _translate("controlStackedWidget", "Routine Check") + ) + + self.rp_button_1.setText(_translate("controlStackedWidget", "Fans")) + self.rp_button_2.setText(_translate("controlStackedWidget", "Axis")) + self.rp_button_3.setText(_translate("controlStackedWidget", "extruder")) + self.rp_button_4.setText(_translate("controlStackedWidget", "Bed Heater")) diff --git a/BlocksScreen/lib/panels/widgets/UtilitiesTab/troubleshootPage.py b/BlocksScreen/lib/panels/widgets/UtilitiesTab/troubleshootPage.py index 1727b210..eba596fb 100644 --- a/BlocksScreen/lib/panels/widgets/UtilitiesTab/troubleshootPage.py +++ b/BlocksScreen/lib/panels/widgets/UtilitiesTab/troubleshootPage.py @@ -1,6 +1,5 @@ -from PyQt6 import QtCore, QtGui, QtWidgets - from lib.utils.icon_button import IconButton +from PyQt6 import QtCore, QtGui, QtWidgets class TroubleshootPage(QtWidgets.QDialog): @@ -48,85 +47,82 @@ def show(self) -> None: return super().show() def _setup_ui(self) -> None: + self.setObjectName("troubleshoot_page") + self.verticalLayout = QtWidgets.QVBoxLayout(self) self.verticalLayout.setObjectName("verticalLayout") - self.leds_slider_header_layout_2 = QtWidgets.QHBoxLayout() - self.leds_slider_header_layout_2.setObjectName("leds_slider_header_layout_2") spacerItem18 = QtWidgets.QSpacerItem( 60, 60, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum, ) - self.leds_slider_header_layout_2.addItem(spacerItem18) spacerItem19 = QtWidgets.QSpacerItem( 181, 60, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum, ) + + spacerItem20 = QtWidgets.QSpacerItem( + 0, + 60, + QtWidgets.QSizePolicy.Policy.Expanding, + QtWidgets.QSizePolicy.Policy.Minimum, + ) + + self.leds_slider_header_layout_2 = QtWidgets.QHBoxLayout() + self.leds_slider_header_layout_2.setObjectName("leds_slider_header_layout_2") + + self.leds_slider_header_layout_2.addItem(spacerItem18) self.leds_slider_header_layout_2.addItem(spacerItem19) - self.tb_tittle_label = QtWidgets.QLabel("Troubleshoot", parent=self) - self.tb_tittle_label.setMinimumSize(QtCore.QSize(0, 60)) - self.tb_tittle_label.setMaximumSize(QtCore.QSize(16777215, 60)) + font = QtGui.QFont() font.setFamily("Momcake") font.setPointSize(24) + + self.tb_tittle_label = QtWidgets.QLabel("Troubleshoot", parent=self) + self.tb_tittle_label.setMinimumSize(QtCore.QSize(0, 60)) + self.tb_tittle_label.setMaximumSize(QtCore.QSize(16777215, 60)) self.tb_tittle_label.setFont(font) self.tb_tittle_label.setStyleSheet("background: transparent; color: white;") self.tb_tittle_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - self.tb_tittle_label.setObjectName("tb_tittle_label") + self.leds_slider_header_layout_2.addWidget(self.tb_tittle_label) - spacerItem20 = QtWidgets.QSpacerItem( - 0, - 60, - QtWidgets.QSizePolicy.Policy.Expanding, - QtWidgets.QSizePolicy.Policy.Minimum, - ) self.leds_slider_header_layout_2.addItem(spacerItem20) - self.tb_back_btn = IconButton(parent=self) + sizePolicy = QtWidgets.QSizePolicy( QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.MinimumExpanding, ) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.tb_back_btn.sizePolicy().hasHeightForWidth()) + + self.tb_back_btn = IconButton(parent=self) self.tb_back_btn.setSizePolicy(sizePolicy) self.tb_back_btn.setMinimumSize(QtCore.QSize(60, 60)) self.tb_back_btn.setMaximumSize(QtCore.QSize(60, 60)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(24) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.tb_back_btn.setFont(font) - self.tb_back_btn.setMouseTracking(False) - self.tb_back_btn.setTabletTracking(True) - self.tb_back_btn.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.tb_back_btn.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.tb_back_btn.setStyleSheet("") - self.tb_back_btn.setAutoDefault(False) - self.tb_back_btn.setFlat(True) self.tb_back_btn.setProperty( "icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/back.svg") ) - self.tb_back_btn.setObjectName("tb_back_btn") + self.leds_slider_header_layout_2.addWidget(self.tb_back_btn) + self.verticalLayout.addLayout(self.leds_slider_header_layout_2) + self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") + self.verticalLayout_10 = QtWidgets.QVBoxLayout() self.verticalLayout_10.setObjectName("verticalLayout_10") - self.label_4 = QtWidgets.QLabel("idk whar to type this", parent=self) + sizePolicy = QtWidgets.QSizePolicy( QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding, ) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_4.sizePolicy().hasHeightForWidth()) + self.label_4 = QtWidgets.QLabel( + "For more information check our website \n www.blockstec.com \n or \nsupport@blockstec.com", + parent=self, + ) self.label_4.setSizePolicy(sizePolicy) font = QtGui.QFont() font.setPointSize(24) diff --git a/BlocksScreen/lib/ui/utilitiesStackedWidget.ui b/BlocksScreen/lib/ui/utilitiesStackedWidget.ui deleted file mode 100644 index 3df1f8fc..00000000 --- a/BlocksScreen/lib/ui/utilitiesStackedWidget.ui +++ /dev/null @@ -1,3072 +0,0 @@ - - - utilitiesStackedWidget - - - - 0 - 0 - 710 - 410 - - - - - 0 - 0 - - - - - 710 - 410 - - - - - 710 - 410 - - - - StackedWidget - - - 5 - - - - - - - - - - 0 - 0 - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - Momcake - 24 - true - - - - background: transparent; color: white; - - - Utilities - - - Qt::AlignCenter - - - title_text - - - - - - - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - Axis -Maint. - - - false - - - true - - - menu_btn - - - :/motion/media/btn_icons/axis_maintenance.svg - - - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - - - - Update - - - true - - - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - Routine -Check - - - false - - - true - - - menu_btn - - - :/ui/media/btn_icons/routine.svg - - - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - Input -Shaper - - - false - - - true - - - menu_btn - - - :/input_shaper/media/btn_icons/input_shaper.svg - - - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - Info - - - false - - - true - - - menu_btn - - - :/ui/media/btn_icons/info.svg - - - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - LED's - - - false - - - true - - - menu_btn - - - :/ui/media/btn_icons/LEDs.svg - - - - - - - - - - - - - Qt::Orientation::Vertical - - - QSizePolicy::Policy::Minimum - - - - 20 - 24 - - - - - - - - - - Qt::Orientation::Horizontal - - - QSizePolicy::Policy::Minimum - - - - 60 - 60 - - - - - - - - - 0 - 0 - - - - - 16777215 - 60 - - - - - Momcake - 24 - - - - background: transparent; color: white; - - - Info - - - Qt::AlignCenter - - - title_text - - - - - - - - 0 - 0 - - - - - 60 - 60 - - - - - 60 - 60 - - - - - Momcake - 20 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - Back - - - false - - - true - - - menu_btn - - - icon - - - :/ui/media/btn_icons/back.svg - - - - - - - - - - - - 350 - 260 - - - - - 350 - 290 - - - - QFrame::Shape::StyledPanel - - - QFrame::Shadow::Raised - - - - - 0 - 10 - 351 - 81 - - - - - 0 - 0 - - - - - 20 - - - - color:white - - - Model: Blocks RF50 - - - Qt::AlignCenter - - - - - - 0 - 110 - 351 - 81 - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 20 - - - - color:white - - - www.blockstec.com - - - Qt::AlignCenter - - - - - - - - - - - - - - Qt::Orientation::Vertical - - - QSizePolicy::Policy::Minimum - - - - 20 - 24 - - - - - - - - - - Qt::Orientation::Horizontal - - - QSizePolicy::Policy::Minimum - - - - 60 - 20 - - - - - - - - - 0 - 0 - - - - - Momcake - 24 - - - - background: transparent; color: white; - - - LED's - - - Qt::AlignCenter - - - title_text - - - - - - - - 0 - 0 - - - - - 60 - 60 - - - - - 60 - 60 - - - - - Momcake - 20 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - Back - - - false - - - true - - - menu_btn - - - icon - - - :/ui/media/btn_icons/back.svg - - - - - - - - - Qt::Orientation::Vertical - - - - 20 - 40 - - - - - - - - Qt::Orientation::Vertical - - - - - - - - - - - - - - Qt::Orientation::Vertical - - - - 20 - 40 - - - - - - - - - - - - Qt::Orientation::Vertical - - - QSizePolicy::Policy::Minimum - - - - 20 - 24 - - - - - - - - QLayout::SizeConstraint::SetMinimumSize - - - - - Qt::Orientation::Horizontal - - - QSizePolicy::Policy::Minimum - - - - 60 - 20 - - - - - - - - - 0 - 0 - - - - - Momcake - 24 - - - - background: transparent; color: white; - - - Routine Check - - - Qt::AlignCenter - - - title_text - - - - - - - - 0 - 0 - - - - - 60 - 60 - - - - - 60 - 60 - - - - - Momcake - 20 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - Back - - - false - - - true - - - menu_btn - - - icon - - - :/ui/media/btn_icons/back.svg - - - - - - - - - Qt::Orientation::Vertical - - - QSizePolicy::Policy::Minimum - - - - 20 - 60 - - - - - - - - 20 - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - Bed Heater - - - false - - - true - - - menu_btn - - - :/temperature_related/media/btn_icons/temperature_plate.svg - - - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - Fans - - - false - - - true - - - menu_btn - - - :/fan_related/media/btn_icons/fan_cage.svg - - - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - Axis - - - false - - - true - - - menu_btn - - - :/motion/media/btn_icons/axis_maintenance.svg - - - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - Extruder - - - false - - - true - - - menu_btn - - - :/extruder_related/media/btn_icons/nozzle.svg - - - - - - - - - Qt::Orientation::Vertical - - - - 20 - 40 - - - - - - - - - - - - Qt::Orientation::Vertical - - - QSizePolicy::Policy::Minimum - - - - 20 - 24 - - - - - - - - - - - 0 - 0 - - - - - 0 - 60 - - - - - Momcake - 24 - - - - background: transparent; color: white; - - - label - - - Qt::AlignCenter - - - title_text - - - - - - - - - 0 - - - - - - 0 - 0 - - - - - 15 - - - - color:white - - - TextLabel - - - Qt::AlignCenter - - - - - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - Yes - - - false - - - true - - - menu_btn - - - :/dialog/media/btn_icons/yes.svg - - - - - - - Qt::Orientation::Horizontal - - - QSizePolicy::Policy::Minimum - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - No - - - false - - - true - - - menu_btn - - - :/dialog/media/btn_icons/no.svg - - - - - - - - - - - - - - - Qt::Orientation::Vertical - - - QSizePolicy::Policy::Minimum - - - - 20 - 24 - - - - - - - - - - Qt::Orientation::Horizontal - - - QSizePolicy::Policy::Minimum - - - - 60 - 20 - - - - - - - - - 0 - 0 - - - - - 16777215 - 60 - - - - - Momcake - 24 - - - - background: transparent; color: white; - - - Axis Maintenance - - - Qt::AlignCenter - - - title_text - - - - - - - - 0 - 0 - - - - - 60 - 60 - - - - - 60 - 60 - - - - - Momcake - 20 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - Back - - - false - - - true - - - menu_btn - - - icon - - - :/ui/media/btn_icons/back.svg - - - - - - - - - - 0 - 0 - - - - - 650 - 0 - - - - QFrame::Shape::StyledPanel - - - QFrame::Shadow::Raised - - - - - - - 60 - 80 - - - - - 250 - 80 - - - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - - - 120 - 120 - 120 - - - - - - - 120 - 120 - 120 - - - - - - - 120 - 120 - 120 - - - - - - - - - 20 - - - - Y - - - true - - - true - - - true - - - true - - - axis_maintenance_gb - - - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - Execute - - - false - - - true - - - menu_btn - - - :/dialog/media/btn_icons/yes.svg - - - - - - - - 60 - 80 - - - - - 250 - 80 - - - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - - - 120 - 120 - 120 - - - - - - - 120 - 120 - 120 - - - - - - - 120 - 120 - 120 - - - - - - - - - 20 - - - - Z - - - true - - - false - - - true - - - true - - - axis_maintenance_gb - - - - - - - - 250 - 80 - - - - - 250 - 80 - - - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - - - 120 - 120 - 120 - - - - - - - 120 - 120 - 120 - - - - - - - 120 - 120 - 120 - - - - - - - - - 20 - - - - X - - - true - - - false - - - true - - - true - - - axis_maintenance_gb - - - - - - - - - - - - - - Qt::Orientation::Vertical - - - QSizePolicy::Policy::Minimum - - - - 20 - 24 - - - - - - - - - - Qt::Orientation::Horizontal - - - QSizePolicy::Policy::Minimum - - - - 60 - 0 - - - - - - - - - 0 - 0 - - - - - 16777215 - 60 - - - - - Momcake - 24 - - - - background: transparent; color: white; - - - Input Shaper - - - Qt::AlignCenter - - - title_text - - - - - - - - 0 - 0 - - - - - 60 - 60 - - - - - 60 - 60 - - - - - Momcake - 20 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - Back - - - false - - - true - - - menu_btn - - - icon - - - :/ui/media/btn_icons/back.svg - - - - - - - - - - - - - - - - - - - 0 - 0 - - - - - 60 - 60 - - - - - 16777215 - 60 - - - - - 20 - - - - color:white - - - Input Shaper - - - Qt::AlignCenter - - - - - - - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - MZV - - - true - - - false - - - true - - - menu_btn - - - - - - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - EI - - - true - - - false - - - true - - - menu_btn - - - - - - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - 3hump_ei - - - true - - - false - - - true - - - menu_btn - - - - - - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - ZV - - - true - - - false - - - true - - - menu_btn - - - - - - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - 2hump_ei - - - true - - - false - - - true - - - menu_btn - - - - - - - - - - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - Cancel - - - false - - - true - - - menu_btn - - - :/dialog/media/btn_icons/no.svg - - - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - Confirm - - - false - - - true - - - menu_btn - - - :/dialog/media/btn_icons/yes.svg - - - - - - - - - - - - - Qt::Orientation::Vertical - - - QSizePolicy::Policy::Minimum - - - - 20 - 24 - - - - - - - - - - - 0 - 0 - - - - - 16777215 - 60 - - - - User Input - - - Qt::AlignCenter - - - - - - - - - - - - 0 - 0 - - - - QFrame::Shape::StyledPanel - - - QFrame::Shadow::Raised - - - - - - - - - - - - 70 - 120 - 100 - 50 - - - - - 100 - 50 - - - - - 100 - 16777215 - - - - PushButton - - - - - - 170 - 150 - 31 - 16 - - - - - Momcake - 11 - - - - color:white - - - On - - - Qt::AlignCenter - - - - - - 40 - 150 - 31 - 16 - - - - - Momcake - 11 - - - - color:white - - - Off - - - Qt::AlignCenter - - - - - - 10 - 30 - 691 - 81 - - - - - - - Qt::Orientation::Horizontal - - - QSizePolicy::Policy::Minimum - - - - 60 - 20 - - - - - - - - - 0 - 0 - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - Momcake - 24 - - - - background: transparent; color: white; - - - LED's - - - Qt::AlignCenter - - - title_text - - - - - - - - 0 - 0 - - - - - 60 - 60 - - - - - 60 - 60 - - - - - Momcake - 20 - false - PreferAntialias - - - - false - - - true - - - Qt::ContextMenuPolicy::NoContextMenu - - - Qt::LayoutDirection::LeftToRight - - - - - - Back - - - false - - - true - - - menu_btn - - - icon - - - :/ui/media/btn_icons/back.svg - - - - - - - - - 10 - 200 - 688 - 101 - - - - - - - - 0 - 0 - - - - - 600 - 90 - - - - - 600 - 90 - - - - 100 - - - 100 - - - Qt::Orientation::Horizontal - - - - - - - - - - BlocksCustomButton - QPushButton -
lib.utils.blocks_button
-
- - IconButton - QPushButton -
lib.utils.icon_button
-
- - GroupButton - QPushButton -
lib.utils.group_button
-
- - BlocksSlider - QSlider -
lib.utils.blocks_slider
-
- - ToggleAnimatedButton - QPushButton -
lib.utils.toggleAnimatedButton
-
- - BlocksCustomFrame - QFrame -
lib.utils.blocks_frame
- 1 -
-
- - - - - - - - - - - - - - - - -
diff --git a/BlocksScreen/lib/ui/utilitiesStackedWidget_ui.py b/BlocksScreen/lib/ui/utilitiesStackedWidget_ui.py deleted file mode 100644 index 2874603a..00000000 --- a/BlocksScreen/lib/ui/utilitiesStackedWidget_ui.py +++ /dev/null @@ -1,1282 +0,0 @@ -# Form implementation generated from reading ui file 'BlocksScreen/lib/ui/utilitiesStackedWidget.ui' -# -# Created by: PyQt6 UI code generator 6.7.1 -# -# WARNING: Any manual changes made to this file will be lost when pyuic6 is -# run again. Do not edit this file unless you know what you are doing. - - -from PyQt6 import QtCore, QtGui, QtWidgets - - -class Ui_utilitiesStackedWidget(object): - def setupUi(self, utilitiesStackedWidget): - utilitiesStackedWidget.setObjectName("utilitiesStackedWidget") - utilitiesStackedWidget.resize(710, 410) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(utilitiesStackedWidget.sizePolicy().hasHeightForWidth()) - utilitiesStackedWidget.setSizePolicy(sizePolicy) - utilitiesStackedWidget.setMinimumSize(QtCore.QSize(710, 410)) - utilitiesStackedWidget.setMaximumSize(QtCore.QSize(710, 410)) - self.utilities_page = QtWidgets.QWidget() - self.utilities_page.setObjectName("utilities_page") - self.verticalLayout = QtWidgets.QVBoxLayout(self.utilities_page) - self.verticalLayout.setObjectName("verticalLayout") - self.utilities_header_layout = QtWidgets.QHBoxLayout() - self.utilities_header_layout.setObjectName("utilities_header_layout") - self.utilities_title_label = QtWidgets.QLabel(parent=self.utilities_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.utilities_title_label.sizePolicy().hasHeightForWidth()) - self.utilities_title_label.setSizePolicy(sizePolicy) - self.utilities_title_label.setMinimumSize(QtCore.QSize(0, 60)) - self.utilities_title_label.setMaximumSize(QtCore.QSize(16777215, 60)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(24) - font.setBold(True) - self.utilities_title_label.setFont(font) - self.utilities_title_label.setStyleSheet("background: transparent; color: white;") - self.utilities_title_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - self.utilities_title_label.setObjectName("utilities_title_label") - self.utilities_header_layout.addWidget(self.utilities_title_label) - self.verticalLayout.addLayout(self.utilities_header_layout) - self.utilities_content_layout = QtWidgets.QGridLayout() - self.utilities_content_layout.setObjectName("utilities_content_layout") - self.utilities_axes_btn = BlocksCustomButton(parent=self.utilities_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.utilities_axes_btn.sizePolicy().hasHeightForWidth()) - self.utilities_axes_btn.setSizePolicy(sizePolicy) - self.utilities_axes_btn.setMinimumSize(QtCore.QSize(250, 80)) - self.utilities_axes_btn.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.utilities_axes_btn.setFont(font) - self.utilities_axes_btn.setMouseTracking(False) - self.utilities_axes_btn.setTabletTracking(True) - self.utilities_axes_btn.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.utilities_axes_btn.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.utilities_axes_btn.setStyleSheet("") - self.utilities_axes_btn.setAutoDefault(False) - self.utilities_axes_btn.setFlat(True) - self.utilities_axes_btn.setProperty("icon_pixmap", QtGui.QPixmap(":/motion/media/btn_icons/axis_maintenance.svg")) - self.utilities_axes_btn.setObjectName("utilities_axes_btn") - self.utilities_content_layout.addWidget(self.utilities_axes_btn, 1, 1, 1, 1) - self.update_btn = BlocksCustomButton(parent=self.utilities_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.update_btn.sizePolicy().hasHeightForWidth()) - self.update_btn.setSizePolicy(sizePolicy) - self.update_btn.setMinimumSize(QtCore.QSize(250, 80)) - self.update_btn.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setBold(False) - self.update_btn.setFont(font) - self.update_btn.setFlat(True) - self.update_btn.setObjectName("update_btn") - self.utilities_content_layout.addWidget(self.update_btn, 2, 0, 1, 1) - self.utilities_routine_check_btn = BlocksCustomButton(parent=self.utilities_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.utilities_routine_check_btn.sizePolicy().hasHeightForWidth()) - self.utilities_routine_check_btn.setSizePolicy(sizePolicy) - self.utilities_routine_check_btn.setMinimumSize(QtCore.QSize(250, 80)) - self.utilities_routine_check_btn.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.utilities_routine_check_btn.setFont(font) - self.utilities_routine_check_btn.setMouseTracking(False) - self.utilities_routine_check_btn.setTabletTracking(True) - self.utilities_routine_check_btn.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.utilities_routine_check_btn.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.utilities_routine_check_btn.setStyleSheet("") - self.utilities_routine_check_btn.setAutoDefault(False) - self.utilities_routine_check_btn.setFlat(True) - self.utilities_routine_check_btn.setProperty("icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/routine.svg")) - self.utilities_routine_check_btn.setObjectName("utilities_routine_check_btn") - self.utilities_content_layout.addWidget(self.utilities_routine_check_btn, 1, 0, 1, 1) - self.utilities_input_shaper_btn = BlocksCustomButton(parent=self.utilities_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.utilities_input_shaper_btn.sizePolicy().hasHeightForWidth()) - self.utilities_input_shaper_btn.setSizePolicy(sizePolicy) - self.utilities_input_shaper_btn.setMinimumSize(QtCore.QSize(250, 80)) - self.utilities_input_shaper_btn.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.utilities_input_shaper_btn.setFont(font) - self.utilities_input_shaper_btn.setMouseTracking(False) - self.utilities_input_shaper_btn.setTabletTracking(True) - self.utilities_input_shaper_btn.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.utilities_input_shaper_btn.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.utilities_input_shaper_btn.setStyleSheet("") - self.utilities_input_shaper_btn.setAutoDefault(False) - self.utilities_input_shaper_btn.setFlat(True) - self.utilities_input_shaper_btn.setProperty("icon_pixmap", QtGui.QPixmap(":/input_shaper/media/btn_icons/input_shaper.svg")) - self.utilities_input_shaper_btn.setObjectName("utilities_input_shaper_btn") - self.utilities_content_layout.addWidget(self.utilities_input_shaper_btn, 2, 1, 1, 1) - self.utilities_info_btn = BlocksCustomButton(parent=self.utilities_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.utilities_info_btn.sizePolicy().hasHeightForWidth()) - self.utilities_info_btn.setSizePolicy(sizePolicy) - self.utilities_info_btn.setMinimumSize(QtCore.QSize(250, 80)) - self.utilities_info_btn.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.utilities_info_btn.setFont(font) - self.utilities_info_btn.setMouseTracking(False) - self.utilities_info_btn.setTabletTracking(True) - self.utilities_info_btn.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.utilities_info_btn.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.utilities_info_btn.setStyleSheet("") - self.utilities_info_btn.setAutoDefault(False) - self.utilities_info_btn.setFlat(True) - self.utilities_info_btn.setProperty("icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/info.svg")) - self.utilities_info_btn.setObjectName("utilities_info_btn") - self.utilities_content_layout.addWidget(self.utilities_info_btn, 0, 0, 1, 1) - self.utilities_leds_btn = BlocksCustomButton(parent=self.utilities_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.utilities_leds_btn.sizePolicy().hasHeightForWidth()) - self.utilities_leds_btn.setSizePolicy(sizePolicy) - self.utilities_leds_btn.setMinimumSize(QtCore.QSize(250, 80)) - self.utilities_leds_btn.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.utilities_leds_btn.setFont(font) - self.utilities_leds_btn.setMouseTracking(False) - self.utilities_leds_btn.setTabletTracking(True) - self.utilities_leds_btn.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.utilities_leds_btn.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.utilities_leds_btn.setStyleSheet("") - self.utilities_leds_btn.setAutoDefault(False) - self.utilities_leds_btn.setFlat(True) - self.utilities_leds_btn.setProperty("icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/LEDs.svg")) - self.utilities_leds_btn.setObjectName("utilities_leds_btn") - self.utilities_content_layout.addWidget(self.utilities_leds_btn, 0, 1, 1, 1) - self.verticalLayout.addLayout(self.utilities_content_layout) - utilitiesStackedWidget.addWidget(self.utilities_page) - self.info_page = QtWidgets.QWidget() - self.info_page.setObjectName("info_page") - self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.info_page) - self.verticalLayout_2.setObjectName("verticalLayout_2") - spacerItem = QtWidgets.QSpacerItem(20, 24, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) - self.verticalLayout_2.addItem(spacerItem) - self.info_header_layout = QtWidgets.QHBoxLayout() - self.info_header_layout.setObjectName("info_header_layout") - spacerItem1 = QtWidgets.QSpacerItem(60, 60, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) - self.info_header_layout.addItem(spacerItem1) - self.info_title_label = QtWidgets.QLabel(parent=self.info_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.info_title_label.sizePolicy().hasHeightForWidth()) - self.info_title_label.setSizePolicy(sizePolicy) - self.info_title_label.setMaximumSize(QtCore.QSize(16777215, 60)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(24) - self.info_title_label.setFont(font) - self.info_title_label.setStyleSheet("background: transparent; color: white;") - self.info_title_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - self.info_title_label.setObjectName("info_title_label") - self.info_header_layout.addWidget(self.info_title_label) - self.info_back_btn = IconButton(parent=self.info_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.info_back_btn.sizePolicy().hasHeightForWidth()) - self.info_back_btn.setSizePolicy(sizePolicy) - self.info_back_btn.setMinimumSize(QtCore.QSize(60, 60)) - self.info_back_btn.setMaximumSize(QtCore.QSize(60, 60)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(20) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.info_back_btn.setFont(font) - self.info_back_btn.setMouseTracking(False) - self.info_back_btn.setTabletTracking(True) - self.info_back_btn.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.info_back_btn.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.info_back_btn.setStyleSheet("") - self.info_back_btn.setAutoDefault(False) - self.info_back_btn.setFlat(True) - self.info_back_btn.setProperty("icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/back.svg")) - self.info_back_btn.setObjectName("info_back_btn") - self.info_header_layout.addWidget(self.info_back_btn) - self.verticalLayout_2.addLayout(self.info_header_layout) - self.info_content_layout = QtWidgets.QVBoxLayout() - self.info_content_layout.setObjectName("info_content_layout") - self.frame = BlocksCustomFrame(parent=self.info_page) - self.frame.setMinimumSize(QtCore.QSize(350, 260)) - self.frame.setMaximumSize(QtCore.QSize(350, 290)) - self.frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) - self.frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) - self.frame.setObjectName("frame") - self.kv_label = QtWidgets.QLabel(parent=self.frame) - self.kv_label.setGeometry(QtCore.QRect(0, 10, 351, 81)) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.kv_label.sizePolicy().hasHeightForWidth()) - self.kv_label.setSizePolicy(sizePolicy) - font = QtGui.QFont() - font.setPointSize(20) - self.kv_label.setFont(font) - self.kv_label.setStyleSheet("color:white") - self.kv_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - self.kv_label.setObjectName("kv_label") - self.smth_label = QtWidgets.QLabel(parent=self.frame) - self.smth_label.setGeometry(QtCore.QRect(0, 110, 351, 81)) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.smth_label.sizePolicy().hasHeightForWidth()) - self.smth_label.setSizePolicy(sizePolicy) - self.smth_label.setMinimumSize(QtCore.QSize(0, 0)) - font = QtGui.QFont() - font.setPointSize(20) - self.smth_label.setFont(font) - self.smth_label.setStyleSheet("color:white") - self.smth_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - self.smth_label.setObjectName("smth_label") - self.info_content_layout.addWidget(self.frame, 0, QtCore.Qt.AlignmentFlag.AlignHCenter) - self.verticalLayout_2.addLayout(self.info_content_layout) - utilitiesStackedWidget.addWidget(self.info_page) - self.leds_page = QtWidgets.QWidget() - self.leds_page.setObjectName("leds_page") - self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.leds_page) - self.verticalLayout_4.setObjectName("verticalLayout_4") - spacerItem2 = QtWidgets.QSpacerItem(20, 24, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) - self.verticalLayout_4.addItem(spacerItem2) - self.leds_header_layout = QtWidgets.QHBoxLayout() - self.leds_header_layout.setObjectName("leds_header_layout") - spacerItem3 = QtWidgets.QSpacerItem(60, 20, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) - self.leds_header_layout.addItem(spacerItem3) - self.leds_title_label = QtWidgets.QLabel(parent=self.leds_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.leds_title_label.sizePolicy().hasHeightForWidth()) - self.leds_title_label.setSizePolicy(sizePolicy) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(24) - self.leds_title_label.setFont(font) - self.leds_title_label.setStyleSheet("background: transparent; color: white;") - self.leds_title_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - self.leds_title_label.setObjectName("leds_title_label") - self.leds_header_layout.addWidget(self.leds_title_label) - self.leds_back_btn = IconButton(parent=self.leds_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.leds_back_btn.sizePolicy().hasHeightForWidth()) - self.leds_back_btn.setSizePolicy(sizePolicy) - self.leds_back_btn.setMinimumSize(QtCore.QSize(60, 60)) - self.leds_back_btn.setMaximumSize(QtCore.QSize(60, 60)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(20) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.leds_back_btn.setFont(font) - self.leds_back_btn.setMouseTracking(False) - self.leds_back_btn.setTabletTracking(True) - self.leds_back_btn.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.leds_back_btn.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.leds_back_btn.setStyleSheet("") - self.leds_back_btn.setAutoDefault(False) - self.leds_back_btn.setFlat(True) - self.leds_back_btn.setProperty("icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/back.svg")) - self.leds_back_btn.setObjectName("leds_back_btn") - self.leds_header_layout.addWidget(self.leds_back_btn) - self.verticalLayout_4.addLayout(self.leds_header_layout) - spacerItem4 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) - self.verticalLayout_4.addItem(spacerItem4) - self.verticalScrollBar = QtWidgets.QScrollBar(parent=self.leds_page) - self.verticalScrollBar.setOrientation(QtCore.Qt.Orientation.Vertical) - self.verticalScrollBar.setObjectName("verticalScrollBar") - self.verticalLayout_4.addWidget(self.verticalScrollBar) - self.leds_content_layout = QtWidgets.QGridLayout() - self.leds_content_layout.setObjectName("leds_content_layout") - self.leds_widget = QtWidgets.QWidget(parent=self.leds_page) - self.leds_widget.setObjectName("leds_widget") - self.leds_content_layout.addWidget(self.leds_widget, 0, 0, 1, 1) - self.verticalLayout_4.addLayout(self.leds_content_layout) - spacerItem5 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) - self.verticalLayout_4.addItem(spacerItem5) - utilitiesStackedWidget.addWidget(self.leds_page) - self.routines_page = QtWidgets.QWidget() - self.routines_page.setObjectName("routines_page") - self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.routines_page) - self.verticalLayout_5.setObjectName("verticalLayout_5") - spacerItem6 = QtWidgets.QSpacerItem(20, 24, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) - self.verticalLayout_5.addItem(spacerItem6) - self.routines_header_layout = QtWidgets.QHBoxLayout() - self.routines_header_layout.setSizeConstraint(QtWidgets.QLayout.SizeConstraint.SetMinimumSize) - self.routines_header_layout.setObjectName("routines_header_layout") - spacerItem7 = QtWidgets.QSpacerItem(60, 20, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) - self.routines_header_layout.addItem(spacerItem7) - self.routines_page_title = QtWidgets.QLabel(parent=self.routines_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.routines_page_title.sizePolicy().hasHeightForWidth()) - self.routines_page_title.setSizePolicy(sizePolicy) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(24) - self.routines_page_title.setFont(font) - self.routines_page_title.setStyleSheet("background: transparent; color: white;") - self.routines_page_title.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - self.routines_page_title.setObjectName("routines_page_title") - self.routines_header_layout.addWidget(self.routines_page_title) - self.routine_check_back_btn = IconButton(parent=self.routines_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.routine_check_back_btn.sizePolicy().hasHeightForWidth()) - self.routine_check_back_btn.setSizePolicy(sizePolicy) - self.routine_check_back_btn.setMinimumSize(QtCore.QSize(60, 60)) - self.routine_check_back_btn.setMaximumSize(QtCore.QSize(60, 60)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(20) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.routine_check_back_btn.setFont(font) - self.routine_check_back_btn.setMouseTracking(False) - self.routine_check_back_btn.setTabletTracking(True) - self.routine_check_back_btn.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.routine_check_back_btn.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.routine_check_back_btn.setStyleSheet("") - self.routine_check_back_btn.setAutoDefault(False) - self.routine_check_back_btn.setFlat(True) - self.routine_check_back_btn.setProperty("icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/back.svg")) - self.routine_check_back_btn.setObjectName("routine_check_back_btn") - self.routines_header_layout.addWidget(self.routine_check_back_btn) - self.verticalLayout_5.addLayout(self.routines_header_layout) - spacerItem8 = QtWidgets.QSpacerItem(20, 60, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) - self.verticalLayout_5.addItem(spacerItem8) - self.routines_content_layout = QtWidgets.QGridLayout() - self.routines_content_layout.setVerticalSpacing(20) - self.routines_content_layout.setObjectName("routines_content_layout") - self.rc_bheat = BlocksCustomButton(parent=self.routines_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rc_bheat.sizePolicy().hasHeightForWidth()) - self.rc_bheat.setSizePolicy(sizePolicy) - self.rc_bheat.setMinimumSize(QtCore.QSize(250, 80)) - self.rc_bheat.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.rc_bheat.setFont(font) - self.rc_bheat.setMouseTracking(False) - self.rc_bheat.setTabletTracking(True) - self.rc_bheat.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.rc_bheat.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.rc_bheat.setStyleSheet("") - self.rc_bheat.setAutoDefault(False) - self.rc_bheat.setFlat(True) - self.rc_bheat.setProperty("icon_pixmap", QtGui.QPixmap(":/temperature_related/media/btn_icons/temperature_plate.svg")) - self.rc_bheat.setObjectName("rc_bheat") - self.routines_content_layout.addWidget(self.rc_bheat, 0, 1, 1, 1) - self.rc_fans = BlocksCustomButton(parent=self.routines_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rc_fans.sizePolicy().hasHeightForWidth()) - self.rc_fans.setSizePolicy(sizePolicy) - self.rc_fans.setMinimumSize(QtCore.QSize(250, 80)) - self.rc_fans.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.rc_fans.setFont(font) - self.rc_fans.setMouseTracking(False) - self.rc_fans.setTabletTracking(True) - self.rc_fans.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.rc_fans.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.rc_fans.setStyleSheet("") - self.rc_fans.setAutoDefault(False) - self.rc_fans.setFlat(True) - self.rc_fans.setProperty("icon_pixmap", QtGui.QPixmap(":/fan_related/media/btn_icons/fan_cage.svg")) - self.rc_fans.setObjectName("rc_fans") - self.routines_content_layout.addWidget(self.rc_fans, 0, 0, 1, 1) - self.rc_axis = BlocksCustomButton(parent=self.routines_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rc_axis.sizePolicy().hasHeightForWidth()) - self.rc_axis.setSizePolicy(sizePolicy) - self.rc_axis.setMinimumSize(QtCore.QSize(250, 80)) - self.rc_axis.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.rc_axis.setFont(font) - self.rc_axis.setMouseTracking(False) - self.rc_axis.setTabletTracking(True) - self.rc_axis.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.rc_axis.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.rc_axis.setStyleSheet("") - self.rc_axis.setAutoDefault(False) - self.rc_axis.setFlat(True) - self.rc_axis.setProperty("icon_pixmap", QtGui.QPixmap(":/motion/media/btn_icons/axis_maintenance.svg")) - self.rc_axis.setObjectName("rc_axis") - self.routines_content_layout.addWidget(self.rc_axis, 1, 1, 1, 1) - self.rc_ext = BlocksCustomButton(parent=self.routines_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rc_ext.sizePolicy().hasHeightForWidth()) - self.rc_ext.setSizePolicy(sizePolicy) - self.rc_ext.setMinimumSize(QtCore.QSize(250, 80)) - self.rc_ext.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.rc_ext.setFont(font) - self.rc_ext.setMouseTracking(False) - self.rc_ext.setTabletTracking(True) - self.rc_ext.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.rc_ext.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.rc_ext.setStyleSheet("") - self.rc_ext.setAutoDefault(False) - self.rc_ext.setFlat(True) - self.rc_ext.setProperty("icon_pixmap", QtGui.QPixmap(":/extruder_related/media/btn_icons/nozzle.svg")) - self.rc_ext.setObjectName("rc_ext") - self.routines_content_layout.addWidget(self.rc_ext, 1, 0, 1, 1) - self.verticalLayout_5.addLayout(self.routines_content_layout) - spacerItem9 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) - self.verticalLayout_5.addItem(spacerItem9) - utilitiesStackedWidget.addWidget(self.routines_page) - self.rc_page = QtWidgets.QWidget() - self.rc_page.setObjectName("rc_page") - self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.rc_page) - self.verticalLayout_6.setObjectName("verticalLayout_6") - spacerItem10 = QtWidgets.QSpacerItem(20, 24, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) - self.verticalLayout_6.addItem(spacerItem10) - self.rc_header_layout = QtWidgets.QHBoxLayout() - self.rc_header_layout.setObjectName("rc_header_layout") - self.rc_tittle = QtWidgets.QLabel(parent=self.rc_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rc_tittle.sizePolicy().hasHeightForWidth()) - self.rc_tittle.setSizePolicy(sizePolicy) - self.rc_tittle.setMinimumSize(QtCore.QSize(0, 60)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(24) - self.rc_tittle.setFont(font) - self.rc_tittle.setStyleSheet("background: transparent; color: white;") - self.rc_tittle.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - self.rc_tittle.setObjectName("rc_tittle") - self.rc_header_layout.addWidget(self.rc_tittle) - self.verticalLayout_6.addLayout(self.rc_header_layout) - self.rc_content_layout = QtWidgets.QGridLayout() - self.rc_content_layout.setVerticalSpacing(0) - self.rc_content_layout.setObjectName("rc_content_layout") - self.rc_label = QtWidgets.QLabel(parent=self.rc_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rc_label.sizePolicy().hasHeightForWidth()) - self.rc_label.setSizePolicy(sizePolicy) - font = QtGui.QFont() - font.setPointSize(15) - self.rc_label.setFont(font) - self.rc_label.setStyleSheet("color:white") - self.rc_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - self.rc_label.setObjectName("rc_label") - self.rc_content_layout.addWidget(self.rc_label, 0, 0, 1, 1) - self.horizontalLayout_3 = QtWidgets.QHBoxLayout() - self.horizontalLayout_3.setObjectName("horizontalLayout_3") - self.rc_yes = BlocksCustomButton(parent=self.rc_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rc_yes.sizePolicy().hasHeightForWidth()) - self.rc_yes.setSizePolicy(sizePolicy) - self.rc_yes.setMinimumSize(QtCore.QSize(250, 80)) - self.rc_yes.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.rc_yes.setFont(font) - self.rc_yes.setMouseTracking(False) - self.rc_yes.setTabletTracking(True) - self.rc_yes.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.rc_yes.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.rc_yes.setStyleSheet("") - self.rc_yes.setAutoDefault(False) - self.rc_yes.setFlat(True) - self.rc_yes.setProperty("icon_pixmap", QtGui.QPixmap(":/dialog/media/btn_icons/yes.svg")) - self.rc_yes.setObjectName("rc_yes") - self.horizontalLayout_3.addWidget(self.rc_yes) - spacerItem11 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) - self.horizontalLayout_3.addItem(spacerItem11) - self.rc_no = BlocksCustomButton(parent=self.rc_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rc_no.sizePolicy().hasHeightForWidth()) - self.rc_no.setSizePolicy(sizePolicy) - self.rc_no.setMinimumSize(QtCore.QSize(250, 80)) - self.rc_no.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.rc_no.setFont(font) - self.rc_no.setMouseTracking(False) - self.rc_no.setTabletTracking(True) - self.rc_no.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.rc_no.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.rc_no.setStyleSheet("") - self.rc_no.setAutoDefault(False) - self.rc_no.setFlat(True) - self.rc_no.setProperty("icon_pixmap", QtGui.QPixmap(":/dialog/media/btn_icons/no.svg")) - self.rc_no.setObjectName("rc_no") - self.horizontalLayout_3.addWidget(self.rc_no) - self.rc_content_layout.addLayout(self.horizontalLayout_3, 1, 0, 1, 1) - self.verticalLayout_6.addLayout(self.rc_content_layout) - utilitiesStackedWidget.addWidget(self.rc_page) - self.axes_page = QtWidgets.QWidget() - self.axes_page.setObjectName("axes_page") - self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.axes_page) - self.verticalLayout_7.setObjectName("verticalLayout_7") - spacerItem12 = QtWidgets.QSpacerItem(20, 24, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) - self.verticalLayout_7.addItem(spacerItem12) - self.lcd_settings_header_layout = QtWidgets.QHBoxLayout() - self.lcd_settings_header_layout.setObjectName("lcd_settings_header_layout") - spacerItem13 = QtWidgets.QSpacerItem(60, 20, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) - self.lcd_settings_header_layout.addItem(spacerItem13) - self.lcd_settings_title_label = QtWidgets.QLabel(parent=self.axes_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.lcd_settings_title_label.sizePolicy().hasHeightForWidth()) - self.lcd_settings_title_label.setSizePolicy(sizePolicy) - self.lcd_settings_title_label.setMaximumSize(QtCore.QSize(16777215, 60)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(24) - self.lcd_settings_title_label.setFont(font) - self.lcd_settings_title_label.setStyleSheet("background: transparent; color: white;") - self.lcd_settings_title_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - self.lcd_settings_title_label.setObjectName("lcd_settings_title_label") - self.lcd_settings_header_layout.addWidget(self.lcd_settings_title_label) - self.axes_back_btn = IconButton(parent=self.axes_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.Minimum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.axes_back_btn.sizePolicy().hasHeightForWidth()) - self.axes_back_btn.setSizePolicy(sizePolicy) - self.axes_back_btn.setMinimumSize(QtCore.QSize(60, 60)) - self.axes_back_btn.setMaximumSize(QtCore.QSize(60, 60)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(20) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.axes_back_btn.setFont(font) - self.axes_back_btn.setMouseTracking(False) - self.axes_back_btn.setTabletTracking(True) - self.axes_back_btn.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.axes_back_btn.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.axes_back_btn.setStyleSheet("") - self.axes_back_btn.setAutoDefault(False) - self.axes_back_btn.setFlat(True) - self.axes_back_btn.setProperty("icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/back.svg")) - self.axes_back_btn.setObjectName("axes_back_btn") - self.lcd_settings_header_layout.addWidget(self.axes_back_btn) - self.verticalLayout_7.addLayout(self.lcd_settings_header_layout) - self.frame_2 = BlocksCustomFrame(parent=self.axes_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.frame_2.sizePolicy().hasHeightForWidth()) - self.frame_2.setSizePolicy(sizePolicy) - self.frame_2.setMinimumSize(QtCore.QSize(650, 0)) - self.frame_2.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) - self.frame_2.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) - self.frame_2.setObjectName("frame_2") - self.gridLayout = QtWidgets.QGridLayout(self.frame_2) - self.gridLayout.setObjectName("gridLayout") - self.am_y = BlocksCustomCheckButton(parent=self.frame_2) - self.am_y.setMinimumSize(QtCore.QSize(60, 80)) - self.am_y.setMaximumSize(QtCore.QSize(250, 80)) - palette = QtGui.QPalette() - brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.WindowText, brush) - brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.Text, brush) - brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.ButtonText, brush) - brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.WindowText, brush) - brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.Text, brush) - brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.ButtonText, brush) - brush = QtGui.QBrush(QtGui.QColor(120, 120, 120)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.WindowText, brush) - brush = QtGui.QBrush(QtGui.QColor(120, 120, 120)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.Text, brush) - brush = QtGui.QBrush(QtGui.QColor(120, 120, 120)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.ButtonText, brush) - self.am_y.setPalette(palette) - font = QtGui.QFont() - font.setPointSize(20) - self.am_y.setFont(font) - self.am_y.setCheckable(True) - self.am_y.setChecked(True) - self.am_y.setAutoExclusive(True) - self.am_y.setFlat(True) - self.am_y.setObjectName("am_y") - self.axis_maintenance_gb = QtWidgets.QButtonGroup(utilitiesStackedWidget) - self.axis_maintenance_gb.setObjectName("axis_maintenance_gb") - self.axis_maintenance_gb.addButton(self.am_y) - self.gridLayout.addWidget(self.am_y, 1, 0, 1, 1) - self.am_execute = BlocksCustomButton(parent=self.frame_2) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.am_execute.sizePolicy().hasHeightForWidth()) - self.am_execute.setSizePolicy(sizePolicy) - self.am_execute.setMinimumSize(QtCore.QSize(250, 80)) - self.am_execute.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.am_execute.setFont(font) - self.am_execute.setMouseTracking(False) - self.am_execute.setTabletTracking(True) - self.am_execute.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.am_execute.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.am_execute.setStyleSheet("") - self.am_execute.setAutoDefault(False) - self.am_execute.setFlat(True) - self.am_execute.setProperty("icon_pixmap", QtGui.QPixmap(":/dialog/media/btn_icons/yes.svg")) - self.am_execute.setObjectName("am_execute") - self.gridLayout.addWidget(self.am_execute, 2, 1, 1, 1) - self.am_z = BlocksCustomCheckButton(parent=self.frame_2) - self.am_z.setMinimumSize(QtCore.QSize(60, 80)) - self.am_z.setMaximumSize(QtCore.QSize(250, 80)) - palette = QtGui.QPalette() - brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.WindowText, brush) - brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.Text, brush) - brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.ButtonText, brush) - brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.WindowText, brush) - brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.Text, brush) - brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.ButtonText, brush) - brush = QtGui.QBrush(QtGui.QColor(120, 120, 120)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.WindowText, brush) - brush = QtGui.QBrush(QtGui.QColor(120, 120, 120)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.Text, brush) - brush = QtGui.QBrush(QtGui.QColor(120, 120, 120)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.ButtonText, brush) - self.am_z.setPalette(palette) - font = QtGui.QFont() - font.setPointSize(20) - self.am_z.setFont(font) - self.am_z.setCheckable(True) - self.am_z.setChecked(False) - self.am_z.setAutoExclusive(True) - self.am_z.setFlat(True) - self.am_z.setObjectName("am_z") - self.axis_maintenance_gb.addButton(self.am_z) - self.gridLayout.addWidget(self.am_z, 2, 0, 1, 1) - self.am_x = BlocksCustomCheckButton(parent=self.frame_2) - self.am_x.setMinimumSize(QtCore.QSize(250, 80)) - self.am_x.setMaximumSize(QtCore.QSize(250, 80)) - palette = QtGui.QPalette() - brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.WindowText, brush) - brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.Text, brush) - brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.ButtonText, brush) - brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.WindowText, brush) - brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.Text, brush) - brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.ButtonText, brush) - brush = QtGui.QBrush(QtGui.QColor(120, 120, 120)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.WindowText, brush) - brush = QtGui.QBrush(QtGui.QColor(120, 120, 120)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.Text, brush) - brush = QtGui.QBrush(QtGui.QColor(120, 120, 120)) - brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) - palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.ButtonText, brush) - self.am_x.setPalette(palette) - font = QtGui.QFont() - font.setPointSize(20) - self.am_x.setFont(font) - self.am_x.setCheckable(True) - self.am_x.setChecked(False) - self.am_x.setAutoExclusive(True) - self.am_x.setFlat(True) - self.am_x.setObjectName("am_x") - self.axis_maintenance_gb.addButton(self.am_x) - self.gridLayout.addWidget(self.am_x, 0, 0, 1, 1) - self.verticalLayout_7.addWidget(self.frame_2, 0, QtCore.Qt.AlignmentFlag.AlignHCenter) - utilitiesStackedWidget.addWidget(self.axes_page) - self.input_shaper_page = QtWidgets.QWidget() - self.input_shaper_page.setObjectName("input_shaper_page") - self.verticalLayout_13 = QtWidgets.QVBoxLayout(self.input_shaper_page) - self.verticalLayout_13.setObjectName("verticalLayout_13") - spacerItem14 = QtWidgets.QSpacerItem(20, 24, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) - self.verticalLayout_13.addItem(spacerItem14) - self.is_header_layout = QtWidgets.QHBoxLayout() - self.is_header_layout.setObjectName("is_header_layout") - spacerItem15 = QtWidgets.QSpacerItem(60, 0, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) - self.is_header_layout.addItem(spacerItem15) - self.label_2 = QtWidgets.QLabel(parent=self.input_shaper_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_2.sizePolicy().hasHeightForWidth()) - self.label_2.setSizePolicy(sizePolicy) - self.label_2.setMaximumSize(QtCore.QSize(16777215, 60)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(24) - self.label_2.setFont(font) - self.label_2.setStyleSheet("background: transparent; color: white;") - self.label_2.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - self.label_2.setObjectName("label_2") - self.is_header_layout.addWidget(self.label_2) - self.input_shaper_back_btn = IconButton(parent=self.input_shaper_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.input_shaper_back_btn.sizePolicy().hasHeightForWidth()) - self.input_shaper_back_btn.setSizePolicy(sizePolicy) - self.input_shaper_back_btn.setMinimumSize(QtCore.QSize(60, 60)) - self.input_shaper_back_btn.setMaximumSize(QtCore.QSize(60, 60)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(20) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.input_shaper_back_btn.setFont(font) - self.input_shaper_back_btn.setMouseTracking(False) - self.input_shaper_back_btn.setTabletTracking(True) - self.input_shaper_back_btn.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.input_shaper_back_btn.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.input_shaper_back_btn.setStyleSheet("") - self.input_shaper_back_btn.setAutoDefault(False) - self.input_shaper_back_btn.setFlat(True) - self.input_shaper_back_btn.setProperty("icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/back.svg")) - self.input_shaper_back_btn.setObjectName("input_shaper_back_btn") - self.is_header_layout.addWidget(self.input_shaper_back_btn) - self.verticalLayout_13.addLayout(self.is_header_layout) - self.is_content_layout = QtWidgets.QHBoxLayout() - self.is_content_layout.setObjectName("is_content_layout") - self.verticalLayout_13.addLayout(self.is_content_layout) - utilitiesStackedWidget.addWidget(self.input_shaper_page) - self.manual_is_res_page = QtWidgets.QWidget() - self.manual_is_res_page.setObjectName("manual_is_res_page") - self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.manual_is_res_page) - self.verticalLayout_3.setObjectName("verticalLayout_3") - self.horizontalLayout_4 = QtWidgets.QHBoxLayout() - self.horizontalLayout_4.setObjectName("horizontalLayout_4") - self.label_3 = QtWidgets.QLabel(parent=self.manual_is_res_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_3.sizePolicy().hasHeightForWidth()) - self.label_3.setSizePolicy(sizePolicy) - self.label_3.setMinimumSize(QtCore.QSize(60, 60)) - self.label_3.setMaximumSize(QtCore.QSize(16777215, 60)) - font = QtGui.QFont() - font.setPointSize(20) - self.label_3.setFont(font) - self.label_3.setStyleSheet("color:white") - self.label_3.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - self.label_3.setObjectName("label_3") - self.horizontalLayout_4.addWidget(self.label_3, 0, QtCore.Qt.AlignmentFlag.AlignHCenter|QtCore.Qt.AlignmentFlag.AlignVCenter) - self.verticalLayout_3.addLayout(self.horizontalLayout_4) - self.gridLayout_3 = QtWidgets.QGridLayout() - self.gridLayout_3.setObjectName("gridLayout_3") - self.am_mzv_2 = BlocksCustomCheckButton(parent=self.manual_is_res_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.am_mzv_2.sizePolicy().hasHeightForWidth()) - self.am_mzv_2.setSizePolicy(sizePolicy) - self.am_mzv_2.setMinimumSize(QtCore.QSize(250, 80)) - self.am_mzv_2.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.am_mzv_2.setFont(font) - self.am_mzv_2.setMouseTracking(False) - self.am_mzv_2.setTabletTracking(True) - self.am_mzv_2.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.am_mzv_2.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.am_mzv_2.setStyleSheet("") - self.am_mzv_2.setCheckable(True) - self.am_mzv_2.setAutoDefault(False) - self.am_mzv_2.setFlat(True) - self.am_mzv_2.setObjectName("am_mzv_2") - self.gridLayout_3.addWidget(self.am_mzv_2, 0, 1, 1, 1) - self.am_ei_2 = BlocksCustomCheckButton(parent=self.manual_is_res_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.am_ei_2.sizePolicy().hasHeightForWidth()) - self.am_ei_2.setSizePolicy(sizePolicy) - self.am_ei_2.setMinimumSize(QtCore.QSize(250, 80)) - self.am_ei_2.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.am_ei_2.setFont(font) - self.am_ei_2.setMouseTracking(False) - self.am_ei_2.setTabletTracking(True) - self.am_ei_2.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.am_ei_2.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.am_ei_2.setStyleSheet("") - self.am_ei_2.setCheckable(True) - self.am_ei_2.setAutoDefault(False) - self.am_ei_2.setFlat(True) - self.am_ei_2.setObjectName("am_ei_2") - self.gridLayout_3.addWidget(self.am_ei_2, 1, 0, 1, 1) - self.am_3hump_ei_2 = BlocksCustomCheckButton(parent=self.manual_is_res_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.am_3hump_ei_2.sizePolicy().hasHeightForWidth()) - self.am_3hump_ei_2.setSizePolicy(sizePolicy) - self.am_3hump_ei_2.setMinimumSize(QtCore.QSize(250, 80)) - self.am_3hump_ei_2.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.am_3hump_ei_2.setFont(font) - self.am_3hump_ei_2.setMouseTracking(False) - self.am_3hump_ei_2.setTabletTracking(True) - self.am_3hump_ei_2.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.am_3hump_ei_2.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.am_3hump_ei_2.setStyleSheet("") - self.am_3hump_ei_2.setCheckable(True) - self.am_3hump_ei_2.setAutoDefault(False) - self.am_3hump_ei_2.setFlat(True) - self.am_3hump_ei_2.setObjectName("am_3hump_ei_2") - self.gridLayout_3.addWidget(self.am_3hump_ei_2, 2, 0, 1, 2, QtCore.Qt.AlignmentFlag.AlignHCenter) - self.am_zv_2 = BlocksCustomCheckButton(parent=self.manual_is_res_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.am_zv_2.sizePolicy().hasHeightForWidth()) - self.am_zv_2.setSizePolicy(sizePolicy) - self.am_zv_2.setMinimumSize(QtCore.QSize(250, 80)) - self.am_zv_2.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.am_zv_2.setFont(font) - self.am_zv_2.setMouseTracking(False) - self.am_zv_2.setTabletTracking(True) - self.am_zv_2.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.am_zv_2.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.am_zv_2.setStyleSheet("") - self.am_zv_2.setCheckable(True) - self.am_zv_2.setAutoDefault(False) - self.am_zv_2.setFlat(True) - self.am_zv_2.setObjectName("am_zv_2") - self.gridLayout_3.addWidget(self.am_zv_2, 0, 0, 1, 1) - self.am_2hump_ei_2 = BlocksCustomCheckButton(parent=self.manual_is_res_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.am_2hump_ei_2.sizePolicy().hasHeightForWidth()) - self.am_2hump_ei_2.setSizePolicy(sizePolicy) - self.am_2hump_ei_2.setMinimumSize(QtCore.QSize(250, 80)) - self.am_2hump_ei_2.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.am_2hump_ei_2.setFont(font) - self.am_2hump_ei_2.setMouseTracking(False) - self.am_2hump_ei_2.setTabletTracking(True) - self.am_2hump_ei_2.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.am_2hump_ei_2.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.am_2hump_ei_2.setStyleSheet("") - self.am_2hump_ei_2.setCheckable(True) - self.am_2hump_ei_2.setAutoDefault(False) - self.am_2hump_ei_2.setFlat(True) - self.am_2hump_ei_2.setObjectName("am_2hump_ei_2") - self.gridLayout_3.addWidget(self.am_2hump_ei_2, 1, 1, 1, 1) - self.verticalLayout_3.addLayout(self.gridLayout_3) - self.horizontalLayout = QtWidgets.QHBoxLayout() - self.horizontalLayout.setObjectName("horizontalLayout") - self.am_cancel = BlocksCustomButton(parent=self.manual_is_res_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.am_cancel.sizePolicy().hasHeightForWidth()) - self.am_cancel.setSizePolicy(sizePolicy) - self.am_cancel.setMinimumSize(QtCore.QSize(250, 80)) - self.am_cancel.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.am_cancel.setFont(font) - self.am_cancel.setMouseTracking(False) - self.am_cancel.setTabletTracking(True) - self.am_cancel.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.am_cancel.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.am_cancel.setStyleSheet("") - self.am_cancel.setAutoDefault(False) - self.am_cancel.setFlat(True) - self.am_cancel.setProperty("icon_pixmap", QtGui.QPixmap(":/dialog/media/btn_icons/no.svg")) - self.am_cancel.setObjectName("am_cancel") - self.horizontalLayout.addWidget(self.am_cancel) - self.am_confirm = BlocksCustomButton(parent=self.manual_is_res_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.am_confirm.sizePolicy().hasHeightForWidth()) - self.am_confirm.setSizePolicy(sizePolicy) - self.am_confirm.setMinimumSize(QtCore.QSize(250, 80)) - self.am_confirm.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.am_confirm.setFont(font) - self.am_confirm.setMouseTracking(False) - self.am_confirm.setTabletTracking(True) - self.am_confirm.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.am_confirm.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.am_confirm.setStyleSheet("") - self.am_confirm.setAutoDefault(False) - self.am_confirm.setFlat(True) - self.am_confirm.setProperty("icon_pixmap", QtGui.QPixmap(":/dialog/media/btn_icons/yes.svg")) - self.am_confirm.setObjectName("am_confirm") - self.horizontalLayout.addWidget(self.am_confirm) - self.verticalLayout_3.addLayout(self.horizontalLayout) - utilitiesStackedWidget.addWidget(self.manual_is_res_page) - self.user_input_page = QtWidgets.QWidget() - self.user_input_page.setObjectName("user_input_page") - self.verticalLayout_9 = QtWidgets.QVBoxLayout(self.user_input_page) - self.verticalLayout_9.setObjectName("verticalLayout_9") - spacerItem16 = QtWidgets.QSpacerItem(20, 24, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) - self.verticalLayout_9.addItem(spacerItem16) - self.horizontalLayout_5 = QtWidgets.QHBoxLayout() - self.horizontalLayout_5.setObjectName("horizontalLayout_5") - self.label_8 = QtWidgets.QLabel(parent=self.user_input_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_8.sizePolicy().hasHeightForWidth()) - self.label_8.setSizePolicy(sizePolicy) - self.label_8.setMaximumSize(QtCore.QSize(16777215, 60)) - self.label_8.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - self.label_8.setObjectName("label_8") - self.horizontalLayout_5.addWidget(self.label_8) - self.verticalLayout_9.addLayout(self.horizontalLayout_5) - self.verticalLayout_10 = QtWidgets.QVBoxLayout() - self.verticalLayout_10.setObjectName("verticalLayout_10") - self.frame_4 = QtWidgets.QFrame(parent=self.user_input_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.frame_4.sizePolicy().hasHeightForWidth()) - self.frame_4.setSizePolicy(sizePolicy) - self.frame_4.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) - self.frame_4.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) - self.frame_4.setObjectName("frame_4") - self.verticalLayout_10.addWidget(self.frame_4) - self.verticalLayout_9.addLayout(self.verticalLayout_10) - utilitiesStackedWidget.addWidget(self.user_input_page) - self.leds_slider_page = QtWidgets.QWidget() - self.leds_slider_page.setObjectName("leds_slider_page") - self.toggle_led_button = ToggleAnimatedButton(parent=self.leds_slider_page) - self.toggle_led_button.setGeometry(QtCore.QRect(70, 120, 100, 50)) - self.toggle_led_button.setMinimumSize(QtCore.QSize(100, 50)) - self.toggle_led_button.setMaximumSize(QtCore.QSize(100, 16777215)) - self.toggle_led_button.setObjectName("toggle_led_button") - self.label_4 = QtWidgets.QLabel(parent=self.leds_slider_page) - self.label_4.setGeometry(QtCore.QRect(170, 150, 31, 16)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(11) - self.label_4.setFont(font) - self.label_4.setStyleSheet("color:white") - self.label_4.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - self.label_4.setObjectName("label_4") - self.label_5 = QtWidgets.QLabel(parent=self.leds_slider_page) - self.label_5.setGeometry(QtCore.QRect(40, 150, 31, 16)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(11) - self.label_5.setFont(font) - self.label_5.setStyleSheet("color:white") - self.label_5.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - self.label_5.setObjectName("label_5") - self.layoutWidget = QtWidgets.QWidget(parent=self.leds_slider_page) - self.layoutWidget.setGeometry(QtCore.QRect(10, 30, 691, 81)) - self.layoutWidget.setObjectName("layoutWidget") - self.leds_slider_header_layout = QtWidgets.QHBoxLayout(self.layoutWidget) - self.leds_slider_header_layout.setContentsMargins(0, 0, 0, 0) - self.leds_slider_header_layout.setObjectName("leds_slider_header_layout") - spacerItem17 = QtWidgets.QSpacerItem(60, 20, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) - self.leds_slider_header_layout.addItem(spacerItem17) - self.leds_slider_tittle_label = QtWidgets.QLabel(parent=self.layoutWidget) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.leds_slider_tittle_label.sizePolicy().hasHeightForWidth()) - self.leds_slider_tittle_label.setSizePolicy(sizePolicy) - self.leds_slider_tittle_label.setMinimumSize(QtCore.QSize(0, 60)) - self.leds_slider_tittle_label.setMaximumSize(QtCore.QSize(16777215, 60)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(24) - self.leds_slider_tittle_label.setFont(font) - self.leds_slider_tittle_label.setStyleSheet("background: transparent; color: white;") - self.leds_slider_tittle_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - self.leds_slider_tittle_label.setObjectName("leds_slider_tittle_label") - self.leds_slider_header_layout.addWidget(self.leds_slider_tittle_label) - self.leds_slider_back_btn = IconButton(parent=self.layoutWidget) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.leds_slider_back_btn.sizePolicy().hasHeightForWidth()) - self.leds_slider_back_btn.setSizePolicy(sizePolicy) - self.leds_slider_back_btn.setMinimumSize(QtCore.QSize(60, 60)) - self.leds_slider_back_btn.setMaximumSize(QtCore.QSize(60, 60)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(20) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.leds_slider_back_btn.setFont(font) - self.leds_slider_back_btn.setMouseTracking(False) - self.leds_slider_back_btn.setTabletTracking(True) - self.leds_slider_back_btn.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.leds_slider_back_btn.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.leds_slider_back_btn.setStyleSheet("") - self.leds_slider_back_btn.setAutoDefault(False) - self.leds_slider_back_btn.setFlat(True) - self.leds_slider_back_btn.setProperty("icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/back.svg")) - self.leds_slider_back_btn.setObjectName("leds_slider_back_btn") - self.leds_slider_header_layout.addWidget(self.leds_slider_back_btn) - self.layoutWidget1 = QtWidgets.QWidget(parent=self.leds_slider_page) - self.layoutWidget1.setGeometry(QtCore.QRect(10, 200, 688, 101)) - self.layoutWidget1.setObjectName("layoutWidget1") - self.verticalLayout_12 = QtWidgets.QVBoxLayout(self.layoutWidget1) - self.verticalLayout_12.setContentsMargins(0, 0, 0, 0) - self.verticalLayout_12.setObjectName("verticalLayout_12") - self.leds_w_slider = BlocksSlider(parent=self.layoutWidget1) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.leds_w_slider.sizePolicy().hasHeightForWidth()) - self.leds_w_slider.setSizePolicy(sizePolicy) - self.leds_w_slider.setMinimumSize(QtCore.QSize(600, 90)) - self.leds_w_slider.setMaximumSize(QtCore.QSize(600, 90)) - self.leds_w_slider.setMaximum(100) - self.leds_w_slider.setProperty("value", 100) - self.leds_w_slider.setOrientation(QtCore.Qt.Orientation.Horizontal) - self.leds_w_slider.setObjectName("leds_w_slider") - self.verticalLayout_12.addWidget(self.leds_w_slider, 0, QtCore.Qt.AlignmentFlag.AlignHCenter) - utilitiesStackedWidget.addWidget(self.leds_slider_page) - - self.retranslateUi(utilitiesStackedWidget) - utilitiesStackedWidget.setCurrentIndex(5) - QtCore.QMetaObject.connectSlotsByName(utilitiesStackedWidget) - - def retranslateUi(self, utilitiesStackedWidget): - _translate = QtCore.QCoreApplication.translate - utilitiesStackedWidget.setWindowTitle(_translate("utilitiesStackedWidget", "StackedWidget")) - self.utilities_title_label.setText(_translate("utilitiesStackedWidget", "Utilities")) - self.utilities_title_label.setProperty("class", _translate("utilitiesStackedWidget", "title_text")) - self.utilities_axes_btn.setText(_translate("utilitiesStackedWidget", "Axis\n" -"Maint.")) - self.utilities_axes_btn.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.update_btn.setText(_translate("utilitiesStackedWidget", "Update")) - self.utilities_routine_check_btn.setText(_translate("utilitiesStackedWidget", "Routine\n" -"Check")) - self.utilities_routine_check_btn.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.utilities_input_shaper_btn.setText(_translate("utilitiesStackedWidget", "Input\n" -"Shaper")) - self.utilities_input_shaper_btn.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.utilities_info_btn.setText(_translate("utilitiesStackedWidget", "Info")) - self.utilities_info_btn.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.utilities_leds_btn.setText(_translate("utilitiesStackedWidget", "LED\'s")) - self.utilities_leds_btn.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.info_title_label.setText(_translate("utilitiesStackedWidget", "Info")) - self.info_title_label.setProperty("class", _translate("utilitiesStackedWidget", "title_text")) - self.info_back_btn.setText(_translate("utilitiesStackedWidget", "Back")) - self.info_back_btn.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.info_back_btn.setProperty("button_type", _translate("utilitiesStackedWidget", "icon")) - self.kv_label.setText(_translate("utilitiesStackedWidget", "Model: Blocks RF50")) - self.smth_label.setText(_translate("utilitiesStackedWidget", "www.blockstec.com ")) - self.leds_title_label.setText(_translate("utilitiesStackedWidget", "LED\'s")) - self.leds_title_label.setProperty("class", _translate("utilitiesStackedWidget", "title_text")) - self.leds_back_btn.setText(_translate("utilitiesStackedWidget", "Back")) - self.leds_back_btn.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.leds_back_btn.setProperty("button_type", _translate("utilitiesStackedWidget", "icon")) - self.routines_page_title.setText(_translate("utilitiesStackedWidget", "Routine Check")) - self.routines_page_title.setProperty("class", _translate("utilitiesStackedWidget", "title_text")) - self.routine_check_back_btn.setText(_translate("utilitiesStackedWidget", "Back")) - self.routine_check_back_btn.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.routine_check_back_btn.setProperty("button_type", _translate("utilitiesStackedWidget", "icon")) - self.rc_bheat.setText(_translate("utilitiesStackedWidget", "Bed Heater")) - self.rc_bheat.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.rc_fans.setText(_translate("utilitiesStackedWidget", "Fans")) - self.rc_fans.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.rc_axis.setText(_translate("utilitiesStackedWidget", "Axis")) - self.rc_axis.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.rc_ext.setText(_translate("utilitiesStackedWidget", "Extruder")) - self.rc_ext.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.rc_tittle.setText(_translate("utilitiesStackedWidget", "label")) - self.rc_tittle.setProperty("class", _translate("utilitiesStackedWidget", "title_text")) - self.rc_label.setText(_translate("utilitiesStackedWidget", "TextLabel")) - self.rc_yes.setText(_translate("utilitiesStackedWidget", "Yes")) - self.rc_yes.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.rc_no.setText(_translate("utilitiesStackedWidget", "No")) - self.rc_no.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.lcd_settings_title_label.setText(_translate("utilitiesStackedWidget", "Axis Maintenance")) - self.lcd_settings_title_label.setProperty("class", _translate("utilitiesStackedWidget", "title_text")) - self.axes_back_btn.setText(_translate("utilitiesStackedWidget", "Back")) - self.axes_back_btn.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.axes_back_btn.setProperty("button_type", _translate("utilitiesStackedWidget", "icon")) - self.am_y.setText(_translate("utilitiesStackedWidget", "Y")) - self.am_execute.setText(_translate("utilitiesStackedWidget", "Execute")) - self.am_execute.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.am_z.setText(_translate("utilitiesStackedWidget", "Z")) - self.am_x.setText(_translate("utilitiesStackedWidget", "X")) - self.label_2.setText(_translate("utilitiesStackedWidget", "Input Shaper")) - self.label_2.setProperty("class", _translate("utilitiesStackedWidget", "title_text")) - self.input_shaper_back_btn.setText(_translate("utilitiesStackedWidget", "Back")) - self.input_shaper_back_btn.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.input_shaper_back_btn.setProperty("button_type", _translate("utilitiesStackedWidget", "icon")) - self.label_3.setText(_translate("utilitiesStackedWidget", "Input Shaper ")) - self.am_mzv_2.setText(_translate("utilitiesStackedWidget", "MZV")) - self.am_mzv_2.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.am_ei_2.setText(_translate("utilitiesStackedWidget", "EI")) - self.am_ei_2.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.am_3hump_ei_2.setText(_translate("utilitiesStackedWidget", "3hump_ei")) - self.am_3hump_ei_2.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.am_zv_2.setText(_translate("utilitiesStackedWidget", "ZV")) - self.am_zv_2.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.am_2hump_ei_2.setText(_translate("utilitiesStackedWidget", "2hump_ei")) - self.am_2hump_ei_2.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.am_cancel.setText(_translate("utilitiesStackedWidget", "Cancel")) - self.am_cancel.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.am_confirm.setText(_translate("utilitiesStackedWidget", "Confirm")) - self.am_confirm.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.label_8.setText(_translate("utilitiesStackedWidget", "User Input")) - self.toggle_led_button.setText(_translate("utilitiesStackedWidget", "PushButton")) - self.label_4.setText(_translate("utilitiesStackedWidget", "On")) - self.label_5.setText(_translate("utilitiesStackedWidget", "Off")) - self.leds_slider_tittle_label.setText(_translate("utilitiesStackedWidget", "LED\'s")) - self.leds_slider_tittle_label.setProperty("class", _translate("utilitiesStackedWidget", "title_text")) - self.leds_slider_back_btn.setText(_translate("utilitiesStackedWidget", "Back")) - self.leds_slider_back_btn.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.leds_slider_back_btn.setProperty("button_type", _translate("utilitiesStackedWidget", "icon")) -from lib.utils.blocks_button import BlocksCustomButton -from lib.utils.blocks_frame import BlocksCustomFrame -from lib.utils.blocks_slider import BlocksSlider -from lib.utils.check_button import BlocksCustomCheckButton -from lib.utils.icon_button import IconButton -from lib.utils.toggleAnimatedButton import ToggleAnimatedButton