Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix tree issues #5052

Merged
merged 10 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Add

- Added `x_axis` and `y_axis` parameters to `Widget.scroll_to_region` https://github.com/Textualize/textual/pull/5047
- Added `Tree.move_cursor_to_line` https://github.com/Textualize/textual/pull/5052

### Changed

- Tree will no longer scroll the X axis when moving the cursor https://github.com/Textualize/textual/pull/5047
- DirectoryTree will no longer select the first node https://github.com/Textualize/textual/pull/5052

### Fixed

- Fixed widgets occasionally not getting Resize events https://github.com/Textualize/textual/pull/5048
- Fixed tree regression https://github.com/Textualize/textual/pull/5052

## [0.80.1] - 2024-09-24

Expand Down
4 changes: 3 additions & 1 deletion src/textual/widgets/_directory_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,9 @@ async def watch_path(self) -> None:
"""
self.reset_node(self.root, str(self.path), DirEntry(self.PATH(self.path)))
await self.reload()
self.move_cursor(self.root, animate=False)
if self.cursor_node is not None:
self.cursor_line = 0
darrenburns marked this conversation as resolved.
Show resolved Hide resolved
self.move_cursor(self.cursor_node, animate=False)

def process_label(self, label: TextType) -> Text:
"""Process a str or Text into a label. May be overridden in a subclass to modify how labels are rendered.
Expand Down
47 changes: 38 additions & 9 deletions src/textual/widgets/_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,7 @@ class Tree(Generic[TreeDataType], ScrollView, can_focus=True):
"""Show the root of the tree."""
hover_line = var(-1)
"""The line number under the mouse pointer, or -1 if not under the mouse pointer."""
cursor_line = var(-1)
cursor_line = var(-1, always_update=True)
"""The line with the cursor, or -1 if no cursor."""
show_guides = reactive(True)
"""Enable display of tree guide lines."""
Expand Down Expand Up @@ -846,7 +846,7 @@ def render_label(

if node._allow_expand:
prefix = (
self.ICON_NODE if node.is_expanded else self.ICON_NODE_EXPANDED,
self.ICON_NODE_EXPANDED if node.is_expanded else self.ICON_NODE,
base_style + TOGGLE_STYLE,
)
else:
Expand Down Expand Up @@ -930,6 +930,24 @@ def move_cursor(
animate=animate and abs(self.cursor_line - previous_cursor_line) > 1,
)

def move_cursor_to_line(self, line: int, animate=False) -> None:
"""Move the cursor to the given line.

Args:
line: The line number (negative indexes are offsets from the last line).
animate: Enable animation.
willmcgugan marked this conversation as resolved.
Show resolved Hide resolved

Raises:
IndexError: If the line doesn't exist.
"""
if line < 0:
line = len(self._tree_lines) + line
willmcgugan marked this conversation as resolved.
Show resolved Hide resolved
try:
node = self._tree_lines[line].node
except IndexError:
raise IndexError("No line no. {line} in the tree")
willmcgugan marked this conversation as resolved.
Show resolved Hide resolved
self.move_cursor(node, animate=animate)

def select_node(self, node: TreeNode[TreeDataType] | None) -> None:
"""Move the cursor to the given node and select it, or reset cursor.

Expand Down Expand Up @@ -1079,22 +1097,33 @@ def watch_hover_line(self, previous_hover_line: int, hover_line: int) -> None:

def watch_cursor_line(self, previous_line: int, line: int) -> None:
previous_node = self._get_node(previous_line)
# Refresh previous cursor node
node = self._get_node(line)

if self.cursor_node is not None:
self.cursor_node._selected = False

if previous_node is not None:
self._refresh_node(previous_node)
previous_node._selected = False

if node is not None:
node._selected = True
self._cursor_node = node
else:
self._cursor_node = None

node = self._get_node(line)
if previous_line == line:
# No change, so no need for refresh
return

# Refresh previous cursor node
if previous_node is not None:
self._refresh_node(previous_node)

# Refresh new node
if node is not None:
self._refresh_node(node)
node._selected = True
self._cursor_node = node
if previous_node != node:
self.post_message(self.NodeHighlighted(node))
else:
self._cursor_node = None

def watch_guide_depth(self, guide_depth: int) -> None:
self._invalidate()
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading