Refactor calendar display: Center content, improve text wrapping, use correct time format

This commit is contained in:
ChuckBuilds
2025-04-21 14:01:54 -05:00
parent 66516c0425
commit b2b1d63b84

View File

@@ -85,56 +85,70 @@ class CalendarManager:
logging.error(f"Error fetching calendar events: {str(e)}") logging.error(f"Error fetching calendar events: {str(e)}")
return [] return []
def draw_event(self, event, y_position): def draw_event(self, event, y_start=1):
"""Draw a single calendar event on the canvas.""" """Draw a single calendar event on the canvas."""
try: try:
# Get event details # Get event details
summary = event.get('summary', 'No Title') summary = event.get('summary', 'No Title')
start = event.get('start', {}).get('dateTime', event.get('start', {}).get('date')) time_str = self._format_event_time(event)
if start:
start_time = datetime.fromisoformat(start.replace('Z', '+00:00'))
time_str = start_time.strftime('%H:%M')
else:
time_str = 'All Day'
# Calculate available width (assuming 32x32 matrix) # Use display manager's font for wrapping
available_width = self.matrix.width - 2 # Leave 1 pixel margin on each side font = self.display_manager.small_font
available_width = self.display_manager.matrix.width - 4 # Leave 2 pixel margin on each side
# Draw time in green # Wrap title text
self.display_manager.draw_text(time_str, y=y_position, color=self.date_color, small_font=True) title_lines = self._wrap_text(summary, available_width, font)
# Draw title, wrapping if needed
title_lines = self._wrap_text(summary, available_width)
for i, line in enumerate(title_lines):
line_y = y_position + 8 + (i * 8) # 8 pixels between lines
if line_y >= self.matrix.height - 8: # Leave space at bottom
break
self.display_manager.draw_text(line, y=line_y, color=self.text_color, small_font=True)
# Return the next available y position
return y_position + 8 + (len(title_lines) * 8)
except Exception as e:
logging.error(f"Error drawing calendar event: {str(e)}")
return y_position
def _wrap_text(self, text, max_width): # Calculate total height needed
"""Wrap text to fit within max_width using small font.""" time_height = 8 # Approximate height for time string with small font
title_height = len(title_lines) * 8 # Approximate height for title lines
total_height = time_height + title_height + (len(title_lines) * 2) # Add 2px spacing per title line
# Calculate starting y position to center vertically
y_pos = (self.display_manager.matrix.height - total_height) // 2
y_pos = max(1, y_pos) # Ensure it doesn't start above the top edge
# Draw time in green
self.display_manager.draw_text(time_str, y=y_pos, color=self.date_color, small_font=True)
y_pos += time_height + 2 # Move down for the title, add 2px spacing
# Draw title lines
for line in title_lines:
if y_pos >= self.display_manager.matrix.height - 8: # Stop if we run out of space
break
self.display_manager.draw_text(line, y=y_pos, color=self.text_color, small_font=True)
y_pos += 8 + 2 # Move down for the next line, add 2px spacing
except Exception as e:
logging.error(f"Error drawing calendar event: {str(e)}", exc_info=True)
def _wrap_text(self, text, max_width, font):
"""Wrap text to fit within max_width using the provided font."""
if not text: if not text:
return [""] return [""]
words = text.split()
lines = [] lines = []
words = text.split()
current_line = [] current_line = []
for word in words: for word in words:
# Test if adding this word would exceed max_width
test_line = ' '.join(current_line + [word]) test_line = ' '.join(current_line + [word])
if len(test_line) * 4 <= max_width: # Assuming small font is ~4 pixels wide # Use textlength for accurate width calculation
text_width = self.display_manager.draw.textlength(test_line, font=font)
if text_width <= max_width:
current_line.append(word) current_line.append(word)
else: else:
if current_line: # If the word itself is too long, add it on its own line (or handle differently if needed)
if not current_line:
lines.append(word)
else:
lines.append(' '.join(current_line)) lines.append(' '.join(current_line))
current_line = [word] current_line = [word]
# Recheck if the new line with just this word is too long
if self.display_manager.draw.textlength(word, font=font) > max_width:
# Handle very long words if necessary (e.g., truncate)
pass
if current_line: if current_line:
lines.append(' '.join(current_line)) lines.append(' '.join(current_line))
@@ -176,6 +190,10 @@ class CalendarManager:
def display(self): def display(self):
"""Display calendar events on the matrix""" """Display calendar events on the matrix"""
if not self.enabled or not self.events: if not self.enabled or not self.events:
# Optionally display a 'No events' message here
# self.display_manager.clear()
# self.display_manager.draw_text("No Events", small_font=True)
# self.display_manager.update_display()
return return
# Clear the display # Clear the display
@@ -186,8 +204,8 @@ class CalendarManager:
self.current_event_index = 0 self.current_event_index = 0
event = self.events[self.current_event_index] event = self.events[self.current_event_index]
# Draw the event starting from the top with proper spacing # Draw the event centered vertically
self.draw_event(event, 1) # Start 1 pixel from top self.draw_event(event)
# Update the display # Update the display
self.display_manager.update_display() self.display_manager.update_display()