build out ui

This commit is contained in:
2026-07-27 20:51:13 +10:00
parent 074791f430
commit de7e3b9070
6 changed files with 226 additions and 10 deletions

View File

@@ -2,24 +2,29 @@ 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
from widgets.prompt import Prompt
from widgets.context_menu import ContextMenu, NoSelectStatic
import os, shutil
class CustomDirectoryTree(DirectoryTree):
DEFAULT_CSS = """
CustomDirectoryTree {
dock: left;
width: 30;
}
"""
ICON_NODE = ""
ICON_NODE_EXPANDED = ""
ICON_FILE = ""
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, file_name: str, result: str):
if result == "Delete":
def delete_confirm(will_delete: bool | None):

34
src/widgets/file_tabs.py Normal file
View File

@@ -0,0 +1,34 @@
from textual.widgets import TabbedContent, TabPane
from widgets.text_editor import TextEditor
from widgets.home_page import HomePage
import os
class FileTabs(TabbedContent):
DEFAULT_CSS = """
FileTabs {
margin: 0 1;
}
"""
async def open_home(self) -> None:
new_pane = TabPane("Home")
new_pane.path = None
await self.add_pane(new_pane)
await new_pane.mount(HomePage())
async def open_file(self, path: str) -> None:
if self.tab_count > 0:
for tab in self.query(TabPane):
if tab.path == path:
self.active = tab.id
return
new_pane = TabPane(os.path.basename(path))
new_pane.path = path
await self.add_pane(new_pane)
await new_pane.mount(TextEditor())

102
src/widgets/home_page.py Normal file
View File

@@ -0,0 +1,102 @@
from textual.widgets import Static, Rule
from textual.containers import Vertical, Horizontal, Center
from textual import on
from textualeffects.widgets import EffectLabel
from terminaltexteffects.utils.graphics import Color
import pyfiglet
class HomePage(Vertical):
DEFAULT_CSS = """
HomePage {
content-align: center top;
Static {
text-align: center;
}
#banner {
height: 6; # probs will need to be updated
margin-bottom: 1;
Rule {
color: $surface-lighten-2;
height: 100%;
content-align: center middle;
margin: 0 3;
}
EffectLabel {
height: 100%;
}
}
#bindings {
Horizontal {
max-width: 50;
width: 50%;
margin-top: 1;
height: 1;
.bind-name {
width: 75%;
}
.bind-keys {
width: 25%;
}
Static {
text-align: left;
link-background: transparent;
link-color: $primary;
}
}
}
}
"""
@on(EffectLabel.EffectFinished)
def restart_effect(self):
self.banner_label.run_worker(self.banner_label.run_effect, exclusive=True)
def compose(self):
with Horizontal(id="banner"):
yield Rule()
self.banner_label = EffectLabel(pyfiglet.figlet_format("berry", font="sub-zero"), effect="Highlight", config={
"final_gradient_stops": [Color("#f263ff"), Color("#946ff2")],
"cycles": 0
})
yield self.banner_label
yield Rule()
yield Static("[dim]The text editor that no one asked for and didn't need.[/]")
# bindings
with Center(id="bindings"):
binds = self.app.bind_keys
with Horizontal():
yield Static("[b] New file[/]", classes="bind-name")
yield Static(f"[@click=app.new]{binds["new"]}[/]", classes="bind-keys")
with Horizontal():
yield Static("[b] Open file[/]", classes="bind-name")
yield Static(f"[@click=app.open]{binds["open"]}[/]", classes="bind-keys")
with Horizontal():
yield Static("[b] Open Folder[/]", classes="bind-name")
yield Static(f"[@click=app.open_folder]{binds["open-folder"]}[/]", classes="bind-keys")
with Horizontal():
yield Static("[b] Settings[/]", classes="bind-name")
yield Static(f"[@click=app.settings]{binds["settings"]}[/]", classes="bind-keys")

View File

@@ -3,4 +3,4 @@ from textual.widgets import TextArea
class TextEditor(TextArea):
def __init__(self, text = "", language = None, read_only = False):
super().__init__(text, language=language, placeholder="Type here . . .", read_only=read_only, theme="css")
super().__init__(text, language=language, placeholder="Type here . . .", read_only=read_only, theme="vscode_dark", show_line_numbers=True, tab_behavior="indent")