From 5e38909640958a67b7835bd1bd0c4188cb840fec Mon Sep 17 00:00:00 2001 From: SpookyDervish <78246495+SpookyDervish@users.noreply.github.com> Date: Fri, 31 Oct 2025 06:47:02 +1100 Subject: [PATCH] implementing some of the right click options --- directory_tree_custom.py | 32 +++++++++++++++- prompt.py | 80 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 prompt.py diff --git a/directory_tree_custom.py b/directory_tree_custom.py index ecc27c9..2fc7052 100644 --- a/directory_tree_custom.py +++ b/directory_tree_custom.py @@ -1,16 +1,46 @@ from textual.widgets import DirectoryTree, Rule from textual.widgets.tree import TreeNode from textual.events import MouseDown + +from prompt import Prompt from context_menu import ContextMenu, NoSelectStatic +import os, shutil + class CustomDirectoryTree(DirectoryTree): def __init__(self, path, *, name = None, id = None, classes = None, disabled = False): super().__init__(path, name=name, id=id, classes=classes, disabled=disabled) self.right_clicked_node: TreeNode | None = None + + def context_menu_chosen(self, result): - self.right_clicked_node = None + if result == "Open": + self.select_node(self.right_clicked_node) + self.right_clicked_node = None + elif result == "Delete": + def delete_confirm(will_delete: bool | None): + if will_delete == True: + shutil.rmtree(self.right_clicked_node.data.path) + self.reload() + + self.notify(f"Deleted \"{self.right_clicked_node.data.path}\".") + self.right_clicked_node = None + + self.app.push_screen(Prompt(f"Are you sure you want to delete \"{self.right_clicked_node.label}\"?", "confirm", "Confirm deletion"), delete_confirm) + elif result == "Rename": + def rename_confirm(new_name: str | None): + if new_name == None: return + + os.rename(self.right_clicked_node.data.path, os.path.join(os.path.dirname(self.right_clicked_node.data.path), new_name)) + self.reload() + + self.notify("Renamed successfully.") + + self.right_clicked_node = None + + self.app.push_screen(Prompt(f"Enter the new name for \"{self.right_clicked_node.label}\".", "string", "Rename"), rename_confirm) def on_mouse_down(self, event: MouseDown): if event.button != 3 or not "line" in event.style.meta: diff --git a/prompt.py b/prompt.py new file mode 100644 index 0000000..17b2558 --- /dev/null +++ b/prompt.py @@ -0,0 +1,80 @@ +from textual.screen import ModalScreen +from textual.containers import Vertical +from textual.widgets import Static, Button, Input +from textual.containers import HorizontalGroup, Center +from textual.binding import Binding +from typing import Literal + + +class Prompt(ModalScreen): + DEFAULT_CSS = """ + Prompt { + align: center middle; + + #window { + max-width: 50; + height: auto; + border: panel $accent; + + #question { + width: 100%; + margin: 2; + margin-top: 1; + } + + #bottom { + dock: bottom; + margin-bottom: 1; + margin-left: 1; + + #yes { + margin-left: 1; + margin-right: 2; + } + + #confirm-string { + margin-left: 1; + } + + Input { + max-width: 25; + } + } + } + } + """ + + BINDINGS = [ + Binding("escape", "close", "Close") + ] + + def action_close(self): + self.dismiss(None) + + def on_button_pressed(self, event: Button.Pressed): + if event.button.id == "yes": + self.dismiss(True) + elif event.button.id == "no": + self.dismiss(False) + elif event.button.id == "confirm-string": + self.dismiss(self.query_one("#input").value) + + def __init__(self, question: str, prompt_type: Literal["confirm", "string"], title: str = "Confirm"): + super().__init__() + self.question = question + self.window_title = title + self.prompt_type = prompt_type + + def compose(self): + with Vertical(id="window") as window: + window.border_title = self.window_title + yield Static(self.question, id="question") + + if self.prompt_type == "confirm": + with HorizontalGroup(id="bottom"): + yield Button("Yes", variant="success", id="yes") + yield Button("No", variant="error", id="no") + elif self.prompt_type == "string": + with HorizontalGroup(id="bottom"): + yield Input(id="input", max_length=30) + yield Button("Confirm", variant="success", id="confirm-string") \ No newline at end of file