Refine tree widget event handling and hover state management
This commit is contained in:
parent
7af12f7035
commit
b7e4c96188
@ -127,14 +127,17 @@ class InputHandler:
|
||||
# Zoom in viewport
|
||||
self.camera.handle_zoom(event.y)
|
||||
elif inspector_rect and inspector_rect.collidepoint(mouse_x, mouse_y) and self.hud.tree_widget:
|
||||
# Scroll tree widget in inspector - convert to local coordinates if needed
|
||||
if not hasattr(event, 'pos'):
|
||||
event.pos = (mouse_x - inspector_rect.x, mouse_y - inspector_rect.y)
|
||||
else:
|
||||
local_x = mouse_x - inspector_rect.x
|
||||
local_y = mouse_y - inspector_rect.y
|
||||
event.pos = (local_x, local_y)
|
||||
self.hud.tree_widget.handle_event(event)
|
||||
# Scroll tree widget in inspector
|
||||
if not viewport_rect.collidepoint(mouse_x, mouse_y):
|
||||
# Convert to local coordinates if needed
|
||||
if not hasattr(event, 'pos'):
|
||||
event.pos = (mouse_x - inspector_rect.x, mouse_y - inspector_rect.y)
|
||||
else:
|
||||
local_x = mouse_x - inspector_rect.x
|
||||
local_y = mouse_y - inspector_rect.y
|
||||
event.pos = (local_x, local_y)
|
||||
print("Passing event to tree widget")
|
||||
self.hud.tree_widget.handle_event(event)
|
||||
else:
|
||||
# Fallback: always zoom if no HUD reference
|
||||
self.camera.handle_zoom(event.y)
|
||||
|
||||
13
ui/hud.py
13
ui/hud.py
@ -368,14 +368,19 @@ class HUD:
|
||||
if (0 <= tree_local_pos[0] < self.tree_widget.rect.width and
|
||||
0 <= tree_local_pos[1] < self.tree_widget.rect.height):
|
||||
event.pos = tree_local_pos
|
||||
# This is the handle_event call that is being run even when the mouse is not over the tree widget
|
||||
if self.tree_widget.handle_event(event):
|
||||
selected_entities = self.tree_widget.get_selected_entities()
|
||||
return 'tree_selection_changed', selected_entities
|
||||
else:
|
||||
# Mouse left the tree widget area, clear hover
|
||||
self.tree_widget.clear_hover()
|
||||
else:
|
||||
# For non-mouse events, try handling them normally
|
||||
if self.tree_widget.handle_event(event):
|
||||
selected_entities = self.tree_widget.get_selected_entities()
|
||||
return 'tree_selection_changed', selected_entities
|
||||
# Handle specific mouse events in tree widget (but not wheel - handled by InputHandler)
|
||||
if event.type in (pygame.MOUSEBUTTONDOWN, pygame.MOUSEBUTTONUP):
|
||||
if self.tree_widget.handle_event(event):
|
||||
selected_entities = self.tree_widget.get_selected_entities()
|
||||
return 'tree_selection_changed', selected_entities
|
||||
|
||||
# Handle simulation control button events using ID matching
|
||||
if event.type == pygame_gui.UI_BUTTON_START_PRESS:
|
||||
|
||||
@ -23,11 +23,7 @@ class TreeNode(ABC):
|
||||
def add_child(self, child: 'TreeNode') -> None:
|
||||
"""Add a child node to this node."""
|
||||
child.parent = self
|
||||
old_depth = child.depth
|
||||
child.depth = self.depth + 1
|
||||
# Debug: check if depth changed incorrectly
|
||||
if hasattr(child, 'entity') and isinstance(child, EntityNode) and old_depth != child.depth:
|
||||
print(f"EntityNode depth changed from {old_depth} to {child.depth} when added to {self.label}")
|
||||
self.children.append(child)
|
||||
|
||||
def remove_child(self, child: 'TreeNode') -> None:
|
||||
@ -81,12 +77,7 @@ class TreeNode(ABC):
|
||||
|
||||
def get_indent(self) -> int:
|
||||
"""Get the indentation width for this node."""
|
||||
indent = self.depth * 20
|
||||
# Debug: print inconsistent depths (only for EntityNodes)
|
||||
if hasattr(self, 'entity') and isinstance(self, EntityNode):
|
||||
if self.depth != 2: # EntityNodes should always be depth 2 (Simulation -> EntityType -> Entity)
|
||||
print(f"Entity {self.entity_id} has inconsistent depth: {self.depth}, indent: {indent}")
|
||||
return indent
|
||||
return self.depth * 20
|
||||
|
||||
|
||||
class SimulationNode(TreeNode):
|
||||
@ -131,9 +122,9 @@ class SimulationNode(TreeNode):
|
||||
else:
|
||||
# Create new type node
|
||||
type_node = EntityTypeNode(type_name, entities)
|
||||
print(f"SimulationNode: adding {type_name} with current depth {type_node.depth}, my depth is {self.depth}")
|
||||
self.add_child(type_node)
|
||||
print(f"SimulationNode: after adding, {type_name} has depth {type_node.depth}")
|
||||
# Now update children after this node has correct depth
|
||||
type_node._update_children()
|
||||
|
||||
|
||||
class EntityTypeNode(TreeNode):
|
||||
@ -142,8 +133,6 @@ class EntityTypeNode(TreeNode):
|
||||
def __init__(self, entity_type: str, entities: List[Any]):
|
||||
super().__init__(entity_type)
|
||||
self.entities = entities
|
||||
# Debug: check depth
|
||||
print(f"EntityTypeNode {entity_type} created with depth {self.depth}")
|
||||
# Don't call _update_children() here - parent will call after adding this node
|
||||
|
||||
def _update_children(self) -> None:
|
||||
@ -162,9 +151,6 @@ class EntityTypeNode(TreeNode):
|
||||
# Update existing node
|
||||
entity_node = existing_ids[entity_id]
|
||||
entity_node.entity = entity
|
||||
# Debug: verify depth is correct for updated nodes
|
||||
if entity_node.depth != self.depth + 1:
|
||||
print(f"Updated EntityNode {entity_id} has wrong depth: {entity_node.depth}, should be {self.depth + 1}")
|
||||
else:
|
||||
# Create new entity node
|
||||
entity_node = EntityNode(entity)
|
||||
|
||||
@ -42,6 +42,7 @@ class TreeWidget(UIElement):
|
||||
self.hovered_node: Optional[TreeNode] = None
|
||||
self.drag_start_node: Optional[TreeNode] = None
|
||||
self.is_dragging = False
|
||||
self.last_mouse_pos: Optional[Tuple[int, int]] = None
|
||||
|
||||
# Scrolling
|
||||
self.scroll_offset = 0
|
||||
@ -183,6 +184,7 @@ class TreeWidget(UIElement):
|
||||
if event.type == pygame.MOUSEBUTTONDOWN:
|
||||
if event.button == 1: # Left click
|
||||
# Event position is already converted to local coordinates by HUD
|
||||
self.last_mouse_pos = event.pos
|
||||
node = self._get_node_at_position_local(event.pos)
|
||||
if node:
|
||||
# Check for expand/collapse click
|
||||
@ -197,6 +199,7 @@ class TreeWidget(UIElement):
|
||||
|
||||
elif event.type == pygame.MOUSEMOTION:
|
||||
# Event position is already converted to local coordinates by HUD
|
||||
self.last_mouse_pos = event.pos
|
||||
self.hovered_node = self._get_node_at_position_local(event.pos)
|
||||
return True
|
||||
|
||||
@ -218,6 +221,9 @@ class TreeWidget(UIElement):
|
||||
if self._should_update_tree():
|
||||
self._update_tree_structure()
|
||||
self._update_visible_nodes()
|
||||
# Recalculate hover state based on last mouse position after structure changes
|
||||
if self.last_mouse_pos:
|
||||
self.hovered_node = self._get_node_at_position_local(self.last_mouse_pos)
|
||||
|
||||
def _should_update_tree(self) -> bool:
|
||||
"""Determine if the tree structure needs updating."""
|
||||
@ -318,3 +324,8 @@ class TreeWidget(UIElement):
|
||||
)
|
||||
|
||||
self._update_node_layout()
|
||||
|
||||
def clear_hover(self) -> None:
|
||||
"""Clear the hover state (called when mouse leaves tree widget)."""
|
||||
self.hovered_node = None
|
||||
self.last_mouse_pos = None
|
||||
Loading…
x
Reference in New Issue
Block a user