|
10 | 10 | from rich.region import Region as LayoutRegion |
11 | 11 | import rich.repr |
12 | 12 | from rich.segment import Segments |
| 13 | +from rich.style import Style |
13 | 14 |
|
14 | 15 | from . import events |
15 | 16 | from ._context import active_app |
16 | 17 | from .layout import Layout, NoWidget |
17 | 18 | from .layouts.dock import DockEdge, DockLayout, Dock |
18 | | -from .geometry import Dimensions, Region |
| 19 | +from .geometry import Dimensions, Point, Region |
19 | 20 | from .messages import UpdateMessage, LayoutMessage |
20 | 21 |
|
21 | 22 | from .widget import StaticWidget, Widget, WidgetID, Widget |
@@ -57,6 +58,9 @@ def is_mounted(self, widget: Widget) -> bool: |
57 | 58 | def render(self) -> RenderableType: |
58 | 59 | return self.layout |
59 | 60 |
|
| 61 | + def get_offset(self, widget: Widget) -> Point: |
| 62 | + return self.layout.get_offset(widget) |
| 63 | + |
60 | 64 | async def message_update(self, message: UpdateMessage) -> None: |
61 | 65 | widget = message.widget |
62 | 66 | assert isinstance(widget, Widget) |
@@ -109,9 +113,15 @@ async def on_resize(self, event: events.Resize) -> None: |
109 | 113 | self.size = Dimensions(event.width, event.height) |
110 | 114 | await self.refresh_layout() |
111 | 115 |
|
| 116 | + def get_widget_at(self, x: int, y: int) -> tuple[Widget, Region]: |
| 117 | + return self.layout.get_widget_at(x, y) |
| 118 | + |
| 119 | + def get_style_at(self, x: int, y: int) -> Style: |
| 120 | + return self.layout.get_style_at(x, y) |
| 121 | + |
112 | 122 | async def _on_mouse_move(self, event: events.MouseMove) -> None: |
113 | 123 | try: |
114 | | - widget, region = self.layout.get_widget_at(event.x, event.y) |
| 124 | + widget, region = self.get_widget_at(event.x, event.y) |
115 | 125 | except NoWidget: |
116 | 126 | await self.app.set_mouse_over(None) |
117 | 127 | else: |
@@ -140,26 +150,24 @@ async def forward_event(self, event: events.Event) -> None: |
140 | 150 | await self._on_mouse_move(event) |
141 | 151 |
|
142 | 152 | elif isinstance(event, events.MouseEvent): |
143 | | - pass |
144 | | - # try: |
145 | | - # widget, region = self.get_widget_at(event.x, event.y, deep=True) |
146 | | - # except NoWidget: |
147 | | - # if isinstance(event, events.MouseDown): |
148 | | - # await self.app.set_focus(None) |
149 | | - # else: |
150 | | - # if isinstance(event, events.MouseDown): |
151 | | - # await self.app.set_focus(widget) |
152 | | - # await widget.forward_event(event.offset(-region.x, -region.y)) |
| 153 | + |
| 154 | + try: |
| 155 | + widget, region = self.get_widget_at(event.x, event.y) |
| 156 | + except NoWidget: |
| 157 | + pass |
| 158 | + else: |
| 159 | + if isinstance(event, events.MouseDown) and widget.can_focus: |
| 160 | + await self.app.set_focus(widget) |
| 161 | + await widget.forward_event(event.offset(-region.x, -region.y)) |
153 | 162 |
|
154 | 163 | elif isinstance(event, (events.MouseScrollDown, events.MouseScrollUp)): |
155 | | - pass |
156 | | - # try: |
157 | | - # widget, _region = self.get_widget_at(event.x, event.y, deep=True) |
158 | | - # except NoWidget: |
159 | | - # return |
160 | | - # scroll_widget = widget or self.focused |
161 | | - # if scroll_widget is not None: |
162 | | - # await scroll_widget.forward_event(event) |
| 164 | + try: |
| 165 | + widget, _region = self.get_widget_at(event.x, event.y) |
| 166 | + except NoWidget: |
| 167 | + return |
| 168 | + scroll_widget = widget or self.focused |
| 169 | + if scroll_widget is not None: |
| 170 | + await scroll_widget.forward_event(event) |
163 | 171 | else: |
164 | 172 | if self.focused is not None: |
165 | 173 | await self.focused.forward_event(event) |
|
0 commit comments