implementing some of the right click options

This commit is contained in:
SpookyDervish
2025-10-31 06:47:02 +11:00
parent a5ee621b46
commit 5e38909640
2 changed files with 111 additions and 1 deletions

View File

@@ -1,16 +1,46 @@
from textual.widgets import DirectoryTree, Rule from textual.widgets import DirectoryTree, Rule
from textual.widgets.tree import TreeNode from textual.widgets.tree import TreeNode
from textual.events import MouseDown from textual.events import MouseDown
from prompt import Prompt
from context_menu import ContextMenu, NoSelectStatic from context_menu import ContextMenu, NoSelectStatic
import os, shutil
class CustomDirectoryTree(DirectoryTree): class CustomDirectoryTree(DirectoryTree):
def __init__(self, path, *, name = None, id = None, classes = None, disabled = False): def __init__(self, path, *, name = None, id = None, classes = None, disabled = False):
super().__init__(path, name=name, id=id, classes=classes, disabled=disabled) super().__init__(path, name=name, id=id, classes=classes, disabled=disabled)
self.right_clicked_node: TreeNode | None = None self.right_clicked_node: TreeNode | None = None
def context_menu_chosen(self, result): 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): def on_mouse_down(self, event: MouseDown):
if event.button != 3 or not "line" in event.style.meta: if event.button != 3 or not "line" in event.style.meta:

80
prompt.py Normal file
View File

@@ -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")