mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
Fix click handler
This commit is contained in:
@@ -4,7 +4,7 @@ Screen {
|
|||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
width: 30;
|
width: 30;
|
||||||
height: auto;
|
height: 3;
|
||||||
margin: 2 2;
|
margin: 2 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
40
docs/widgets/list_item.md
Normal file
40
docs/widgets/list_item.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# List Item
|
||||||
|
|
||||||
|
`ListItem` is the type of the elements in a `ListView`.
|
||||||
|
|
||||||
|
- [] Focusable
|
||||||
|
- [] Container
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
The example below shows an app with a simple `ListView`, consisting
|
||||||
|
of multiple `ListItem`s. The arrow keys can be used to navigate the list.
|
||||||
|
|
||||||
|
=== "Output"
|
||||||
|
|
||||||
|
```{.textual path="docs/examples/widgets/list_view.py"}
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "list_view.py"
|
||||||
|
|
||||||
|
```python
|
||||||
|
--8<-- "docs/examples/widgets/list_view.py"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Reactive Attributes
|
||||||
|
|
||||||
|
| Name | Type | Default | Description |
|
||||||
|
|---------------|--------|---------|--------------------------------------|
|
||||||
|
| `highlighted` | `bool` | `False` | True if this ListItem is highlighted |
|
||||||
|
|
||||||
|
## Messages
|
||||||
|
|
||||||
|
#### Attributes
|
||||||
|
|
||||||
|
| attribute | type | purpose |
|
||||||
|
|-----------|------------|-----------------------------|
|
||||||
|
| `item` | `ListItem` | The item that was selected. |
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
* [ListView](../api/list_view.md) code reference
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# List View
|
# List View
|
||||||
|
|
||||||
Displays a vertical list of widgets which can be highlighted and selected.
|
Displays a vertical list of `ListItem`s which can be highlighted and selected.
|
||||||
Supports keyboard navigation.
|
Supports keyboard navigation.
|
||||||
|
|
||||||
- [x] Focusable
|
- [x] Focusable
|
||||||
@@ -57,6 +57,22 @@ or by clicking on it.
|
|||||||
|-----------|------------|-----------------------------|
|
|-----------|------------|-----------------------------|
|
||||||
| `item` | `ListItem` | The item that was selected. |
|
| `item` | `ListItem` | The item that was selected. |
|
||||||
|
|
||||||
|
|
||||||
|
### ChildrenUpdated
|
||||||
|
|
||||||
|
The `ListView.ChildrenUpdated` message is emitted when the elements in the `ListView`
|
||||||
|
are changed (e.g. a child is added, or the list is cleared)
|
||||||
|
|
||||||
|
- [x] Bubbles
|
||||||
|
|
||||||
|
#### Attributes
|
||||||
|
|
||||||
|
| attribute | type | purpose |
|
||||||
|
|------------|------------------|---------------------------|
|
||||||
|
| `children` | `list[ListItem]` | The new ListView children |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## See Also
|
## See Also
|
||||||
|
|
||||||
* [ListView](../api/list_view.md) code reference
|
* [ListView](../api/list_view.md) code reference
|
||||||
|
|||||||
@@ -28,10 +28,12 @@ class ListItem(Widget, can_focus=False):
|
|||||||
highlighted = reactive(False)
|
highlighted = reactive(False)
|
||||||
|
|
||||||
def on_click(self, event: events.Click) -> None:
|
def on_click(self, event: events.Click) -> None:
|
||||||
self.emit_no_wait(self.ChildSelected(self))
|
self.emit_no_wait(self._ChildClicked(self))
|
||||||
|
|
||||||
def watch_highlighted(self, value: bool) -> None:
|
def watch_highlighted(self, value: bool) -> None:
|
||||||
self.set_class(value, "--highlight")
|
self.set_class(value, "--highlight")
|
||||||
|
|
||||||
class ChildSelected(Message):
|
class _ChildClicked(Message):
|
||||||
|
"""For informing with the parent ListView that we were clicked"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -40,6 +40,11 @@ class ListView(Vertical, can_focus=True, can_focus_children=False):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def highlighted_child(self) -> ListItem | None:
|
def highlighted_child(self) -> ListItem | None:
|
||||||
|
"""Get the currently highlighted ListItem
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
ListItem | None: The currently highlighted ListItem, or None if nothing is highlighted.
|
||||||
|
"""
|
||||||
if self.index is None:
|
if self.index is None:
|
||||||
return None
|
return None
|
||||||
elif 0 <= self.index < len(self.children):
|
elif 0 <= self.index < len(self.children):
|
||||||
@@ -51,10 +56,12 @@ class ListView(Vertical, can_focus=True, can_focus_children=False):
|
|||||||
return self._clamp_index(index)
|
return self._clamp_index(index)
|
||||||
|
|
||||||
def _clamp_index(self, index: int) -> int:
|
def _clamp_index(self, index: int) -> int:
|
||||||
|
"""Clamp the index to a valid value given the current list of children"""
|
||||||
last_index = max(len(self.children) - 1, 0)
|
last_index = max(len(self.children) - 1, 0)
|
||||||
return clamp(index, 0, last_index)
|
return clamp(index, 0, last_index)
|
||||||
|
|
||||||
def _is_valid_index(self, index: int | None) -> bool:
|
def _is_valid_index(self, index: int | None) -> bool:
|
||||||
|
"""Return True if the current index is valid given the current list of children"""
|
||||||
if index is None:
|
if index is None:
|
||||||
return False
|
return False
|
||||||
return 0 <= index < len(self.children)
|
return 0 <= index < len(self.children)
|
||||||
@@ -92,7 +99,7 @@ class ListView(Vertical, can_focus=True, can_focus_children=False):
|
|||||||
selected_child = self.highlighted_child
|
selected_child = self.highlighted_child
|
||||||
self.emit_no_wait(self.Selected(self, selected_child))
|
self.emit_no_wait(self.Selected(self, selected_child))
|
||||||
|
|
||||||
def on_list_item_child_selected(self, event: ListItem.ChildSelected) -> None:
|
def on_list_item__child_clicked(self, event: ListItem._ChildClicked) -> None:
|
||||||
self.focus()
|
self.focus()
|
||||||
self.index = self.children.index(event.sender)
|
self.index = self.children.index(event.sender)
|
||||||
self.emit_no_wait(self.Selected(self, event.sender))
|
self.emit_no_wait(self.Selected(self, event.sender))
|
||||||
@@ -108,6 +115,7 @@ class ListView(Vertical, can_focus=True, can_focus_children=False):
|
|||||||
self.index += 1
|
self.index += 1
|
||||||
|
|
||||||
def _scroll_highlighted_region(self) -> None:
|
def _scroll_highlighted_region(self) -> None:
|
||||||
|
"""Used to keep the highlighted index within vision"""
|
||||||
if self.highlighted_child is not None:
|
if self.highlighted_child is not None:
|
||||||
self.scroll_to_widget(self.highlighted_child, animate=False)
|
self.scroll_to_widget(self.highlighted_child, animate=False)
|
||||||
|
|
||||||
@@ -115,16 +123,23 @@ class ListView(Vertical, can_focus=True, can_focus_children=False):
|
|||||||
return len(self.children)
|
return len(self.children)
|
||||||
|
|
||||||
class Highlighted(Message, bubble=True):
|
class Highlighted(Message, bubble=True):
|
||||||
|
"""Emitted when the highlighted item changes. Highlighted item is controlled using up/down keys"""
|
||||||
|
|
||||||
def __init__(self, sender: ListView, item: ListItem | None) -> None:
|
def __init__(self, sender: ListView, item: ListItem | None) -> None:
|
||||||
super().__init__(sender)
|
super().__init__(sender)
|
||||||
self.item = item
|
self.item = item
|
||||||
|
|
||||||
class Selected(Message, bubble=True):
|
class Selected(Message, bubble=True):
|
||||||
|
"""Emitted when a list item is selected, e.g. when you press the enter key on it"""
|
||||||
|
|
||||||
def __init__(self, sender: ListView, item: ListItem) -> None:
|
def __init__(self, sender: ListView, item: ListItem) -> None:
|
||||||
super().__init__(sender)
|
super().__init__(sender)
|
||||||
self.item = item
|
self.item = item
|
||||||
|
|
||||||
class ChildrenUpdated(Message, bubble=True):
|
class ChildrenUpdated(Message, bubble=True):
|
||||||
|
"""Emitted when the elements in the `ListView` are changed (e.g. a child is
|
||||||
|
added, or the list is cleared)"""
|
||||||
|
|
||||||
def __init__(self, sender: ListView, children: list[ListItem]) -> None:
|
def __init__(self, sender: ListView, children: list[ListItem]) -> None:
|
||||||
super().__init__(sender)
|
super().__init__(sender)
|
||||||
self.children = children
|
self.children = children
|
||||||
|
|||||||
Reference in New Issue
Block a user