Improve selection behavior: click anywhere to select, single-line text for selected events
- Allow clicking anywhere on event line to select person (like selecting event) - Selected events always show single-line text (no multi-line expansion) - Force is_expanded=False for selected events to prevent text switching - Always collapse expanded events when selecting person - Selection and expansion are now completely separate actions
This commit is contained in:
parent
52fece65a9
commit
079049952a
@ -616,8 +616,10 @@ class MyTimelineView(NavigationView):
|
||||
timeline_x = TIMELINE_MARGIN_LEFT
|
||||
marker_area_width = EVENT_MARKER_SIZE + 20
|
||||
|
||||
# Allow person selection from anywhere on the line
|
||||
# Clicking anywhere on the event line selects the person
|
||||
# Clicking anywhere on the event line selects the person (like selecting the event)
|
||||
# Always collapse any expanded event when selecting
|
||||
self.expanded_event_index = None
|
||||
|
||||
if clicked_person:
|
||||
person_handle = clicked_person.get_handle()
|
||||
if self.selected_person_handle == person_handle:
|
||||
@ -630,13 +632,6 @@ class MyTimelineView(NavigationView):
|
||||
# No person for this event, deselect
|
||||
self.selected_person_handle = None
|
||||
|
||||
# Also toggle expansion if clicking on label area (right side)
|
||||
if scaled_x > timeline_x + marker_area_width:
|
||||
if self.expanded_event_index == clicked_index:
|
||||
self.expanded_event_index = None
|
||||
else:
|
||||
self.expanded_event_index = clicked_index
|
||||
|
||||
self.drawing_area.queue_draw()
|
||||
return False
|
||||
|
||||
@ -709,35 +704,75 @@ class MyTimelineView(NavigationView):
|
||||
date_range = 1
|
||||
|
||||
timeline_x = TIMELINE_MARGIN_LEFT
|
||||
timeline_y_start = TIMELINE_MARGIN_TOP
|
||||
timeline_y_end = height - TIMELINE_MARGIN_BOTTOM
|
||||
|
||||
# Calculate initial Y positions (same as in on_draw)
|
||||
events_with_y_pos = []
|
||||
for i, event_data in enumerate(self.events):
|
||||
date_sort, date_obj, event, person, event_type, expanded, _ = event_data
|
||||
y_pos = TIMELINE_MARGIN_TOP + (
|
||||
y_pos = timeline_y_start + (
|
||||
(date_sort - min_date) / date_range
|
||||
) * (height - TIMELINE_MARGIN_TOP - TIMELINE_MARGIN_BOTTOM)
|
||||
events_with_y_pos.append((i, y_pos, event_data))
|
||||
) * (timeline_y_end - timeline_y_start)
|
||||
events_with_y_pos.append((date_sort, date_obj, event, person, event_type, expanded, y_pos))
|
||||
|
||||
# Check each event using adjusted positions
|
||||
# We need to simulate the collision detection, but for simplicity,
|
||||
# we'll check against the calculated positions and use a wider tolerance
|
||||
for i, y_pos, event_data in events_with_y_pos:
|
||||
date_sort, date_obj, event, person, event_type, expanded, _ = event_data
|
||||
# Apply same collision detection as in on_draw
|
||||
# Create a temporary Cairo surface for text measurement
|
||||
import cairo
|
||||
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 1, 1)
|
||||
temp_context = cairo.Context(surface)
|
||||
layout = PangoCairo.create_layout(temp_context)
|
||||
layout.set_font_description(Pango.font_description_from_string("Sans 11"))
|
||||
|
||||
# Calculate clickable area - wider to include label area
|
||||
marker_size = EVENT_MARKER_SIZE
|
||||
label_x = timeline_x + 25
|
||||
adjusted_events = []
|
||||
min_spacing = 30 # Minimum spacing between labels in pixels
|
||||
|
||||
# Estimate label width (we'll use a reasonable default)
|
||||
# For whole-line selection, check if click is in the event's horizontal band
|
||||
clickable_width = 600 # Reasonable width for label area
|
||||
clickable_height = max(marker_size * 2, 30) # At least marker size or 30px
|
||||
for event_data in events_with_y_pos:
|
||||
date_sort, date_obj, event, person, event_type, expanded, y_pos = event_data
|
||||
|
||||
# Calculate label height (same as detect_label_overlaps)
|
||||
if person:
|
||||
person_name = name_displayer.display(person)
|
||||
date_str = get_date(event)
|
||||
event_type_str = str(event_type)
|
||||
label_text = f"{date_str} - {event_type_str} - {person_name}"
|
||||
else:
|
||||
date_str = get_date(event)
|
||||
event_type_str = str(event_type)
|
||||
label_text = f"{date_str} - {event_type_str}"
|
||||
|
||||
layout.set_text(label_text, -1)
|
||||
text_width, text_height = layout.get_pixel_size()
|
||||
label_height = text_height + 16 # Add padding
|
||||
|
||||
# Check for overlap with previous events
|
||||
adjusted_y = y_pos
|
||||
for prev_data in adjusted_events:
|
||||
prev_y_pos = prev_data[6] # Get y_pos from previous event
|
||||
# Check if labels would overlap
|
||||
if abs(adjusted_y - prev_y_pos) < min_spacing:
|
||||
# Adjust downward
|
||||
adjusted_y = prev_y_pos + min_spacing
|
||||
|
||||
# Ensure adjusted position is within bounds
|
||||
adjusted_y = max(timeline_y_start, min(adjusted_y, timeline_y_end))
|
||||
|
||||
# Create new event data with adjusted Y position
|
||||
adjusted_events.append((date_sort, date_obj, event, person, event_type, expanded, adjusted_y))
|
||||
|
||||
# Now check each event using adjusted positions
|
||||
marker_size = EVENT_MARKER_SIZE
|
||||
label_x = timeline_x + 25
|
||||
clickable_width = 600 # Reasonable width for label area
|
||||
clickable_height = max(marker_size * 2, 30) # At least marker size or 30px
|
||||
|
||||
for i, event_data in enumerate(adjusted_events):
|
||||
date_sort, date_obj, event, person, event_type, expanded, adjusted_y = event_data
|
||||
|
||||
# Check if click is in the event's area (marker + label)
|
||||
if (scaled_x >= timeline_x - marker_size - 10 and
|
||||
scaled_x <= label_x + clickable_width and
|
||||
abs(scaled_y - y_pos) < clickable_height / 2):
|
||||
abs(scaled_y - adjusted_y) < clickable_height / 2):
|
||||
return i
|
||||
|
||||
return None
|
||||
@ -925,6 +960,11 @@ class MyTimelineView(NavigationView):
|
||||
is_selected = (self.selected_person_handle is not None and
|
||||
person and person.get_handle() == self.selected_person_handle)
|
||||
|
||||
# Selected events should not show expanded (multi-line) text
|
||||
# Only show expanded text if explicitly expanded AND not selected
|
||||
if is_selected:
|
||||
is_expanded = False
|
||||
|
||||
# Draw event marker with modern styling
|
||||
self.draw_event_marker(context, timeline_x, y_pos, event_type, is_hovered, is_selected)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user