You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
5.5 KiB

"""
Leaderboard Screen
Display global and device leaderboards with rankings and scores
"""
from .base_screen import BaseScreen
class LeaderboardScreen(BaseScreen):
"""Leaderboard display screen implementation"""
def __init__(self, data_manager, ui_renderer, screen_manager):
super().__init__(data_manager, ui_renderer, screen_manager)
# Leaderboard state
self.leaderboard_type = "device" # "device" or "global"
self.leaderboard_data = []
def render(self) -> None:
"""Render leaderboard screen"""
title = f"{self.leaderboard_type.title()} Leaderboard"
self.ui_renderer.draw_header(title)
if not self.data_manager.api_enabled:
self.ui_renderer.draw_text("Server offline - No leaderboard available",
320, 150, 'red', 'medium', center=True)
self.ui_renderer.draw_button("← Back", 270, 200, 100, 30, True)
return
# Controls
toggle_text = f"Type: {self.leaderboard_type.title()} (Left/Right to toggle)"
toggle_selected = (self.selected_index == 0)
self.ui_renderer.draw_button(toggle_text, 120, 90, 400, 25, toggle_selected)
refresh_selected = (self.selected_index == 1)
back_selected = (self.selected_index == 2)
self.ui_renderer.draw_button("Refresh", 150, 125, 80, 25, refresh_selected)
self.ui_renderer.draw_button("← Back", 250, 125, 80, 25, back_selected)
# Leaderboard data
if not self.leaderboard_data:
self.ui_renderer.draw_text("No leaderboard data available", 320, 200,
'yellow', 'medium', center=True)
else:
self._render_leaderboard_data()
self.ui_renderer.draw_footer_help(self.get_help_text())
def _render_leaderboard_data(self) -> None:
"""Render the leaderboard data table"""
# Draw leaderboard entries
panel_height = min(250, len(self.leaderboard_data) * 25 + 40)
self.ui_renderer.draw_panel(50, 160, 540, panel_height, 'black', 'gray')
# Headers
self.ui_renderer.draw_text("Rank", 60, 175, 'light_blue', 'small')
self.ui_renderer.draw_text("Player", 120, 175, 'light_blue', 'small')
self.ui_renderer.draw_text("Score", 350, 175, 'light_blue', 'small')
self.ui_renderer.draw_text("Games", 450, 175, 'light_blue', 'small')
if self.leaderboard_type == "global":
self.ui_renderer.draw_text("Device", 520, 175, 'light_blue', 'small')
# Entries
for i, entry in enumerate(self.leaderboard_data):
entry_y = 195 + i * 22
# Highlight current user
is_current = (self.data_manager.active_profile and
entry.get('user_id') == self.data_manager.active_profile)
text_color = 'light_green' if is_current else 'light_gray'
self.ui_renderer.draw_text(str(entry.get('rank', i+1)), 60, entry_y, text_color, 'tiny')
player_name = entry.get('user_id', 'Unknown')[:20]
self.ui_renderer.draw_text(player_name, 120, entry_y, text_color, 'tiny')
self.ui_renderer.draw_text(str(entry.get('best_score', 0)), 350, entry_y, text_color, 'tiny')
self.ui_renderer.draw_text(str(entry.get('total_games', 0)), 450, entry_y, text_color, 'tiny')
if self.leaderboard_type == "global":
device = entry.get('device_id', '')[:8]
self.ui_renderer.draw_text(device, 520, entry_y, text_color, 'tiny')
def handle_input(self, action: str) -> bool:
"""Handle leaderboard input"""
max_index = 2 # Toggle, Refresh, Back
if action == 'up':
self.navigate_up()
return True
elif action == 'down':
self.navigate_down(max_index)
return True
elif action == 'left':
if self.selected_index == 0: # Toggle leaderboard type
self.toggle_leaderboard_type()
return True
elif action == 'right':
if self.selected_index == 0: # Toggle leaderboard type
self.toggle_leaderboard_type()
return True
elif action == 'confirm':
self.handle_confirm()
return True
elif action == 'back':
self.handle_back()
return True
return False
def toggle_leaderboard_type(self) -> None:
"""Toggle between device and global leaderboard"""
self.leaderboard_type = "global" if self.leaderboard_type == "device" else "device"
self.load_leaderboard_data()
def handle_confirm(self) -> None:
"""Handle leaderboard actions"""
if self.selected_index == 1: # Refresh
self.load_leaderboard_data()
elif self.selected_index == 2: # Back
self.handle_back()
def load_leaderboard_data(self) -> None:
"""Load leaderboard data from data manager"""
self.leaderboard_data = self.data_manager.get_leaderboard_data(self.leaderboard_type)
def reset_state(self) -> None:
"""Reset screen state when entering"""
super().reset_state()
self.load_leaderboard_data()
def get_help_text(self) -> str:
"""Get help text for leaderboard"""
return "Left/Right: Toggle Type • Enter: Select • Escape: Back"