Skip to content

Commit

Permalink
event verbosity
Browse files Browse the repository at this point in the history
  • Loading branch information
willmcgugan committed Aug 2, 2021
1 parent 79e4a60 commit 3e7eb0e
Show file tree
Hide file tree
Showing 13 changed files with 52 additions and 102 deletions.
2 changes: 1 addition & 1 deletion examples/grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ async def on_mount(self, event: events.Mount) -> None:
area3=Placeholder(name="area3"),
area4=Placeholder(name="area4"),
)
await self.view.update_layout()
self.view.refresh(layout=True)


GridTest.run(title="Grid Test", log="textual.log")
3 changes: 2 additions & 1 deletion src/textual/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ async def process_messages(self) -> None:
active_app.set(self)
driver = self._driver = self.driver_class(self.console, self)

log("---")
log(f"driver={self.driver_class}")

await self.dispatch_message(events.Load(sender=self))
Expand Down Expand Up @@ -332,7 +333,7 @@ async def shutdown(self):
driver.disable_input()
await self.close_messages()

def refresh(self) -> None:
def refresh(self, repaint: bool = True, layout: bool = False) -> None:
sync_available = os.environ.get("TERM_PROGRAM", "") != "Apple_Terminal"
if not self._closed:
console = self.console
Expand Down
8 changes: 4 additions & 4 deletions src/textual/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ def __init_subclass__(cls, bubble: bool = False, verbosity: int = 1) -> None:
super().__init_subclass__(bubble=bubble, verbosity=verbosity)


class Null(Event):
class Null(Event, verbosity=3):
def can_replace(self, message: Message) -> bool:
return isinstance(message, Null)


@rich.repr.auto
class Callback(Event, bubble=False):
class Callback(Event, bubble=False, verbosity=3):
def __init__(
self, sender: MessageTarget, callback: Callable[[], Awaitable[None]]
) -> None:
Expand Down Expand Up @@ -88,7 +88,7 @@ def __rich_repr__(self) -> rich.repr.RichReprResult:
yield "action", self.action


class Resize(Event):
class Resize(Event, verbosity=2):
"""Sent when the app or widget has been resized."""

__slots__ = ["size"]
Expand Down Expand Up @@ -360,7 +360,7 @@ class DoubleClick(MouseEvent):


@rich.repr.auto
class Timer(Event):
class Timer(Event, verbosity=3):
__slots__ = ["time", "count", "callback"]

def __init__(
Expand Down
14 changes: 1 addition & 13 deletions src/textual/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,6 @@ def __rich_console__(

def update_widget(self, console: Console, widget: Widget) -> LayoutUpdate | None:

log("UPDATE", widget)
if widget not in self.regions:
return None

Expand All @@ -430,18 +429,7 @@ def update_widget(self, console: Console, widget: Widget) -> LayoutUpdate | None
if not region.size:
return None

widget._clear_render_cache()
# if not region or not clip:
# return

# widget._clear_render_cache()
# widget.render_lines()

# new_lines = console.render_lines(
# widget, console.options.update_dimensions(region.width, region.height)
# )

# self.regions[widget] = (region, clip, new_lines)
widget.clear_render_cache()

update_region = region.intersection(clip)
update_lines = self.render(console, update_region).lines
Expand Down
4 changes: 2 additions & 2 deletions src/textual/layout_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def add_widget(
sub_map = widget.layout.generate_map(
console, region.size, clip, widget.scroll
)
for widget, (sub_region, sub_order, sub_clip) in sub_map.items():
for sub_widget, (sub_region, sub_order, sub_clip) in sub_map.items():
sub_region += region.origin
sub_clip = sub_clip.intersection(clip)
self.add_widget(console, widget, sub_region, sub_order, sub_clip)
self.add_widget(console, sub_widget, sub_region, sub_order, sub_clip)
14 changes: 13 additions & 1 deletion src/textual/message_pump.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import asyncio
from asyncio import CancelledError
from asyncio import Queue, QueueEmpty, Task
import inspect
from typing import TYPE_CHECKING, Awaitable, Iterable, Callable
from weakref import WeakSet

Expand All @@ -24,6 +25,10 @@ class NoParent(Exception):
pass


class CallbackError(Exception):
pass


class MessagePumpClosed(Exception):
pass

Expand Down Expand Up @@ -301,4 +306,11 @@ async def on_timer(self, event: events.Timer) -> None:
event.prevent_default()
event.stop()
if event.callback is not None:
await event.callback()
try:
callback_result = event.callback()
if inspect.isawaitable(callback_result):
await callback_result
except Exception as error:
raise CallbackError(
f"unable to run callback {event.callback!r}; {error}"
)
4 changes: 2 additions & 2 deletions src/textual/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@


@rich.repr.auto
class UpdateMessage(Message):
class UpdateMessage(Message, verbosity=3):
def __init__(
self,
sender: MessagePump,
Expand All @@ -30,6 +30,6 @@ def can_replace(self, message: Message) -> bool:


@rich.repr.auto
class LayoutMessage(Message):
class LayoutMessage(Message, verbosity=3):
def can_replace(self, message: Message) -> bool:
return isinstance(message, LayoutMessage)
4 changes: 2 additions & 2 deletions src/textual/reactive.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ def __set__(self, obj: Reactable, value: ReactiveType) -> None:
self.check_watchers(obj, name, current_value)

if self.layout:
obj.require_layout()
obj.refresh(layout=True)
elif self.repaint:
obj.require_repaint()
obj.refresh()

@classmethod
def check_watchers(cls, obj: Reactable, name: str, old_value: Any) -> None:
Expand Down
44 changes: 3 additions & 41 deletions src/textual/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,40 +57,6 @@ def scroll(self) -> Offset:

virtual_size: Reactive[Size] = Reactive(Size(0, 0))

# @property
# def virtual_size(self) -> Dimensions:
# return self.layout.map.size if self.layout.map else Dimensions(0, 0)

# virtual_width: Reactive[int | None] = Reactive(None)
# virtual_height: Reactive[int | None] = Reactive(None)

# @property
# def virtual_size(self) -> Dimensions:
# virtual_width = self.virtual_width
# virtual_height = self.virtual_height
# return Dimensions(
# (virtual_width if virtual_width is not None else self.size.width),
# (virtual_height if virtual_height is not None else self.size.height),
# )

# @virtual_size.setter
# def virtual_size(self, size: tuple[int, int]) -> None:
# width, height = size
# self.virtual_width = width
# self.virtual_height = height

# @property
# def offset(self) -> Point:
# return Point(self.offset_x, self.offset_y)

# @property
# def viewport(self) -> Region:
# virtual_width = self.virtual_width
# virtual_height = self.virtual_height
# width = virtual_width if virtual_width is not None else self.size.width
# height = virtual_height if virtual_height is not None else self.size.height
# return Region(self.offset_x, self.offset_y, width, height)

def __rich_console__(
self, console: Console, options: ConsoleOptions
) -> RenderResult:
Expand All @@ -109,7 +75,7 @@ def is_visual(self) -> bool:

@property
def is_root_view(self) -> bool:
return self._parent and self.parent is self.app
return bool(self._parent and self.parent is self.app)

def is_mounted(self, widget: Widget) -> bool:
return widget in self.widgets
Expand Down Expand Up @@ -159,16 +125,12 @@ async def refresh_layout(self) -> None:
return

width, height = self.console.size
# virtual_width, virtual_height = self.virtual_size
hidden, shown, resized = self.layout.reflow(
self.console, width, height, self.scroll
)
assert self.layout.map is not None
self.virtual_size = self.layout.map.virtual_size
# for widget, region in self.layout:
# widget._update_size(region.size)

# self.app.refresh()
# self.virtual_size = self.layout.map.virtual_size
self.log("VIRTUAL_SIZE", self, type(self.layout), self.virtual_size)

for widget in hidden:
widget.post_message_no_wait(events.Hide(self))
Expand Down
7 changes: 4 additions & 3 deletions src/textual/views/_window_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ async def update(self, widget: Widget | RenderableType) -> None:
await self.emit(VirtualSizeChange(self))

async def watch_virtual_size(self, size: Size) -> None:
self.log("VIRTUAL SIZE CHAGE")
await self.emit(VirtualSizeChange(self))

async def on_resize(self, event: events.Resize) -> None:
# self.layout.renders.pop(self.widget)
self.require_repaint()
# async def on_resize(self, event: events.Resize) -> None:
# # self.layout.renders.pop(self.widget)
# self.require_repaint()
45 changes: 17 additions & 28 deletions src/textual/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,6 @@ def layout_offset(self) -> tuple[int, int]:

def _update_size(self, size: Size) -> None:
self._size = size
# if self._render_cache and self._render_cache.size != size:
# self.render_lines()
# self.require_repaint()
# self.size = size

def render_lines(self) -> RenderCache:
width, height = self.size
Expand Down Expand Up @@ -161,7 +157,7 @@ def _get_lines(self) -> Lines:
lines = self.render_cache.lines
return lines

def _clear_render_cache(self) -> None:
def clear_render_cache(self) -> None:
self.render_cache = None

def require_repaint(self) -> None:
Expand Down Expand Up @@ -199,17 +195,22 @@ async def call_later(self, callback: Callable, *args, **kwargs) -> None:
async def forward_event(self, event: events.Event) -> None:
await self.post_message(event)

async def refresh(self) -> None:
"""Re-render the window and repaint it."""
self.require_repaint()
await self.repaint()
def refresh(self, repaint: bool = True, layout: bool = False) -> None:
"""Initiate a refresh of the widget.
async def repaint(self) -> None:
"""Instructs parent to repaint this widget."""
await self.emit(UpdateMessage(self, self))
This method sets an internal flag to perform a refresh, which will be done on the
next idle event. Only one refresh will be done even if this method is called multiple times.
async def update_layout(self) -> None:
await self.emit(LayoutMessage(self))
Args:
repaint (bool, optional): Repaint the widget (will call render() again). Defaults to True.
layout (bool, optional): Also layout widgets in the view. Defaults to False.
"""
if layout:
self._layout_required = True
elif repaint:
self.clear_render_cache()
self._repaint_required = True
self.post_message_no_wait(events.Null(self))

def render(self) -> RenderableType:
"""Get renderable for widget.
Expand All @@ -231,25 +232,17 @@ async def post_message(self, message: Message) -> bool:
self.log(self, "IS NOT RUNNING")
return await super().post_message(message)

# async def on_event(self, event: events.Event) -> None:
# if isinstance(event, events.Resize):
# if self.size != event.size:
# # self.size = event.size
# self.require_repaint()
# await super().on_event(event)

async def on_resize(self, event: events.Resize) -> None:
self.log("RESIZE", self)
self.render_lines()

async def on_idle(self, event: events.Idle) -> None:
if self.check_layout():
self.reset_check_repaint()
self.reset_check_layout()
await self.update_layout()
await self.emit(LayoutMessage(self))
elif self.check_repaint():
self.reset_check_repaint()
await self.repaint()
await self.emit(UpdateMessage(self, self))

async def focus(self) -> None:
await self.app.set_focus(self)
Expand All @@ -276,10 +269,6 @@ async def dispatch_key(self, event: events.Key) -> None:
if key_method is not None:
await key_method()

# async def on_repaint(self) -> None:
# if self._render_cache is None or self._render_cache.size != self.size:
# self._render_cache = self.render_lines()

async def on_mouse_down(self, event: events.MouseUp) -> None:
await self.broker_event("mouse.down", event)

Expand Down
3 changes: 0 additions & 3 deletions src/textual/widgets/_scroll_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,12 +185,9 @@ async def message_scroll_to(self, message: ScrollTo) -> None:
self.animate("y", self.target_y, speed=150, easing="out_cubic")

async def message_virtual_size_change(self, message: Message) -> None:

virtual_size = self.window.virtual_size
self.log("VIRTUAL_SIZE", self.size, virtual_size)
self.x = self.validate_x(self.x)
self.y = self.validate_y(self.y)
self.log(self.y)
self.vscroll.virtual_size = virtual_size.height
self.vscroll.window_size = self.size.height

Expand Down
2 changes: 1 addition & 1 deletion src/textual/widgets/_static.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def __init__(
self.padding = padding

def render(self) -> RenderableType:
self.log("RENDERING", self.renderable)
# self.log("RENDERING", self.renderable)
renderable = self.renderable
if self.padding:
renderable = Padding(renderable, self.padding)
Expand Down

0 comments on commit 3e7eb0e

Please sign in to comment.