Skip to content
Draft
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
21 changes: 21 additions & 0 deletions BlocksScreen/lib/panels/filamentTab.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,16 @@ def _build_spool_page(self) -> QtWidgets.QWidget:
frame_lay.addWidget(self._spool_load_widget, 1)
self._spool_list_view.hide()

self._no_spools_label = QtWidgets.QLabel("", frame)
self._no_spools_label.setWordWrap(True)
self._no_spools_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self._no_spools_label.setStyleSheet("color: gray;")
no_spools_font = QtGui.QFont()
no_spools_font.setPointSize(13)
self._no_spools_label.setFont(no_spools_font)
self._no_spools_label.hide()
frame_lay.addWidget(self._no_spools_label)

self._add_spool_page = AddSpoolPage(self)
self._add_filament_page = AddFilamentPage(self)

Expand Down Expand Up @@ -617,6 +627,7 @@ def on_spools_received(self, result: dict) -> None:
"""Handles the result from the API call to get spools for the spoolman page."""
self._spool_load_widget.hide()
self._spool_list_view.show()
self._no_spools_label.hide()

self.reset_spool_info()

Expand Down Expand Up @@ -660,6 +671,16 @@ def on_spools_received(self, result: dict) -> None:
self._spool_id_map[name] = spool
self.update()

if self._spool_id_map:
self._no_spools_label.hide()
else:
self._no_spools_label.setText(
f'No spools found for "{self._material_filter}"'
if self._material_filter
else "No spools found"
)
self._no_spools_label.show()

def _on_spool_selected(self) -> None:
item = self._spool_model.get_selected_item()
if item is None:
Expand Down
74 changes: 46 additions & 28 deletions BlocksScreen/lib/panels/widgets/addFilamentPage.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class AddFilamentPage(QtWidgets.QWidget):
def __init__(self, parent=None) -> None:
super().__init__(parent)
self._keyboard_field: QtWidgets.QLineEdit | None = None
self._color_hex = "ffffff"

self._build_ui()

Expand Down Expand Up @@ -66,7 +67,7 @@ def setData(self, material: str, extruder_temp: int):
def reset(self):
self._name_field.setText("")
self._material_field.setText("---")
self._color_field.setText("ffffff")
self._set_color("ffffff")
self._ext_temp_field.setText("---")
self._bed_temp_field.setText("---")
self._density_field.setText("---")
Expand Down Expand Up @@ -135,30 +136,37 @@ def _on_bed_temp_change(self, _name: str, value: int) -> None:
self._bed_temp_field.setText(str(value))

def _open_color_wheel(self) -> None:
self.color_whell.set_color_hex(
self._color_field.text().strip().lstrip("#") or "ffffff"
)
self.color_whell.set_color_hex(self._color_hex or "ffffff")
self._color_whell_popup.show()

@QtCore.pyqtSlot(str, name="on-color-selected")
def _on_color_selected(self, hex_str: str) -> None:
self._color_field.setText(hex_str)

def _update_swatch(self) -> None:
hex_text = self._color_field.text().strip("#").strip()
if len(hex_text) == 6:
color = QtGui.QColor(f"#{hex_text}")
self._color_swatch.setStyleSheet(
f"border-radius: 8px;"
f"background: rgb({color.red()},{color.green()},{color.blue()});"
f"border: 2px solid rgba(255,255,255,80);"
)
self._set_color(hex_str)

def _set_color(self, hex_str: str) -> None:
"""Stores *hex_str* (what the Spoolman API needs) and updates the
RGB text label + swatch preview shown to the user."""
hex_text = hex_str.strip().lstrip("#")
if len(hex_text) != 6:
return
self._color_hex = hex_text
color = QtGui.QColor(f"#{hex_text}")
self._color_field.setText(
f"<span style='color:#ff0000;'>R</span>:{color.red()} "
f"<span style='color:#00ff00;'>G</span>:{color.green()} "
f"<span style='color:#0000ff;'>B</span>:{color.blue()}"
)
self._color_swatch.setStyleSheet(
f"border-radius: 8px;"
f"background: rgb({color.red()},{color.green()},{color.blue()});"
f"border: 2px solid rgba(255,255,255,80);"
)

def _on_submit(self) -> None:
body: dict = {}
name = self._name_field.text().strip()
material = self._material_field.text().strip()
color_hex = self._color_field.text().strip().strip("#")
color_hex = self._color_hex
ext_temp = self._ext_temp_field.text().strip()
bed_temp = self._bed_temp_field.text().strip()
density_text = self._density_field.text().strip()
Expand All @@ -184,7 +192,7 @@ def _on_submit(self) -> None:
body["density"] = 1.24

body["diameter"] = 1.75 # Default diameter, can be modified later if needed
if not vendor_text == "---":
if vendor_text != "---":
self.request_add_manufacturer.emit({"name": vendor_text})
self.request_filament_body = body
return
Expand Down Expand Up @@ -232,7 +240,7 @@ def _make_field(parent: QtWidgets.QWidget) -> BlocksCustomLinEdit:
blank.setFixedSize(60, 60)
hdr.addWidget(blank)

title_lbl = QtWidgets.QLabel("Add Filament", self)
title_lbl = QtWidgets.QLabel("New Filament", self)
title_lbl.setFont(_f(22))
title_lbl.setFixedHeight(60)
title_lbl.setStyleSheet("color: white; background: transparent;")
Expand All @@ -257,27 +265,33 @@ def _make_field(parent: QtWidgets.QWidget) -> BlocksCustomLinEdit:

self._name_field = _make_field(left_frame)
self._material_field = _make_field(left_frame)
self._color_field = _make_field(left_frame)

self._color_field = QtWidgets.QLabel(left_frame)
self._color_field.setFont(_f(14))
self._color_field.setFixedHeight(46)
self._color_field.setStyleSheet("color: rgb(255, 255, 255);")

self._color_swatch = QtWidgets.QLabel(left_frame)
self._color_swatch.setFixedSize(70, 70)
self._color_swatch.setStyleSheet(
"border-radius: 8px; background: #ffffff; border: 2px solid rgba(255,255,255,80);"
)
self._color_swatch.setCursor(QtCore.Qt.CursorShape.PointingHandCursor)
self._color_swatch.mousePressEvent = lambda event: self._open_color_wheel()

left_lay.addWidget(_key_lbl("Name:", left_frame))
left_lay.addWidget(self._name_field)

left_lay.addWidget(_key_lbl("Material:", left_frame))
left_lay.addWidget(self._material_field)

left_lay.addWidget(_key_lbl("Color (hex):", left_frame))
left_lay.addWidget(_key_lbl("Color:", left_frame))
color_row = QtWidgets.QHBoxLayout()
color_row.setSpacing(30)
color_row.setContentsMargins(0, 0, 0, 0)
self._color_field.setMaximumWidth(100)
color_row.addWidget(self._color_field)
self._color_field.setMaximumWidth(220)
color_row.addWidget(self._color_swatch)
color_row.addWidget(self._color_field)
color_row.addStretch(1)
left_lay.addLayout(color_row)

Expand Down Expand Up @@ -324,7 +338,7 @@ def _make_field(parent: QtWidgets.QWidget) -> BlocksCustomLinEdit:

self._name_field.setPlaceholderText("e.g. PLA Generic")
self._material_field.setText("PLA")
self._color_field.setText("ffffff")
self._set_color("ffffff")
self._ext_temp_field.setText("220")
self._bed_temp_field.setText("60")
self._density_field.setText("1.24")
Expand All @@ -334,7 +348,6 @@ def _make_field(parent: QtWidgets.QWidget) -> BlocksCustomLinEdit:
self._material_field.clicked.connect(
lambda: self._show_keyboard(self._material_field)
)
self._color_field.clicked.connect(self._open_color_wheel)
self._ext_temp_field.clicked.connect(
lambda: self.request_numpad[str, int, "PyQt_PyObject", int, int].emit(
"Extruder Temp",
Expand All @@ -360,13 +373,18 @@ def _make_field(parent: QtWidgets.QWidget) -> BlocksCustomLinEdit:
lambda: self._show_keyboard(self._vendor_field, max_char=65)
)

self._color_field.textChanged.connect(self._update_swatch)

spacer = QtWidgets.QSpacerItem(
5,
5,
QtWidgets.QSizePolicy.Policy.Minimum,
QtWidgets.QSizePolicy.Policy.Minimum,
)
root.addItem(spacer)
# Submit
submit_btn = BlocksCustomButton(self)
submit_btn.setFixedSize(220, 80)
submit_btn.setFixedSize(400, 80)
submit_btn.setFont(_f(16))
submit_btn.setText("Add\nFilament")
submit_btn.setText("New Filament")
submit_btn.setPixmap(
QtGui.QPixmap(":/filament_related/media/btn_icons/add filament.svg")
)
Expand Down
31 changes: 29 additions & 2 deletions BlocksScreen/lib/panels/widgets/addSpoolPage.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,15 @@ def reset(self) -> None:
"""Clear state and trigger a fresh filament fetch. Call before showing."""
self._selected_filament_id = None
self._submit_btn.setEnabled(False)
self._lot_field.setEnabled(False)
self._weight_field.setEnabled(False)
self._location_field.setEnabled(False)
self._location_field.clear()
self._lot_field.clear()
self._weight_field.clear()
self._fil_list_view.hide()
self._fil_load_widget.show()
self._no_filaments_label.hide()
self._fil_model.clear()
self._fil_delegate.clear()
self.request_filaments.emit()
Expand All @@ -87,7 +91,7 @@ def on_filaments_received(self, result: dict) -> None:
self._fil_delegate.clear()
self._fil_model.add_item(
ListItem(
text="+ Add Filament",
text=" New Filament",
left_icon=self._make_add_pixmap(),
_lfontsize=14,
height=60,
Expand Down Expand Up @@ -116,6 +120,16 @@ def on_filaments_received(self, result: dict) -> None:
self._filament_id_map[name] = fil
self.update()

if self._filament_id_map:
self._no_filaments_label.hide()
else:
self._no_filaments_label.setText(
f'No filaments found for "{self._material_filter}"'
if self._material_filter
else "No filaments found"
)
self._no_filaments_label.show()

@staticmethod
def _make_add_pixmap() -> QtGui.QPixmap:
pixmap = QtGui.QPixmap(32, 32)
Expand All @@ -142,12 +156,15 @@ def on_add_spool_result(self, result: dict) -> None:
def _on_filament_selected(self, item: ListItem) -> None:
if not item:
return
if item.text == "+ Add Filament":
if item.text == " New Filament":
self.open_add_filament.emit()
return
filament = self._filament_id_map.get(item.text)
if filament:
self._selected_filament_id = filament.get("id")
self._lot_field.setEnabled(True)
self._weight_field.setEnabled(True)
self._location_field.setEnabled(True)
self._submit_btn.setEnabled(True)

def _show_keyboard(
Expand Down Expand Up @@ -341,6 +358,16 @@ def _key_lbl(text: str) -> QtWidgets.QLabel:
left_lay.addWidget(self._fil_load_widget, 1)
self._fil_list_view.hide()

self._no_filaments_label = QtWidgets.QLabel("", left_frame)
self._no_filaments_label.setWordWrap(True)
self._no_filaments_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self._no_filaments_label.setStyleSheet("color: gray;")
no_fil_font = QtGui.QFont()
no_fil_font.setPointSize(13)
self._no_filaments_label.setFont(no_fil_font)
self._no_filaments_label.hide()
left_lay.addWidget(self._no_filaments_label)

body.addWidget(left_frame, 1)

# Right: optional spool fields
Expand Down
27 changes: 25 additions & 2 deletions BlocksScreen/lib/panels/widgets/spoolmanPage.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ def _build_model_list(self) -> None:

self.model.add_item(
ListItem(
text="+ Add Spool",
text=" Add Spool",
left_icon=self._make_add_pixmap(),
_lfontsize=14,
height=60,
Expand Down Expand Up @@ -234,12 +234,17 @@ def _build_model_list(self) -> None:

self.spool_list_widget.blockSignals(False)

if self._display_name_to_spool:
self._no_spools_label.hide()
else:
self._no_spools_label.show()

@QtCore.pyqtSlot(ListItem, name="on-item-clicked")
def on_item_clicked(self, item: ListItem) -> None:
"""Handle when a spool item is clicked in the list."""
if not item:
return
if item.text == "+ Add Spool":
if item.text == " Add Spool":
self._on_add_spool_clicked()
return
self._selected_spool = self._display_name_to_spool.get(item.text)
Expand Down Expand Up @@ -398,9 +403,19 @@ def _icon_btn(icon_path: str) -> IconButton:
QtWidgets.QScroller.ScrollerGestureType.LeftMouseButtonGesture,
)

self._no_spools_label = QtWidgets.QLabel("No spools found", list_frame)
self._no_spools_label.setWordWrap(True)
self._no_spools_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self._no_spools_label.setStyleSheet("color: gray;")
no_spools_font = QtGui.QFont()
no_spools_font.setPointSize(13)
self._no_spools_label.setFont(no_spools_font)
self._no_spools_label.hide()

list_layout = QtWidgets.QVBoxLayout()
list_layout.setContentsMargins(4, 4, 4, 4)
list_layout.addWidget(self.spool_list_widget, 1)
list_layout.addWidget(self._no_spools_label)
list_frame.setLayout(list_layout)
main_layout.addWidget(list_frame, 3)

Expand All @@ -421,6 +436,14 @@ def _icon_btn(icon_path: str) -> IconButton:
white_palette.ColorRole.WindowText, QtGui.QColor("#FFFFFF")
)

spacer = QtWidgets.QSpacerItem(
30,
30,
QtWidgets.QSizePolicy.Policy.Minimum,
QtWidgets.QSizePolicy.Policy.Minimum,
)
info_layout.addItem(spacer)

def _add_row(title_text: str) -> QtWidgets.QLabel:
row = QtWidgets.QHBoxLayout()
row.setSpacing(4)
Expand Down
Loading