Skip to content

Commit

Permalink
Merge pull request #39 from Textualize/colors-and-borders-demo-updates
Browse files Browse the repository at this point in the history
Fixes and updates in demo apps for new themes
  • Loading branch information
darrenburns authored Nov 18, 2024
2 parents e654d8c + a50de8e commit 6485ab6
Show file tree
Hide file tree
Showing 6 changed files with 751 additions and 562 deletions.
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

0 comments on commit 6485ab6

Please sign in to comment.