Merge pull request #5311 from Textualize/scroll-optimization
optimize scroll
|
|
@ -82,10 +82,8 @@ class ScrollView(ScrollableContainer):
|
|||
layout: Perform layout if required.
|
||||
|
||||
Returns:
|
||||
True if anything changed, or False if nothing changed.
|
||||
True if a resize event should be sent, otherwise False.
|
||||
"""
|
||||
if self._size != size or self._container_size != container_size:
|
||||
self.refresh()
|
||||
if (
|
||||
self._size != size
|
||||
or virtual_size != self.virtual_size
|
||||
|
|
@ -96,9 +94,8 @@ class ScrollView(ScrollableContainer):
|
|||
virtual_size = self.virtual_size
|
||||
self._container_size = size - self.styles.gutter.totals
|
||||
self._scroll_update(virtual_size)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
return self._size != size or self._container_size != container_size
|
||||
|
||||
def render(self) -> RenderableType:
|
||||
"""Render the scrollable region (if `render_lines` is not implemented).
|
||||
|
|
|
|||
|
|
@ -3695,8 +3695,9 @@ class Widget(DOMNode):
|
|||
layout: Perform layout if required.
|
||||
|
||||
Returns:
|
||||
True if anything changed, or False if nothing changed.
|
||||
True if a resize event should be sent, otherwise False.
|
||||
"""
|
||||
|
||||
self._layout_cache.clear()
|
||||
if (
|
||||
self._size != size
|
||||
|
|
|
|||
|
|
@ -362,11 +362,12 @@ class OptionList(ScrollView, can_focus=True):
|
|||
self._lines.append(OptionLineSpan(-1, 0))
|
||||
|
||||
self.virtual_size = Size(width, len(self._lines))
|
||||
self.refresh(layout=self.styles.auto_dimensions)
|
||||
self._scroll_update(self.virtual_size)
|
||||
|
||||
def _populate(self) -> None:
|
||||
"""Populate the lines data-structure."""
|
||||
if self._lines is not None:
|
||||
return
|
||||
|
||||
self._lines = []
|
||||
self._spans = []
|
||||
|
||||
|
|
@ -374,7 +375,6 @@ class OptionList(ScrollView, can_focus=True):
|
|||
self._contents,
|
||||
self.scrollable_content_region.width - self._left_gutter_width(),
|
||||
)
|
||||
self.refresh(layout=True)
|
||||
|
||||
def get_content_width(self, container: Size, viewport: Size) -> int:
|
||||
"""Get maximum width of options."""
|
||||
|
|
@ -824,8 +824,9 @@ class OptionList(ScrollView, can_focus=True):
|
|||
) from None
|
||||
|
||||
def render_line(self, y: int) -> Strip:
|
||||
self._populate()
|
||||
assert self._lines is not None
|
||||
if not self._lines:
|
||||
self._populate()
|
||||
|
||||
_scroll_x, scroll_y = self.scroll_offset
|
||||
line_number = scroll_y + y
|
||||
|
|
@ -879,9 +880,12 @@ class OptionList(ScrollView, can_focus=True):
|
|||
top: Scroll highlight to top of the list.
|
||||
"""
|
||||
highlighted = self.highlighted
|
||||
if highlighted is None or self._spans is None:
|
||||
if highlighted is None or not self.is_mounted:
|
||||
return
|
||||
|
||||
if not self._spans:
|
||||
self._populate()
|
||||
|
||||
try:
|
||||
y, height = self._spans[highlighted]
|
||||
except IndexError:
|
||||
|
|
@ -894,6 +898,7 @@ class OptionList(ScrollView, can_focus=True):
|
|||
force=True,
|
||||
animate=False,
|
||||
top=top,
|
||||
immediate=True,
|
||||
)
|
||||
|
||||
def validate_highlighted(self, highlighted: int | None) -> int | None:
|
||||
|
|
@ -953,7 +958,6 @@ class OptionList(ScrollView, can_focus=True):
|
|||
# If we find ourselves in a position where we don't know where we're
|
||||
# going, we need a fallback location. Where we go will depend on the
|
||||
# direction.
|
||||
self._populate()
|
||||
assert self._spans is not None
|
||||
assert self._lines is not None
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ class SelectOverlay(OptionList):
|
|||
index: Index of new selection.
|
||||
"""
|
||||
self.highlighted = index
|
||||
self.scroll_to_highlight(top=True)
|
||||
self.scroll_to_highlight()
|
||||
|
||||
def action_dismiss(self) -> None:
|
||||
"""Dismiss the overlay."""
|
||||
|
|
@ -520,7 +520,7 @@ class Select(Generic[SelectType], Vertical, can_focus=True):
|
|||
value = self.value
|
||||
for index, (_prompt, prompt_value) in enumerate(self._options):
|
||||
if value == prompt_value:
|
||||
overlay.select(index)
|
||||
self.call_after_refresh(overlay.select, index)
|
||||
break
|
||||
self.query_one(SelectCurrent).has_value = True
|
||||
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |