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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 87 additions & 21 deletions BlocksScreen/lib/panels/printTab.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
import logging
import os
import typing
from functools import partial

from lib.panels.widgets.babystepPage import BabystepPage
from lib.panels.widgets.tunePage import TuneWidget
from configfile import BlocksScreenConfig, get_configparser
from lib.files import Files
from lib.moonrakerComm import MoonWebSocket
from lib.panels.widgets.babystepPage import BabystepPage
from lib.panels.widgets.basePopup import BasePopup
from lib.panels.widgets.confirmPage import ConfirmWidget
from lib.panels.widgets.filesPage import FilesPage
from lib.panels.widgets.jobStatusPage import JobStatusWidget
from lib.panels.widgets.loadWidget import LoadingOverlayWidget
from lib.panels.widgets.numpadPage import CustomNumpad
from lib.panels.widgets.sensorsPanel import SensorsWindow
from lib.printer import Printer
from lib.panels.widgets.slider_selector_page import SliderPage
from lib.panels.widgets.tunePage import TuneWidget
from lib.printer import Printer
from lib.utils.blocks_button import BlocksCustomButton
from lib.panels.widgets.numpadPage import CustomNumpad
from lib.panels.widgets.loadWidget import LoadingOverlayWidget
from lib.panels.widgets.basePopup import BasePopup
from configfile import BlocksScreenConfig, get_configparser
from lib.utils.display_button import DisplayButton
from PyQt6 import QtCore, QtGui, QtWidgets

logger = logging.getLogger(name="logs/BlocksScreen.log")


class PrintTab(QtWidgets.QStackedWidget):
"""QStackedWidget that contains the following widget panels:
Expand Down Expand Up @@ -61,6 +65,8 @@ class PrintTab(QtWidgets.QStackedWidget):
)

_z_offset: float = 0.0
_active_z_offset: float = 0.0
_finish_print_handled: bool = False

def __init__(
self,
Expand Down Expand Up @@ -97,6 +103,7 @@ def __init__(
self.addWidget(self.filesPage_widget)

self.BasePopup = BasePopup(self)
self.BasePopup_z_offset = BasePopup(self, floating=True)

self.confirmPage_widget = ConfirmWidget(self)
self.addWidget(self.confirmPage_widget)
Expand Down Expand Up @@ -137,7 +144,6 @@ def __init__(
lambda: self.change_page(self.indexOf(self.jobStatusPage_widget))
)
self.jobStatusPage_widget.hide_request.connect(
# lambda: self.change_page(self.indexOf(self.panel.print_page))
lambda: self.change_page(self.indexOf(self.print_page))
)
self.jobStatusPage_widget.request_file_info.connect(
Expand All @@ -148,6 +154,7 @@ def __init__(
self.jobStatusPage_widget.print_resume.connect(self.ws.api.resume_print)
self.jobStatusPage_widget.print_cancel.connect(self.handle_cancel_print)
self.jobStatusPage_widget.print_pause.connect(self.ws.api.pause_print)
self.jobStatusPage_widget.print_finish.connect(self.finish_print_signal)
self.jobStatusPage_widget.request_query_print_stats.connect(
self.ws.api.object_query
)
Expand Down Expand Up @@ -176,6 +183,7 @@ def __init__(
self.printer.gcode_move_update[str, list].connect(
self.jobStatusPage_widget.on_gcode_move_update
)
self.printer.request_available_objects_signal.connect(self.klipper_ready_signal)
self.babystepPage = BabystepPage(self)
self.babystepPage.request_back.connect(self.back_button)
self.addWidget(self.babystepPage)
Expand Down Expand Up @@ -203,6 +211,7 @@ def __init__(
self.printer.gcode_move_update[str, list].connect(
self.babystepPage.on_gcode_move_update
)
self.printer.gcode_move_update[str, list].connect(self.activate_save_button)
self.tune_page.run_gcode.connect(self.ws.api.run_gcode)
self.tune_page.request_sliderPage[str, int, "PyQt_PyObject"].connect(
self.on_slidePage_request
Expand Down Expand Up @@ -245,6 +254,8 @@ def __init__(
self.run_gcode_signal.connect(self.ws.api.run_gcode)
self.confirmPage_widget.on_delete.connect(self.delete_file)
self.change_page(self.indexOf(self.print_page)) # force set the initial page
self.save_config_btn.clicked.connect(self.save_config)
self.BasePopup_z_offset.accepted.connect(self.update_configuration_file)

@QtCore.pyqtSlot(str, dict, name="on_print_stats_update")
@QtCore.pyqtSlot(str, float, name="on_print_stats_update")
Expand Down Expand Up @@ -305,26 +316,45 @@ def delete_file(self, filename: str, directory: str = "gcodes") -> None:
)
self.BasePopup.open()

def save_config(self) -> None:
"""Handle Save configuration behaviour, shows confirmation dialog"""
if self._finish_print_handled:
self.run_gcode_signal.emit("Z_OFFSET_APPLY_PROBE")
self._z_offset = self._active_z_offset
self.babystepPage.bbp_z_offset_title_label.setText(
f"Z: {self._z_offset:.3f}mm"
)
self.BasePopup_z_offset.set_message(
f"The Z‑Offset is now {self._active_z_offset:.3f} mm.\n"
"Would you like to save this change permanently?\n"
"The machine will restart."
)
self.BasePopup_z_offset.cancel_button_text("Later")
self.BasePopup_z_offset.open()

def update_configuration_file(self):
"""Runs the `SAVE_CONFIG` gcode"""
self.run_gcode_signal.emit("Z_OFFSET_APPLY_PROBE")
self.run_gcode_signal.emit("SAVE_CONFIG")
self.BasePopup_z_offset.disconnect()

@QtCore.pyqtSlot(str, list, name="activate_save_button")
def activate_save_button(self, name: str, value: list) -> None:
"""Sync the `Save config` popup with the save_config_pending state"""
if not value:
return

if name == "homing_origin":
self._active_z_offset = value[2]
self.save_config_btn.setVisible(value[2] != 0)

def _on_delete_file_confirmed(self, filename: str, directory: str) -> None:
"""Handle confirmed file deletion after user accepted the dialog"""
self.file_data.on_request_delete_file(filename, directory)
self.request_back.emit()
self.filesPage_widget.reset_dir()
self.BasePopup.disconnect()

def paintEvent(self, a0: QtGui.QPaintEvent) -> None:
"""Widget painting"""
if self.babystepPage.isVisible():
_button_name_str = f"nozzle_offset_{self._z_offset}"
if hasattr(self, _button_name_str):
_button_attr = getattr(self, _button_name_str)
if callable(_button_attr) and isinstance(
_button_attr, BlocksCustomButton
):
_button_attr.setChecked(True)

return super().paintEvent(a0)

def setProperty(self, name: str, value: typing.Any) -> bool:
"""Intercept the set property method

Expand Down Expand Up @@ -360,6 +390,21 @@ def back_button(self) -> None:
"""Goes back to the previous page"""
self.request_back.emit()

@QtCore.pyqtSlot(name="klipper_ready_signal")
def klipper_ready_signal(self) -> None:
"""React to klipper ready signal"""
self.babystepPage.baby_stepchange = False
self._finish_print_handled = False

@QtCore.pyqtSlot(name="finish_print_signal")
def finish_print_signal(self) -> None:
"""Behaviour when the print ends — but only once."""
if self._finish_print_handled:
return
if self._active_z_offset != 0 and self.babystepPage.baby_stepchange:
self.save_config()
self._finish_print_handled = True

def setupMainPrintPage(self) -> None:
"""Setup UI for print page"""
self.setObjectName("printStackedWidget")
Expand Down Expand Up @@ -424,6 +469,27 @@ def setupMainPrintPage(self) -> None:
"icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/print.svg")
)
self.main_print_btn.setObjectName("main_print_btn")
self.save_config_btn = DisplayButton(parent=self.print_page)
self.save_config_btn.setGeometry(QtCore.QRect(540, 20, 170, 50))
font.setPointSize(8)
font.setFamily("Montserrat")
self.save_config_btn.setFont(font)
self.save_config_btn.setMouseTracking(False)
self.save_config_btn.setTabletTracking(True)
self.save_config_btn.setContextMenuPolicy(
QtCore.Qt.ContextMenuPolicy.NoContextMenu
)
self.save_config_btn.setProperty(
"icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/save.svg")
)
self.save_config_btn.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight)
self.save_config_btn.setStyleSheet("")
self.save_config_btn.setAutoDefault(False)
self.save_config_btn.setFlat(True)
self.save_config_btn.setMinimumSize(QtCore.QSize(170, 50))
self.save_config_btn.setMaximumSize(QtCore.QSize(170, 50))
self.save_config_btn.setText("Save\nZ-Offset")
self.save_config_btn.hide()
self.main_text_label = QtWidgets.QLabel(parent=self.print_page)
self.main_text_label.setEnabled(True)
self.main_text_label.setGeometry(QtCore.QRect(105, 180, 500, 200))
Expand Down
97 changes: 43 additions & 54 deletions BlocksScreen/lib/panels/widgets/babystepPage.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import typing

from lib.utils.blocks_button import BlocksCustomButton
from lib.utils.blocks_label import BlocksLabel
from lib.utils.icon_button import IconButton
from lib.utils.check_button import BlocksCustomCheckButton
from lib.utils.icon_button import IconButton
from PyQt6 import QtCore, QtGui, QtWidgets


Expand Down Expand Up @@ -33,28 +32,38 @@ def __init__(self, parent) -> None:
self.bbp_nozzle_offset_025.toggled.connect(self.handle_z_offset_change)
self.bbp_nozzle_offset_05.toggled.connect(self.handle_z_offset_change)
self.bbp_nozzle_offset_1.toggled.connect(self.handle_z_offset_change)
self._baby_stepchange = False

self.savebutton.clicked.connect(self.save_value)
@property
def baby_stepchange(self):
"""Returns if the babystep was changed during print"""
return self._baby_stepchange

@baby_stepchange.setter
def baby_stepchange(self, value: bool) -> None:
if not isinstance(value, bool):
raise ValueError("Value must be a bool")
self._baby_stepchange = value

@QtCore.pyqtSlot(name="on_move_nozzle_close")
def on_move_nozzle_close(self) -> None:
"""Move the nozzle closer to the print plate
by the amount set in **` self._z_offset`**
"""
self.run_gcode.emit(
f"SET_GCODE_OFFSET Z_ADJUST=-{self._z_offset}" # Z_ADJUST adds the value to the existing offset
f"SET_GCODE_OFFSET Z_ADJUST=-{self._z_offset} MOVE=1" # Z_ADJUST adds the value to the existing offset
)
self.savebutton.setVisible(True)
self._baby_stepchange = True

@QtCore.pyqtSlot(name="on_move_nozzle_away")
def on_move_nozzle_away(self) -> None:
"""Slot for Babystep button to get far from the
bed by **` self._z_offset`** amount
"""
self.run_gcode.emit(
f"SET_GCODE_OFFSET Z_ADJUST=+{self._z_offset}" # Z_ADJUST adds the value to the existing offset
f"SET_GCODE_OFFSET Z_ADJUST=+{self._z_offset} MOVE=1" # Z_ADJUST adds the value to the existing offset
)
self.savebutton.setVisible(True)
self._baby_stepchange = True

@QtCore.pyqtSlot(name="handle_z_offset_change")
def handle_z_offset_change(self) -> None:
Expand All @@ -67,18 +76,11 @@ def handle_z_offset_change(self) -> None:

Possible values are: 0.01, 0.025, 0.05, 0.1 **mm**
"""
_possible_z_values: typing.List = [0.01, 0.025, 0.05, 0.1]
_sender: QtCore.QObject | None = self.sender()
if self._z_offset == float(_sender.text()[:-3]):
return
self._z_offset = float(_sender.text()[:-3])

def save_value(self):
"""Save new z offset value"""
self.run_gcode.emit("Z_OFFSET_APPLY_PROBE")
self.savebutton.setVisible(False)
self.bbp_z_offset_title_label.setText(self.bbp_z_offset_current_value.text())

def on_gcode_move_update(self, name: str, value: list) -> None:
"""Handle gcode move updates"""
if not value:
Expand All @@ -87,8 +89,6 @@ def on_gcode_move_update(self, name: str, value: list) -> None:
if name == "homing_origin":
self._z_offset_text = value[2]
self.bbp_z_offset_current_value.setText(f"Z: {self._z_offset_text:.3f}mm")
if self.bbp_z_offset_title_label.text() == "smth":
self.bbp_z_offset_title_label.setText(f"Z: {self._z_offset_text:.3f}mm")

def setupUI(self):
"""Setup babystep page ui"""
Expand Down Expand Up @@ -143,16 +143,6 @@ def setupUI(self):
self.bbp_header_title.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.bbp_header_title.setObjectName("bbp_header_title")

self.savebutton = BlocksCustomButton(self)
self.savebutton.setGeometry(QtCore.QRect(460, 340, 200, 60))
self.savebutton.setText("Save?")
self.savebutton.setObjectName("savebutton")
self.savebutton.setPixmap(QtGui.QPixmap(":/ui/media/btn_icons/save.svg"))
self.savebutton.setVisible(False)
font = QtGui.QFont()
font.setPointSize(15)
self.savebutton.setFont(font)

spacerItem = QtWidgets.QSpacerItem(
60,
20,
Expand Down Expand Up @@ -234,6 +224,30 @@ def setupUI(self):
QtCore.Qt.AlignmentFlag.AlignHCenter | QtCore.Qt.AlignmentFlag.AlignVCenter,
)

# 0.05mm button
self.bbp_nozzle_offset_05 = BlocksCustomCheckButton(
parent=self.bbp_offset_steps_buttons_group_box
)
self.bbp_nozzle_offset_05.setMinimumSize(QtCore.QSize(100, 70))
self.bbp_nozzle_offset_05.setMaximumSize(
QtCore.QSize(100, 70)
) # Increased max width by 5 pixels
self.bbp_nozzle_offset_05.setText("0.05 mm")

font = QtGui.QFont()
font.setPointSize(14)
self.bbp_nozzle_offset_05.setFont(font)
self.bbp_nozzle_offset_05.setCheckable(True)
self.bbp_nozzle_offset_05.setFlat(True)
self.bbp_nozzle_offset_05.setProperty("button_type", "")
self.bbp_nozzle_offset_05.setObjectName("bbp_nozzle_offset_05")
self.bbp_offset_value_selector_group.addButton(self.bbp_nozzle_offset_05)
self.bbp_offset_steps_buttons.addWidget(
self.bbp_nozzle_offset_05,
0,
QtCore.Qt.AlignmentFlag.AlignHCenter | QtCore.Qt.AlignmentFlag.AlignVCenter,
)

# Line separator for 0.1mm - set size policy to expanding horizontally

# 0.01mm button
Expand All @@ -260,30 +274,6 @@ def setupUI(self):
QtCore.Qt.AlignmentFlag.AlignHCenter | QtCore.Qt.AlignmentFlag.AlignVCenter,
)

# 0.05mm button
self.bbp_nozzle_offset_05 = BlocksCustomCheckButton(
parent=self.bbp_offset_steps_buttons_group_box
)
self.bbp_nozzle_offset_05.setMinimumSize(QtCore.QSize(100, 70))
self.bbp_nozzle_offset_05.setMaximumSize(
QtCore.QSize(100, 70)
) # Increased max width by 5 pixels
self.bbp_nozzle_offset_05.setText("0.05 mm")

font = QtGui.QFont()
font.setPointSize(14)
self.bbp_nozzle_offset_05.setFont(font)
self.bbp_nozzle_offset_05.setCheckable(True)
self.bbp_nozzle_offset_05.setFlat(True)
self.bbp_nozzle_offset_05.setProperty("button_type", "")
self.bbp_nozzle_offset_05.setObjectName("bbp_nozzle_offset_05")
self.bbp_offset_value_selector_group.addButton(self.bbp_nozzle_offset_05)
self.bbp_offset_steps_buttons.addWidget(
self.bbp_nozzle_offset_05,
0,
QtCore.Qt.AlignmentFlag.AlignHCenter | QtCore.Qt.AlignmentFlag.AlignVCenter,
)

# 0.025mm button
self.bbp_nozzle_offset_025 = BlocksCustomCheckButton(
parent=self.bbp_offset_steps_buttons_group_box
Expand Down Expand Up @@ -351,9 +341,8 @@ def setupUI(self):
self.bbp_z_offset_title_label.setStyleSheet(
"color: gray; background: transparent;"
)
self.bbp_z_offset_title_label.setText("Z-Offset")
self.bbp_z_offset_title_label.setObjectName("bbp_z_offset_title_label")
self.bbp_z_offset_title_label.setText("smth")
self.bbp_z_offset_title_label.setText("Z: 0.000mm")
self.bbp_z_offset_title_label.setGeometry(420, 270, 200, 30)

# === END OF NEW LABEL ===
Expand Down Expand Up @@ -399,7 +388,7 @@ def setupUI(self):
self.bbp_mvup.setText("")
self.bbp_mvup.setFlat(True)
self.bbp_mvup.setPixmap(
QtGui.QPixmap(":/arrow_icons/media/btn_icons/up_arrow.svg")
QtGui.QPixmap(":/baby_step/media/btn_icons/move_nozzle_close.svg")
)
self.bbp_mvup.setObjectName("bbp_away_from_bed")
self.bbp_option_button_group = QtWidgets.QButtonGroup(self)
Expand All @@ -416,7 +405,7 @@ def setupUI(self):
self.bbp_mvdown.setText("")
self.bbp_mvdown.setFlat(True)
self.bbp_mvdown.setPixmap(
QtGui.QPixmap(":/arrow_icons/media/btn_icons/down_arrow.svg")
QtGui.QPixmap(":/baby_step/media/btn_icons/move_nozzle_away.svg")
)
self.bbp_mvdown.setObjectName("bbp_close_to_bed")
self.bbp_option_button_group.addButton(self.bbp_mvdown)
Expand Down
Loading
Loading