From 1807b193fafeca3c446560a7f9ddf95db66b1f74 Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Sun, 7 Dec 2025 00:58:33 -0500 Subject: [PATCH 1/2] ui: preserve and update `current_ref` in `TreeOptionDialog` init (#1562) * ui: preserve and update `current_ref` in `TreeOptionDialog` init * do it in init instead --- system/ui/sunnypilot/widgets/tree_dialog.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/system/ui/sunnypilot/widgets/tree_dialog.py b/system/ui/sunnypilot/widgets/tree_dialog.py index cfc0a5caf1..27a978153e 100644 --- a/system/ui/sunnypilot/widgets/tree_dialog.py +++ b/system/ui/sunnypilot/widgets/tree_dialog.py @@ -78,7 +78,7 @@ class TreeItemWidget(Button): class TreeOptionDialog(MultiOptionDialog): def __init__(self, title, folders, current_ref="", fav_param="", option_font_weight=FontWeight.MEDIUM, search_prompt=None, get_folders_fn=None, on_exit=None, display_func=None, search_funcs=None, search_title=None, search_subtitle=None): - super().__init__(title, [], "", option_font_weight) + super().__init__(title, [], current_ref, option_font_weight) self.folders = folders self.selection_ref = current_ref self.fav_param = fav_param @@ -101,6 +101,19 @@ class TreeOptionDialog(MultiOptionDialog): self.search_dialog = None self._search_pressed = False + if current_ref: + found = False + for folder in folders: + for node in folder.nodes: + if node.ref == current_ref: + display = self.display_func(node) + self.selection = display + self.current = display + found = True + break + if found: + break + self._build_visible_items() def _on_search_confirm(self, result, text): @@ -156,6 +169,7 @@ class TreeOptionDialog(MultiOptionDialog): self.visible_items.append(TreeItemWidget(self.display_func(node), node.ref, False, 1 if folder.folder else 0, lambda node_ref=node: self._select_node(node_ref), favorite_cb, node.ref in self.favorites, is_expanded=expanded)) + self.option_buttons = self.visible_items self.options = [item.text for item in self.visible_items] self.scroller._items = self.visible_items From 35b78c3d0b74a55f1d8424e3322011861a883c3b Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Sun, 7 Dec 2025 01:23:07 -0500 Subject: [PATCH 2/2] ui: improve `TreeOptionDialog` node selection and item handling --- system/ui/sunnypilot/widgets/tree_dialog.py | 41 +++++++++++++++------ 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/system/ui/sunnypilot/widgets/tree_dialog.py b/system/ui/sunnypilot/widgets/tree_dialog.py index 27a978153e..2dd5e3a2dc 100644 --- a/system/ui/sunnypilot/widgets/tree_dialog.py +++ b/system/ui/sunnypilot/widgets/tree_dialog.py @@ -101,18 +101,22 @@ class TreeOptionDialog(MultiOptionDialog): self.search_dialog = None self._search_pressed = False - if current_ref: - found = False - for folder in folders: - for node in folder.nodes: - if node.ref == current_ref: - display = self.display_func(node) - self.selection = display - self.current = display - found = True - break - if found: + self.selection_node = None + # Try to match by ref, by display text, or fall back to "Default" when no ref is set + for folder in self.folders: + for node in folder.nodes: + display = self.display_func(node) + if ( + node.ref == current_ref or + display == current_ref or + (not current_ref and node.ref == "Default") + ): + self.selection = display + self.current = display + self.selection_node = node break + if self.selection_node is not None: + break self._build_visible_items() @@ -155,6 +159,17 @@ class TreeOptionDialog(MultiOptionDialog): def _build_visible_items(self, reset_scroll=True): self.visible_items = [] + + # Pinned selected item at the very top (if any) + if getattr(self, "selection_node", None) is not None: + node = self.selection_node + display = self.display_func(node) + self.selection = self.current = display + favorite_cb = (lambda node_ref=node: self._toggle_favorite(node_ref)) if self.fav_param and node.ref != "Default" else None + self.visible_items.append(TreeItemWidget(self.display_func(node), node.ref, False, 0, + lambda node_ref=node: self._select_node(node_ref), + favorite_cb, node.ref in self.favorites, is_expanded=True)) + for folder in self.folders: nodes = [node for node in folder.nodes if not self.query or search_from_list(self.query, [search_func(node) for search_func in self.search_funcs])] if not nodes and self.query: @@ -165,6 +180,10 @@ class TreeOptionDialog(MultiOptionDialog): lambda folder_ref=folder: self._toggle_folder(folder_ref))) if expanded: for node in nodes: + # Skip duplicate root-level item for the selected node + if self.selection_node is not None and node.ref == self.selection_node.ref and not folder.folder: + continue + favorite_cb = (lambda node_ref=node: self._toggle_favorite(node_ref)) if self.fav_param and node.ref != "Default" else None self.visible_items.append(TreeItemWidget(self.display_func(node), node.ref, False, 1 if folder.folder else 0, lambda node_ref=node: self._select_node(node_ref),