mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
version bump
This commit is contained in:
@@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
## [0.1.10] - Unreleased
|
## [0.1.10] - 2021-08-25
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ class Colorizer(App):
|
|||||||
await self.bind("g", "color('green')")
|
await self.bind("g", "color('green')")
|
||||||
await self.bind("b", "color('blue')")
|
await self.bind("b", "color('blue')")
|
||||||
|
|
||||||
async def action_color(self, color: str) -> None:
|
def action_color(self, color: str) -> None:
|
||||||
self.background = f"on {color}"
|
self.background = f"on {color}"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class MyApp(App):
|
|||||||
|
|
||||||
# Note the directory is also in a scroll view
|
# Note the directory is also in a scroll view
|
||||||
await self.view.dock(
|
await self.view.dock(
|
||||||
ScrollView(self.directory), edge="left", size=64, name="sidebar"
|
ScrollView(self.directory), edge="left", size=48, name="sidebar"
|
||||||
)
|
)
|
||||||
await self.view.dock(self.body, edge="top")
|
await self.view.dock(self.body, edge="top")
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class Bindings:
|
|||||||
description,
|
description,
|
||||||
show=show,
|
show=show,
|
||||||
key_display=key_display,
|
key_display=key_display,
|
||||||
allow_forward=True,
|
allow_forward=allow_forward,
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_key(self, key: str) -> Binding:
|
def get_key(self, key: str) -> Binding:
|
||||||
|
|||||||
@@ -189,7 +189,6 @@ class Region(NamedTuple):
|
|||||||
Returns:
|
Returns:
|
||||||
tuple[int, int]: [description]
|
tuple[int, int]: [description]
|
||||||
"""
|
"""
|
||||||
return (self.x, self.x + self.width)
|
|
||||||
return (self.y, self.y + self.height)
|
return (self.y, self.y + self.height)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
@@ -3,12 +3,9 @@ from __future__ import annotations
|
|||||||
import asyncio
|
import asyncio
|
||||||
from asyncio import CancelledError
|
from asyncio import CancelledError
|
||||||
from asyncio import Queue, QueueEmpty, Task
|
from asyncio import Queue, QueueEmpty, Task
|
||||||
import inspect
|
|
||||||
from typing import TYPE_CHECKING, Awaitable, Iterable, Callable
|
from typing import TYPE_CHECKING, Awaitable, Iterable, Callable
|
||||||
from weakref import WeakSet
|
from weakref import WeakSet
|
||||||
|
|
||||||
from rich.traceback import Traceback
|
|
||||||
|
|
||||||
from . import events
|
from . import events
|
||||||
from . import log
|
from . import log
|
||||||
from ._timer import Timer, TimerCallback
|
from ._timer import Timer, TimerCallback
|
||||||
@@ -174,7 +171,7 @@ class MessagePump:
|
|||||||
except CancelledError:
|
except CancelledError:
|
||||||
pass
|
pass
|
||||||
finally:
|
finally:
|
||||||
self._runnning = False
|
self._running = False
|
||||||
|
|
||||||
async def _process_messages(self) -> None:
|
async def _process_messages(self) -> None:
|
||||||
"""Process messages until the queue is closed."""
|
"""Process messages until the queue is closed."""
|
||||||
@@ -195,6 +192,7 @@ class MessagePump:
|
|||||||
pending = self.peek_message()
|
pending = self.peek_message()
|
||||||
if pending is None or not message.can_replace(pending):
|
if pending is None or not message.can_replace(pending):
|
||||||
break
|
break
|
||||||
|
# self.log(message, "replaced with", pending)
|
||||||
try:
|
try:
|
||||||
message = await self.get_message()
|
message = await self.get_message()
|
||||||
except MessagePumpClosed:
|
except MessagePumpClosed:
|
||||||
|
|||||||
@@ -34,9 +34,7 @@ class UpdateMessage(Message, verbosity=3):
|
|||||||
@rich.repr.auto
|
@rich.repr.auto
|
||||||
class LayoutMessage(Message, verbosity=3):
|
class LayoutMessage(Message, verbosity=3):
|
||||||
def can_replace(self, message: Message) -> bool:
|
def can_replace(self, message: Message) -> bool:
|
||||||
return isinstance(
|
return isinstance(message, LayoutMessage)
|
||||||
message, LayoutMessage
|
|
||||||
) # or isinstance(message, UpdateMessage)
|
|
||||||
|
|
||||||
|
|
||||||
@rich.repr.auto
|
@rich.repr.auto
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ from ..widgets import Static
|
|||||||
|
|
||||||
|
|
||||||
class WindowChange(Message):
|
class WindowChange(Message):
|
||||||
pass
|
def can_replace(self, message: Message) -> bool:
|
||||||
|
return isinstance(message, WindowChange)
|
||||||
|
|
||||||
|
|
||||||
class WindowView(View, layout=VerticalLayout):
|
class WindowView(View, layout=VerticalLayout):
|
||||||
@@ -39,6 +40,10 @@ class WindowView(View, layout=VerticalLayout):
|
|||||||
self.refresh(layout=True)
|
self.refresh(layout=True)
|
||||||
await self.emit(WindowChange(self))
|
await self.emit(WindowChange(self))
|
||||||
|
|
||||||
|
async def message_update(self, message: UpdateMessage) -> None:
|
||||||
|
message.prevent_default()
|
||||||
|
await self.emit(WindowChange(self))
|
||||||
|
|
||||||
async def watch_virtual_size(self, size: Size) -> None:
|
async def watch_virtual_size(self, size: Size) -> None:
|
||||||
await self.emit(WindowChange(self))
|
await self.emit(WindowChange(self))
|
||||||
|
|
||||||
|
|||||||
@@ -206,17 +206,10 @@ class Widget(MessagePump):
|
|||||||
self.render_cache = RenderCache(Size(width, len(lines)), lines)
|
self.render_cache = RenderCache(Size(width, len(lines)), lines)
|
||||||
|
|
||||||
def _get_lines(self) -> Lines:
|
def _get_lines(self) -> Lines:
|
||||||
"""Get render lines for given dimensions.
|
"""Get segment lines to render the widget."""
|
||||||
|
|
||||||
Args:
|
|
||||||
width (int): [description]
|
|
||||||
height (int): [description]
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Lines: [description]
|
|
||||||
"""
|
|
||||||
if self.render_cache is None:
|
if self.render_cache is None:
|
||||||
self.render_lines()
|
self.render_lines()
|
||||||
|
assert self.render_cache is not None
|
||||||
lines = self.render_cache.lines
|
lines = self.render_cache.lines
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ class TreeNode(Generic[NodeDataType]):
|
|||||||
data: NodeDataType,
|
data: NodeDataType,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self._node_id = node_id
|
self.id = node_id
|
||||||
self._control = control
|
self._control = control
|
||||||
self._tree = tree
|
self._tree = tree
|
||||||
self.label = label
|
self.label = label
|
||||||
@@ -46,10 +46,6 @@ class TreeNode(Generic[NodeDataType]):
|
|||||||
self._tree.expanded = False
|
self._tree.expanded = False
|
||||||
self.children: list[TreeNode] = []
|
self.children: list[TreeNode] = []
|
||||||
|
|
||||||
@property
|
|
||||||
def id(self) -> NodeID:
|
|
||||||
return self._node_id
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def control(self) -> TreeControl:
|
def control(self) -> TreeControl:
|
||||||
return self._control
|
return self._control
|
||||||
@@ -150,8 +146,8 @@ class TreeNode(Generic[NodeDataType]):
|
|||||||
await self.expand(not self._expanded)
|
await self.expand(not self._expanded)
|
||||||
|
|
||||||
async def add(self, label: TextType, data: NodeDataType) -> None:
|
async def add(self, label: TextType, data: NodeDataType) -> None:
|
||||||
await self._control.add(self._node_id, label, data=data)
|
await self._control.add(self.id, label, data=data)
|
||||||
self._control.refresh()
|
self._control.refresh(layout=True)
|
||||||
self._empty = False
|
self._empty = False
|
||||||
|
|
||||||
def __rich__(self) -> RenderableType:
|
def __rich__(self) -> RenderableType:
|
||||||
@@ -175,29 +171,29 @@ class TreeControl(Generic[NodeDataType], Widget):
|
|||||||
) -> None:
|
) -> None:
|
||||||
self.data = data
|
self.data = data
|
||||||
|
|
||||||
self._node_id = NodeID(0)
|
self.id = NodeID(0)
|
||||||
self.nodes: dict[NodeID, TreeNode[NodeDataType]] = {}
|
self.nodes: dict[NodeID, TreeNode[NodeDataType]] = {}
|
||||||
self._tree = Tree(label)
|
self._tree = Tree(label)
|
||||||
self.root: TreeNode[NodeDataType] = TreeNode(
|
self.root: TreeNode[NodeDataType] = TreeNode(
|
||||||
None, self._node_id, self, self._tree, label, data
|
None, self.id, self, self._tree, label, data
|
||||||
)
|
)
|
||||||
|
|
||||||
self._tree.label = self.root
|
self._tree.label = self.root
|
||||||
self.nodes[NodeID(self._node_id)] = self.root
|
self.nodes[NodeID(self.id)] = self.root
|
||||||
super().__init__(name=name)
|
super().__init__(name=name)
|
||||||
self.padding = padding
|
self.padding = padding
|
||||||
|
|
||||||
hover_node: Reactive[NodeID | None] = Reactive(None)
|
hover_node: Reactive[NodeID | None] = Reactive(None)
|
||||||
cursor: Reactive[NodeID] = Reactive(NodeID(0))
|
cursor: Reactive[NodeID] = Reactive(NodeID(0), layout=True)
|
||||||
cursor_line: Reactive[int] = Reactive(0, repaint=False)
|
cursor_line: Reactive[int] = Reactive(0, repaint=False)
|
||||||
show_cursor: Reactive[bool] = Reactive(False)
|
show_cursor: Reactive[bool] = Reactive(False, layout=True)
|
||||||
|
|
||||||
def watch_show_cursor(self, value: bool) -> None:
|
def watch_show_cursor(self, value: bool) -> None:
|
||||||
self.emit_no_wait(CursorMoveMessage(self, self.cursor_line))
|
self.emit_no_wait(CursorMoveMessage(self, self.cursor_line))
|
||||||
|
|
||||||
async def watch_cursor_line(self, value: int) -> None:
|
def watch_cursor_line(self, value: int) -> None:
|
||||||
if self.show_cursor:
|
if self.show_cursor:
|
||||||
await self.emit(CursorMoveMessage(self, value + self.gutter.top))
|
self.emit_no_wait(CursorMoveMessage(self, value + self.gutter.top))
|
||||||
|
|
||||||
async def add(
|
async def add(
|
||||||
self,
|
self,
|
||||||
@@ -206,14 +202,14 @@ class TreeControl(Generic[NodeDataType], Widget):
|
|||||||
data: NodeDataType,
|
data: NodeDataType,
|
||||||
) -> None:
|
) -> None:
|
||||||
parent = self.nodes[node_id]
|
parent = self.nodes[node_id]
|
||||||
self._node_id = NodeID(self._node_id + 1)
|
self.id = NodeID(self.id + 1)
|
||||||
child_tree = parent._tree.add(label)
|
child_tree = parent._tree.add(label)
|
||||||
child_node: TreeNode[NodeDataType] = TreeNode(
|
child_node: TreeNode[NodeDataType] = TreeNode(
|
||||||
parent, self._node_id, self, child_tree, label, data
|
parent, self.id, self, child_tree, label, data
|
||||||
)
|
)
|
||||||
parent.children.append(child_node)
|
parent.children.append(child_node)
|
||||||
child_tree.label = child_node
|
child_tree.label = child_node
|
||||||
self.nodes[self._node_id] = child_node
|
self.nodes[self.id] = child_node
|
||||||
|
|
||||||
self.refresh(layout=True)
|
self.refresh(layout=True)
|
||||||
|
|
||||||
@@ -221,16 +217,10 @@ class TreeControl(Generic[NodeDataType], Widget):
|
|||||||
"""Find the line location for the cursor node."""
|
"""Find the line location for the cursor node."""
|
||||||
|
|
||||||
node_id = self.cursor
|
node_id = self.cursor
|
||||||
node = self.root
|
|
||||||
line = 0
|
line = 0
|
||||||
|
|
||||||
stack: list[Iterator[TreeNode[NodeDataType]]] = []
|
stack: list[Iterator[TreeNode[NodeDataType]]]
|
||||||
|
stack = [iter([self.root])]
|
||||||
if node.id == node_id:
|
|
||||||
return line
|
|
||||||
|
|
||||||
if node.expanded and node.children:
|
|
||||||
stack.append(iter(node.children))
|
|
||||||
|
|
||||||
pop = stack.pop
|
pop = stack.pop
|
||||||
push = stack.append
|
push = stack.append
|
||||||
@@ -241,11 +231,11 @@ class TreeControl(Generic[NodeDataType], Widget):
|
|||||||
except StopIteration:
|
except StopIteration:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
line += 1
|
|
||||||
if node.id == node_id:
|
if node.id == node_id:
|
||||||
return line
|
return line
|
||||||
|
line += 1
|
||||||
push(iter_children)
|
push(iter_children)
|
||||||
if node.expanded and node.children:
|
if node.children and node.expanded:
|
||||||
push(iter(node.children))
|
push(iter(node.children))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user