diff --git a/BlocksScreen/lib/panels/widgets/jobStatusPage.py b/BlocksScreen/lib/panels/widgets/jobStatusPage.py index 0d7c4e29..9f74ba6e 100644 --- a/BlocksScreen/lib/panels/widgets/jobStatusPage.py +++ b/BlocksScreen/lib/panels/widgets/jobStatusPage.py @@ -85,6 +85,11 @@ def toggle_thumbnail_expansion(self) -> None: self.headerWidget.show() self.show() + def showEvent(self, a0) -> None: + """Reimplemented method, handle `show` Event""" + if self._current_file_name: + self.request_file_info.emit(self._current_file_name) + def eventFilter(self, sender_obj: QtCore.QObject, event: events.QEvent) -> bool: """Filter events, @@ -110,9 +115,7 @@ def _load_thumbnails(self, *thumbnails) -> None: logger.debug("Unable to load thumbnails, no thumbnails provided") return self.create_thumbnail_widget() - self.thumbnail_view.installEventFilter( - self - ) # Filter events on this widget, for clicks + self.thumbnail_view.installEventFilter(self) scene = QtWidgets.QGraphicsScene() _biggest_thumb = self.thumbnail_graphics[-1] self.thumbnail_view.setSceneRect( @@ -172,11 +175,13 @@ def on_print_start(self, file: str) -> None: else: raise TypeError("QApplication.instance expected non None value") except Exception as e: - logger.debug(f"Unexpected error while posting print job start event: {e}") + logger.debug("Unexpected error while posting print job start event: %s", e) @QtCore.pyqtSlot(dict, name="on_fileinfo") def on_fileinfo(self, fileinfo: dict) -> None: """Handle received file information/metadata""" + if not self.isVisible(): + return self.total_layers = str(fileinfo.get("layer_count", "?")) self.layer_display_button.setText("?") self.layer_display_button.secondary_text = str(self.total_layers) @@ -185,24 +190,59 @@ def on_fileinfo(self, fileinfo: dict) -> None: @QtCore.pyqtSlot(name="pause_resume_print") def pause_resume_print(self) -> None: - """Handle pause/resume print job""" - if not getattr(self, "_pause_locked", False): - self._pause_locked = True - self.pause_printing_btn.setEnabled(False) - - if self._internal_print_status == "printing": - self.print_pause.emit() - self._internal_print_status = "paused" - - elif self._internal_print_status == "paused": - self.print_resume.emit() - self._internal_print_status = "printing" - - QtCore.QTimer.singleShot(5000, self._unlock_pause_button) - - def _unlock_pause_button(self): - self._pause_locked = False - self.pause_printing_btn.setEnabled(True) + """Handle pause/resume print job button clicked""" + self.pause_printing_btn.setEnabled(False) + if self._internal_print_status == "printing": + self._internal_print_status = "paused" + self.print_pause.emit() + elif self._internal_print_status == "paused": + self._internal_print_status = "printing" + self.print_resume.emit() + + def _handle_print_state(self, state: str) -> None: + """Handle print state change received from + printer_status object updated + """ + valid_states = {"printing", "paused"} + invalid_states = {"cancelled", "complete", "error", "standby"} + lstate = state.lower() + if lstate in valid_states: + self._internal_print_status = lstate + if lstate == "paused": + self.pause_printing_btn.setText(" Resume") + self.pause_printing_btn.setPixmap( + QtGui.QPixmap(":/ui/media/btn_icons/play.svg") + ) + elif lstate == "printing": + self.pause_printing_btn.setText("Pause") + self.pause_printing_btn.setPixmap( + QtGui.QPixmap(":/ui/media/btn_icons/pause.svg") + ) + self.pause_printing_btn.setEnabled(True) + self.request_query_print_stats.emit({"print_stats": ["filename"]}) + self.show_request.emit() + lstate = "start" + elif lstate in invalid_states: + self._current_file_name = "" + self._internal_print_status = "" + self.total_layers = "?" + self.file_metadata.clear() + self.hide_request.emit() + if hasattr(self, "thumbnail_view"): + getattr(self, "thumbnail_view").deleteLater() + # Send Event on Print state + if hasattr(events, str("Print" + lstate.capitalize())): + event_obj = getattr(events, str("Print" + lstate.capitalize())) + event = event_obj(self._current_file_name, self.file_metadata) + instance = QtWidgets.QApplication.instance() + if instance: + instance.postEvent(self.window(), event) + return + logger.error( + "QApplication.instance expected non None value,\ + Unable to post event %s", + str("Print" + lstate.capitalize()), + ) @QtCore.pyqtSlot(str, dict, name="on_print_stats_update") @QtCore.pyqtSlot(str, float, name="on_print_stats_update") @@ -216,82 +256,42 @@ def on_print_stats_update(self, field: str, value: dict | float | str) -> None: value (dict | float | str): The value for the field. """ if isinstance(value, str): + if "state" in field: + self._handle_print_state(value) if "filename" in field: self._current_file_name = value if self.js_file_name_label.text().lower() != value.lower(): self.js_file_name_label.setText(self._current_file_name) - self.request_file_info.emit(value) # Request file metadata - if "state" in field: - if value.lower() == "printing" or value == "paused": - self._internal_print_status = value - if value == "paused": - self.pause_printing_btn.setText(" Resume") - self.pause_printing_btn.setPixmap( - QtGui.QPixmap(":/ui/media/btn_icons/play.svg") - ) - elif value == "printing": - self.pause_printing_btn.setText("Pause") - self.pause_printing_btn.setPixmap( - QtGui.QPixmap(":/ui/media/btn_icons/pause.svg") - ) - self.request_query_print_stats.emit({"print_stats": ["filename"]}) - self.show_request.emit() - value = "start" # This is for event compatibility - elif value in ("cancelled", "complete", "error", "standby"): - self._current_file_name = "" - self._internal_print_status = "" - self.total_layers = "?" - self.file_metadata.clear() - self.hide_request.emit() - self.thumbnail_view.deleteLater() - self.thumbnail_view_layout.deleteLater() - - if hasattr(events, str("Print" + value.capitalize())): - event_obj = getattr(events, str("Print" + value.capitalize())) - event = event_obj(self._current_file_name, self.file_metadata) - try: - instance = QtWidgets.QApplication.instance() - if instance: - instance.postEvent(self.window(), event) - else: - raise TypeError( - "QApplication.instance expected non None value" - ) - except Exception as e: - logger.info( - f"Unexpected error while posting print job start event: {e}" - ) - + if self.isVisible(): + self.request_file_info.emit(value) if not self.file_metadata: return + if not self.isVisible(): + return if isinstance(value, dict): if "total_layer" in value.keys(): - self.total_layers = value["total_layer"] + self.total_layers = value.get("total_layer", "?") self.layer_display_button.secondary_text = str(self.total_layers) if "current_layer" in value.keys(): - if value["current_layer"] is not None: - _current_layer = value["current_layer"] - if _current_layer is not None: - self.layer_display_button.setText(f"{int(_current_layer)}") + _current_layer = value.get("current_layer", None) + if _current_layer: + self.layer_display_button.setText(f"{int(_current_layer)}") elif isinstance(value, float): if "total_duration" in field: - self.print_total_duration = value - _time = estimate_print_time(int(self.print_total_duration)) + _time = estimate_print_time(int(value)) _print_time_string = ( f"{_time[0]}Day {_time[1]}H {_time[2]}min {_time[3]} s" if _time[0] != 0 else f"{_time[1]}H {_time[2]}min {_time[3]}s" ) self.print_time_display_button.setText(_print_time_string) - elif "print_duration" in field: - self.current_print_duration_seconds = value - elif "filament_used" in field: - self.filament_used_mm = value @QtCore.pyqtSlot(str, list, name="on_gcode_move_update") def on_gcode_move_update(self, field: str, value: list) -> None: """Handle gcode move""" - if "gcode_position" in field: # Without offsets + if not self.isVisible(): + return + if "gcode_position" in field: if self._internal_print_status == "printing": _current_layer = calculate_current_layer( z_position=value[2], @@ -314,12 +314,10 @@ def virtual_sdcard_update(self, field: str, value: float | bool) -> None: field (str): Name of the updated field on the virtual_sdcard object value (float | bool): The updated information for the corresponding field """ - if isinstance(value, bool): - ... + if not self.isVisible(): + return if "progress" == field: self.printing_progress_bar.setValue(value) - if "file_position" == field: - ... def _setupUI(self) -> None: """Setup widget ui""" @@ -330,8 +328,6 @@ def _setupUI(self) -> None: sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(1) sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth()) - # ----------------------------------size policy - self.setSizePolicy(sizePolicy) self.setMinimumSize(QtCore.QSize(710, 420)) self.setMaximumSize(QtCore.QSize(720, 420)) @@ -369,7 +365,6 @@ def _setupUI(self) -> None: font = QtGui.QFont() font.setFamily("Montserrat") font.setPointSize(14) - # ------------------------------Header self.js_file_name_icon = BlocksLabel(parent=self) self.js_file_name_icon.setSizePolicy(sizePolicy) self.js_file_name_icon.setMinimumSize(QtCore.QSize(60, 60)) @@ -383,7 +378,6 @@ def _setupUI(self) -> None: QtGui.QPixmap(":/files/media/btn_icons/file_icon.svg"), ) self.js_file_name_icon.setObjectName("js_file_name_icon") - self.js_file_name_label = BlocksLabel(parent=self) self.js_file_name_label.setEnabled(True) self.js_file_name_label.setSizePolicy(sizePolicy) @@ -395,7 +389,6 @@ def _setupUI(self) -> None: self.js_file_name_label.setObjectName("js_file_name_label") self.job_status_header_layout.addWidget(self.js_file_name_icon) self.job_status_header_layout.addWidget(self.js_file_name_label) - # -----------------------------buttons font.setPointSize(18) self.pause_printing_btn = BlocksCustomButton(self) self.pause_printing_btn.setSizePolicy(sizePolicy) @@ -430,45 +423,34 @@ def _setupUI(self) -> None: self.tune_menu_btn.setText("Tune") self.stop_printing_btn.setText("Cancel") self.pause_printing_btn.setText("Pause") - # -----------------------------Progress bar self.printing_progress_bar = CustomProgressBar(self) self.printing_progress_bar.setMinimumHeight(150) self.printing_progress_bar.setObjectName("printing_progress_bar") self.printing_progress_bar.setSizePolicy(sizePolicy) self.job_status_progress_layout.addWidget(self.printing_progress_bar) - - # -----------------------------display buttons - self.layer_display_button = DisplayButton(self) self.layer_display_button.button_type = "display_secondary" self.layer_display_button.setEnabled(False) self.layer_display_button.setSizePolicy(sizePolicy) - self.layer_display_button.setMinimumSize(QtCore.QSize(200, 80)) - self.layer_display_button.setProperty( "icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/layers.svg") ) self.layer_display_button.setObjectName("layer_display_button") - self.print_time_display_button = DisplayButton(self) self.print_time_display_button.button_type = "normal" self.print_time_display_button.setEnabled(False) self.print_time_display_button.setSizePolicy(sizePolicy) - self.print_time_display_button.setMinimumSize(QtCore.QSize(200, 80)) - self.print_time_display_button.setProperty( "icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/time.svg") ) self.print_time_display_button.setObjectName("print_time_display_button") - self.job_stats_display_layout.addWidget( self.layer_display_button, 0, QtCore.Qt.AlignmentFlag.AlignHCenter | QtCore.Qt.AlignmentFlag.AlignVCenter, ) - self.job_stats_display_layout.addWidget( self.print_time_display_button, 0, @@ -480,7 +462,6 @@ def create_thumbnail_widget(self) -> None: """Create thumbnail graphics view widget""" self.thumbnail_view = QtWidgets.QGraphicsView() self.thumbnail_view.setMinimumSize(QtCore.QSize(48, 48)) - # self.thumbnail_view.setMaximumSize(QtCore.QSize(300, 300)) self.thumbnail_view.setAttribute( QtCore.Qt.WidgetAttribute.WA_TranslucentBackground, True ) diff --git a/BlocksScreen/lib/utils/blocks_progressbar.py b/BlocksScreen/lib/utils/blocks_progressbar.py index a05aafa5..414097bb 100644 --- a/BlocksScreen/lib/utils/blocks_progressbar.py +++ b/BlocksScreen/lib/utils/blocks_progressbar.py @@ -40,27 +40,29 @@ def set_pen_width(self, value) -> None: self._pen_width = value self.update() + def _scale_pixmap(self) -> None: + self._inner_rect = self._calculate_inner_geometry() + self._pixmap_cached = self._pixmap.scaled( + self._inner_rect.size().toSize(), + QtCore.Qt.AspectRatioMode.KeepAspectRatio, + QtCore.Qt.TransformationMode.SmoothTransformation, + ) + def set_inner_pixmap(self, pixmap: QtGui.QPixmap) -> None: """Set the inner icon pixmap on the progress bar circumference. """ self._pixmap = pixmap - self.update() + self._scale_pixmap() def resizeEvent(self, a0) -> None: - """Re-implemented method, handle widget resize Events + """Reimplemented method, handle widget resize Events Currently rescales the set pixmap so it has the optimal size. """ - self._inner_rect = self._calculate_inner_geometry() - self._pixmap_cached = self._pixmap.scaled( - self._inner_rect.size().toSize(), - QtCore.Qt.AspectRatioMode.KeepAspectRatio, - QtCore.Qt.TransformationMode.SmoothTransformation, - ) + self._scale_pixmap() self.update() - return super().resizeEvent(a0) def sizeHint(self) -> QtCore.QSize: """Re-implemented method, preferable widget size"""