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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 78 additions & 97 deletions BlocksScreen/lib/panels/widgets/jobStatusPage.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,

Expand All @@ -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(
Expand Down Expand Up @@ -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)
Expand All @@ -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")
Expand All @@ -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],
Expand All @@ -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"""
Expand All @@ -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))
Expand Down Expand Up @@ -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))
Expand All @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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,
Expand All @@ -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
)
Expand Down
20 changes: 11 additions & 9 deletions BlocksScreen/lib/utils/blocks_progressbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"""
Expand Down