Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes and updates in demo apps for new themes #39

Merged
merged 3 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,163 changes: 659 additions & 504 deletions poetry.lock

Large diffs are not rendered by default.

9 changes: 3 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "textual-dev"
version = "1.6.0"
version = "1.7.0"
homepage = "https://github.com/Textualize/textual-dev"
description = "Development tools for working with Textual"
authors = [
Expand All @@ -26,8 +26,8 @@ classifiers = [
include = ["src/textual_dev/py.typed", { path = "tests", format = "sdist" }]

[tool.poetry.dependencies]
python = "^3.8"
textual = ">=0.36.0"
python = "^3.8.1"
textual = ">=0.86.2"
textual_serve = ">=1.0.3"
aiohttp = ">=3.8.1"
click = ">=8.1.2"
Expand Down Expand Up @@ -56,9 +56,6 @@ textual = "textual_dev.cli:run"
asyncio_mode = "auto"
testpaths = ["tests"]
addopts = "--strict-markers"
markers = [
"integration_test: marks tests as slow integration tests (deselect with '-m \"not integration_test\"')",
]

[tool.mypy]
implicit_reexport = false
61 changes: 34 additions & 27 deletions src/textual_dev/previews/borders.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from typing import cast

from textual.app import App, ComposeResult
from textual.containers import Vertical
from textual.css.constants import VALID_BORDER
from textual.css.types import EdgeType
from textual.widgets import Button, Label
from textual.widgets import Label, OptionList
from textual.widgets.option_list import Option

TEXT = """I must not fear.
Fear is the mind-killer.
Expand All @@ -15,25 +15,6 @@
Where the fear has gone there will be nothing. Only I will remain."""


class BorderButtons(Vertical):
DEFAULT_CSS = """
BorderButtons {
dock: left;
width: 24;
overflow-y: scroll;
}

BorderButtons > Button {
width: 100%;
}
"""

def compose(self) -> ComposeResult:
for border in sorted(VALID_BORDER):
if border:
yield Button(border, id=border)


class BorderApp(App[None]):
"""Demonstrates the border styles."""

Expand All @@ -42,10 +23,15 @@ class BorderApp(App[None]):
align: center middle;
overflow: auto;
}
OptionList#sidebar {
width: 20;
dock: left;
height: 1fr;
}
#text {
margin: 2 4;
padding: 2 4;
border: solid $secondary;
border: solid $border;
height: auto;
background: $panel;
color: $text;
Expand All @@ -54,17 +40,38 @@ class BorderApp(App[None]):
"""

def compose(self) -> ComposeResult:
yield BorderButtons()
yield OptionList(
*[Option(border, id=border) for border in sorted(VALID_BORDER) if border],
id="sidebar",
)

self.text = Label(TEXT, id="text")
self.text.shrink = True
self.text.border_title = "solid"
self.text.border_subtitle = "border subtitle"
yield self.text

def on_button_pressed(self, event: Button.Pressed) -> None:
self.text.border_title = event.button.id
def on_mount(self) -> None:
self.theme_changed_signal.subscribe(self, self.update_border)

@property
def sidebar(self) -> OptionList:
return self.query_one("#sidebar", OptionList)

def on_option_list_option_highlighted(
self, event: OptionList.OptionHighlighted
) -> None:
border_name = event.option.id
self.text.border_title = border_name
self.update_border(self.app.current_theme)

def update_border(self, _) -> None:
self.text.styles.border = (
cast(EdgeType, event.button.id),
self.stylesheet._variables["secondary"],
cast(
EdgeType,
self.sidebar.get_option_at_index(self.sidebar.highlighted or 0).id,
),
self.theme_variables["border"],
)


Expand Down
58 changes: 45 additions & 13 deletions src/textual_dev/previews/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
from textual.containers import Horizontal, Vertical, VerticalScroll
from textual.design import ColorSystem
from textual.widget import Widget
from textual.widgets import Button, Footer, Label, Static, TabbedContent
from textual.widgets import Footer, Label, OptionList, Static, TabbedContent
from textual.widgets.option_list import Option

try:
from textual.lazy import Lazy
Expand All @@ -14,12 +15,6 @@ def Lazy(widget: Widget) -> Widget: # type: ignore
return widget


class ThemeColorButtons(VerticalScroll):
def compose(self) -> ComposeResult:
for color_name in ColorSystem.COLOR_NAMES:
yield Button(color_name, id=color_name)


class ColorBar(Static):
pass

Expand Down Expand Up @@ -56,7 +51,7 @@ def compose(self) -> ComposeResult:
yield ColorBar(f"{color.rgb}", classes="text text-left")


class ThemeColorsView(ColorsView):
class ThemeColorsView(ColorsView, can_focus=False):
def compose(self) -> ComposeResult:
LEVELS = [
"darken-3",
Expand All @@ -80,22 +75,59 @@ def compose(self) -> ComposeResult:


class ColorsApp(App[None]):
CSS_PATH = "colors.css"
CSS_PATH = "colors.tcss"

BINDINGS = [("d", "toggle_dark", "Toggle dark mode")]
BINDINGS = [
("[", "previous_theme", "Previous theme"),
("]", "next_theme", "Next theme"),
]

def __init__(self) -> None:
super().__init__()
self.theme_names = [
theme for theme in self.available_themes if theme != "textual-ansi"
]

def compose(self) -> ComposeResult:
yield Footer()
with ColorTabs("Theme Colors", "Named Colors"):
yield Content(ThemeColorButtons(), ThemeColorsView(), id="theme")
with Content(id="theme"):
sidebar = OptionList(
*[
Option(color_name, id=color_name)
for color_name in ColorSystem.COLOR_NAMES
],
id="sidebar",
)
sidebar.border_title = "Theme Colors"
yield sidebar
yield ThemeColorsView()
yield Lazy(NamedColorsView())

def on_button_pressed(self, event: Button.Pressed) -> None:
def on_option_list_option_highlighted(
self, event: OptionList.OptionHighlighted
) -> None:
self.query(ColorGroup).remove_class("-active")
group = self.query_one(f"#group-{event.button.id}", ColorGroup)
group = self.query_one(f"#group-{event.option.id}", ColorGroup)
group.add_class("-active")
group.scroll_visible(top=True, speed=150)

def action_next_theme(self) -> None:
themes = self.theme_names
index = themes.index(self.current_theme.name)
self.theme = themes[(index + 1) % len(themes)]
self.notify_new_theme(self.current_theme.name)

def action_previous_theme(self) -> None:
themes = self.theme_names
index = themes.index(self.current_theme.name)
self.theme = themes[(index - 1) % len(themes)]
self.notify_new_theme(self.current_theme.name)

def notify_new_theme(self, theme_name: str) -> None:
self.clear_notifications()
self.notify(f"Theme is {theme_name}")


if __name__ == "__main__":
ColorsApp().run()
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ Label {
width: 100%;
}

ThemeColorButtons {
dock: left;
overflow-y: auto;
width: 30;

Tabs {
margin: 1 2;
}

ThemeColorButtons > Button {
width: 100%;
#sidebar {
dock: left;
width: auto;
padding: 1 2;
border: panel $border;
}

ColorsView {
Expand Down Expand Up @@ -49,12 +51,12 @@ ColorGroup {
height: auto;
padding: 1 4 2 4;
background: $surface;
border: wide $surface;
border: wide $border-blurred;
}


ColorGroup.-active {
border: wide $secondary;
border: wide $border;
}

NamedColorsView {
Expand Down
4 changes: 0 additions & 4 deletions src/textual_dev/previews/easing.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ def on_load(self) -> None:
self.bind(
"ctrl+p", "focus('duration-input')", description="Focus: Duration Input"
)
self.bind("ctrl+b", "toggle_dark", description="Toggle Dark")

def compose(self) -> ComposeResult:
self.animated_bar = Bar()
Expand Down Expand Up @@ -112,9 +111,6 @@ def on_input_changed(self, event: Input.Changed) -> None:
if new_duration is not None:
self.duration = new_duration

def action_toggle_dark(self) -> None:
self.dark = not self.dark


def _try_float(string: str) -> float | None:
try:
Expand Down
Loading