Skip to content

Commit

Permalink
Merge pull request #5159 from TomJGooding/feat-events-add-control-pro…
Browse files Browse the repository at this point in the history
…perty-to-enter-and-leave

feat(events): add control property to Enter and Leave
  • Loading branch information
willmcgugan authored Oct 25, 2024
2 parents b9be24f + 9a72e06 commit 60979e0
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 1 deletion.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## Unreleased

### Changed
Expand All @@ -29,6 +28,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Added new demo `python -m textual`, not *quite* finished but better than the old one https://github.com/Textualize/textual/pull/5174
- Added `Screen.can_view_partial` and `Widget.can_view_partial` https://github.com/Textualize/textual/pull/5174
- Added `App.is_web` property to indicate if the app is running via a web browser https://github.com/Textualize/textual/pull/5128
- `Enter` and `Leave` events can now be used with the `on` decorator https://github.com/Textualize/textual/pull/5159

### Fixed

Expand Down
10 changes: 10 additions & 0 deletions src/textual/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,11 @@ def __init__(self, node: DOMNode) -> None:
"""The node directly under the mouse."""
super().__init__()

@property
def control(self) -> DOMNode:
"""Alias for the `node` under the mouse."""
return self.node


class Leave(Event, bubble=True, verbose=True):
"""Sent when the mouse is moved away from a widget, or if a widget is
Expand All @@ -592,6 +597,11 @@ def __init__(self, node: DOMNode) -> None:
"""The node that was previously directly under the mouse."""
super().__init__()

@property
def control(self) -> DOMNode:
"""Alias for the `node` that was previously under the mouse."""
return self.node


class Focus(Event, bubble=False):
"""Sent when a widget is focussed.
Expand Down
26 changes: 26 additions & 0 deletions tests/test_on.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from textual import on
from textual._on import OnDecoratorError
from textual.app import App, ComposeResult
from textual.events import Enter, Leave
from textual.message import Message
from textual.widget import Widget
from textual.widgets import Button, TabbedContent, TabPane
Expand Down Expand Up @@ -352,3 +353,28 @@ def on_mount(self) -> None:
pass

assert posted == ["parent", "child", "parent"]


async def test_on_with_enter_and_leave_events():
class EnterLeaveApp(App):
messages = []

def compose(self) -> ComposeResult:
yield Button("OK")

@on(Enter, "Button")
@on(Leave, "Button")
def record(self, event: Enter | Leave) -> None:
self.messages.append(event.__class__.__name__)

app = EnterLeaveApp()
async with app.run_test() as pilot:
expected_messages = []

await pilot.hover(Button)
expected_messages.append("Enter")
assert app.messages == expected_messages

await pilot.hover(Button, offset=(0, 20))
expected_messages.append("Leave")
assert app.messages == expected_messages

0 comments on commit 60979e0

Please sign in to comment.