Optimising focus sort order

This commit is contained in:
Darren Burns
2022-08-05 13:33:00 +01:00
parent 5c86331c9a
commit 3bbbc560f4
3 changed files with 20 additions and 18 deletions

View File

@@ -26,7 +26,7 @@ Screen {
}
#middle_pane:focus {
outline: #8bc34a;
tint: cyan 40%;
}
#right_pane {
@@ -35,7 +35,7 @@ Screen {
}
.box:focus {
outline: #8bc34a;
tint: cyan 40%;
}
#box1 {

View File

@@ -1,6 +1,7 @@
from __future__ import annotations
from inspect import getfile
from operator import attrgetter
from typing import ClassVar, Iterable, Iterator, Type, TYPE_CHECKING
import rich.repr
@@ -426,15 +427,6 @@ class DOMNode(MessagePump):
"""The children which don't have display: none set."""
return [child for child in self.children if child.display]
@property
def focusable_children(self) -> list[DOMNode]:
"""Get the children which may be focused."""
focusable = [
child for child in self.children if child.display and child.visible
]
sorted_focusable = sorted(focusable, key=_focus_sort_key)
return sorted_focusable
def get_pseudo_classes(self) -> Iterable[str]:
"""Get any pseudo classes applicable to this Node, e.g. hover, focus.
@@ -600,8 +592,3 @@ class DOMNode(MessagePump):
def refresh(self, *, repaint: bool = True, layout: bool = False) -> None:
pass
def _focus_sort_key(widget: Widget) -> tuple[int, int]:
x, y, _, _ = widget.region_with_margin
return y, x

View File

@@ -1,6 +1,7 @@
from __future__ import annotations
from fractions import Fraction
from operator import attrgetter
from typing import (
TYPE_CHECKING,
Any,
@@ -495,7 +496,7 @@ class Widget(DOMNode):
return window_region
@property
def region_with_margin(self) -> Region:
def virtual_region_with_margin(self) -> Region:
"""The widget region relative to its container (*including margin*), which may not be visible,
depending on the scroll offset.
@@ -504,6 +505,20 @@ class Widget(DOMNode):
"""
return self.virtual_region.grow(self.styles.margin)
@property
def focusable_children(self) -> list[Widget]:
"""Get the children which may be focused."""
focusable = [
child for child in self.children if child.display and child.visible
]
return sorted(focusable, key=attrgetter("_focus_sort_key"))
@property
def _focus_sort_key(self) -> tuple[int, int]:
x, y, _, _ = self.virtual_region
top, _, _, left = self.styles.margin
return y - top, x - left
@property
def scroll_offset(self) -> Offset:
return Offset(int(self.scroll_x), int(self.scroll_y))
@@ -746,7 +761,7 @@ class Widget(DOMNode):
"""
# Grow the region by the margin so to keep the margin in view.
region = widget.region_with_margin
region = widget.virtual_region_with_margin
scrolled = False
while isinstance(widget.parent, Widget) and widget is not self: