From e181ffb4db796bbb3d752d87a5fed6bcf915062c Mon Sep 17 00:00:00 2001 From: Guilherme Costa Date: Wed, 26 Nov 2025 03:47:11 +0000 Subject: [PATCH 1/8] FilesPage: Refactor almost complete missing passing the directory by itemclick helper_methods: updated the get_file_loc method to return always the filename instead of the full path Signed-off-by: Guilherme Costa --- BlocksScreen/helper_methods.py | 27 ++++ BlocksScreen/lib/panels/widgets/filesPage.py | 155 ++++++++++++++++--- 2 files changed, 159 insertions(+), 23 deletions(-) diff --git a/BlocksScreen/helper_methods.py b/BlocksScreen/helper_methods.py index 0dd2b2db..86a21acb 100644 --- a/BlocksScreen/helper_methods.py +++ b/BlocksScreen/helper_methods.py @@ -324,3 +324,30 @@ def check_file_on_path( """Check if file exists on path. Returns true if file exists on that specified directory""" _filepath = os.path.join(path, filename) return os.path.exists(_filepath) + + +def get_file_loc(filename: typing.Optional[str]) -> str: + # If filename is None or empty, return empty string instead of None + if not filename: + return "" + # Remove trailing slashes or backslashes + filename = filename.rstrip("/\\") + + # Normalize Windows backslashes to forward slashes + filename = filename.replace("\\", "/") + + parts = filename.split("/") + + # Split and return the last path component + return parts[-1] if filename else "" + + +# def get_hash(data) -> hashlib._Hash: +# hash = hashlib.sha256() +# hash.update(data.encode()) +# hash.digest() +# return hash + + + +def digest_hash() -> None: ... diff --git a/BlocksScreen/lib/panels/widgets/filesPage.py b/BlocksScreen/lib/panels/widgets/filesPage.py index 8de160c0..f4e1a179 100644 --- a/BlocksScreen/lib/panels/widgets/filesPage.py +++ b/BlocksScreen/lib/panels/widgets/filesPage.py @@ -7,6 +7,9 @@ from lib.utils.icon_button import IconButton from lib.utils.list_button import ListCustomButton from PyQt6 import QtCore, QtGui, QtWidgets +from lib.utils.blocks_frame import BlocksCustomFrame + +from lib.utils.list_model import EntryDelegate, EntryListModel, ListItem logger = logging.getLogger("logs/BlocksScreen.log") @@ -35,7 +38,10 @@ class FilesPage(QtWidgets.QWidget): directories: list = [] def __init__(self, parent) -> None: - super().__init__(parent) + super().__init__() + #VM + self.model = EntryListModel() + self.entry_delegate = EntryDelegate() self._setupUI() self.setMouseTracking(True) self.setAttribute(QtCore.Qt.WidgetAttribute.WA_AcceptTouchEvents, True) @@ -49,6 +55,12 @@ def __init__(self, parent) -> None: lambda value: self.listWidget.verticalScrollBar().setValue(value) ) self.back_btn.clicked.connect(self.reset_dir) + + self.entry_delegate.item_selected.connect(self._on_item_selected) + + @QtCore.pyqtSlot(ListItem, name="on-item-selected") + def _on_item_selected(self, item: ListItem) -> None: + logger.debug("Item Selected") @QtCore.pyqtSlot(name="reset-dir") def reset_dir(self) -> None: @@ -66,6 +78,11 @@ def on_file_list(self, file_list: list) -> None: """Handle receiving files list from websocket""" self.files_data.clear() self.file_list = file_list +<<<<<<< HEAD +======= + # if self.isVisible(): # Only build the list when directories come + # self._build_file_list() +>>>>>>> 342be69 (FilesPage: Refactor almost complete missing passing the directory by itemclick) @QtCore.pyqtSlot(list, name="on-dirs") def on_directories(self, directories_data: list) -> None: @@ -108,7 +125,9 @@ def on_fileinfo(self, filedata: dict) -> None: time_str = f"{hours}h {minutes}m" else: time_str = f"{minutes}m" + +<<<<<<< HEAD list_items = [self.listWidget.item(i) for i in range(self.listWidget.count())] if not list_items: return @@ -116,23 +135,42 @@ def on_fileinfo(self, filedata: dict) -> None: item_widget = self.listWidget.itemWidget(list_item) if item_widget.text() in filename: item_widget.setRightText(f"{filament_type} - {time_str}") +======= + + name = helper_methods.get_file_loc(filename) + item = ListItem( + text=name[:-6], + right_text=f"{filament_type} - {time_str}", + right_icon=QtGui.QPixmap(":/arrow_icons/media/btn_icons/right_arrow.svg"), + left_icon=None, + callback=lambda: self._fileItemClicked(item), + selected=False, + allow_check=False, + _lfontsize=17, + _rfontsize=12, + height=80, + notificate=False + ) + + self.model.add_item(item) +>>>>>>> 342be69 (FilesPage: Refactor almost complete missing passing the directory by itemclick) - @QtCore.pyqtSlot(QtWidgets.QListWidgetItem, name="file-item-clicked") - def _fileItemClicked(self, item: QtWidgets.QListWidgetItem) -> None: + + @QtCore.pyqtSlot(ListItem,str, name="file-item-clicked") + def _fileItemClicked(self, item: ListItem,path:str ) -> None: """Slot for List Item clicked Args: item (QListWidgetItem): Clicked item """ if item: - widget = self.listWidget.itemWidget(item) for file in self.file_list: path = ( file.get("path") if "path" in file.keys() else file.get("filename") ) if not path: return - if widget.text() in path: + if item.text in path: file_path = ( path if not self.curr_dir else str(self.curr_dir + "/" + path) ) @@ -143,19 +181,27 @@ def _fileItemClicked(self, item: QtWidgets.QListWidgetItem) -> None: ), # Defaults to Nothing ) +<<<<<<< HEAD @QtCore.pyqtSlot(QtWidgets.QListWidgetItem, str, name="dir-item-clicked") def _dirItemClicked(self, item: QtWidgets.QListWidgetItem, directory: str) -> None: +======= + def _dirItemClicked( + self, directory: str + ) -> None: +>>>>>>> 342be69 (FilesPage: Refactor almost complete missing passing the directory by itemclick) self.curr_dir = self.curr_dir + directory self.request_dir_info[str].emit(self.curr_dir) def _build_file_list(self) -> None: """Inserts the currently available gcode files on the QListWidget""" - self.listWidget.blockSignals(True) - self.listWidget.clear() - if not self.file_list and not self.directories: + #self.listWidget.blockSignals(True) + self.model.clear() + self.entry_delegate.clear() + + if not self.file_list and not self.directories and os.path.islink(self.curr_dir): self._add_placeholder() return - self.listWidget.setSpacing(35) + if self.directories or self.curr_dir != "": if self.curr_dir != "" and self.curr_dir != "/": self._add_back_folder_entry() @@ -166,15 +212,17 @@ def _build_file_list(self) -> None: sorted_list = sorted(self.file_list, key=lambda x: x["modified"], reverse=True) for item in sorted_list: self._add_file_list_item(item) + self._add_spacer() self._setup_scrollbar() - self.listWidget.blockSignals(False) - self.repaint() + #self.listWidget.blockSignals(False) + self.listWidget.repaint() def _add_directory_list_item(self, dir_data: dict) -> None: dir_name = dir_data.get("dirname", "") if not dir_name: return +<<<<<<< HEAD button = ListCustomButton() button.setText(str(dir_data.get("dirname"))) button.setSecondPixmap(QtGui.QPixmap(":/ui/media/btn_icons/folderIcon.svg")) @@ -200,10 +248,40 @@ def _add_back_folder_entry(self) -> None: list_item.setSizeHint(button.sizeHint()) self.listWidget.addItem(list_item) self.listWidget.setItemWidget(list_item, button) +======= + item = ListItem( + text=str(dir_name), + left_icon=QtGui.QPixmap(":/ui/media/btn_icons/folderIcon.svg"), + right_text="", + selected=False, + callback=lambda name=dir_name: self._dirItemClicked("/" + str(name)), + allow_check=False, + _lfontsize=17, + _rfontsize=12, + height=80 + ) + self.model.add_item(item) + + def _add_back_folder_entry(self) -> None: +>>>>>>> 342be69 (FilesPage: Refactor almost complete missing passing the directory by itemclick) go_back_path = os.path.dirname(self.curr_dir) if go_back_path == "/": go_back_path = "" - button.clicked.connect(lambda: (self._on_goback_dir(go_back_path))) + + item = ListItem( + text="Go Back", + right_text="", + right_icon=None, + left_icon=QtGui.QPixmap(":/ui/media/btn_icons/back_folder.svg"), + callback= lambda: self._on_goback_dir(go_back_path), + selected=False, + allow_check=False, + _lfontsize=17, + _rfontsize=12, + height=80, + notificate=False + ) + self.model.add_item(item) @QtCore.pyqtSlot(str, str, name="on-goback-dir") def _on_goback_dir(self, directory) -> None: @@ -222,6 +300,7 @@ def _add_file_list_item(self, file_data_item) -> None: if not name.endswith(".gcode"): # Only list .gcode files, all else ignore return +<<<<<<< HEAD button = ListCustomButton() button.setText(name[:-6]) button.setPixmap(QtGui.QPixmap(":/arrow_icons/media/btn_icons/right_arrow.svg")) @@ -234,9 +313,12 @@ def _add_file_list_item(self, file_data_item) -> None: self.listWidget.addItem(list_item) self.listWidget.setItemWidget(list_item, button) button.clicked.connect(lambda: self._fileItemClicked(list_item)) +======= +>>>>>>> 342be69 (FilesPage: Refactor almost complete missing passing the directory by itemclick) file_path = ( name if not self.curr_dir else str(self.curr_dir + "/" + name) ).removeprefix("/") + self.request_file_metadata.emit(file_path.removeprefix("/")) self.request_file_info.emit(file_path.removeprefix("/")) @@ -245,9 +327,10 @@ def _add_spacer(self) -> None: spacer_widget = QtWidgets.QWidget() spacer_widget.setFixedHeight(10) spacer_item.setSizeHint(spacer_widget.sizeHint()) - self.listWidget.addItem(spacer_item) + #self.listWidget.addItem(spacer_item) def _add_placeholder(self) -> None: +<<<<<<< HEAD self.listWidget.setSpacing(-1) placeholder_label = QtWidgets.QLabel("No Files found") font = QtGui.QFont() @@ -260,13 +343,13 @@ def _add_placeholder(self) -> None: placeholder_label.setMinimumSize( QtCore.QSize(self.listWidget.width(), self.listWidget.height()) ) +======= +>>>>>>> 342be69 (FilesPage: Refactor almost complete missing passing the directory by itemclick) self.scrollbar.hide() - placeholder_item = QtWidgets.QListWidgetItem() - placeholder_item.setSizeHint( - QtCore.QSize(self.listWidget.width(), self.listWidget.height()) - ) - self.listWidget.addItem(placeholder_item) - self.listWidget.setItemWidget(placeholder_item, placeholder_label) + self.listWidget.hide() + + self.label.show() + def _handle_scrollbar(self, value): # Block signals to avoid recursion @@ -290,6 +373,7 @@ def _setupUI(self): sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth()) self.setSizePolicy(sizePolicy) self.setMinimumSize(QtCore.QSize(710, 400)) + #self.setMaximumSize(QtCore.QSize(500, 400)) font = QtGui.QFont() font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) self.setFont(font) @@ -330,9 +414,17 @@ def _setupUI(self): self.line.setObjectName("line") self.verticalLayout_5.addWidget(self.line) self.fp_content_layout = QtWidgets.QHBoxLayout() - self.fp_content_layout.setContentsMargins(0, 0, 0, 0) + #self.fp_content_layout.setContentsMargins(0, 0, 0, 0) self.fp_content_layout.setObjectName("fp_content_layout") - self.listWidget = QtWidgets.QListWidget(parent=self) + #self.setMinimumSize(QtCore.QSize(800, 500)) + + + + #Listwidget + self.listWidget = QtWidgets.QListView(parent=self) + self.listWidget.setModel(self.model) + self.listWidget.setItemDelegate(self.entry_delegate) + self.listWidget.setSpacing(5) self.listWidget.setProperty("showDropIndicator", False) self.listWidget.setProperty("selectionMode", "NoSelection") self.listWidget.setStyleSheet("background: transparent;") @@ -378,13 +470,27 @@ def _setupUI(self): QtWidgets.QScroller.scroller(self.listWidget).setScrollerProperties( scroller_props ) + font = QtGui.QFont() font.setPointSize(25) - placeholder_item = QtWidgets.QListWidgetItem() - placeholder_item.setSizeHint( + #placeholder_item = QtWidgets.QListWidgetItem() + #placeholder_item.setSizeHint( + # QtCore.QSize(self.listWidget.width(), self.listWidget.height()) + #) + self.label = QtWidgets.QLabel("No Files found") + # self.label.setBuddy(self.listWidget) + self.label.setFont(font) + self.label.setStyleSheet("color: gray;") + self.label.setMinimumSize( QtCore.QSize(self.listWidget.width(), self.listWidget.height()) ) + self.label.setAlignment( + QtCore.Qt.AlignmentFlag.AlignHCenter + | QtCore.Qt.AlignmentFlag.AlignVCenter + ) + self.fp_content_layout.addWidget(self.listWidget) + self.fp_content_layout.addWidget(self.label) self.scrollbar = CustomScrollBar() self.fp_content_layout.addWidget(self.scrollbar) self.verticalLayout_5.addLayout(self.fp_content_layout) @@ -392,3 +498,6 @@ def _setupUI(self): QtCore.Qt.WidgetAttribute.WA_TransparentForMouseEvents, True ) self.scroller = QtWidgets.QScroller.scroller(self.listWidget) + self.label.hide() + + From f45b5155f2b02b15762a0a3ae15d50b715b05d9c Mon Sep 17 00:00:00 2001 From: Guilherme Costa Date: Wed, 26 Nov 2025 12:10:46 +0000 Subject: [PATCH 2/8] filesPage.py: refactor concluded, scrollbar bugfix Signed-off-by: Guilherme Costa --- BlocksScreen/lib/panels/widgets/filesPage.py | 59 +++++++++++++------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/BlocksScreen/lib/panels/widgets/filesPage.py b/BlocksScreen/lib/panels/widgets/filesPage.py index f4e1a179..282593a2 100644 --- a/BlocksScreen/lib/panels/widgets/filesPage.py +++ b/BlocksScreen/lib/panels/widgets/filesPage.py @@ -79,10 +79,15 @@ def on_file_list(self, file_list: list) -> None: self.files_data.clear() self.file_list = file_list <<<<<<< HEAD +<<<<<<< HEAD ======= # if self.isVisible(): # Only build the list when directories come # self._build_file_list() >>>>>>> 342be69 (FilesPage: Refactor almost complete missing passing the directory by itemclick) +======= + if self.isVisible(): # Only build the list when directories come + self._build_file_list() +>>>>>>> 44841b3 (filesPage.py: refactor concluded, scrollbar bugfix) @QtCore.pyqtSlot(list, name="on-dirs") def on_directories(self, directories_data: list) -> None: @@ -143,7 +148,7 @@ def on_fileinfo(self, filedata: dict) -> None: right_text=f"{filament_type} - {time_str}", right_icon=QtGui.QPixmap(":/arrow_icons/media/btn_icons/right_arrow.svg"), left_icon=None, - callback=lambda: self._fileItemClicked(item), + callback=lambda namelam=filename: self._fileItemClicked(namelam), selected=False, allow_check=False, _lfontsize=17, @@ -156,13 +161,14 @@ def on_fileinfo(self, filedata: dict) -> None: >>>>>>> 342be69 (FilesPage: Refactor almost complete missing passing the directory by itemclick) - @QtCore.pyqtSlot(ListItem,str, name="file-item-clicked") - def _fileItemClicked(self, item: ListItem,path:str ) -> None: + @QtCore.pyqtSlot(str, name="file-item-clicked") + def _fileItemClicked(self, filename: str) -> None: """Slot for List Item clicked Args: - item (QListWidgetItem): Clicked item + filename (str): Clicked item path """ +<<<<<<< HEAD if item: for file in self.file_list: path = ( @@ -176,15 +182,23 @@ def _fileItemClicked(self, item: ListItem,path:str ) -> None: ) self.file_selected.emit( str(file_path.removeprefix("/")), +======= + self.file_selected.emit( + str(filename.removeprefix("/")), +>>>>>>> 44841b3 (filesPage.py: refactor concluded, scrollbar bugfix) self.files_data.get( - file_path.removeprefix("/") + filename.removeprefix("/") ), # Defaults to Nothing ) +<<<<<<< HEAD <<<<<<< HEAD @QtCore.pyqtSlot(QtWidgets.QListWidgetItem, str, name="dir-item-clicked") def _dirItemClicked(self, item: QtWidgets.QListWidgetItem, directory: str) -> None: ======= +======= + +>>>>>>> 44841b3 (filesPage.py: refactor concluded, scrollbar bugfix) def _dirItemClicked( self, directory: str ) -> None: @@ -212,10 +226,8 @@ def _build_file_list(self) -> None: sorted_list = sorted(self.file_list, key=lambda x: x["modified"], reverse=True) for item in sorted_list: self._add_file_list_item(item) - - self._add_spacer() + self._setup_scrollbar() - #self.listWidget.blockSignals(False) self.listWidget.repaint() def _add_directory_list_item(self, dir_data: dict) -> None: @@ -322,13 +334,6 @@ def _add_file_list_item(self, file_data_item) -> None: self.request_file_metadata.emit(file_path.removeprefix("/")) self.request_file_info.emit(file_path.removeprefix("/")) - def _add_spacer(self) -> None: - spacer_item = QtWidgets.QListWidgetItem() - spacer_widget = QtWidgets.QWidget() - spacer_widget.setFixedHeight(10) - spacer_item.setSizeHint(spacer_widget.sizeHint()) - #self.listWidget.addItem(spacer_item) - def _add_placeholder(self) -> None: <<<<<<< HEAD self.listWidget.setSpacing(-1) @@ -358,9 +363,24 @@ def _handle_scrollbar(self, value): self.scrollbar.blockSignals(False) def _setup_scrollbar(self) -> None: +<<<<<<< HEAD self.scrollbar.setMinimum(self.listWidget.verticalScrollBar().minimum()) self.scrollbar.setMaximum(self.listWidget.verticalScrollBar().maximum()) self.scrollbar.setPageStep(self.listWidget.verticalScrollBar().pageStep()) +======= + idx = self.model.index(0, 0) + + rect = self.listWidget.rectForIndex(idx) + self.scrollbar.setMinimum( + self.listWidget.verticalScrollBar().minimum() + ) + self.scrollbar.setMaximum( + self.listWidget.verticalScrollBar().maximum() + ) + self.scrollbar.setPageStep( + self.listWidget.verticalScrollBar().pageStep() + ) +>>>>>>> 44841b3 (filesPage.py: refactor concluded, scrollbar bugfix) self.scrollbar.show() def _setupUI(self): @@ -494,10 +514,11 @@ def _setupUI(self): self.scrollbar = CustomScrollBar() self.fp_content_layout.addWidget(self.scrollbar) self.verticalLayout_5.addLayout(self.fp_content_layout) - self.scrollbar.setAttribute( - QtCore.Qt.WidgetAttribute.WA_TransparentForMouseEvents, True - ) - self.scroller = QtWidgets.QScroller.scroller(self.listWidget) + #self.scrollbar.setAttribute( + # QtCore.Qt.WidgetAttribute.WA_TransparentForMouseEvents, True + #) + #self.scroller = QtWidgets.QScroller.scroller(self.listWidget) + self.scrollbar.show() self.label.hide() From 33ef18dcdbb49b9d67b38662478743473423b051 Mon Sep 17 00:00:00 2001 From: Guilherme Costa Date: Tue, 2 Dec 2025 12:39:41 +0000 Subject: [PATCH 3/8] helper_method.py: Change naming of a method from get_file_loc to get_file_name Signed-off-by: Guilherme Costa --- BlocksScreen/helper_methods.py | 5 ++++- BlocksScreen/lib/panels/widgets/filesPage.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/BlocksScreen/helper_methods.py b/BlocksScreen/helper_methods.py index 86a21acb..03f28ff5 100644 --- a/BlocksScreen/helper_methods.py +++ b/BlocksScreen/helper_methods.py @@ -326,7 +326,10 @@ def check_file_on_path( return os.path.exists(_filepath) -def get_file_loc(filename: typing.Optional[str]) -> str: +def get_file_loc(filename) -> pathlib.Path: + ... + +def get_file_name(filename: typing.Optional[str]) -> str: # If filename is None or empty, return empty string instead of None if not filename: return "" diff --git a/BlocksScreen/lib/panels/widgets/filesPage.py b/BlocksScreen/lib/panels/widgets/filesPage.py index 282593a2..79fb54ed 100644 --- a/BlocksScreen/lib/panels/widgets/filesPage.py +++ b/BlocksScreen/lib/panels/widgets/filesPage.py @@ -142,7 +142,7 @@ def on_fileinfo(self, filedata: dict) -> None: item_widget.setRightText(f"{filament_type} - {time_str}") ======= - name = helper_methods.get_file_loc(filename) + name = helper_methods.get_file_name(filename) item = ListItem( text=name[:-6], right_text=f"{filament_type} - {time_str}", From 56a7218d5e5769f90d83ac8a96e12c3d4c6983cf Mon Sep 17 00:00:00 2001 From: Guilherme Costa Date: Tue, 2 Dec 2025 14:48:34 +0000 Subject: [PATCH 4/8] filesPage.py: code cleanup, small docstring generation and add missing commented lines Signed-off-by: Guilherme Costa --- BlocksScreen/lib/panels/widgets/filesPage.py | 51 +++++++++++--------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/BlocksScreen/lib/panels/widgets/filesPage.py b/BlocksScreen/lib/panels/widgets/filesPage.py index 79fb54ed..67af06d6 100644 --- a/BlocksScreen/lib/panels/widgets/filesPage.py +++ b/BlocksScreen/lib/panels/widgets/filesPage.py @@ -5,9 +5,7 @@ import helper_methods from lib.utils.blocks_Scrollbar import CustomScrollBar from lib.utils.icon_button import IconButton -from lib.utils.list_button import ListCustomButton from PyQt6 import QtCore, QtGui, QtWidgets -from lib.utils.blocks_frame import BlocksCustomFrame from lib.utils.list_model import EntryDelegate, EntryListModel, ListItem @@ -39,7 +37,6 @@ class FilesPage(QtWidgets.QWidget): def __init__(self, parent) -> None: super().__init__() - #VM self.model = EntryListModel() self.entry_delegate = EntryDelegate() self._setupUI() @@ -60,6 +57,14 @@ def __init__(self, parent) -> None: @QtCore.pyqtSlot(ListItem, name="on-item-selected") def _on_item_selected(self, item: ListItem) -> None: + """Slot called when a list item is selected in the UI. + This method is connected to the `item_selected` signal of the entry delegate. + It handles the selection of a `ListItem` and is intended to be overridden + or customized for each specific item type, allowing different behavior + depending on the item. + Args: + item : ListItem The item that was selected by the user. + """ logger.debug("Item Selected") @QtCore.pyqtSlot(name="reset-dir") @@ -103,7 +108,11 @@ def on_delete_file(self, filename: str) -> None: @QtCore.pyqtSlot(dict, name="on-fileinfo") def on_fileinfo(self, filedata: dict) -> None: +<<<<<<< HEAD """Handle receive file information/metadata""" +======= + """Method called per file to contruct file entry to the list""" +>>>>>>> a5ed680 (filesPage.py: code cleanup, small docstring generation and add missing commented lines) if not filedata or not self.isVisible(): return filename = filedata.get("filename", "") @@ -130,6 +139,7 @@ def on_fileinfo(self, filedata: dict) -> None: time_str = f"{hours}h {minutes}m" else: time_str = f"{minutes}m" +<<<<<<< HEAD <<<<<<< HEAD @@ -142,6 +152,9 @@ def on_fileinfo(self, filedata: dict) -> None: item_widget.setRightText(f"{filament_type} - {time_str}") ======= +======= + +>>>>>>> a5ed680 (filesPage.py: code cleanup, small docstring generation and add missing commented lines) name = helper_methods.get_file_name(filename) item = ListItem( text=name[:-6], @@ -202,16 +215,19 @@ def _dirItemClicked(self, item: QtWidgets.QListWidgetItem, directory: str) -> No def _dirItemClicked( self, directory: str ) -> None: +<<<<<<< HEAD >>>>>>> 342be69 (FilesPage: Refactor almost complete missing passing the directory by itemclick) +======= + """Method that changes the current view in the list """ +>>>>>>> a5ed680 (filesPage.py: code cleanup, small docstring generation and add missing commented lines) self.curr_dir = self.curr_dir + directory self.request_dir_info[str].emit(self.curr_dir) def _build_file_list(self) -> None: """Inserts the currently available gcode files on the QListWidget""" - #self.listWidget.blockSignals(True) + self.listWidget.blockSignals(True) self.model.clear() self.entry_delegate.clear() - if not self.file_list and not self.directories and os.path.islink(self.curr_dir): self._add_placeholder() return @@ -228,9 +244,11 @@ def _build_file_list(self) -> None: self._add_file_list_item(item) self._setup_scrollbar() + self.listWidget.blockSignals(False) self.listWidget.repaint() def _add_directory_list_item(self, dir_data: dict) -> None: + """Method that adds directories to the list """ dir_name = dir_data.get("dirname", "") if not dir_name: return @@ -275,7 +293,11 @@ def _add_back_folder_entry(self) -> None: self.model.add_item(item) def _add_back_folder_entry(self) -> None: +<<<<<<< HEAD >>>>>>> 342be69 (FilesPage: Refactor almost complete missing passing the directory by itemclick) +======= + """Method to insert in the list the "Go back" item """ +>>>>>>> a5ed680 (filesPage.py: code cleanup, small docstring generation and add missing commented lines) go_back_path = os.path.dirname(self.curr_dir) if go_back_path == "/": go_back_path = "" @@ -352,7 +374,6 @@ def _add_placeholder(self) -> None: >>>>>>> 342be69 (FilesPage: Refactor almost complete missing passing the directory by itemclick) self.scrollbar.hide() self.listWidget.hide() - self.label.show() @@ -393,7 +414,6 @@ def _setupUI(self): sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth()) self.setSizePolicy(sizePolicy) self.setMinimumSize(QtCore.QSize(710, 400)) - #self.setMaximumSize(QtCore.QSize(500, 400)) font = QtGui.QFont() font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) self.setFont(font) @@ -434,13 +454,8 @@ def _setupUI(self): self.line.setObjectName("line") self.verticalLayout_5.addWidget(self.line) self.fp_content_layout = QtWidgets.QHBoxLayout() - #self.fp_content_layout.setContentsMargins(0, 0, 0, 0) + self.fp_content_layout.setContentsMargins(0, 0, 0, 0) self.fp_content_layout.setObjectName("fp_content_layout") - #self.setMinimumSize(QtCore.QSize(800, 500)) - - - - #Listwidget self.listWidget = QtWidgets.QListView(parent=self) self.listWidget.setModel(self.model) self.listWidget.setItemDelegate(self.entry_delegate) @@ -452,7 +467,6 @@ def _setupUI(self): self.listWidget.setUniformItemSizes(True) self.listWidget.setObjectName("listWidget") self.listWidget.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) - self.listWidget.setDefaultDropAction(QtCore.Qt.DropAction.IgnoreAction) self.listWidget.setSelectionBehavior( QtWidgets.QAbstractItemView.SelectionBehavior.SelectItems ) @@ -493,12 +507,7 @@ def _setupUI(self): font = QtGui.QFont() font.setPointSize(25) - #placeholder_item = QtWidgets.QListWidgetItem() - #placeholder_item.setSizeHint( - # QtCore.QSize(self.listWidget.width(), self.listWidget.height()) - #) self.label = QtWidgets.QLabel("No Files found") - # self.label.setBuddy(self.listWidget) self.label.setFont(font) self.label.setStyleSheet("color: gray;") self.label.setMinimumSize( @@ -514,10 +523,6 @@ def _setupUI(self): self.scrollbar = CustomScrollBar() self.fp_content_layout.addWidget(self.scrollbar) self.verticalLayout_5.addLayout(self.fp_content_layout) - #self.scrollbar.setAttribute( - # QtCore.Qt.WidgetAttribute.WA_TransparentForMouseEvents, True - #) - #self.scroller = QtWidgets.QScroller.scroller(self.listWidget) self.scrollbar.show() self.label.hide() From 7eee1bc5d989589d9da87359df2e249f3371418e Mon Sep 17 00:00:00 2001 From: Guilherme Costa Date: Tue, 2 Dec 2025 14:54:55 +0000 Subject: [PATCH 5/8] filesPage.py: remove unused lines of code Signed-off-by: Guilherme Costa --- BlocksScreen/lib/panels/widgets/filesPage.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/BlocksScreen/lib/panels/widgets/filesPage.py b/BlocksScreen/lib/panels/widgets/filesPage.py index 67af06d6..b14c8d6f 100644 --- a/BlocksScreen/lib/panels/widgets/filesPage.py +++ b/BlocksScreen/lib/panels/widgets/filesPage.py @@ -384,6 +384,7 @@ def _handle_scrollbar(self, value): self.scrollbar.blockSignals(False) def _setup_scrollbar(self) -> None: +<<<<<<< HEAD <<<<<<< HEAD self.scrollbar.setMinimum(self.listWidget.verticalScrollBar().minimum()) self.scrollbar.setMaximum(self.listWidget.verticalScrollBar().maximum()) @@ -392,6 +393,8 @@ def _setup_scrollbar(self) -> None: idx = self.model.index(0, 0) rect = self.listWidget.rectForIndex(idx) +======= +>>>>>>> e8b88d5 (filesPage.py: remove unused lines of code) self.scrollbar.setMinimum( self.listWidget.verticalScrollBar().minimum() ) From 3fa110f5e36050da0ae8f98086979553cfca39f2 Mon Sep 17 00:00:00 2001 From: Guilherme Costa Date: Thu, 11 Dec 2025 14:25:03 +0000 Subject: [PATCH 6/8] filesPage.py - fix rebase conflits Signed-off-by: Guilherme Costa --- BlocksScreen/lib/panels/widgets/filesPage.py | 202 +++---------------- 1 file changed, 28 insertions(+), 174 deletions(-) diff --git a/BlocksScreen/lib/panels/widgets/filesPage.py b/BlocksScreen/lib/panels/widgets/filesPage.py index b14c8d6f..1f11d270 100644 --- a/BlocksScreen/lib/panels/widgets/filesPage.py +++ b/BlocksScreen/lib/panels/widgets/filesPage.py @@ -52,7 +52,7 @@ def __init__(self, parent) -> None: lambda value: self.listWidget.verticalScrollBar().setValue(value) ) self.back_btn.clicked.connect(self.reset_dir) - + self.entry_delegate.item_selected.connect(self._on_item_selected) @QtCore.pyqtSlot(ListItem, name="on-item-selected") @@ -69,50 +69,32 @@ def _on_item_selected(self, item: ListItem) -> None: @QtCore.pyqtSlot(name="reset-dir") def reset_dir(self) -> None: - """Reset current directory""" self.curr_dir = "" self.request_dir_info[str].emit(self.curr_dir) def showEvent(self, a0: QtGui.QShowEvent) -> None: - """Re-implemented method, handle widget show event""" self._build_file_list() return super().showEvent(a0) @QtCore.pyqtSlot(list, name="on-file-list") def on_file_list(self, file_list: list) -> None: - """Handle receiving files list from websocket""" self.files_data.clear() self.file_list = file_list -<<<<<<< HEAD -<<<<<<< HEAD -======= - # if self.isVisible(): # Only build the list when directories come + # if self.isVisible(): # Only build the list when directories come # self._build_file_list() ->>>>>>> 342be69 (FilesPage: Refactor almost complete missing passing the directory by itemclick) -======= - if self.isVisible(): # Only build the list when directories come - self._build_file_list() ->>>>>>> 44841b3 (filesPage.py: refactor concluded, scrollbar bugfix) @QtCore.pyqtSlot(list, name="on-dirs") def on_directories(self, directories_data: list) -> None: - """Handle receiving available directories from websocket""" self.directories = directories_data if self.isVisible(): self._build_file_list() @QtCore.pyqtSlot(str, name="on-delete-file") - def on_delete_file(self, filename: str) -> None: - """Handle file deleted""" - ... + def on_delete_file(self, filename: str) -> None: ... @QtCore.pyqtSlot(dict, name="on-fileinfo") def on_fileinfo(self, filedata: dict) -> None: -<<<<<<< HEAD - """Handle receive file information/metadata""" -======= """Method called per file to contruct file entry to the list""" ->>>>>>> a5ed680 (filesPage.py: code cleanup, small docstring generation and add missing commented lines) if not filedata or not self.isVisible(): return filename = filedata.get("filename", "") @@ -139,40 +121,23 @@ def on_fileinfo(self, filedata: dict) -> None: time_str = f"{hours}h {minutes}m" else: time_str = f"{minutes}m" -<<<<<<< HEAD - -<<<<<<< HEAD - list_items = [self.listWidget.item(i) for i in range(self.listWidget.count())] - if not list_items: - return - for list_item in list_items: - item_widget = self.listWidget.itemWidget(list_item) - if item_widget.text() in filename: - item_widget.setRightText(f"{filament_type} - {time_str}") -======= - -======= - ->>>>>>> a5ed680 (filesPage.py: code cleanup, small docstring generation and add missing commented lines) name = helper_methods.get_file_name(filename) item = ListItem( text=name[:-6], right_text=f"{filament_type} - {time_str}", right_icon=QtGui.QPixmap(":/arrow_icons/media/btn_icons/right_arrow.svg"), left_icon=None, - callback=lambda namelam=filename: self._fileItemClicked(namelam), + callback=lambda: self._fileItemClicked(filename), selected=False, allow_check=False, _lfontsize=17, _rfontsize=12, height=80, - notificate=False + notificate=False, ) - - self.model.add_item(item) ->>>>>>> 342be69 (FilesPage: Refactor almost complete missing passing the directory by itemclick) + self.model.add_item(item) @QtCore.pyqtSlot(str, name="file-item-clicked") def _fileItemClicked(self, filename: str) -> None: @@ -181,45 +146,13 @@ def _fileItemClicked(self, filename: str) -> None: Args: filename (str): Clicked item path """ -<<<<<<< HEAD - if item: - for file in self.file_list: - path = ( - file.get("path") if "path" in file.keys() else file.get("filename") - ) - if not path: - return - if item.text in path: - file_path = ( - path if not self.curr_dir else str(self.curr_dir + "/" + path) - ) - self.file_selected.emit( - str(file_path.removeprefix("/")), -======= self.file_selected.emit( - str(filename.removeprefix("/")), ->>>>>>> 44841b3 (filesPage.py: refactor concluded, scrollbar bugfix) - self.files_data.get( - filename.removeprefix("/") - ), # Defaults to Nothing - ) - -<<<<<<< HEAD -<<<<<<< HEAD - @QtCore.pyqtSlot(QtWidgets.QListWidgetItem, str, name="dir-item-clicked") - def _dirItemClicked(self, item: QtWidgets.QListWidgetItem, directory: str) -> None: -======= -======= - ->>>>>>> 44841b3 (filesPage.py: refactor concluded, scrollbar bugfix) - def _dirItemClicked( - self, directory: str - ) -> None: -<<<<<<< HEAD ->>>>>>> 342be69 (FilesPage: Refactor almost complete missing passing the directory by itemclick) -======= - """Method that changes the current view in the list """ ->>>>>>> a5ed680 (filesPage.py: code cleanup, small docstring generation and add missing commented lines) + str(filename.removeprefix("/")), + self.files_data.get(filename.removeprefix("/")), # Defaults to Nothing + ) + + def _dirItemClicked(self, directory: str) -> None: + """Method that changes the current view in the list""" self.curr_dir = self.curr_dir + directory self.request_dir_info[str].emit(self.curr_dir) @@ -228,10 +161,14 @@ def _build_file_list(self) -> None: self.listWidget.blockSignals(True) self.model.clear() self.entry_delegate.clear() - if not self.file_list and not self.directories and os.path.islink(self.curr_dir): + if ( + not self.file_list + and not self.directories + and os.path.islink(self.curr_dir) + ): self._add_placeholder() return - + if self.directories or self.curr_dir != "": if self.curr_dir != "" and self.curr_dir != "/": self._add_back_folder_entry() @@ -242,43 +179,16 @@ def _build_file_list(self) -> None: sorted_list = sorted(self.file_list, key=lambda x: x["modified"], reverse=True) for item in sorted_list: self._add_file_list_item(item) - + self._setup_scrollbar() self.listWidget.blockSignals(False) self.listWidget.repaint() def _add_directory_list_item(self, dir_data: dict) -> None: - """Method that adds directories to the list """ + """Method that adds directories to the list""" dir_name = dir_data.get("dirname", "") if not dir_name: return -<<<<<<< HEAD - button = ListCustomButton() - button.setText(str(dir_data.get("dirname"))) - button.setSecondPixmap(QtGui.QPixmap(":/ui/media/btn_icons/folderIcon.svg")) - button.setMinimumSize(600, 80) - button.setMaximumSize(700, 80) - button.setLeftFontSize(17) - button.setRightFontSize(12) - list_item = QtWidgets.QListWidgetItem() - list_item.setSizeHint(button.sizeHint()) - self.listWidget.addItem(list_item) - self.listWidget.setItemWidget(list_item, button) - button.clicked.connect(lambda: self._dirItemClicked(list_item, "/" + dir_name)) - - def _add_back_folder_entry(self) -> None: - button = ListCustomButton() - button.setText("Go Back") - button.setSecondPixmap(QtGui.QPixmap(":/ui/media/btn_icons/back_folder.svg")) - button.setMinimumSize(600, 80) - button.setMaximumSize(700, 80) - button.setLeftFontSize(17) - button.setRightFontSize(12) - list_item = QtWidgets.QListWidgetItem() - list_item.setSizeHint(button.sizeHint()) - self.listWidget.addItem(list_item) - self.listWidget.setItemWidget(list_item, button) -======= item = ListItem( text=str(dir_name), left_icon=QtGui.QPixmap(":/ui/media/btn_icons/folderIcon.svg"), @@ -288,32 +198,28 @@ def _add_back_folder_entry(self) -> None: allow_check=False, _lfontsize=17, _rfontsize=12, - height=80 + height=80, ) self.model.add_item(item) def _add_back_folder_entry(self) -> None: -<<<<<<< HEAD ->>>>>>> 342be69 (FilesPage: Refactor almost complete missing passing the directory by itemclick) -======= - """Method to insert in the list the "Go back" item """ ->>>>>>> a5ed680 (filesPage.py: code cleanup, small docstring generation and add missing commented lines) + """Method to insert in the list the "Go back" item""" go_back_path = os.path.dirname(self.curr_dir) if go_back_path == "/": go_back_path = "" - + item = ListItem( text="Go Back", right_text="", right_icon=None, left_icon=QtGui.QPixmap(":/ui/media/btn_icons/back_folder.svg"), - callback= lambda: self._on_goback_dir(go_back_path), + callback=lambda: self._on_goback_dir(go_back_path), selected=False, allow_check=False, _lfontsize=17, _rfontsize=12, height=80, - notificate=False + notificate=False, ) self.model.add_item(item) @@ -334,49 +240,18 @@ def _add_file_list_item(self, file_data_item) -> None: if not name.endswith(".gcode"): # Only list .gcode files, all else ignore return -<<<<<<< HEAD - button = ListCustomButton() - button.setText(name[:-6]) - button.setPixmap(QtGui.QPixmap(":/arrow_icons/media/btn_icons/right_arrow.svg")) - button.setMinimumSize(600, 80) - button.setMaximumSize(700, 80) - button.setLeftFontSize(17) - button.setRightFontSize(12) - list_item = QtWidgets.QListWidgetItem() - list_item.setSizeHint(button.sizeHint()) - self.listWidget.addItem(list_item) - self.listWidget.setItemWidget(list_item, button) - button.clicked.connect(lambda: self._fileItemClicked(list_item)) -======= ->>>>>>> 342be69 (FilesPage: Refactor almost complete missing passing the directory by itemclick) file_path = ( name if not self.curr_dir else str(self.curr_dir + "/" + name) ).removeprefix("/") - + self.request_file_metadata.emit(file_path.removeprefix("/")) self.request_file_info.emit(file_path.removeprefix("/")) def _add_placeholder(self) -> None: -<<<<<<< HEAD - self.listWidget.setSpacing(-1) - placeholder_label = QtWidgets.QLabel("No Files found") - font = QtGui.QFont() - font.setPointSize(25) - placeholder_label.setFont(font) - placeholder_label.setStyleSheet("color: gray;") - placeholder_label.setAlignment( - QtCore.Qt.AlignmentFlag.AlignHCenter | QtCore.Qt.AlignmentFlag.AlignVCenter - ) - placeholder_label.setMinimumSize( - QtCore.QSize(self.listWidget.width(), self.listWidget.height()) - ) -======= ->>>>>>> 342be69 (FilesPage: Refactor almost complete missing passing the directory by itemclick) self.scrollbar.hide() self.listWidget.hide() self.label.show() - def _handle_scrollbar(self, value): # Block signals to avoid recursion self.scrollbar.blockSignals(True) @@ -384,27 +259,9 @@ def _handle_scrollbar(self, value): self.scrollbar.blockSignals(False) def _setup_scrollbar(self) -> None: -<<<<<<< HEAD -<<<<<<< HEAD self.scrollbar.setMinimum(self.listWidget.verticalScrollBar().minimum()) self.scrollbar.setMaximum(self.listWidget.verticalScrollBar().maximum()) self.scrollbar.setPageStep(self.listWidget.verticalScrollBar().pageStep()) -======= - idx = self.model.index(0, 0) - - rect = self.listWidget.rectForIndex(idx) -======= ->>>>>>> e8b88d5 (filesPage.py: remove unused lines of code) - self.scrollbar.setMinimum( - self.listWidget.verticalScrollBar().minimum() - ) - self.scrollbar.setMaximum( - self.listWidget.verticalScrollBar().maximum() - ) - self.scrollbar.setPageStep( - self.listWidget.verticalScrollBar().pageStep() - ) ->>>>>>> 44841b3 (filesPage.py: refactor concluded, scrollbar bugfix) self.scrollbar.show() def _setupUI(self): @@ -507,7 +364,7 @@ def _setupUI(self): QtWidgets.QScroller.scroller(self.listWidget).setScrollerProperties( scroller_props ) - + font = QtGui.QFont() font.setPointSize(25) self.label = QtWidgets.QLabel("No Files found") @@ -517,8 +374,7 @@ def _setupUI(self): QtCore.QSize(self.listWidget.width(), self.listWidget.height()) ) self.label.setAlignment( - QtCore.Qt.AlignmentFlag.AlignHCenter - | QtCore.Qt.AlignmentFlag.AlignVCenter + QtCore.Qt.AlignmentFlag.AlignHCenter | QtCore.Qt.AlignmentFlag.AlignVCenter ) self.fp_content_layout.addWidget(self.listWidget) @@ -528,5 +384,3 @@ def _setupUI(self): self.verticalLayout_5.addLayout(self.fp_content_layout) self.scrollbar.show() self.label.hide() - - From b098f1be5ae0ba656c626b7a17f064005e3ebb76 Mon Sep 17 00:00:00 2001 From: Guilherme Costa Date: Thu, 11 Dec 2025 17:46:12 +0000 Subject: [PATCH 7/8] formatting fix Signed-off-by: Guilherme Costa --- BlocksScreen/helper_methods.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/BlocksScreen/helper_methods.py b/BlocksScreen/helper_methods.py index 03f28ff5..8de5fc13 100644 --- a/BlocksScreen/helper_methods.py +++ b/BlocksScreen/helper_methods.py @@ -326,21 +326,21 @@ def check_file_on_path( return os.path.exists(_filepath) -def get_file_loc(filename) -> pathlib.Path: - ... - +def get_file_loc(filename) -> pathlib.Path: ... + + def get_file_name(filename: typing.Optional[str]) -> str: # If filename is None or empty, return empty string instead of None if not filename: return "" # Remove trailing slashes or backslashes filename = filename.rstrip("/\\") - + # Normalize Windows backslashes to forward slashes filename = filename.replace("\\", "/") - + parts = filename.split("/") - + # Split and return the last path component return parts[-1] if filename else "" @@ -352,5 +352,4 @@ def get_file_name(filename: typing.Optional[str]) -> str: # return hash - def digest_hash() -> None: ... From 54ce58b22a241c3aa68848a3be9829069c8c42b3 Mon Sep 17 00:00:00 2001 From: Guilherme Costa Date: Tue, 16 Dec 2025 16:17:39 +0000 Subject: [PATCH 8/8] filesPage.py: Add sync timeout and change click behavior in files page Set file list to refresh after 1.5s to improve UI responsiveness. Clicks are now handled in the _on_item_selected slot instead of inline callbacks to separate logic and unify behavior. --- BlocksScreen/lib/panels/widgets/filesPage.py | 76 +++++++++++++------- 1 file changed, 52 insertions(+), 24 deletions(-) diff --git a/BlocksScreen/lib/panels/widgets/filesPage.py b/BlocksScreen/lib/panels/widgets/filesPage.py index cd648ee2..f8fa490f 100644 --- a/BlocksScreen/lib/panels/widgets/filesPage.py +++ b/BlocksScreen/lib/panels/widgets/filesPage.py @@ -54,37 +54,52 @@ def __init__(self, parent) -> None: self.back_btn.clicked.connect(self.reset_dir) self.entry_delegate.item_selected.connect(self._on_item_selected) + self._refresh_one_and_half_sec_timer = QtCore.QTimer() + self._refresh_one_and_half_sec_timer.timeout.connect( + lambda: self.request_dir_info[str].emit(self.curr_dir) + ) + self._refresh_one_and_half_sec_timer.start(1500) @QtCore.pyqtSlot(ListItem, name="on-item-selected") def _on_item_selected(self, item: ListItem) -> None: """Slot called when a list item is selected in the UI. This method is connected to the `item_selected` signal of the entry delegate. - It handles the selection of a `ListItem` and is intended to be overridden - or customized for each specific item type, allowing different behavior - depending on the item. + It handles the selection of a `ListItem` and process it accoding it with its type Args: item : ListItem The item that was selected by the user. """ - logger.debug("Item Selected") + if not item.left_icon: + filename = self.curr_dir + "/" + item.text + ".gcode" + self._fileItemClicked(filename) + else: + if item.text == "Go Back": + go_back_path = os.path.dirname(self.curr_dir) + if go_back_path == "/": + go_back_path = "" + self._on_goback_dir(go_back_path) + else: + self._dirItemClicked("/" + item.text) @QtCore.pyqtSlot(name="reset-dir") def reset_dir(self) -> None: + """Reset current directory""" self.curr_dir = "" self.request_dir_info[str].emit(self.curr_dir) def showEvent(self, a0: QtGui.QShowEvent) -> None: + """Re-implemented method, handle widget show event""" self._build_file_list() return super().showEvent(a0) @QtCore.pyqtSlot(list, name="on-file-list") def on_file_list(self, file_list: list) -> None: + """Handle receiving files list from websocket""" self.files_data.clear() self.file_list = file_list - # if self.isVisible(): # Only build the list when directories come - # self._build_file_list() @QtCore.pyqtSlot(list, name="on-dirs") def on_directories(self, directories_data: list) -> None: + """Handle receiving available directories from websocket""" self.directories = directories_data if self.isVisible(): self._build_file_list() @@ -123,9 +138,9 @@ def on_fileinfo(self, filedata: dict) -> None: item = ListItem( text=name[:-6], right_text=f"{filament_type} - {time_str}", - right_icon=QtGui.QPixmap(":/arrow_icons/media/btn_icons/right_arrow.svg"), + right_icon=self.path.get("right_arrow"), left_icon=None, - callback=lambda: self._fileItemClicked(filename), + callback=None, selected=False, allow_check=False, _lfontsize=17, @@ -145,7 +160,7 @@ def _fileItemClicked(self, filename: str) -> None: """ self.file_selected.emit( str(filename.removeprefix("/")), - self.files_data.get(filename.removeprefix("/")), # Defaults to Nothing + self.files_data.get(filename.removeprefix("/")), ) def _dirItemClicked(self, directory: str) -> None: @@ -179,7 +194,7 @@ def _build_file_list(self) -> None: self._setup_scrollbar() self.listWidget.blockSignals(False) - self.listWidget.repaint() + self.listWidget.update() def _add_directory_list_item(self, dir_data: dict) -> None: """Method that adds directories to the list""" @@ -188,10 +203,10 @@ def _add_directory_list_item(self, dir_data: dict) -> None: return item = ListItem( text=str(dir_name), - left_icon=QtGui.QPixmap(":/ui/media/btn_icons/folderIcon.svg"), + left_icon=self.path.get("folderIcon"), right_text="", selected=False, - callback=lambda name=dir_name: self._dirItemClicked("/" + str(name)), + callback=None, allow_check=False, _lfontsize=17, _rfontsize=12, @@ -209,8 +224,8 @@ def _add_back_folder_entry(self) -> None: text="Go Back", right_text="", right_icon=None, - left_icon=QtGui.QPixmap(":/ui/media/btn_icons/back_folder.svg"), - callback=lambda: self._on_goback_dir(go_back_path), + left_icon=self.path.get("back_folder"), + callback=None, selected=False, allow_check=False, _lfontsize=17, @@ -222,10 +237,12 @@ def _add_back_folder_entry(self) -> None: @QtCore.pyqtSlot(str, str, name="on-goback-dir") def _on_goback_dir(self, directory) -> None: + """Go back behaviour""" self.request_dir_info[str].emit(directory) self.curr_dir = directory def _add_file_list_item(self, file_data_item) -> None: + """Request file information and metadata to create filelist""" if not file_data_item: return @@ -235,7 +252,6 @@ def _add_file_list_item(self, file_data_item) -> None: else file_data_item["filename"] ) if not name.endswith(".gcode"): - # Only list .gcode files, all else ignore return file_path = ( name if not self.curr_dir else str(self.curr_dir + "/" + name) @@ -245,17 +261,19 @@ def _add_file_list_item(self, file_data_item) -> None: self.request_file_info.emit(file_path.removeprefix("/")) def _add_placeholder(self) -> None: + """Shows placeholder when no items exist""" self.scrollbar.hide() self.listWidget.hide() self.label.show() def _handle_scrollbar(self, value): - # Block signals to avoid recursion + """Updates scrollbar value""" self.scrollbar.blockSignals(True) self.scrollbar.setValue(value) self.scrollbar.blockSignals(False) def _setup_scrollbar(self) -> None: + """Syncs the scrollbar with the list size""" self.scrollbar.setMinimum(self.listWidget.verticalScrollBar().minimum()) self.scrollbar.setMaximum(self.listWidget.verticalScrollBar().maximum()) self.scrollbar.setPageStep(self.listWidget.verticalScrollBar().pageStep()) @@ -327,7 +345,7 @@ def _setupUI(self): self.listWidget.setSelectionBehavior( QtWidgets.QAbstractItemView.SelectionBehavior.SelectItems ) - self.listWidget.setHorizontalScrollBarPolicy( # No horizontal scroll + self.listWidget.setHorizontalScrollBarPolicy( QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOff ) self.listWidget.setVerticalScrollMode( @@ -352,11 +370,11 @@ def _setupUI(self): scroller_props = scroller_instance.scrollerProperties() scroller_props.setScrollMetric( QtWidgets.QScrollerProperties.ScrollMetric.DragVelocitySmoothingFactor, - 0.05, # Lower = more responsive + 0.05, ) scroller_props.setScrollMetric( QtWidgets.QScrollerProperties.ScrollMetric.DecelerationFactor, - 0.4, # higher = less inertia + 0.4, ) QtWidgets.QScroller.scroller(self.listWidget).setScrollerProperties( scroller_props @@ -370,14 +388,24 @@ def _setupUI(self): self.label.setMinimumSize( QtCore.QSize(self.listWidget.width(), self.listWidget.height()) ) - self.label.setAlignment( - QtCore.Qt.AlignmentFlag.AlignHCenter | QtCore.Qt.AlignmentFlag.AlignVCenter - ) - self.fp_content_layout.addWidget(self.listWidget) - self.fp_content_layout.addWidget(self.label) self.scrollbar = CustomScrollBar() + + self.fp_content_layout.addWidget( + self.label, + alignment=QtCore.Qt.AlignmentFlag.AlignHCenter + | QtCore.Qt.AlignmentFlag.AlignVCenter, + ) + self.fp_content_layout.addWidget(self.listWidget) self.fp_content_layout.addWidget(self.scrollbar) self.verticalLayout_5.addLayout(self.fp_content_layout) self.scrollbar.show() self.label.hide() + + self.path = { + "back_folder": QtGui.QPixmap(":/ui/media/btn_icons/back_folder.svg"), + "folderIcon": QtGui.QPixmap(":/ui/media/btn_icons/folderIcon.svg"), + "right_arrow": QtGui.QPixmap( + ":/arrow_icons/media/btn_icons/right_arrow.svg" + ), + }