mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
point -> offset
This commit is contained in:
@@ -17,7 +17,7 @@ from . import events
|
|||||||
from . import actions
|
from . import actions
|
||||||
from ._animator import Animator
|
from ._animator import Animator
|
||||||
from .binding import Bindings, NoBinding
|
from .binding import Bindings, NoBinding
|
||||||
from .geometry import Point, Region
|
from .geometry import Offset, Region
|
||||||
from . import log
|
from . import log
|
||||||
from ._context import active_app
|
from ._context import active_app
|
||||||
from ._event_broker import extract_handler_actions, NoHandler
|
from ._event_broker import extract_handler_actions, NoHandler
|
||||||
@@ -103,7 +103,7 @@ class App(MessagePump):
|
|||||||
self._action_targets = {"app", "view"}
|
self._action_targets = {"app", "view"}
|
||||||
self._animator = Animator(self)
|
self._animator = Animator(self)
|
||||||
self.animate = self._animator.bind(self)
|
self.animate = self._animator.bind(self)
|
||||||
self.mouse_position = Point(0, 0)
|
self.mouse_position = Offset(0, 0)
|
||||||
self.bindings = Bindings()
|
self.bindings = Bindings()
|
||||||
self._title = title
|
self._title = title
|
||||||
|
|
||||||
@@ -370,7 +370,7 @@ class App(MessagePump):
|
|||||||
|
|
||||||
if isinstance(event, events.InputEvent):
|
if isinstance(event, events.InputEvent):
|
||||||
if isinstance(event, events.MouseEvent):
|
if isinstance(event, events.MouseEvent):
|
||||||
self.mouse_position = Point(event.x, event.y)
|
self.mouse_position = Offset(event.x, event.y)
|
||||||
if isinstance(event, events.Key) and self.focused is not None:
|
if isinstance(event, events.Key) and self.focused is not None:
|
||||||
await self.focused.forward_event(event)
|
await self.focused.forward_event(event)
|
||||||
await self.view.forward_event(event)
|
await self.view.forward_event(event)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from typing import Awaitable, Callable, Type, TYPE_CHECKING, TypeVar
|
|||||||
import rich.repr
|
import rich.repr
|
||||||
from rich.style import Style
|
from rich.style import Style
|
||||||
|
|
||||||
from .geometry import Point, Dimensions
|
from .geometry import Offset, Dimensions
|
||||||
from .message import Message
|
from .message import Message
|
||||||
from ._types import MessageTarget
|
from ._types import MessageTarget
|
||||||
from .keys import Keys
|
from .keys import Keys
|
||||||
@@ -143,7 +143,7 @@ class MouseCapture(Event):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, sender: MessageTarget, mouse_position: Point) -> None:
|
def __init__(self, sender: MessageTarget, mouse_position: Offset) -> None:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -161,7 +161,7 @@ class MouseCapture(Event):
|
|||||||
class MouseRelease(Event):
|
class MouseRelease(Event):
|
||||||
"""Mouse has been released."""
|
"""Mouse has been released."""
|
||||||
|
|
||||||
def __init__(self, sender: MessageTarget, mouse_position: Point) -> None:
|
def __init__(self, sender: MessageTarget, mouse_position: Offset) -> None:
|
||||||
"""
|
"""
|
||||||
Args:
|
Args:
|
||||||
sender (MessageTarget): The sender of the event, (in this case the app).
|
sender (MessageTarget): The sender of the event, (in this case the app).
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ def clamp(value: T, minimum: T, maximum: T) -> T:
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
class Point(NamedTuple):
|
class Offset(NamedTuple):
|
||||||
"""A point defined by x and y coordinates."""
|
"""A point defined by x and y coordinates."""
|
||||||
|
|
||||||
x: int
|
x: int
|
||||||
@@ -36,21 +36,21 @@ class Point(NamedTuple):
|
|||||||
"""Check if the point is at the origin (0, 0)"""
|
"""Check if the point is at the origin (0, 0)"""
|
||||||
return self == (0, 0)
|
return self == (0, 0)
|
||||||
|
|
||||||
def __add__(self, other: object) -> Point:
|
def __add__(self, other: object) -> Offset:
|
||||||
if isinstance(other, tuple):
|
if isinstance(other, tuple):
|
||||||
_x, _y = self
|
_x, _y = self
|
||||||
x, y = other
|
x, y = other
|
||||||
return Point(_x + x, _y + y)
|
return Offset(_x + x, _y + y)
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
|
|
||||||
def __sub__(self, other: object) -> Point:
|
def __sub__(self, other: object) -> Offset:
|
||||||
if isinstance(other, tuple):
|
if isinstance(other, tuple):
|
||||||
_x, _y = self
|
_x, _y = self
|
||||||
x, y = other
|
x, y = other
|
||||||
return Point(_x - x, _y - y)
|
return Offset(_x - x, _y - y)
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
|
|
||||||
def blend(self, destination: Point, factor: float) -> Point:
|
def blend(self, destination: Offset, factor: float) -> Offset:
|
||||||
"""Blend (interpolate) to a new point.
|
"""Blend (interpolate) to a new point.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -62,7 +62,7 @@ class Point(NamedTuple):
|
|||||||
"""
|
"""
|
||||||
x1, y1 = self
|
x1, y1 = self
|
||||||
x2, y2 = destination
|
x2, y2 = destination
|
||||||
return Point(int(x1 + (x2 - x1) * factor), int((y1 + (y2 - y1) * factor)))
|
return Offset(int(x1 + (x2 - x1) * factor), int((y1 + (y2 - y1) * factor)))
|
||||||
|
|
||||||
|
|
||||||
class Dimensions(NamedTuple):
|
class Dimensions(NamedTuple):
|
||||||
@@ -173,9 +173,9 @@ class Region(NamedTuple):
|
|||||||
return self.width * self.height
|
return self.width * self.height
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def origin(self) -> Point:
|
def origin(self) -> Offset:
|
||||||
"""Get the start point of the region."""
|
"""Get the start point of the region."""
|
||||||
return Point(self.x, self.y)
|
return Offset(self.x, self.y)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def size(self) -> Dimensions:
|
def size(self) -> Dimensions:
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ from ._loop import loop_last
|
|||||||
from .layout_map import LayoutMap
|
from .layout_map import LayoutMap
|
||||||
from ._types import Lines
|
from ._types import Lines
|
||||||
|
|
||||||
from .geometry import clamp, Region, Point, Dimensions
|
from .geometry import clamp, Region, Offset, Dimensions
|
||||||
|
|
||||||
|
|
||||||
PY38 = sys.version_info >= (3, 8)
|
PY38 = sys.version_info >= (3, 8)
|
||||||
@@ -191,7 +191,7 @@ class Layout(ABC):
|
|||||||
for widget, (region, _order, clip) in layers:
|
for widget, (region, _order, clip) in layers:
|
||||||
yield widget, region.intersection(clip)
|
yield widget, region.intersection(clip)
|
||||||
|
|
||||||
def get_offset(self, widget: Widget) -> Point:
|
def get_offset(self, widget: Widget) -> Offset:
|
||||||
try:
|
try:
|
||||||
return self.map[widget].region.origin
|
return self.map[widget].region.origin
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ from typing import Iterable, NamedTuple
|
|||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
|
|
||||||
from .._layout_resolve import layout_resolve
|
from .._layout_resolve import layout_resolve
|
||||||
from ..geometry import Dimensions, Point, Region
|
from ..geometry import Dimensions, Offset, Region
|
||||||
from ..layout import Layout
|
from ..layout import Layout
|
||||||
from ..layout_map import LayoutMap
|
from ..layout_map import LayoutMap
|
||||||
from ..widget import Widget
|
from ..widget import Widget
|
||||||
@@ -369,7 +369,7 @@ class GridLayout(Layout):
|
|||||||
}
|
}
|
||||||
order = 1
|
order = 1
|
||||||
from_corners = Region.from_corners
|
from_corners = Region.from_corners
|
||||||
gutter = Point(self.column_gutter, self.row_gutter)
|
gutter = Offset(self.column_gutter, self.row_gutter)
|
||||||
for widget, area in widget_areas:
|
for widget, area in widget_areas:
|
||||||
column_start, column_end, row_start, row_end = self.areas[area]
|
column_start, column_end, row_start, row_end = self.areas[area]
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from typing import Iterable
|
|||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
|
|
||||||
|
|
||||||
from ..geometry import Point, Region, Dimensions
|
from ..geometry import Offset, Region, Dimensions
|
||||||
from ..layout import Layout
|
from ..layout import Layout
|
||||||
from ..layout_map import LayoutMap
|
from ..layout_map import LayoutMap
|
||||||
from ..widget import Widget
|
from ..widget import Widget
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from rich.padding import Padding, PaddingDimensions
|
|||||||
from rich.segment import Segment
|
from rich.segment import Segment
|
||||||
from rich.style import StyleType
|
from rich.style import StyleType
|
||||||
|
|
||||||
from .geometry import Dimensions, Point
|
from .geometry import Dimensions, Offset
|
||||||
from .message import Message
|
from .message import Message
|
||||||
from .widget import Widget, Reactive
|
from .widget import Widget, Reactive
|
||||||
|
|
||||||
@@ -35,14 +35,14 @@ class PageRender:
|
|||||||
self.height = height
|
self.height = height
|
||||||
self.style = style
|
self.style = style
|
||||||
self.padding = padding
|
self.padding = padding
|
||||||
self.offset = Point(0, 0)
|
self.offset = Offset(0, 0)
|
||||||
self._render_width: int | None = None
|
self._render_width: int | None = None
|
||||||
self._render_height: int | None = None
|
self._render_height: int | None = None
|
||||||
self.size = Dimensions(0, 0)
|
self.size = Dimensions(0, 0)
|
||||||
self._lines: list[list[Segment]] = []
|
self._lines: list[list[Segment]] = []
|
||||||
|
|
||||||
def move_to(self, x: int = 0, y: int = 0) -> None:
|
def move_to(self, x: int = 0, y: int = 0) -> None:
|
||||||
self.offset = Point(x, y)
|
self.offset = Offset(x, y)
|
||||||
|
|
||||||
def clear(self) -> None:
|
def clear(self) -> None:
|
||||||
self._render_width = None
|
self._render_width = None
|
||||||
@@ -112,11 +112,11 @@ class Page(Widget):
|
|||||||
|
|
||||||
async def watch_scroll_x(self, new: int) -> None:
|
async def watch_scroll_x(self, new: int) -> None:
|
||||||
x, y = self._page.offset
|
x, y = self._page.offset
|
||||||
self._page.offset = Point(new, y)
|
self._page.offset = Offset(new, y)
|
||||||
|
|
||||||
async def watch_scroll_y(self, new: int) -> None:
|
async def watch_scroll_y(self, new: int) -> None:
|
||||||
x, y = self._page.offset
|
x, y = self._page.offset
|
||||||
self._page.offset = Point(x, new)
|
self._page.offset = Offset(x, new)
|
||||||
|
|
||||||
def update(self, renderable: RenderableType | None = None) -> None:
|
def update(self, renderable: RenderableType | None = None) -> None:
|
||||||
if renderable:
|
if renderable:
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from rich.console import Console, RenderableType
|
|||||||
from rich.control import Control
|
from rich.control import Control
|
||||||
from rich.segment import Segment, Segments
|
from rich.segment import Segment, Segments
|
||||||
|
|
||||||
from .geometry import Point
|
from .geometry import Offset
|
||||||
from ._loop import loop_last
|
from ._loop import loop_last
|
||||||
|
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ class ScreenUpdate:
|
|||||||
self.lines = console.render_lines(
|
self.lines = console.render_lines(
|
||||||
renderable, console.options.update_dimensions(width, height)
|
renderable, console.options.update_dimensions(width, height)
|
||||||
)
|
)
|
||||||
self.offset = Point(0, 0)
|
self.offset = Offset(0, 0)
|
||||||
|
|
||||||
def render(self, x: int, y: int) -> Iterable[Segment]:
|
def render(self, x: int, y: int) -> Iterable[Segment]:
|
||||||
move_to = Control.move_to
|
move_to = Control.move_to
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from rich.segment import Segment, Segments
|
|||||||
from rich.style import Style, StyleType
|
from rich.style import Style, StyleType
|
||||||
|
|
||||||
from . import events
|
from . import events
|
||||||
from .geometry import Point
|
from .geometry import Offset
|
||||||
from ._types import MessageTarget
|
from ._types import MessageTarget
|
||||||
from .message import Message
|
from .message import Message
|
||||||
from .widget import Reactive, Widget
|
from .widget import Reactive, Widget
|
||||||
@@ -184,7 +184,7 @@ class ScrollBar(Widget):
|
|||||||
window_size: Reactive[int] = Reactive(0)
|
window_size: Reactive[int] = Reactive(0)
|
||||||
position: Reactive[int] = Reactive(0)
|
position: Reactive[int] = Reactive(0)
|
||||||
mouse_over: Reactive[bool] = Reactive(False)
|
mouse_over: Reactive[bool] = Reactive(False)
|
||||||
grabbed: Reactive[Point | None] = Reactive(None)
|
grabbed: Reactive[Offset | None] = Reactive(None)
|
||||||
|
|
||||||
def __rich_repr__(self) -> rich.repr.RichReprResult:
|
def __rich_repr__(self) -> rich.repr.RichReprResult:
|
||||||
yield "virtual_size", self.virtual_size
|
yield "virtual_size", self.virtual_size
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from rich.style import Style
|
|||||||
from . import events
|
from . import events
|
||||||
from . import log
|
from . import log
|
||||||
from .layout import Layout, NoWidget
|
from .layout import Layout, NoWidget
|
||||||
from .geometry import Dimensions, Point, Region
|
from .geometry import Dimensions, Offset, Region
|
||||||
from .messages import UpdateMessage, LayoutMessage
|
from .messages import UpdateMessage, LayoutMessage
|
||||||
from .reactive import Reactive, watch
|
from .reactive import Reactive, watch
|
||||||
|
|
||||||
@@ -53,8 +53,8 @@ class View(Widget):
|
|||||||
scroll_y: Reactive[int] = Reactive(0)
|
scroll_y: Reactive[int] = Reactive(0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def scroll_offset(self) -> Point:
|
def scroll_offset(self) -> Offset:
|
||||||
return Point(self.scroll_x, self.scroll_y)
|
return Offset(self.scroll_x, self.scroll_y)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def virtual_size(self) -> Dimensions:
|
def virtual_size(self) -> Dimensions:
|
||||||
@@ -116,7 +116,7 @@ class View(Widget):
|
|||||||
def render(self) -> RenderableType:
|
def render(self) -> RenderableType:
|
||||||
return self.layout
|
return self.layout
|
||||||
|
|
||||||
def get_offset(self, widget: Widget) -> Point:
|
def get_offset(self, widget: Widget) -> Offset:
|
||||||
return self.layout.get_offset(widget)
|
return self.layout.get_offset(widget)
|
||||||
|
|
||||||
def check_layout(self) -> bool:
|
def check_layout(self) -> bool:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from textual.geometry import clamp, Point, Dimensions, Region
|
from textual.geometry import clamp, Offset, Dimensions, Region
|
||||||
|
|
||||||
|
|
||||||
def test_dimensions_region():
|
def test_dimensions_region():
|
||||||
@@ -18,13 +18,13 @@ def test_dimensions_contains():
|
|||||||
|
|
||||||
|
|
||||||
def test_dimensions_contains_point():
|
def test_dimensions_contains_point():
|
||||||
assert Dimensions(10, 10).contains_point(Point(5, 5))
|
assert Dimensions(10, 10).contains_point(Offset(5, 5))
|
||||||
assert Dimensions(10, 10).contains_point(Point(9, 9))
|
assert Dimensions(10, 10).contains_point(Offset(9, 9))
|
||||||
assert Dimensions(10, 10).contains_point(Point(0, 0))
|
assert Dimensions(10, 10).contains_point(Offset(0, 0))
|
||||||
assert not Dimensions(10, 10).contains_point(Point(10, 9))
|
assert not Dimensions(10, 10).contains_point(Offset(10, 9))
|
||||||
assert not Dimensions(10, 10).contains_point(Point(9, 10))
|
assert not Dimensions(10, 10).contains_point(Offset(9, 10))
|
||||||
assert not Dimensions(10, 10).contains_point(Point(-1, 0))
|
assert not Dimensions(10, 10).contains_point(Offset(-1, 0))
|
||||||
assert not Dimensions(10, 10).contains_point(Point(0, -1))
|
assert not Dimensions(10, 10).contains_point(Offset(0, -1))
|
||||||
|
|
||||||
|
|
||||||
def test_dimensions_contains_special():
|
def test_dimensions_contains_special():
|
||||||
@@ -63,32 +63,32 @@ def test_clamp():
|
|||||||
|
|
||||||
|
|
||||||
def test_point_is_origin():
|
def test_point_is_origin():
|
||||||
assert Point(0, 0).is_origin
|
assert Offset(0, 0).is_origin
|
||||||
assert not Point(1, 0).is_origin
|
assert not Offset(1, 0).is_origin
|
||||||
|
|
||||||
|
|
||||||
def test_point_add():
|
def test_point_add():
|
||||||
assert Point(1, 1) + Point(2, 2) == Point(3, 3)
|
assert Offset(1, 1) + Offset(2, 2) == Offset(3, 3)
|
||||||
assert Point(1, 2) + Point(3, 4) == Point(4, 6)
|
assert Offset(1, 2) + Offset(3, 4) == Offset(4, 6)
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
Point(1, 1) + "foo"
|
Offset(1, 1) + "foo"
|
||||||
|
|
||||||
|
|
||||||
def test_point_sub():
|
def test_point_sub():
|
||||||
assert Point(1, 1) - Point(2, 2) == Point(-1, -1)
|
assert Offset(1, 1) - Offset(2, 2) == Offset(-1, -1)
|
||||||
assert Point(3, 4) - Point(2, 1) == Point(1, 3)
|
assert Offset(3, 4) - Offset(2, 1) == Offset(1, 3)
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
Point(1, 1) - "foo"
|
Offset(1, 1) - "foo"
|
||||||
|
|
||||||
|
|
||||||
def test_point_blend():
|
def test_point_blend():
|
||||||
assert Point(1, 2).blend(Point(3, 4), 0) == Point(1, 2)
|
assert Offset(1, 2).blend(Offset(3, 4), 0) == Offset(1, 2)
|
||||||
assert Point(1, 2).blend(Point(3, 4), 1) == Point(3, 4)
|
assert Offset(1, 2).blend(Offset(3, 4), 1) == Offset(3, 4)
|
||||||
assert Point(1, 2).blend(Point(3, 4), 0.5) == Point(2, 3)
|
assert Offset(1, 2).blend(Offset(3, 4), 0.5) == Offset(2, 3)
|
||||||
|
|
||||||
|
|
||||||
def test_region_from_origin():
|
def test_region_from_origin():
|
||||||
assert Region.from_origin(Point(3, 4), (5, 6)) == Region(3, 4, 5, 6)
|
assert Region.from_origin(Offset(3, 4), (5, 6)) == Region(3, 4, 5, 6)
|
||||||
|
|
||||||
|
|
||||||
def test_region_area():
|
def test_region_area():
|
||||||
@@ -102,7 +102,7 @@ def test_region_size():
|
|||||||
|
|
||||||
|
|
||||||
def test_region_origin():
|
def test_region_origin():
|
||||||
assert Region(1, 2, 3, 4).origin == Point(1, 2)
|
assert Region(1, 2, 3, 4).origin == Offset(1, 2)
|
||||||
|
|
||||||
|
|
||||||
def test_region_add():
|
def test_region_add():
|
||||||
|
|||||||
Reference in New Issue
Block a user