136 lines
5.5 KiB
Python
136 lines
5.5 KiB
Python
"""
|
|
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"
|