mirror of
https://github.com/Textualize/trogon.git
synced 2023-05-22 11:05:13 +03:00
tweaks and fixes
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
||||
*.pyc
|
||||
.vscode
|
||||
|
||||
1042
poetry.lock
generated
1042
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||
|
||||
|
||||
4
textual_click/constants.py
Normal file
4
textual_click/constants.py
Normal file
@@ -0,0 +1,4 @@
|
||||
APP_TITLE = "Trogon"
|
||||
PACKAGE_NAME = "trogon"
|
||||
TEXTUAL_URL = "https://github.com/textualize/textual"
|
||||
ORGANIZATION_NAME = "T"
|
||||
@@ -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):
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
103
textual_click/widgets/about.py
Normal file
103
textual_click/widgets/about.py
Normal 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)
|
||||
@@ -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(
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user