22from collections import deque
33from typing import Deque
44
5- from PyQt6 import QtCore , QtGui , QtWidgets
6-
75from devices .amu import AMUManager
86from devices .amu .models import GateStatus
97from lib .panels .widgets .addFilamentPage import AddFilamentPage
108from lib .panels .widgets .addSpoolPage import AddSpoolPage
119from lib .panels .widgets .amuPage import AMUpage
12- from lib .panels .widgets .basicFilamentPanel import BasicFilamentPanel
1310from lib .panels .widgets .basePopup import BasePopup
11+ from lib .panels .widgets .basicFilamentPanel import BasicFilamentPanel
1412from lib .panels .widgets .colorWheelWidget import ColorWheelWidget
1513from lib .panels .widgets .keyboardPage import CustomQwertyKeyboard
1614from lib .panels .widgets .loadWidget import LoadingOverlayWidget
1715from lib .panels .widgets .numpadPage import CustomNumpad
16+ from lib .panels .widgets .spoolmanPage import SpoolmanPage
1817from lib .printer import Printer
1918from lib .utils .blocks_button import BlocksCustomButton
2019from lib .utils .blocks_frame import BlocksCustomFrame
2120from lib .utils .blocks_linedit import BlocksCustomLinEdit
2221from lib .utils .icon_button import IconButton
2322from lib .utils .list_model import EntryDelegate , EntryListModel , ListItem
24- from lib .panels .widgets .spoolmanPage import SpoolmanPage
25-
23+ from PyQt6 import QtCore , QtGui , QtWidgets
2624
2725logger = logging .getLogger (__name__ )
2826
@@ -48,7 +46,7 @@ def __init__(
4846 self .cfg = config
4947 self .amu_manager : AMUManager = amu_manager
5048 self .amu_configured = False
51-
49+ self . _popup_callback = None
5250 self .ui = self .setupUi ()
5351 self .change_page (self .indexOf (self .ui ))
5452
@@ -104,6 +102,7 @@ def __init__(
104102 self ._basic_panel .call_load_panel .connect (self .call_load_panel )
105103 self ._basic_panel .request_back .connect (self .request_back )
106104 self ._basic_panel .request_change_tab .connect (self .request_change_tab )
105+ self ._basic_panel .filament_selected .connect (self .open_pregate_popup )
107106 self .amu_manager .mmu_state_changed .connect (
108107 self ._basic_panel .on_mmu_state_changed
109108 )
@@ -228,8 +227,7 @@ def _field():
228227
229228 self ._popup_name .setPlaceholderText ("e.g. PLA Generic" )
230229 self ._popup_color .setText ("ffffff" )
231- self ._popup_material .setText ("PLA" )
232- self ._popup_temp .setText ("220" )
230+ self ._popup_temp .setText ("250" )
233231
234232 self ._popup_name .clicked .connect (
235233 lambda : self ._on_show_keyboard (self ._popup_name )
@@ -278,12 +276,22 @@ def _update_swatch():
278276 self .spoolman_btn .clicked .connect (self ._on_spoolman_clicked )
279277 btn_row .addWidget (self .spoolman_btn )
280278
279+ skip_btn = BlocksCustomButton (page )
280+ skip_btn .setFixedSize (230 , 80 )
281+ skip_btn .setText ("Skip" )
282+ skip_btn .setFont (font )
283+ skip_btn .clicked .connect (self .handle_skip_button )
284+ skip_btn .setPixmap (
285+ QtGui .QPixmap (":/arrow_icons/media/btn_icons/right_arrow.svg" )
286+ )
287+ btn_row .addWidget (skip_btn )
288+
281289 accept_btn = BlocksCustomButton (page )
282290 accept_btn .setFixedSize (230 , 80 )
283291 accept_btn .setText ("Accept" )
284292 accept_btn .setFont (font )
285- accept_btn .setPixmap (QtGui .QPixmap (":/dialog/media/btn_icons/yes.svg" ))
286293 accept_btn .clicked .connect (self .on_popup_accept )
294+ accept_btn .setPixmap (QtGui .QPixmap (":/dialog/media/btn_icons/yes.svg" ))
287295 btn_row .addWidget (accept_btn )
288296
289297 root .addLayout (btn_row )
@@ -413,23 +421,57 @@ def _build_spool_page(self) -> QtWidgets.QWidget:
413421 root .addWidget (frame , 1 )
414422 return page
415423
416- def handle_popup (self ):
417- """Handles showing the popup for pre-gate filament detection. If multiple gates trigger, they will be queued and shown one at a time."""
424+ def handle_skip_button (self ):
425+ gate = self .pre_gate_idx .get ("gate" , 0 )
426+ self .popup .hide ()
427+ self ._reset_popup ()
428+ self .run_gcode .emit (
429+ f"MMU_GATE_MAP GATE={ gate } MATERIAL=N/A NAME=N/A COLOR=FFFFFF SPOOLID=-1 TEMP=250 QUIET=1"
430+ )
431+ if self ._popup_callback is not None :
432+ try :
433+ self ._popup_callback ()
434+ except Exception as e :
435+ logger .error (f"Error executing pre-gate accept callback: { e } " )
436+ finally :
437+ self ._popup_callback = None
438+
439+ def handle_popup (self , force = False ):
440+ """Handles showing the popup for pre-gate filament detection.
441+ If multiple gates trigger, they will be queued and shown one at a time.
442+
443+ Args:
444+ force (bool): If True, forces the popup to open even if no gates are queued.
445+ """
418446 if self .popup .isVisible ():
419447 return
420448 if not self .popup_gates :
421- return
422- self .pre_gate_idx = self .popup_gates .popleft ()
423- gate = self .pre_gate_idx ["gate" ]
424- self ._popup_title_lbl .setText (f"Filament Detected — Gate { gate } " )
449+ if force :
450+ self .pre_gate_idx = {"gate" : 0 }
451+ self ._popup_title_lbl .setText ("Load filament information" )
452+ else :
453+ return
454+ else :
455+ self .pre_gate_idx = self .popup_gates .popleft ()
456+ gate = self .pre_gate_idx .get ("gate" , - 1 )
457+ self ._popup_title_lbl .setText (f"Filament Detected — Gate { gate } " )
458+
425459 self ._popup_stack .setCurrentIndex (0 )
426460 self ._selected_spool_id = - 2
427461 self .popup .show ()
428462
463+ @QtCore .pyqtSlot (int , str , str , "PyQt_PyObject" , name = "open-pregate-popup" )
464+ def open_pregate_popup (self , temp , material , name , callback = None ):
465+ self ._popup_name .setText (name )
466+ self ._popup_material .setText (material )
467+ self ._popup_temp .setText (str (temp ))
468+ self ._popup_callback = callback
469+ self .handle_popup (True )
470+
429471 def on_popup_accept (self ):
430472 """Handles the accept action from the pre-gate popup to send the appropriate G-code to map the gate to the spool."""
431- gate = self .pre_gate_idx [ "gate" ]
432- name = self ._popup_name .text ().strip ()
473+ gate = self .pre_gate_idx . get ( "gate" , 0 )
474+ name = self ._popup_name .text ().strip () or "N/A"
433475 color = self ._popup_color .text ().strip ("#" ).strip ()
434476 material = self ._popup_material .text ().strip ()
435477 try :
@@ -452,9 +494,25 @@ def on_popup_accept(self):
452494
453495 self .run_gcode .emit (" " .join (parts ))
454496 self .run_gcode .emit ("MMU_GATE_MAP REFRESH=1" )
497+
498+ if self ._popup_callback is not None :
499+ try :
500+ self ._popup_callback ()
501+ except Exception as e :
502+ logger .error (f"Error executing pre-gate accept callback: { e } " )
503+ finally :
504+ self ._popup_callback = None
505+
506+ self ._reset_popup ()
455507 self .popup .hide ()
456508 self .handle_popup ()
457509
510+ def _reset_popup (self ):
511+ self ._popup_name .setText ("" )
512+ self ._popup_color .setText ("ffffff" )
513+ self ._popup_material .setText ("" )
514+ self ._popup_temp .setText ("250" )
515+
458516 @QtCore .pyqtSlot (dict , name = "on-spools-received" )
459517 def on_spools_received (self , result : dict ) -> None :
460518 """Handles the result from the API call to get spools for the spoolman page."""
@@ -631,7 +689,8 @@ def on_mmu_state_changed(self, mmu_state):
631689 and self ._previous_gate_states [gate_info .index ] is True
632690 ):
633691 self .popup_gates .append ({"gate" : gate_info .index })
634- self .handle_popup ()
692+ if len (mmu_state .gates ) > 1 :
693+ self .handle_popup ()
635694
636695 if not self .amu_configured :
637696 if len (mmu_state .gates ) > 1 :
0 commit comments