Created
March 29, 2024 22:12
-
-
Save sneakers-the-rat/1bf4974c28dd0e8512315ece591c68fb to your computer and use it in GitHub Desktop.
Choose multiple directories with Textual
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from pathlib import Path | |
from typing import Iterable, List | |
from textual.app import App, ComposeResult | |
from textual.widgets import DirectoryTree, Header | |
from textual import events | |
from rich.text import Text, TextType | |
from textual.containers import Container | |
class MultiSelectDirectoryTree(DirectoryTree): | |
def __init__(self, auto_expand=False,*args, **kwargs): | |
self.selected = [] | |
super().__init__(auto_expand, *args,**kwargs) | |
def render_label(self, node, base_style=None, style=None): | |
label = super().render_label(node, base_style, style) | |
if node not in self.selected: | |
check = ('[ ]', base_style) | |
else: | |
check = ('[*]', base_style) | |
return Text.assemble(check, label) | |
def selected_paths(self): | |
return [node.data.path for node in self.selected] | |
def toggle_selected(self, node): | |
if node in self.selected: | |
self.selected.remove(node) | |
else: | |
self.selected.append(node) | |
node.set_label(node.label) | |
def action_select_cursor(self) -> None: | |
try: | |
line = self._tree_lines[self.cursor_line] | |
except IndexError: | |
pass | |
else: | |
node = line.path[-1] | |
if self._safe_is_dir(node.data.path): | |
pass | |
self.toggle_selected(node) | |
class DirectoryTreeApp(App): | |
def __init__(self): | |
super().__init__() | |
self.file_tree = MultiSelectDirectoryTree('./') | |
def compose(self) -> ComposeResult: | |
yield Header() | |
yield self.file_tree | |
def on_mount(self): | |
self.title = "Directory Chooser" | |
self.sub_title = "Enter to select, Space to expand/collapse, ctrl+c to end" | |
def choose_directories() -> List[Path]: | |
app = DirectoryTreeApp() | |
app.run() | |
return app.file_tree.selected_paths() | |
if __name__ == "__main__": | |
paths = choose_directories() | |
print(paths) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment