tweaks and fixes

This commit is contained in:
Will McGugan
2023-05-18 16:32:13 +01:00
parent 15737439cf
commit 4b0f1625c6
9 changed files with 656 additions and 531 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
*.pyc
.vscode

1042
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@ packages = [{include = "textual_click"}]
[tool.poetry.dependencies]
python = "^3.7"
textual = {extras = ["dev"], version = ">=0.20.1"}
textual = {extras = ["dev"], version = ">=0.25.0"}
#textual = {extras = ["dev"], path = "../textual", develop = true}
click = ">=8.0.0"

View File

@@ -0,0 +1,4 @@
APP_TITLE = "Trogon"
PACKAGE_NAME = "trogon"
TEXTUAL_URL = "https://github.com/textualize/textual"
ORGANIZATION_NAME = "T"

View File

@@ -3,6 +3,7 @@ from __future__ import annotations
import os
import shlex
from pathlib import Path
from webbrowser import open as open_url
import click
from rich.console import Console
@@ -49,6 +50,7 @@ class CommandBuilder(Screen):
key="ctrl+t", action="focus_command_tree", description="Focus Command Tree"
),
Binding(key="ctrl+o", action="show_command_info", description="Command Info"),
Binding(key="ctrl+a", action="about", description="About Trogon"),
]
def __init__(
@@ -128,6 +130,11 @@ class CommandBuilder(Screen):
self.app.execute_on_exit = True
self.app.exit()
def action_about(self) -> None:
from .widgets.about import AboutDialog
self.app.push_screen(AboutDialog())
async def on_mount(self, event: events.Mount) -> None:
await self._refresh_command_form()
@@ -263,6 +270,14 @@ class TextualClick(App):
command_builder = self.query_one(CommandBuilder)
self.push_screen(CommandInfo(command_builder.selected_command_schema))
def action_visit(self, url: str) -> None:
"""Visit the given URL, via the operating system.
Args:
url: The URL to visit.
"""
open_url(url)
def tui(name: str | None = None):
def decorator(app: click.Group | click.Command):

View File

@@ -56,7 +56,7 @@
#home-command-description {
width: 1fr;
height: 2;
height: 2;
}
#home-command-description-container {
@@ -89,7 +89,7 @@ CommandBuilder .command-name-syntax {
CommandTree {
background: $background-lighten-1;
scrollbar-gutter: stable;
scrollbar-size-vertical: 1;
scrollbar-size-vertical: 2;
width: auto;
height: 1fr;
padding: 1 2;
@@ -97,7 +97,7 @@ CommandTree {
}
CommandTree :focus {
outline: solid $primary-lighten-2;
outline: tall $secondary;
}
CommandTree > .tree--cursor {
@@ -158,16 +158,16 @@ Pretty {
}
.add-another-button {
dock: right;
margin: 0 2;
padding: 0 1;
height: 1;
border: none;
border: none;
}
.add-another-button-container {
width: 1fr;
height: auto;
align: right top;
}
CommandInfo {
@@ -227,4 +227,4 @@ CommandInfo Tab {
Tabs:focus .underline--bar {
color: $accent-lighten-1;
}
}

View File

@@ -0,0 +1,103 @@
"""Provides a base modal dialog for showing text to the user."""
from rich.text import Text, TextType
from textual.app import ComposeResult
from textual.binding import Binding
from textual.containers import Center, Vertical
from textual.screen import ModalScreen
from textual.widgets import Button, Static
from textual.widgets._button import ButtonVariant
from .. import constants
class TextDialog(ModalScreen[None]):
"""Base modal dialog for showing information."""
DEFAULT_CSS = """
TextDialog {
align: center middle;
}
TextDialog Center {
width: 100%;
}
TextDialog > Vertical {
background: $boost;
min-width: 30%;
width: auto;
height: auto;
border: round $primary;
}
TextDialog Static {
width: auto;
}
TextDialog .spaced {
padding: 1 4;
}
TextDialog #message {
min-width: 100%;
}
"""
"""Default CSS for the base text modal dialog."""
BINDINGS = [
Binding("escape", "dismiss(None)", "", show=False),
]
"""Bindings for the base text modal dialog."""
def __init__(self, title: TextType, message: TextType) -> None:
"""Initialise the dialog.
Args:
title: The title for the dialog.
message: The message to show.
"""
super().__init__()
self._title = title
self._message = message
@property
def button_style(self) -> ButtonVariant:
"""The style for the dialog's button."""
return "primary"
def compose(self) -> ComposeResult:
"""Compose the content of the modal dialog."""
with Vertical():
with Center():
yield Static(self._title, classes="spaced")
yield Static(self._message, id="message", classes="spaced")
with Center(classes="spaced"):
yield Button("OK", variant=self.button_style)
def on_mount(self) -> None:
"""Configure the dialog once the DOM has loaded."""
self.query_one(Button).focus()
def on_button_pressed(self) -> None:
"""Handle the OK button being pressed."""
self.dismiss(None)
class AboutDialog(TextDialog):
DEFAULT_CSS = """
TextDialog > Vertical {
border: thick $primary 50%;
}
"""
def __init__(self) -> None:
title = f"About Trogon"
message = Text.from_markup(
f"Built with [@click=app.visit('https://github.com/textualize/textual')]Textual[/] "
f"by [@click=app.visit('https://textualize.io')]Textualize[/].\n\n"
f"[@click=app.visit('https://github.com/textualize/{constants.PACKAGE_NAME}')]"
f"https://github.com/textualize/{constants.PACKAGE_NAME}[/]",
)
super().__init__(title, message)

View File

@@ -15,7 +15,8 @@ class CommandTree(Tree[CommandSchema]):
def __init__(self, label: TextType, cli_metadata: dict[CommandName, CommandSchema]):
super().__init__(label)
self.show_root = False
self.guide_depth = 2
self.guide_depth = 3
self.show_guides = True
self.cli_metadata = cli_metadata
def render_label(

View File

@@ -57,7 +57,7 @@ class CommandForm(Widget):
margin: 1 2;
height: auto;
background: $boost;
border: panel $primary 60%;
border: panel $background;
border-title-color: $text 80%;
border-title-style: bold;
border-subtitle-color: $text 30%;
@@ -107,7 +107,8 @@ class CommandForm(Widget):
v.border_title = (
f"{'' if is_inherited else ''}{command_node.name}"
)
v.border_subtitle = f"{'(parameters inherited from parent)' if is_inherited else ''}"
if is_inherited:
v.border_title += " [dim not bold](inherited)"
if arguments:
yield Label(f"Arguments", classes="command-form-heading")
for argument in arguments: