mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
Further removal of App.dark from various places, swapping in App.theme equivalents
This commit is contained in:
@@ -327,7 +327,7 @@ The `background: green` is only applied to the Button underneath the mouse curso
|
||||
Here are some other pseudo classes:
|
||||
|
||||
- `:blur` Matches widgets which *do not* have input focus.
|
||||
- `:dark` Matches widgets in dark mode (where `App.dark == True`).
|
||||
- `:dark` Matches widgets in dark themes (where `App.theme.dark == True`).
|
||||
- `:disabled` Matches widgets which are in a disabled state.
|
||||
- `:enabled` Matches widgets which are in an enabled state.
|
||||
- `:even` Matches a widget at an evenly numbered position within its siblings.
|
||||
@@ -336,7 +336,7 @@ Here are some other pseudo classes:
|
||||
- `:focus` Matches widgets which have input focus.
|
||||
- `:inline` Matches widgets when the app is running in inline mode.
|
||||
- `:last-of-type` Matches a widget that is the last of its type amongst its siblings.
|
||||
- `:light` Matches widgets in dark mode (where `App.dark == False`).
|
||||
- `:light` Matches widgets in light themes (where `App.theme.dark == False`).
|
||||
- `:odd` Matches a widget at an oddly numbered position within its siblings.
|
||||
|
||||
## Combinators
|
||||
|
||||
@@ -248,7 +248,7 @@ class ChangingThemeApp(App[None]):
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
with Grid(id="palette"):
|
||||
theme = self.get_theme(self.theme)
|
||||
theme = self.current_theme
|
||||
for variable, value in vars(theme).items():
|
||||
if variable not in {
|
||||
"name",
|
||||
|
||||
@@ -90,8 +90,7 @@ class TextAreaTheme:
|
||||
if self.base_style.color is None:
|
||||
self.base_style = Style(color="#f3f3f3", bgcolor=self.base_style.bgcolor)
|
||||
|
||||
app = text_area.app
|
||||
app_theme = app.get_theme(app.theme)
|
||||
app_theme = text_area.app.current_theme
|
||||
|
||||
if self.base_style.bgcolor is None:
|
||||
self.base_style = Style(
|
||||
|
||||
@@ -558,7 +558,9 @@ class App(Generic[ReturnType], DOMNode):
|
||||
|
||||
This excludes the built-in themes."""
|
||||
|
||||
ansi_theme = self.ansi_theme_dark if self.dark else self.ansi_theme_light
|
||||
ansi_theme = (
|
||||
self.ansi_theme_dark if self.current_theme.dark else self.ansi_theme_light
|
||||
)
|
||||
self.set_reactive(App.ansi_color, ansi_color)
|
||||
self._filters: list[LineFilter] = [
|
||||
ANSIToTruecolor(ansi_theme, enabled=not ansi_color)
|
||||
@@ -764,8 +766,8 @@ class App(Generic[ReturnType], DOMNode):
|
||||
perform work after the app has resumed.
|
||||
"""
|
||||
|
||||
self.set_class(self.dark, "-dark-mode")
|
||||
self.set_class(not self.dark, "-light-mode")
|
||||
self.set_class(self.current_theme.dark, "-dark-mode")
|
||||
self.set_class(not self.current_theme.dark, "-light-mode")
|
||||
|
||||
self.animation_level: AnimationLevel = constants.TEXTUAL_ANIMATIONS
|
||||
"""Determines what type of animations the app will display.
|
||||
@@ -1183,11 +1185,7 @@ class App(Generic[ReturnType], DOMNode):
|
||||
Returns:
|
||||
A mapping of variable name to value.
|
||||
"""
|
||||
theme = self.get_theme(self.theme)
|
||||
if theme is None:
|
||||
# This should never happen thanks to the `App.theme` validator.
|
||||
return {}
|
||||
|
||||
theme = self.current_theme
|
||||
# Build the Textual color system from the theme.
|
||||
# This will contain $secondary, $primary, $background, etc.
|
||||
variables = theme.to_color_system().generate()
|
||||
@@ -1265,28 +1263,13 @@ class App(Generic[ReturnType], DOMNode):
|
||||
self.call_next(self.refresh_css)
|
||||
self.call_next(self.theme_changed_signal.publish, theme)
|
||||
|
||||
def watch_dark(self, dark: bool) -> None:
|
||||
"""Watches the dark bool.
|
||||
|
||||
This method handles the transition between light and dark mode when you
|
||||
change the [dark][textual.app.App.dark] attribute.
|
||||
"""
|
||||
self.set_class(dark, "-dark-mode", update=False)
|
||||
self.set_class(not dark, "-light-mode", update=False)
|
||||
self._refresh_truecolor_filter(self.ansi_theme)
|
||||
self.call_next(self.refresh_css)
|
||||
|
||||
def watch_ansi_theme_dark(self, theme: TerminalTheme) -> None:
|
||||
app_theme = self.get_theme(self.theme)
|
||||
assert app_theme is not None # validated by _validate_theme
|
||||
if app_theme.dark:
|
||||
if self.current_theme.dark:
|
||||
self._refresh_truecolor_filter(theme)
|
||||
self.call_next(self.refresh_css)
|
||||
|
||||
def watch_ansi_theme_light(self, theme: TerminalTheme) -> None:
|
||||
app_theme = self.get_theme(self.theme)
|
||||
assert app_theme is not None # validated by _validate_theme
|
||||
if not app_theme.dark:
|
||||
if not self.current_theme.dark:
|
||||
self._refresh_truecolor_filter(theme)
|
||||
self.call_next(self.refresh_css)
|
||||
|
||||
@@ -1297,9 +1280,9 @@ class App(Generic[ReturnType], DOMNode):
|
||||
Defines how colors defined as ANSI (e.g. `magenta`) inside Rich renderables
|
||||
are mapped to hex codes.
|
||||
"""
|
||||
app_theme = self.get_theme(self.theme)
|
||||
assert app_theme is not None # validated by _validate_theme
|
||||
return self.ansi_theme_dark if app_theme.dark else self.ansi_theme_light
|
||||
return (
|
||||
self.ansi_theme_dark if self.current_theme.dark else self.ansi_theme_light
|
||||
)
|
||||
|
||||
def _refresh_truecolor_filter(self, theme: TerminalTheme) -> None:
|
||||
"""Update the ANSI to Truecolor filter, if available, with a new theme mapping.
|
||||
|
||||
@@ -237,7 +237,7 @@ class DOMNode(MessagePump):
|
||||
|
||||
Example:
|
||||
```python
|
||||
self.set_reactive(App.dark_mode, True)
|
||||
self.set_reactive(App.theme, "textual-light")
|
||||
```
|
||||
|
||||
Args:
|
||||
@@ -247,15 +247,14 @@ class DOMNode(MessagePump):
|
||||
Raises:
|
||||
AttributeError: If the first argument is not a reactive.
|
||||
"""
|
||||
name = reactive.name
|
||||
if not isinstance(reactive, Reactive):
|
||||
raise TypeError(
|
||||
"A Reactive class is required; for example: MyApp.dark_mode"
|
||||
)
|
||||
if reactive.name not in self._reactives:
|
||||
raise TypeError("A Reactive class is required; for example: MyApp.theme")
|
||||
if name not in self._reactives:
|
||||
raise AttributeError(
|
||||
"No reactive called {name!r}; Have you called super().__init__(...) in the {self.__class__.__name__} constructor?"
|
||||
f"No reactive called {name!r}; Have you called super().__init__(...) in the {self.__class__.__name__} constructor?"
|
||||
)
|
||||
setattr(self, f"_reactive_{reactive.name}", value)
|
||||
setattr(self, f"_reactive_{name}", value)
|
||||
|
||||
def mutate_reactive(self, reactive: Reactive[ReactiveType]) -> None:
|
||||
"""Force an update to a mutable reactive.
|
||||
@@ -1218,11 +1217,11 @@ class DOMNode(MessagePump):
|
||||
|
||||
Example:
|
||||
```python
|
||||
def on_dark_change(old_value:bool, new_value:bool) -> None:
|
||||
# Called when app.dark changes.
|
||||
print("App.dark went from {old_value} to {new_value}")
|
||||
def on_theme_change(old_value:str, new_value:str) -> None:
|
||||
# Called when app.theme changes.
|
||||
print(f"App.theme went from {old_value} to {new_value}")
|
||||
|
||||
self.watch(self.app, "dark", self.on_dark_change, init=False)
|
||||
self.watch(self.app, "theme", self.on_theme_change, init=False)
|
||||
```
|
||||
|
||||
Args:
|
||||
|
||||
@@ -375,8 +375,8 @@ class Widget(DOMNode):
|
||||
"can-focus": lambda widget: widget.can_focus,
|
||||
"disabled": lambda widget: widget.is_disabled,
|
||||
"enabled": lambda widget: not widget.is_disabled,
|
||||
"dark": lambda widget: widget.app.dark,
|
||||
"light": lambda widget: not widget.app.dark,
|
||||
"dark": lambda widget: widget.app.current_theme.dark,
|
||||
"light": lambda widget: not widget.app.current_theme.dark,
|
||||
"focus-within": lambda widget: widget.has_focus_within,
|
||||
"inline": lambda widget: widget.app.is_inline,
|
||||
"ansi": lambda widget: widget.app.ansi_color,
|
||||
|
||||
@@ -619,10 +619,9 @@ class MarkdownFence(MarkdownBlock):
|
||||
super().__init__(markdown)
|
||||
self.code = code
|
||||
self.lexer = lexer
|
||||
app_theme = self.app.get_theme(self.app.theme)
|
||||
self.theme = (
|
||||
self._markdown.code_dark_theme
|
||||
if app_theme.dark
|
||||
if self.app.current_theme.dark
|
||||
else self._markdown.code_light_theme
|
||||
)
|
||||
|
||||
@@ -642,10 +641,9 @@ class MarkdownFence(MarkdownBlock):
|
||||
|
||||
def _retheme(self) -> None:
|
||||
"""Rerender when the theme changes."""
|
||||
app_theme = self.app.get_theme(self.app.theme)
|
||||
self.theme = (
|
||||
self._markdown.code_dark_theme
|
||||
if app_theme.dark
|
||||
if self.app.current_theme.dark
|
||||
else self._markdown.code_light_theme
|
||||
)
|
||||
self.get_child_by_type(Static).update(self._block())
|
||||
@@ -807,13 +805,13 @@ class Markdown(Widget):
|
||||
|
||||
def _watch_code_dark_theme(self) -> None:
|
||||
"""React to the dark theme being changed."""
|
||||
if self.app.dark:
|
||||
if self.app.current_theme.dark:
|
||||
for block in self.query(MarkdownFence):
|
||||
block._retheme()
|
||||
|
||||
def _watch_code_light_theme(self) -> None:
|
||||
"""React to the light theme being changed."""
|
||||
if not self.app.dark:
|
||||
if not self.app.current_theme.dark:
|
||||
for block in self.query(MarkdownFence):
|
||||
block._retheme()
|
||||
|
||||
|
||||
@@ -745,7 +745,7 @@ TextArea {
|
||||
if padding is applied, the colors match."""
|
||||
self._set_theme(theme)
|
||||
|
||||
def _app_dark_toggled(self) -> None:
|
||||
def _app_theme_changed(self) -> None:
|
||||
self._set_theme(self._theme.name)
|
||||
|
||||
def _set_theme(self, theme: str) -> None:
|
||||
@@ -1521,8 +1521,8 @@ TextArea {
|
||||
return gutter_width
|
||||
|
||||
def _on_mount(self, event: events.Mount) -> None:
|
||||
# When `app.dark` is toggled, reset the theme (since it caches values).
|
||||
self.watch(self.app, "dark", self._app_dark_toggled, init=False)
|
||||
# When `app.theme` reactive is changed, reset the theme to clear cached styles.
|
||||
self.watch(self.app, "theme", self._app_theme_changed, init=False)
|
||||
|
||||
self.blink_timer = self.set_interval(
|
||||
0.5,
|
||||
|
||||
Reference in New Issue
Block a user