mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
fix refresh
This commit is contained in:
@@ -11,10 +11,14 @@ App > DockView {
|
||||
height: 1fr;
|
||||
layer: panels;
|
||||
border-right: outer #09312e;
|
||||
offset-x: -50%;
|
||||
offset-x: -100%;
|
||||
transition: offset-x 1.2s in_cubic 200ms, offset-y 1s linear;
|
||||
}
|
||||
|
||||
#sidebar.-active {
|
||||
offset-x: 0;
|
||||
}
|
||||
|
||||
#header {
|
||||
text: on #173f5f;
|
||||
dock-group: header;
|
||||
|
||||
@@ -5,16 +5,17 @@ from textual.widget import Widget
|
||||
class BasicApp(App):
|
||||
"""A basic app demonstrating CSS"""
|
||||
|
||||
def on_mount(self) -> None:
|
||||
"""Build layout here."""
|
||||
def on_load(self):
|
||||
self.bind("t", "toggle('#sidebar', '-active')")
|
||||
|
||||
self.view.mount(
|
||||
def on_mount(self):
|
||||
"""Build layout here."""
|
||||
self.mount(
|
||||
header=Widget(),
|
||||
content=Widget(),
|
||||
footer=Widget(),
|
||||
sidebar=Widget(),
|
||||
)
|
||||
self.panic(self.query("#sidebar").first().styles)
|
||||
|
||||
|
||||
BasicApp.run(log="textual.log", css_file="basic.css")
|
||||
BasicApp.run(log="textual.log", css_file="basic.css", log_verbosity=3)
|
||||
|
||||
@@ -31,6 +31,7 @@ from .driver import Driver
|
||||
from .layouts.dock import DockLayout, Dock
|
||||
from ._linux_driver import LinuxDriver
|
||||
from ._types import MessageTarget
|
||||
from . import messages
|
||||
from .message_pump import MessagePump
|
||||
from ._profile import timer
|
||||
from .view import View
|
||||
@@ -66,8 +67,6 @@ class ActionError(Exception):
|
||||
class App(DOMNode):
|
||||
"""The base class for Textual Applications"""
|
||||
|
||||
KEYS: ClassVar[dict[str, str]] = {}
|
||||
|
||||
css = ""
|
||||
|
||||
def __init__(
|
||||
@@ -215,6 +214,10 @@ class App(DOMNode):
|
||||
|
||||
asyncio.run(run_app())
|
||||
|
||||
def mount(self, *anon_widgets: Widget, **widgets: Widget) -> None:
|
||||
self.register(self.view, *anon_widgets, **widgets)
|
||||
self.view.refresh()
|
||||
|
||||
async def push_view(self, view: ViewType) -> ViewType:
|
||||
self._view_stack.append(view)
|
||||
return view
|
||||
@@ -354,7 +357,9 @@ class App(DOMNode):
|
||||
return True
|
||||
return False
|
||||
|
||||
def mount(self, parent: DOMNode, *anon_widgets: Widget, **widgets: Widget) -> None:
|
||||
def register(
|
||||
self, parent: DOMNode, *anon_widgets: Widget, **widgets: Widget
|
||||
) -> None:
|
||||
"""Mount widget(s) so they may receive events.
|
||||
|
||||
Args:
|
||||
@@ -467,7 +472,7 @@ class App(DOMNode):
|
||||
# If the event has been forwarded it may have bubbled up back to the App
|
||||
if isinstance(event, events.Mount):
|
||||
view = DockView()
|
||||
self.mount(self, view)
|
||||
self.register(self, view)
|
||||
await self.push_view(view)
|
||||
await super().on_event(event)
|
||||
|
||||
@@ -567,6 +572,7 @@ class App(DOMNode):
|
||||
|
||||
async def action_toggle(self, selector: str, class_name: str) -> None:
|
||||
self.view.query(selector).toggle_class(class_name)
|
||||
self.view.refresh(layout=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -14,8 +14,8 @@ from .scalar import (
|
||||
ScalarOffset,
|
||||
ScalarParseError,
|
||||
)
|
||||
from ..geometry import Offset, Spacing, SpacingDimensions
|
||||
from .constants import NULL_SPACING, VALID_EDGE
|
||||
from ..geometry import Spacing, SpacingDimensions
|
||||
from .constants import NULL_SPACING
|
||||
from .errors import StyleTypeError, StyleValueError
|
||||
from .transition import Transition
|
||||
from ._error_tools import friendly_list
|
||||
|
||||
@@ -7,6 +7,7 @@ from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
from typing import Iterable
|
||||
|
||||
from .. import log
|
||||
from ..dom import DOMNode
|
||||
from .styles import Styles
|
||||
from .tokenize import Token
|
||||
|
||||
@@ -64,6 +64,5 @@ class DOMQuery:
|
||||
node.remove_class(*class_names)
|
||||
|
||||
def toggle_class(self, *class_names: str) -> None:
|
||||
|
||||
for node in self._nodes:
|
||||
node.remove_class(*class_names)
|
||||
node.toggle_class(*class_names)
|
||||
|
||||
@@ -55,6 +55,7 @@ class DockGroup(NamedTuple):
|
||||
@dataclass
|
||||
class Styles:
|
||||
|
||||
_changed: float = 0
|
||||
_rule_display: Display | None = None
|
||||
_rule_visibility: Visibility | None = None
|
||||
_rule_layout: str | None = None
|
||||
|
||||
@@ -122,10 +122,14 @@ class Stylesheet:
|
||||
rule_attributes[key].append((rule_specificity, value))
|
||||
|
||||
get_first_item = itemgetter(0)
|
||||
|
||||
log(rule_attributes.get("offset"))
|
||||
|
||||
node_rules = [
|
||||
(name, max(specificity_rules, key=get_first_item)[1])
|
||||
for name, specificity_rules in rule_attributes.items()
|
||||
]
|
||||
|
||||
node.styles.apply_rules(node_rules)
|
||||
|
||||
|
||||
|
||||
@@ -172,6 +172,8 @@ class DOMNode(MessagePump):
|
||||
def toggle_class(self, *class_names: str) -> None:
|
||||
"""Toggle class names"""
|
||||
self._classes.symmetric_difference_update(class_names)
|
||||
self.app.stylesheet.apply(self)
|
||||
self.log(self.styles.css)
|
||||
|
||||
def has_psuedo_class(self, *class_names: str) -> bool:
|
||||
"""Check for psuedo class (such as hover, focus etc)"""
|
||||
|
||||
@@ -29,6 +29,9 @@ if TYPE_CHECKING:
|
||||
ReactiveType = TypeVar("ReactiveType")
|
||||
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
class Reactive(Generic[ReactiveType]):
|
||||
"""Reactive descriptor."""
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ class View(Widget):
|
||||
self.app.refresh()
|
||||
|
||||
def mount(self, *anon_widgets: Widget, **widgets: Widget) -> None:
|
||||
self.app.mount(self, *anon_widgets, **widgets)
|
||||
self.app.register(self, *anon_widgets, **widgets)
|
||||
self.refresh()
|
||||
|
||||
async def refresh_layout(self) -> None:
|
||||
@@ -170,7 +170,7 @@ class View(Widget):
|
||||
widget.post_message_no_wait(
|
||||
events.Resize(self, unclipped_region.size)
|
||||
)
|
||||
except:
|
||||
except Exception:
|
||||
self.app.panic()
|
||||
|
||||
async def on_resize(self, event: events.Resize) -> None:
|
||||
|
||||
@@ -285,15 +285,18 @@ class Widget(DOMNode):
|
||||
self.refresh()
|
||||
|
||||
async def on_idle(self, event: events.Idle) -> None:
|
||||
self.log("Widget.on_idle")
|
||||
if self.check_layout():
|
||||
self.log("layout required")
|
||||
self.render_cache = None
|
||||
self.reset_check_repaint()
|
||||
self.reset_check_layout()
|
||||
await self.emit(Layout(self))
|
||||
await self.post_message(Layout(self))
|
||||
elif self.check_repaint():
|
||||
self.log("repaint required")
|
||||
self.render_cache = None
|
||||
self.reset_check_repaint()
|
||||
await self.emit(Update(self, self))
|
||||
await self.post_message(Update(self, self))
|
||||
|
||||
async def focus(self) -> None:
|
||||
await self.app.set_focus(self)
|
||||
|
||||
Reference in New Issue
Block a user