2025-07-10 22:32:35 +02:00
import pygame # type: ignore
2025-07-06 19:47:21 +02:00
import config
2025-07-10 22:32:35 +02:00
from utils import truncate_text_middle , wrap_text , load_system_image
2025-07-06 19:47:21 +02:00
import logging
2025-07-10 22:32:35 +02:00
import math
2025-07-07 02:48:05 +02:00
from history import load_history # Ajout de l'import
2025-07-06 19:47:21 +02:00
logger = logging . getLogger ( __name__ )
2025-07-06 22:05:20 +02:00
OVERLAY = None # Initialisé dans init_display()
2025-07-06 21:13:39 +02:00
2025-07-10 22:32:35 +02:00
# Couleurs modernes pour le thème
THEME_COLORS = {
# Fond des lignes sélectionnées
" fond_lignes " : ( 0 , 255 , 0 ) , # vert
# Fond par défaut des images de grille des systèmes
" fond_image " : ( 50 , 50 , 70 ) , # Bleu sombre métal
# Néon image grille des systèmes
" neon " : ( 0 , 134 , 179 ) , # bleu
# Dégradé sombre pour le fond
" background_top " : ( 30 , 40 , 50 ) ,
" background_bottom " : ( 60 , 80 , 100 ) , # noir vers bleu foncé
# Fond des cadres
" button_idle " : ( 50 , 50 , 70 , 150 ) , # Bleu sombre métal
# Fond des boutons sélectionnés dans les popups ou menu
" button_hover " : ( 255 , 0 , 255 , 220 ) , # Rose
# Générique
" text " : ( 255 , 255 , 255 ) , # blanc
# Erreur
" error_text " : ( 255 , 0 , 0 ) , # rouge
# Avertissement
" warning_text " : ( 255 , 100 , 0 ) , # orange
# Titres
" title_text " : ( 200 , 200 , 200 ) , # gris clair
# Bordures
" border " : ( 150 , 150 , 150 ) , # Bordures grises subtiles
}
# Général, résolution, overlay
2025-07-06 19:47:21 +02:00
def init_display ( ) :
2025-07-07 03:46:28 +02:00
""" Initialise l ' écran et les ressources globales. """
2025-07-06 21:47:06 +02:00
global OVERLAY
2025-07-07 03:46:28 +02:00
logger . debug ( " Initialisation de l ' écran " )
display_info = pygame . display . Info ( )
screen_width = display_info . current_w
screen_height = display_info . current_h
screen = pygame . display . set_mode ( ( screen_width , screen_height ) )
config . screen_width = screen_width
config . screen_height = screen_height
# Initialisation de OVERLAY
OVERLAY = pygame . Surface ( ( screen_width , screen_height ) , pygame . SRCALPHA )
2025-07-10 22:32:35 +02:00
OVERLAY . fill ( ( 0 , 0 , 0 , 150 ) ) # Transparence augmentée
2025-07-07 03:46:28 +02:00
logger . debug ( f " Écran initialisé avec résolution : { screen_width } x { screen_height } " )
2025-07-06 19:47:21 +02:00
return screen
2025-07-06 22:05:20 +02:00
2025-07-10 22:32:35 +02:00
# Fond d'écran dégradé
2025-07-06 19:47:21 +02:00
def draw_gradient ( screen , top_color , bottom_color ) :
2025-07-10 22:32:35 +02:00
""" Dessine un fond dégradé vertical avec des couleurs vibrantes. """
2025-07-06 19:47:21 +02:00
height = screen . get_height ( )
top_color = pygame . Color ( * top_color )
bottom_color = pygame . Color ( * bottom_color )
for y in range ( height ) :
ratio = y / height
color = top_color . lerp ( bottom_color , ratio )
pygame . draw . line ( screen , color , ( 0 , y ) , ( screen . get_width ( ) , y ) )
2025-07-10 22:32:35 +02:00
# Nouvelle fonction pour dessiner un bouton stylisé
def draw_stylized_button ( screen , text , x , y , width , height , selected = False ) :
""" Dessine un bouton moderne avec effet de survol et bordure arrondie. """
button_surface = pygame . Surface ( ( width , height ) , pygame . SRCALPHA )
button_color = THEME_COLORS [ " button_hover " ] if selected else THEME_COLORS [ " button_idle " ]
pygame . draw . rect ( button_surface , button_color , ( 0 , 0 , width , height ) , border_radius = 12 )
pygame . draw . rect ( button_surface , THEME_COLORS [ " border " ] , ( 0 , 0 , width , height ) , 2 , border_radius = 12 )
if selected :
glow_surface = pygame . Surface ( ( width + 10 , height + 10 ) , pygame . SRCALPHA )
pygame . draw . rect ( glow_surface , THEME_COLORS [ " fond_lignes " ] + ( 50 , ) , ( 5 , 5 , width , height ) , border_radius = 12 )
screen . blit ( glow_surface , ( x - 5 , y - 5 ) )
screen . blit ( button_surface , ( x , y ) )
text_surface = config . font . render ( text , True , THEME_COLORS [ " text " ] )
text_rect = text_surface . get_rect ( center = ( x + width / / 2 , y + height / / 2 ) )
screen . blit ( text_surface , text_rect )
# Transition d'image lors de la sélection d'un système
2025-07-09 01:13:55 +02:00
def draw_validation_transition ( screen , platform_index ) :
2025-07-10 22:32:35 +02:00
""" Affiche une animation de transition fluide pour la sélection d’ une plateforme. """
2025-07-09 01:13:55 +02:00
platform_dict = config . platform_dicts [ platform_index ]
image = load_system_image ( platform_dict )
if not image :
return
2025-07-10 22:32:35 +02:00
# Dimensions originales et calcul du ratio pour préserver les proportions
2025-07-09 01:13:55 +02:00
orig_width , orig_height = image . get_width ( ) , image . get_height ( )
base_size = int ( config . screen_width * 0.0781 ) # ~150px pour 1920p
2025-07-10 22:32:35 +02:00
ratio = min ( base_size / orig_width , base_size / orig_height ) # Maintenir les proportions
base_width = int ( orig_width * ratio )
base_height = int ( orig_height * ratio )
# Paramètres de l'animation
2025-07-09 01:13:55 +02:00
start_time = pygame . time . get_ticks ( )
2025-07-10 22:32:35 +02:00
duration = 1000 # Durée augmentée à 1 seconde
fps = 60
frame_time = 1000 / fps # Temps par frame en ms
2025-07-09 01:13:55 +02:00
while pygame . time . get_ticks ( ) - start_time < duration :
2025-07-10 22:32:35 +02:00
# Fond dégradé
draw_gradient ( screen , THEME_COLORS [ " background_top " ] , THEME_COLORS [ " background_bottom " ] )
# Calcul de l'échelle avec une courbe sinusoïdale pour une transition fluide
2025-07-09 01:13:55 +02:00
elapsed = pygame . time . get_ticks ( ) - start_time
2025-07-10 22:32:35 +02:00
progress = elapsed / duration
# Courbe sinusoïdale pour une montée/descente douce
scale = 1.5 + 1.0 * math . sin ( math . pi * progress ) # Échelle de 1.5 à 2.5
new_width = int ( base_width * scale )
new_height = int ( base_height * scale )
# Redimensionner l'image en préservant les proportions
2025-07-09 01:13:55 +02:00
scaled_image = pygame . transform . smoothscale ( image , ( new_width , new_height ) )
image_rect = scaled_image . get_rect ( center = ( config . screen_width / / 2 , config . screen_height / / 2 ) )
2025-07-10 22:32:35 +02:00
# Effet de fondu (opacité de 50% à 100% puis retour à 50%)
alpha = int ( 128 + 127 * math . cos ( math . pi * progress ) ) # Opacité entre 128 et 255
scaled_image . set_alpha ( alpha )
# Effet de glow néon pour l'image sélectionnée
neon_color = THEME_COLORS [ " neon " ] # Cyan vif
padding = 24
neon_surface = pygame . Surface ( ( new_width + 2 * padding , new_height + 2 * padding ) , pygame . SRCALPHA )
pygame . draw . rect ( neon_surface , neon_color + ( 40 , ) , neon_surface . get_rect ( ) , border_radius = 24 )
pygame . draw . rect ( neon_surface , neon_color + ( 100 , ) , neon_surface . get_rect ( ) . inflate ( - 10 , - 10 ) , border_radius = 18 )
screen . blit ( neon_surface , ( image_rect . left - padding , image_rect . top - padding ) , special_flags = pygame . BLEND_RGBA_ADD )
# Afficher l'image
2025-07-09 01:13:55 +02:00
screen . blit ( scaled_image , image_rect )
pygame . display . flip ( )
2025-07-10 22:32:35 +02:00
# Contrôler la fréquence de rendu
pygame . time . wait ( int ( frame_time ) )
# Afficher l'image finale sans effet pour une transition propre
draw_gradient ( screen , THEME_COLORS [ " background_top " ] , THEME_COLORS [ " background_bottom " ] )
final_image = pygame . transform . smoothscale ( image , ( base_width , base_height ) )
final_image . set_alpha ( 255 ) # Opacité complète
final_rect = final_image . get_rect ( center = ( config . screen_width / / 2 , config . screen_height / / 2 ) )
screen . blit ( final_image , final_rect )
pygame . display . flip ( )
# Écran de chargement
2025-07-06 19:47:21 +02:00
def draw_loading_screen ( screen ) :
2025-07-10 22:32:35 +02:00
""" Affiche l’ écran de chargement avec un style moderne. """
2025-07-06 19:47:21 +02:00
disclaimer_lines = [
" Bienvenue dans RGSX " ,
" It ' s dangerous to go alone, take all you need! " ,
" Mais ne téléchargez que des jeux " ,
" dont vous possédez les originaux ! "
]
2025-07-10 22:32:35 +02:00
margin_horizontal = int ( config . screen_width * 0.025 )
padding_vertical = int ( config . screen_height * 0.0185 )
padding_between = int ( config . screen_height * 0.0074 )
2025-07-06 19:47:21 +02:00
border_radius = 16
border_width = 3
shadow_offset = 6
2025-07-09 01:13:55 +02:00
line_height = config . small_font . get_height ( ) + padding_between
2025-07-06 19:47:21 +02:00
total_height = line_height * len ( disclaimer_lines ) - padding_between
rect_width = config . screen_width - 2 * margin_horizontal
rect_height = total_height + 2 * padding_vertical
rect_x = margin_horizontal
2025-07-10 22:32:35 +02:00
rect_y = int ( config . screen_height * 0.0185 )
2025-07-06 19:47:21 +02:00
shadow_rect = pygame . Rect ( rect_x + shadow_offset , rect_y + shadow_offset , rect_width , rect_height )
shadow_surface = pygame . Surface ( ( rect_width , rect_height ) , pygame . SRCALPHA )
pygame . draw . rect ( shadow_surface , ( 0 , 0 , 0 , 100 ) , shadow_surface . get_rect ( ) , border_radius = border_radius )
screen . blit ( shadow_surface , shadow_rect . topleft )
disclaimer_rect = pygame . Rect ( rect_x , rect_y , rect_width , rect_height )
disclaimer_surface = pygame . Surface ( ( rect_width , rect_height ) , pygame . SRCALPHA )
2025-07-10 22:32:35 +02:00
pygame . draw . rect ( disclaimer_surface , THEME_COLORS [ " button_idle " ] , disclaimer_surface . get_rect ( ) , border_radius = border_radius )
2025-07-06 19:47:21 +02:00
screen . blit ( disclaimer_surface , disclaimer_rect . topleft )
2025-07-10 22:32:35 +02:00
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , disclaimer_rect , border_width , border_radius = border_radius )
2025-07-06 19:47:21 +02:00
2025-07-06 22:05:20 +02:00
max_text_width = rect_width - 2 * padding_vertical
2025-07-06 19:47:21 +02:00
for i , line in enumerate ( disclaimer_lines ) :
2025-07-09 01:13:55 +02:00
wrapped_lines = wrap_text ( line , config . small_font , max_text_width )
2025-07-06 22:05:20 +02:00
for j , wrapped_line in enumerate ( wrapped_lines ) :
2025-07-10 22:32:35 +02:00
text_surface = config . small_font . render ( wrapped_line , True , THEME_COLORS [ " title_text " ] )
2025-07-06 22:05:20 +02:00
text_rect = text_surface . get_rect ( center = (
config . screen_width / / 2 ,
rect_y + padding_vertical + ( i * len ( wrapped_lines ) + j + 0.5 ) * line_height - padding_between / / 2
) )
screen . blit ( text_surface , text_rect )
2025-07-10 22:32:35 +02:00
loading_y = rect_y + rect_height + int ( config . screen_height * 0.0926 )
text = config . small_font . render ( truncate_text_middle ( f " { config . current_loading_system } " , config . small_font , config . screen_width - 2 * margin_horizontal ) , True , THEME_COLORS [ " text " ] )
2025-07-06 19:47:21 +02:00
text_rect = text . get_rect ( center = ( config . screen_width / / 2 , loading_y ) )
screen . blit ( text , text_rect )
2025-07-10 22:32:35 +02:00
progress_text = config . small_font . render ( f " Progression : { int ( config . loading_progress ) } % " , True , THEME_COLORS [ " text " ] )
progress_rect = progress_text . get_rect ( center = ( config . screen_width / / 2 , loading_y + int ( config . screen_height * 0.0463 ) ) )
2025-07-06 19:47:21 +02:00
screen . blit ( progress_text , progress_rect )
2025-07-10 22:32:35 +02:00
bar_width = int ( config . screen_width * 0.2083 )
bar_height = int ( config . screen_height * 0.037 )
2025-07-06 19:47:21 +02:00
progress_width = ( bar_width * config . loading_progress ) / 100
2025-07-10 22:32:35 +02:00
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , ( config . screen_width / / 2 - bar_width / / 2 , loading_y + int ( config . screen_height * 0.0926 ) , bar_width , bar_height ) , border_radius = 8 )
pygame . draw . rect ( screen , THEME_COLORS [ " fond_lignes " ] , ( config . screen_width / / 2 - bar_width / / 2 , loading_y + int ( config . screen_height * 0.0926 ) , progress_width , bar_height ) , border_radius = 8 )
2025-07-06 19:47:21 +02:00
2025-07-10 22:32:35 +02:00
# Écran d'erreur
2025-07-06 19:47:21 +02:00
def draw_error_screen ( screen ) :
2025-07-10 22:32:35 +02:00
""" Affiche l’ écran d’ erreur avec un style moderne. """
wrapped_message = wrap_text ( config . error_message , config . small_font , config . screen_width - 80 )
line_height = config . small_font . get_height ( ) + 5
text_height = len ( wrapped_message ) * line_height
button_height = int ( config . screen_height * 0.0463 )
margin_top_bottom = 20
rect_height = text_height + button_height + 2 * margin_top_bottom
max_text_width = max ( [ config . small_font . size ( line ) [ 0 ] for line in wrapped_message ] , default = 300 )
rect_width = max_text_width + 80
rect_x = ( config . screen_width - rect_width ) / / 2
rect_y = ( config . screen_height - rect_height ) / / 2
screen . blit ( OVERLAY , ( 0 , 0 ) )
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , ( rect_x , rect_y , rect_width , rect_height ) , border_radius = 12 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , ( rect_x , rect_y , rect_width , rect_height ) , 2 , border_radius = 12 )
2025-07-06 22:05:20 +02:00
for i , line in enumerate ( wrapped_message ) :
2025-07-10 22:32:35 +02:00
text = config . small_font . render ( line , True , THEME_COLORS [ " error_text " ] )
text_rect = text . get_rect ( center = ( config . screen_width / / 2 , rect_y + margin_top_bottom + i * line_height + line_height / / 2 ) )
2025-07-06 22:05:20 +02:00
screen . blit ( text , text_rect )
2025-07-09 01:13:55 +02:00
2025-07-10 22:32:35 +02:00
draw_stylized_button ( screen , " Valider " , rect_x + rect_width / / 2 - 80 , rect_y + text_height + margin_top_bottom , 160 , button_height , selected = True )
# Récupérer les noms d'affichage des contrôles
2025-07-09 01:13:55 +02:00
def get_control_display ( action , default ) :
""" Récupère le nom d ' affichage d ' une action depuis controls_config. """
if not config . controls_config :
logger . warning ( f " controls_config vide pour l ' action { action } , utilisation de la valeur par défaut " )
return default
return config . controls_config . get ( action , { } ) . get ( ' display ' , default )
2025-07-06 19:47:21 +02:00
2025-07-10 22:32:35 +02:00
# Grille des systèmes 3x3
2025-07-06 19:47:21 +02:00
def draw_platform_grid ( screen ) :
2025-07-10 22:32:35 +02:00
""" Affiche la grille des plateformes avec un style moderne. """
2025-07-07 00:27:08 +02:00
if not config . platforms or config . selected_platform > = len ( config . platforms ) :
platform_name = " Aucune plateforme "
logger . warning ( " Aucune plateforme ou selected_platform hors limites " )
else :
platform = config . platforms [ config . selected_platform ]
platform_name = config . platform_names . get ( platform , platform )
2025-07-07 00:02:20 +02:00
title_text = f " { platform_name } "
2025-07-10 22:32:35 +02:00
title_surface = config . title_font . render ( title_text , True , THEME_COLORS [ " text " ] )
title_rect = title_surface . get_rect ( center = ( config . screen_width / / 2 , title_surface . get_height ( ) / / 2 + 20 ) )
title_rect_inflated = title_rect . inflate ( 60 , 30 )
title_rect_inflated . topleft = ( ( config . screen_width - title_rect_inflated . width ) / / 2 , 10 )
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , title_rect_inflated , border_radius = 12 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , title_rect_inflated , 2 , border_radius = 12 )
2025-07-07 00:02:20 +02:00
screen . blit ( title_surface , title_rect )
2025-07-10 22:32:35 +02:00
margin_left = int ( config . screen_width * 0.026 )
2025-07-06 22:05:20 +02:00
margin_right = int ( config . screen_width * 0.026 )
2025-07-10 22:32:35 +02:00
margin_top = int ( config . screen_height * 0.140 )
margin_bottom = int ( config . screen_height * 0.0648 )
2025-07-06 19:47:21 +02:00
num_cols = 3
2025-07-10 22:32:35 +02:00
num_rows = 4
2025-07-06 19:47:21 +02:00
systems_per_page = num_cols * num_rows
available_width = config . screen_width - margin_left - margin_right
available_height = config . screen_height - margin_top - margin_bottom
col_width = available_width / / num_cols
row_height = available_height / / num_rows
x_positions = [ margin_left + col_width * i + col_width / / 2 for i in range ( num_cols ) ]
y_positions = [ margin_top + row_height * i + row_height / / 2 for i in range ( num_rows ) ]
start_idx = config . current_page * systems_per_page
for idx in range ( start_idx , start_idx + systems_per_page ) :
if idx > = len ( config . platforms ) :
break
grid_idx = idx - start_idx
row = grid_idx / / num_cols
col = grid_idx % num_cols
x = x_positions [ col ]
y = y_positions [ row ]
scale = 1.5 if idx == config . selected_platform else 1.0
platform_dict = config . platform_dicts [ idx ]
image = load_system_image ( platform_dict )
if image :
orig_width , orig_height = image . get_width ( ) , image . get_height ( )
2025-07-10 22:32:35 +02:00
max_size = int ( min ( col_width , row_height ) * scale * 1.1 ) # Légèrement plus grand que la cellule
2025-07-06 19:47:21 +02:00
ratio = min ( max_size / orig_width , max_size / orig_height )
new_width = int ( orig_width * ratio )
new_height = int ( orig_height * ratio )
image = pygame . transform . smoothscale ( image , ( new_width , new_height ) )
image_rect = image . get_rect ( center = ( x , y ) )
if idx == config . selected_platform :
2025-07-10 22:32:35 +02:00
neon_color = THEME_COLORS [ " neon " ]
border_radius = 12
padding = 12
2025-07-06 19:47:21 +02:00
rect_width = image_rect . width + 2 * padding
rect_height = image_rect . height + 2 * padding
neon_surface = pygame . Surface ( ( rect_width , rect_height ) , pygame . SRCALPHA )
2025-07-10 22:32:35 +02:00
pygame . draw . rect ( neon_surface , neon_color + ( 40 , ) , neon_surface . get_rect ( ) , border_radius = border_radius )
pygame . draw . rect ( neon_surface , neon_color + ( 100 , ) , neon_surface . get_rect ( ) . inflate ( - 10 , - 10 ) , border_radius = border_radius )
pygame . draw . rect ( neon_surface , neon_color + ( 200 , ) , neon_surface . get_rect ( ) . inflate ( - 20 , - 20 ) , width = 1 , border_radius = border_radius )
2025-07-06 19:47:21 +02:00
screen . blit ( neon_surface , ( image_rect . left - padding , image_rect . top - padding ) , special_flags = pygame . BLEND_RGBA_ADD )
2025-07-10 22:32:35 +02:00
background_surface = pygame . Surface ( ( image_rect . width + 10 , image_rect . height + 10 ) , pygame . SRCALPHA )
pygame . draw . rect ( background_surface , THEME_COLORS [ " fond_image " ] + ( 180 , ) , background_surface . get_rect ( ) , border_radius = 12 )
screen . blit ( background_surface , ( image_rect . left - 5 , image_rect . top - 5 ) )
2025-07-06 19:47:21 +02:00
screen . blit ( image , image_rect )
2025-07-10 22:32:35 +02:00
# Liste des jeux
2025-07-07 00:02:20 +02:00
def draw_game_list ( screen ) :
2025-07-10 22:32:35 +02:00
""" Affiche la liste des jeux avec un style moderne. """
2025-07-07 00:02:20 +02:00
platform = config . platforms [ config . current_platform ]
platform_name = config . platform_names . get ( platform , platform )
games = config . filtered_games if config . filter_active or config . search_mode else config . games
game_count = len ( games )
if not games :
logger . debug ( " Aucune liste de jeux disponible " )
message = " Aucun jeu disponible "
lines = wrap_text ( message , config . font , config . screen_width - 80 )
line_height = config . font . get_height ( ) + 5
text_height = len ( lines ) * line_height
margin_top_bottom = 20
rect_height = text_height + 2 * margin_top_bottom
max_text_width = max ( [ config . font . size ( line ) [ 0 ] for line in lines ] , default = 300 )
2025-07-10 22:32:35 +02:00
rect_width = max_text_width + 80
2025-07-07 00:02:20 +02:00
rect_x = ( config . screen_width - rect_width ) / / 2
rect_y = ( config . screen_height - rect_height ) / / 2
screen . blit ( OVERLAY , ( 0 , 0 ) )
2025-07-10 22:32:35 +02:00
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , ( rect_x , rect_y , rect_width , rect_height ) , border_radius = 12 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , ( rect_x , rect_y , rect_width , rect_height ) , 2 , border_radius = 12 )
2025-07-07 00:02:20 +02:00
for i , line in enumerate ( lines ) :
2025-07-10 22:32:35 +02:00
text_surface = config . font . render ( line , True , THEME_COLORS [ " text " ] )
2025-07-07 00:02:20 +02:00
text_rect = text_surface . get_rect ( center = ( config . screen_width / / 2 , rect_y + margin_top_bottom + i * line_height + line_height / / 2 ) )
screen . blit ( text_surface , text_rect )
return
2025-07-09 01:13:55 +02:00
line_height = config . small_font . get_height ( ) + 10
2025-07-07 00:27:08 +02:00
margin_top_bottom = 20
2025-07-09 01:13:55 +02:00
extra_margin_top = 20
2025-07-10 22:32:35 +02:00
extra_margin_bottom = 60
2025-07-09 01:13:55 +02:00
title_height = config . title_font . get_height ( ) + 20
2025-07-07 00:02:20 +02:00
available_height = config . screen_height - title_height - extra_margin_top - extra_margin_bottom - 2 * margin_top_bottom
2025-07-09 01:13:55 +02:00
items_per_page = available_height / / line_height
rect_height = items_per_page * line_height + 2 * margin_top_bottom
rect_width = int ( 0.95 * config . screen_width )
2025-07-07 00:02:20 +02:00
rect_x = ( config . screen_width - rect_width ) / / 2
rect_y = title_height + extra_margin_top + ( config . screen_height - title_height - extra_margin_top - extra_margin_bottom - rect_height ) / / 2
2025-07-09 01:13:55 +02:00
config . scroll_offset = max ( 0 , min ( config . scroll_offset , max ( 0 , len ( games ) - items_per_page ) ) )
2025-07-07 00:02:20 +02:00
if config . current_game < config . scroll_offset :
config . scroll_offset = config . current_game
2025-07-09 01:13:55 +02:00
elif config . current_game > = config . scroll_offset + items_per_page :
config . scroll_offset = config . current_game - items_per_page + 1
2025-07-07 00:02:20 +02:00
screen . blit ( OVERLAY , ( 0 , 0 ) )
if config . search_mode :
search_text = f " Filtrer : { config . search_query } _ "
2025-07-10 22:32:35 +02:00
title_surface = config . search_font . render ( search_text , True , THEME_COLORS [ " text " ] )
title_rect = title_surface . get_rect ( center = ( config . screen_width / / 2 , title_surface . get_height ( ) / / 2 + 20 ) )
title_rect_inflated = title_rect . inflate ( 60 , 30 )
title_rect_inflated . topleft = ( ( config . screen_width - title_rect_inflated . width ) / / 2 , 10 )
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , title_rect_inflated , border_radius = 12 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , title_rect_inflated , 2 , border_radius = 12 )
2025-07-07 00:02:20 +02:00
screen . blit ( title_surface , title_rect )
elif config . filter_active :
filter_text = f " Filtre actif : { config . search_query } "
2025-07-10 22:32:35 +02:00
title_surface = config . small_font . render ( filter_text , True , THEME_COLORS [ " text " ] )
title_rect = title_surface . get_rect ( center = ( config . screen_width / / 2 , title_surface . get_height ( ) / / 2 + 20 ) )
title_rect_inflated = title_rect . inflate ( 60 , 30 )
title_rect_inflated . topleft = ( ( config . screen_width - title_rect_inflated . width ) / / 2 , 10 )
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , title_rect_inflated , border_radius = 12 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , title_rect_inflated , 2 , border_radius = 12 )
2025-07-07 00:02:20 +02:00
screen . blit ( title_surface , title_rect )
else :
title_text = f " { platform_name } ( { game_count } jeux) "
2025-07-10 22:32:35 +02:00
title_surface = config . title_font . render ( title_text , True , THEME_COLORS [ " text " ] )
title_rect = title_surface . get_rect ( center = ( config . screen_width / / 2 , title_surface . get_height ( ) / / 2 + 20 ) )
title_rect_inflated = title_rect . inflate ( 60 , 30 )
title_rect_inflated . topleft = ( ( config . screen_width - title_rect_inflated . width ) / / 2 , 10 )
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , title_rect_inflated , border_radius = 12 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , title_rect_inflated , 2 , border_radius = 12 )
2025-07-07 00:02:20 +02:00
screen . blit ( title_surface , title_rect )
2025-07-10 22:32:35 +02:00
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , ( rect_x , rect_y , rect_width , rect_height ) , border_radius = 12 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , ( rect_x , rect_y , rect_width , rect_height ) , 2 , border_radius = 12 )
2025-07-07 00:02:20 +02:00
2025-07-09 01:13:55 +02:00
for i in range ( config . scroll_offset , min ( config . scroll_offset + items_per_page , len ( games ) ) ) :
2025-07-07 00:02:20 +02:00
game_name = games [ i ] [ 0 ] if isinstance ( games [ i ] , ( list , tuple ) ) else games [ i ]
2025-07-10 22:32:35 +02:00
color = THEME_COLORS [ " fond_lignes " ] if i == config . current_game else THEME_COLORS [ " text " ]
2025-07-09 01:13:55 +02:00
game_text = truncate_text_middle ( game_name , config . small_font , rect_width - 40 )
text_surface = config . small_font . render ( game_text , True , color )
2025-07-07 00:02:20 +02:00
text_rect = text_surface . get_rect ( center = ( config . screen_width / / 2 , rect_y + margin_top_bottom + ( i - config . scroll_offset ) * line_height + line_height / / 2 ) )
2025-07-10 22:32:35 +02:00
if i == config . current_game :
glow_surface = pygame . Surface ( ( text_rect . width + 20 , text_rect . height + 10 ) , pygame . SRCALPHA )
pygame . draw . rect ( glow_surface , THEME_COLORS [ " fond_lignes " ] + ( 50 , ) , ( 10 , 5 , text_rect . width , text_rect . height ) , border_radius = 8 )
screen . blit ( glow_surface , ( text_rect . left - 10 , text_rect . top - 5 ) )
2025-07-07 00:02:20 +02:00
screen . blit ( text_surface , text_rect )
2025-07-09 01:13:55 +02:00
if len ( games ) > items_per_page :
try :
draw_game_scrollbar (
screen ,
config . scroll_offset ,
len ( games ) ,
items_per_page ,
rect_x + rect_width - 10 ,
rect_y ,
rect_height
)
except NameError as e :
logger . error ( f " Erreur : draw_game_scrollbar non défini: { str ( e ) } " )
2025-07-10 22:32:35 +02:00
# Barre de défilement des jeux
2025-07-09 01:13:55 +02:00
def draw_game_scrollbar ( screen , scroll_offset , total_items , visible_items , x , y , height ) :
""" Affiche la barre de défilement pour la liste des jeux. """
if total_items < = visible_items :
return
game_area_height = height
scrollbar_height = game_area_height * ( visible_items / total_items )
scrollbar_y = y + ( game_area_height - scrollbar_height ) * ( scroll_offset / max ( 1 , total_items - visible_items ) )
2025-07-10 22:32:35 +02:00
pygame . draw . rect ( screen , THEME_COLORS [ " fond_lignes " ] , ( x , scrollbar_y , 15 , scrollbar_height ) , border_radius = 4 )
2025-07-07 02:48:05 +02:00
def draw_history_list ( screen ) :
2025-07-10 22:32:35 +02:00
""" Affiche l ' historique des téléchargements avec un style moderne. """
2025-07-07 02:48:05 +02:00
history = config . history if hasattr ( config , ' history ' ) else load_history ( )
history_count = len ( history )
2025-07-09 01:13:55 +02:00
col_platform_width = int ( ( 0.95 * config . screen_width - 60 ) * 0.33 )
col_game_width = int ( ( 0.95 * config . screen_width - 60 ) * 0.50 )
col_status_width = int ( ( 0.95 * config . screen_width - 60 ) * 0.17 )
2025-07-10 22:32:35 +02:00
rect_width = int ( 0.95 * config . screen_width )
2025-07-09 01:13:55 +02:00
line_height = config . small_font . get_height ( ) + 10
header_height = line_height
margin_top_bottom = 20
2025-07-10 22:32:35 +02:00
extra_margin_top = 40
extra_margin_bottom = 80
2025-07-09 01:13:55 +02:00
title_height = config . title_font . get_height ( ) + 20
2025-07-07 02:48:05 +02:00
if not history :
logger . debug ( " Aucun historique disponible " )
message = " Aucun téléchargement dans l ' historique "
lines = wrap_text ( message , config . font , config . screen_width - 80 )
line_height = config . font . get_height ( ) + 5
text_height = len ( lines ) * line_height
rect_height = text_height + 2 * margin_top_bottom
max_text_width = max ( [ config . font . size ( line ) [ 0 ] for line in lines ] , default = 300 )
2025-07-10 22:32:35 +02:00
rect_width = max_text_width + 80
2025-07-07 02:48:05 +02:00
rect_x = ( config . screen_width - rect_width ) / / 2
rect_y = ( config . screen_height - rect_height ) / / 2
screen . blit ( OVERLAY , ( 0 , 0 ) )
2025-07-10 22:32:35 +02:00
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , ( rect_x , rect_y , rect_width , rect_height ) , border_radius = 12 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , ( rect_x , rect_y , rect_width , rect_height ) , 2 , border_radius = 12 )
2025-07-07 02:48:05 +02:00
for i , line in enumerate ( lines ) :
2025-07-10 22:32:35 +02:00
text_surface = config . font . render ( line , True , THEME_COLORS [ " text " ] )
2025-07-07 02:48:05 +02:00
text_rect = text_surface . get_rect ( center = ( config . screen_width / / 2 , rect_y + margin_top_bottom + i * line_height + line_height / / 2 ) )
screen . blit ( text_surface , text_rect )
return
available_height = config . screen_height - title_height - extra_margin_top - extra_margin_bottom - 2 * margin_top_bottom
items_per_page = available_height / / line_height
2025-07-09 01:13:55 +02:00
rect_height = header_height + items_per_page * line_height + 2 * margin_top_bottom
2025-07-07 02:48:05 +02:00
rect_x = ( config . screen_width - rect_width ) / / 2
rect_y = title_height + extra_margin_top + ( config . screen_height - title_height - extra_margin_top - extra_margin_bottom - rect_height ) / / 2
config . history_scroll_offset = max ( 0 , min ( config . history_scroll_offset , max ( 0 , len ( history ) - items_per_page ) ) )
if config . current_history_item < config . history_scroll_offset :
config . history_scroll_offset = config . current_history_item
elif config . current_history_item > = config . history_scroll_offset + items_per_page :
config . history_scroll_offset = config . current_history_item - items_per_page + 1
screen . blit ( OVERLAY , ( 0 , 0 ) )
title_text = f " Historique des téléchargements ( { history_count } ) "
2025-07-10 22:32:35 +02:00
title_surface = config . title_font . render ( title_text , True , THEME_COLORS [ " text " ] )
title_rect = title_surface . get_rect ( center = ( config . screen_width / / 2 , title_surface . get_height ( ) / / 2 + 20 ) )
title_rect_inflated = title_rect . inflate ( 60 , 30 )
title_rect_inflated . topleft = ( ( config . screen_width - title_rect_inflated . width ) / / 2 , 10 )
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , title_rect_inflated , border_radius = 12 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , title_rect_inflated , 2 , border_radius = 12 )
2025-07-07 02:48:05 +02:00
screen . blit ( title_surface , title_rect )
2025-07-10 22:32:35 +02:00
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , ( rect_x , rect_y , rect_width , rect_height ) , border_radius = 12 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , ( rect_x , rect_y , rect_width , rect_height ) , 2 , border_radius = 12 )
2025-07-07 02:48:05 +02:00
headers = [ " Système " , " Nom du jeu " , " État " ]
2025-07-09 01:13:55 +02:00
header_y = rect_y + margin_top_bottom + header_height / / 2
2025-07-07 02:48:05 +02:00
header_x_positions = [
rect_x + 20 + col_platform_width / / 2 ,
rect_x + 20 + col_platform_width + col_game_width / / 2 ,
rect_x + 20 + col_platform_width + col_game_width + col_status_width / / 2
]
for header , x_pos in zip ( headers , header_x_positions ) :
2025-07-10 22:32:35 +02:00
text_surface = config . small_font . render ( header , True , THEME_COLORS [ " text " ] )
2025-07-07 02:48:05 +02:00
text_rect = text_surface . get_rect ( center = ( x_pos , header_y ) )
screen . blit ( text_surface , text_rect )
2025-07-10 22:32:35 +02:00
# Ajouter un séparateur sous les en-têtes
separator_y = rect_y + margin_top_bottom + header_height
pygame . draw . line ( screen , THEME_COLORS [ " border " ] , ( rect_x + 20 , separator_y ) , ( rect_x + rect_width - 20 , separator_y ) , 2 )
2025-07-09 01:13:55 +02:00
for idx , i in enumerate ( range ( config . history_scroll_offset , min ( config . history_scroll_offset + items_per_page , len ( history ) ) ) ) :
2025-07-07 02:48:05 +02:00
entry = history [ i ]
2025-07-09 01:13:55 +02:00
platform = entry . get ( " platform " , " Inconnu " )
game_name = entry . get ( " game_name " , " Inconnu " )
status = entry . get ( " status " , " Inconnu " )
2025-07-10 22:32:35 +02:00
color = THEME_COLORS [ " fond_lignes " ] if i == config . current_history_item else THEME_COLORS [ " text " ]
2025-07-09 01:13:55 +02:00
platform_text = truncate_text_middle ( platform , config . small_font , col_platform_width - 10 )
game_text = truncate_text_middle ( game_name , config . small_font , col_game_width - 10 )
status_text = truncate_text_middle ( status , config . small_font , col_status_width - 10 )
2025-07-10 22:32:35 +02:00
2025-07-09 01:13:55 +02:00
y_pos = rect_y + margin_top_bottom + header_height + idx * line_height + line_height / / 2
2025-07-07 02:48:05 +02:00
platform_surface = config . small_font . render ( platform_text , True , color )
game_surface = config . small_font . render ( game_text , True , color )
status_surface = config . small_font . render ( status_text , True , color )
2025-07-10 22:32:35 +02:00
2025-07-07 02:48:05 +02:00
platform_rect = platform_surface . get_rect ( center = ( header_x_positions [ 0 ] , y_pos ) )
game_rect = game_surface . get_rect ( center = ( header_x_positions [ 1 ] , y_pos ) )
status_rect = status_surface . get_rect ( center = ( header_x_positions [ 2 ] , y_pos ) )
2025-07-10 22:32:35 +02:00
if i == config . current_history_item :
glow_surface = pygame . Surface ( ( rect_width - 40 , line_height ) , pygame . SRCALPHA )
pygame . draw . rect ( glow_surface , THEME_COLORS [ " fond_lignes " ] + ( 50 , ) , ( 0 , 0 , rect_width - 40 , line_height ) , border_radius = 8 )
screen . blit ( glow_surface , ( rect_x + 20 , y_pos - line_height / / 2 ) )
2025-07-07 02:48:05 +02:00
screen . blit ( platform_surface , platform_rect )
screen . blit ( game_surface , game_rect )
screen . blit ( status_surface , status_rect )
2025-07-09 01:13:55 +02:00
if len ( history ) > items_per_page :
try :
draw_history_scrollbar (
screen ,
config . history_scroll_offset ,
len ( history ) ,
items_per_page ,
rect_x + rect_width - 10 ,
rect_y ,
rect_height
)
except NameError as e :
logger . error ( f " Erreur : draw_history_scrollbar non défini: { str ( e ) } " )
2025-07-10 22:32:35 +02:00
# Barre de défilement de l'historique
2025-07-09 01:13:55 +02:00
def draw_history_scrollbar ( screen , scroll_offset , total_items , visible_items , x , y , height ) :
2025-07-10 22:32:35 +02:00
""" Affiche la barre de défilement avec un style moderne. """
if total_items < = visible_items :
2025-07-07 02:48:05 +02:00
return
2025-07-10 22:32:35 +02:00
game_area_height = height
scrollbar_height = game_area_height * ( visible_items / total_items ) - 10
scrollbar_y = y + ( game_area_height - scrollbar_height ) * ( scroll_offset / max ( 1 , total_items - visible_items ) ) + 10
pygame . draw . rect ( screen , THEME_COLORS [ " fond_lignes " ] , ( x , scrollbar_y , 5 , scrollbar_height ) , border_radius = 4 )
2025-07-07 02:48:05 +02:00
2025-07-10 22:32:35 +02:00
# Écran confirmation vider historique
2025-07-09 01:13:55 +02:00
def draw_clear_history_dialog ( screen ) :
""" Affiche la boîte de dialogue de confirmation pour vider l ' historique. """
screen . blit ( OVERLAY , ( 0 , 0 ) )
message = " Vider l ' historique ? "
wrapped_message = wrap_text ( message , config . font , config . screen_width - 80 )
line_height = config . font . get_height ( ) + 5
text_height = len ( wrapped_message ) * line_height
2025-07-10 22:32:35 +02:00
button_height = int ( config . screen_height * 0.0463 )
2025-07-09 01:13:55 +02:00
margin_top_bottom = 20
rect_height = text_height + button_height + 2 * margin_top_bottom
max_text_width = max ( [ config . font . size ( line ) [ 0 ] for line in wrapped_message ] , default = 300 )
2025-07-10 22:32:35 +02:00
rect_width = max_text_width + 150
2025-07-09 01:13:55 +02:00
rect_x = ( config . screen_width - rect_width ) / / 2
rect_y = ( config . screen_height - rect_height ) / / 2
2025-07-10 22:32:35 +02:00
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , ( rect_x , rect_y , rect_width , rect_height ) , border_radius = 12 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , ( rect_x , rect_y , rect_width , rect_height ) , 2 , border_radius = 12 )
2025-07-09 01:13:55 +02:00
for i , line in enumerate ( wrapped_message ) :
2025-07-10 22:32:35 +02:00
text = config . font . render ( line , True , THEME_COLORS [ " text " ] )
2025-07-09 01:13:55 +02:00
text_rect = text . get_rect ( center = ( config . screen_width / / 2 , rect_y + margin_top_bottom + i * line_height + line_height / / 2 ) )
screen . blit ( text , text_rect )
2025-07-10 22:32:35 +02:00
draw_stylized_button ( screen , " Oui " , rect_x + rect_width / / 2 - 180 , rect_y + text_height + margin_top_bottom , 160 , button_height , selected = config . confirm_clear_selection == 1 )
draw_stylized_button ( screen , " Non " , rect_x + rect_width / / 2 + 20 , rect_y + text_height + margin_top_bottom , 160 , button_height , selected = config . confirm_clear_selection == 0 )
2025-07-09 01:13:55 +02:00
2025-07-10 22:32:35 +02:00
# Affichage du clavier virtuel sur non-PC
2025-07-06 19:47:21 +02:00
def draw_virtual_keyboard ( screen ) :
2025-07-10 22:32:35 +02:00
""" Affiche un clavier virtuel avec un style moderne. """
2025-07-06 19:47:21 +02:00
keyboard_layout = [
[ ' 0 ' , ' 1 ' , ' 2 ' , ' 3 ' , ' 4 ' , ' 5 ' , ' 6 ' , ' 7 ' , ' 8 ' , ' 9 ' ] ,
[ ' A ' , ' Z ' , ' E ' , ' R ' , ' T ' , ' Y ' , ' U ' , ' I ' , ' O ' , ' P ' ] ,
[ ' Q ' , ' S ' , ' D ' , ' F ' , ' G ' , ' H ' , ' J ' , ' K ' , ' L ' , ' M ' ] ,
[ ' W ' , ' X ' , ' C ' , ' V ' , ' B ' , ' N ' ]
]
2025-07-10 22:32:35 +02:00
key_width = int ( config . screen_width * 0.03125 )
key_height = int ( config . screen_height * 0.0556 )
key_spacing = int ( config . screen_width * 0.0052 )
2025-07-06 19:47:21 +02:00
keyboard_width = len ( keyboard_layout [ 0 ] ) * ( key_width + key_spacing ) - key_spacing
keyboard_height = len ( keyboard_layout ) * ( key_height + key_spacing ) - key_spacing
start_x = ( config . screen_width - keyboard_width ) / / 2
2025-07-10 22:32:35 +02:00
search_bottom_y = int ( config . screen_height * 0.111 ) + ( config . search_font . get_height ( ) + 40 ) / / 2
controls_y = config . screen_height - int ( config . screen_height * 0.037 )
2025-07-06 19:47:21 +02:00
available_height = controls_y - search_bottom_y
start_y = search_bottom_y + ( available_height - keyboard_height - 40 ) / / 2
keyboard_rect = pygame . Rect ( start_x - 20 , start_y - 20 , keyboard_width + 40 , keyboard_height + 40 )
2025-07-10 22:32:35 +02:00
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , keyboard_rect , border_radius = 12 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , keyboard_rect , 2 , border_radius = 12 )
2025-07-06 19:47:21 +02:00
for row_idx , row in enumerate ( keyboard_layout ) :
for col_idx , key in enumerate ( row ) :
x = start_x + col_idx * ( key_width + key_spacing )
y = start_y + row_idx * ( key_height + key_spacing )
key_rect = pygame . Rect ( x , y , key_width , key_height )
if ( row_idx , col_idx ) == config . selected_key :
2025-07-10 22:32:35 +02:00
pygame . draw . rect ( screen , THEME_COLORS [ " fond_lignes " ] + ( 150 , ) , key_rect , border_radius = 8 )
2025-07-06 19:47:21 +02:00
else :
2025-07-10 22:32:35 +02:00
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , key_rect , border_radius = 8 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , key_rect , 1 , border_radius = 8 )
text = config . font . render ( key , True , THEME_COLORS [ " text " ] )
2025-07-06 19:47:21 +02:00
text_rect = text . get_rect ( center = key_rect . center )
screen . blit ( text , text_rect )
2025-07-10 22:32:35 +02:00
# Écran de progression de téléchargement/extraction
2025-07-06 19:47:21 +02:00
def draw_progress_screen ( screen ) :
2025-07-10 22:32:35 +02:00
""" Affiche l ' écran de progression des téléchargements avec un style moderne. """
2025-07-06 19:47:21 +02:00
if not config . download_tasks :
logger . debug ( " Aucune tâche de téléchargement active " )
return
task = list ( config . download_tasks . keys ( ) ) [ 0 ]
game_name = config . download_tasks [ task ] [ 2 ]
url = config . download_tasks [ task ] [ 1 ]
progress = config . download_progress . get ( url , { " downloaded_size " : 0 , " total_size " : 0 , " status " : " Téléchargement " , " progress_percent " : 0 } )
status = progress . get ( " status " , " Téléchargement " )
downloaded_size = progress [ " downloaded_size " ]
total_size = progress [ " total_size " ]
progress_percent = progress [ " progress_percent " ]
2025-07-06 21:13:39 +02:00
screen . blit ( OVERLAY , ( 0 , 0 ) )
2025-07-06 19:47:21 +02:00
2025-07-09 01:13:55 +02:00
title_text = f " { status } : { truncate_text_middle ( game_name , config . font , config . screen_width - 200 ) } "
2025-07-06 22:05:20 +02:00
title_lines = wrap_text ( title_text , config . font , config . screen_width - 80 )
line_height = config . font . get_height ( ) + 5
2025-07-07 00:02:20 +02:00
text_height = len ( title_lines ) * line_height
margin_top_bottom = 20
2025-07-10 22:32:35 +02:00
bar_height = int ( config . screen_height * 0.0278 )
percent_height = config . progress_font . get_height ( ) + 5
2025-07-07 00:02:20 +02:00
rect_height = text_height + bar_height + percent_height + 3 * margin_top_bottom
max_text_width = max ( [ config . font . size ( line ) [ 0 ] for line in title_lines ] , default = 300 )
2025-07-07 02:48:05 +02:00
bar_width = max_text_width
2025-07-10 22:32:35 +02:00
rect_width = max_text_width + 80
2025-07-07 00:02:20 +02:00
rect_x = ( config . screen_width - rect_width ) / / 2
rect_y = ( config . screen_height - rect_height ) / / 2
2025-07-10 22:32:35 +02:00
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , ( rect_x , rect_y , rect_width , rect_height ) , border_radius = 12 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , ( rect_x , rect_y , rect_width , rect_height ) , 2 , border_radius = 12 )
2025-07-07 00:02:20 +02:00
2025-07-06 22:05:20 +02:00
for i , line in enumerate ( title_lines ) :
2025-07-10 22:32:35 +02:00
title_render = config . font . render ( line , True , THEME_COLORS [ " text " ] )
2025-07-07 00:02:20 +02:00
title_rect = title_render . get_rect ( center = ( config . screen_width / / 2 , rect_y + margin_top_bottom + i * line_height + line_height / / 2 ) )
2025-07-06 22:05:20 +02:00
screen . blit ( title_render , title_rect )
2025-07-06 19:47:21 +02:00
2025-07-07 00:02:20 +02:00
bar_y = rect_y + text_height + margin_top_bottom
progress_width = 0
2025-07-10 22:32:35 +02:00
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , ( rect_x + 20 , bar_y , bar_width , bar_height ) , border_radius = 8 )
2025-07-07 00:02:20 +02:00
if total_size > 0 :
progress_width = int ( bar_width * ( progress_percent / 100 ) )
2025-07-10 22:32:35 +02:00
pygame . draw . rect ( screen , THEME_COLORS [ " fond_lignes " ] , ( rect_x + 20 , bar_y , progress_width , bar_height ) , border_radius = 8 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , ( rect_x + 20 , bar_y , bar_width , bar_height ) , 2 , border_radius = 8 )
2025-07-07 00:02:20 +02:00
downloaded_mb = downloaded_size / ( 1024 * 1024 )
total_mb = total_size / ( 1024 * 1024 )
size_text = f " { downloaded_mb : .1f } Mo / { total_mb : .1f } Mo "
percent_text = f " { int ( progress_percent ) } % { size_text } "
2025-07-10 22:32:35 +02:00
percent_lines = wrap_text ( percent_text , config . progress_font , config . screen_width - 80 )
2025-07-07 00:02:20 +02:00
text_y = bar_y + bar_height + margin_top_bottom
for i , line in enumerate ( percent_lines ) :
2025-07-10 22:32:35 +02:00
percent_render = config . progress_font . render ( line , True , THEME_COLORS [ " text " ] )
percent_rect = percent_render . get_rect ( center = ( config . screen_width / / 2 , text_y + i * percent_height + percent_height / / 2 ) )
2025-07-07 00:02:20 +02:00
screen . blit ( percent_render , percent_rect )
2025-07-06 19:47:21 +02:00
2025-07-10 22:32:35 +02:00
# Écran popup résultat téléchargement
def draw_popup_result_download ( screen , message , is_error ) :
2025-07-06 19:47:21 +02:00
""" Affiche une popup avec un message de résultat. """
2025-07-06 21:13:39 +02:00
screen . blit ( OVERLAY , ( 0 , 0 ) )
2025-07-09 01:13:55 +02:00
if message is None :
message = " Téléchargement annulé "
logger . debug ( f " Message popup : { message } , is_error= { is_error } " )
2025-07-10 22:32:35 +02:00
# Réduire la largeur maximale pour le wrapping
wrapped_message = wrap_text ( message , config . small_font , config . screen_width - 160 )
# Débogage pour vérifier les lignes wrappées
logger . debug ( f " Lignes wrappées : { wrapped_message } " )
2025-07-09 01:13:55 +02:00
line_height = config . small_font . get_height ( ) + 5
2025-07-10 22:32:35 +02:00
text_height = len ( wrapped_message ) * line_height
margin_top_bottom = 20
rect_height = text_height + 2 * margin_top_bottom
max_text_width = max ( [ config . small_font . size ( line ) [ 0 ] for line in wrapped_message ] , default = 300 )
rect_width = max_text_width + 100 # Augmenter la marge
rect_x = ( config . screen_width - rect_width ) / / 2
rect_y = ( config . screen_height - rect_height ) / / 2
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , ( rect_x , rect_y , rect_width , rect_height ) , border_radius = 12 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , ( rect_x , rect_y , rect_width , rect_height ) , 2 , border_radius = 12 )
2025-07-06 22:05:20 +02:00
for i , line in enumerate ( wrapped_message ) :
2025-07-10 22:32:35 +02:00
text = config . small_font . render ( line , True , THEME_COLORS [ " error_text " ] if is_error else THEME_COLORS [ " fond_lignes " ] )
text_rect = text . get_rect ( center = ( config . screen_width / / 2 , rect_y + margin_top_bottom + i * line_height + line_height / / 2 ) )
2025-07-06 22:05:20 +02:00
screen . blit ( text , text_rect )
2025-07-06 19:47:21 +02:00
2025-07-10 22:32:35 +02:00
# Écran avertissement extension non supportée téléchargement
2025-07-06 19:47:21 +02:00
def draw_extension_warning ( screen ) :
""" Affiche un avertissement pour une extension non reconnue ou un fichier ZIP. """
if not config . pending_download :
2025-07-06 21:13:39 +02:00
logger . error ( " config.pending_download est None ou vide dans extension_warning " )
2025-07-06 19:47:21 +02:00
message = " Erreur : Aucun téléchargement en attente. "
is_zip = False
game_name = " Inconnu "
else :
url , platform , game_name , is_zip_non_supported = config . pending_download
2025-07-06 21:13:39 +02:00
logger . debug ( f " config.pending_download: url= { url } , platform= { platform } , game_name= { game_name } , is_zip_non_supported= { is_zip_non_supported } " )
2025-07-06 19:47:21 +02:00
is_zip = is_zip_non_supported
if not game_name :
game_name = " Inconnu "
logger . warning ( " game_name vide, utilisation de ' Inconnu ' " )
if is_zip :
message = f " Le fichier ' { game_name } ' est une archive et Batocera ne prend pas en charge les archives pour ce système. L ' extraction automatique du fichier aura lieu après le téléchargement, continuer ? "
else :
message = f " L ' extension du fichier ' { game_name } ' n ' est pas supportée par Batocera d ' après le fichier info.txt. Voulez-vous continuer ? "
max_width = config . screen_width - 80
lines = wrap_text ( message , config . font , max_width )
2025-07-06 21:13:39 +02:00
logger . debug ( f " Lignes générées : { lines } " )
2025-07-06 19:47:21 +02:00
try :
line_height = config . font . get_height ( ) + 5
text_height = len ( lines ) * line_height
2025-07-10 22:32:35 +02:00
button_height = int ( config . screen_height * 0.0463 )
2025-07-06 19:47:21 +02:00
margin_top_bottom = 20
rect_height = text_height + button_height + 2 * margin_top_bottom
max_text_width = max ( [ config . font . size ( line ) [ 0 ] for line in lines ] , default = 300 )
2025-07-10 22:32:35 +02:00
rect_width = max_text_width + 80
2025-07-06 19:47:21 +02:00
rect_x = ( config . screen_width - rect_width ) / / 2
rect_y = ( config . screen_height - rect_height ) / / 2
2025-07-06 21:13:39 +02:00
screen . blit ( OVERLAY , ( 0 , 0 ) )
2025-07-10 22:32:35 +02:00
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , ( rect_x , rect_y , rect_width , rect_height ) , border_radius = 12 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , ( rect_x , rect_y , rect_width , rect_height ) , 2 , border_radius = 12 )
2025-07-06 21:13:39 +02:00
2025-07-07 00:02:20 +02:00
for i , line in enumerate ( lines ) :
2025-07-10 22:32:35 +02:00
text_surface = config . font . render ( line , True , THEME_COLORS [ " warning_text " ] )
2025-07-07 00:02:20 +02:00
text_rect = text_surface . get_rect ( center = ( config . screen_width / / 2 , rect_y + margin_top_bottom + i * line_height + line_height / / 2 ) )
screen . blit ( text_surface , text_rect )
2025-07-10 22:32:35 +02:00
draw_stylized_button ( screen , " Oui " , rect_x + rect_width / / 2 - 180 , rect_y + text_height + margin_top_bottom , 160 , button_height , selected = config . extension_confirm_selection == 1 )
draw_stylized_button ( screen , " Non " , rect_x + rect_width / / 2 + 20 , rect_y + text_height + margin_top_bottom , 160 , button_height , selected = config . extension_confirm_selection == 0 )
2025-07-06 19:47:21 +02:00
except Exception as e :
logger . error ( f " Erreur lors du rendu de extension_warning : { str ( e ) } " )
error_message = " Erreur d ' affichage de l ' avertissement. "
2025-07-06 22:05:20 +02:00
wrapped_error = wrap_text ( error_message , config . font , config . screen_width - 80 )
2025-07-07 00:02:20 +02:00
line_height = config . font . get_height ( ) + 5
rect_height = len ( wrapped_error ) * line_height + 2 * 20
max_text_width = max ( [ config . font . size ( line ) [ 0 ] for line in wrapped_error ] , default = 300 )
2025-07-10 22:32:35 +02:00
rect_width = max_text_width + 80
2025-07-07 00:02:20 +02:00
rect_x = ( config . screen_width - rect_width ) / / 2
rect_y = ( config . screen_height - rect_height ) / / 2
screen . blit ( OVERLAY , ( 0 , 0 ) )
2025-07-10 22:32:35 +02:00
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , ( rect_x , rect_y , rect_width , rect_height ) , border_radius = 12 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , ( rect_x , rect_y , rect_width , rect_height ) , 2 , border_radius = 12 )
2025-07-07 00:02:20 +02:00
2025-07-06 22:05:20 +02:00
for i , line in enumerate ( wrapped_error ) :
2025-07-10 22:32:35 +02:00
error_surface = config . font . render ( line , True , THEME_COLORS [ " error_text " ] )
2025-07-07 00:02:20 +02:00
error_rect = error_surface . get_rect ( center = ( config . screen_width / / 2 , rect_y + 20 + i * line_height + line_height / / 2 ) )
2025-07-06 22:05:20 +02:00
screen . blit ( error_surface , error_rect )
2025-07-06 19:47:21 +02:00
2025-07-10 22:32:35 +02:00
# Affichage des contrôles en bas de page
2025-07-06 19:47:21 +02:00
def draw_controls ( screen , menu_state ) :
2025-07-10 22:32:35 +02:00
""" Affiche les contrôles sur une seule ligne en bas de l’ écran. """
2025-07-06 21:13:39 +02:00
start_button = get_control_display ( ' start ' , ' START ' )
2025-07-10 22:32:35 +02:00
control_text = f " RGSX v { config . app_version } - { start_button } : Options - History - Help "
2025-07-06 19:47:21 +02:00
max_width = config . screen_width - 40
2025-07-07 00:02:20 +02:00
wrapped_controls = wrap_text ( control_text , config . small_font , max_width )
line_height = config . small_font . get_height ( ) + 5
2025-07-06 22:05:20 +02:00
rect_height = len ( wrapped_controls ) * line_height + 20
2025-07-07 02:48:05 +02:00
rect_y = config . screen_height - rect_height - 5
2025-07-10 22:32:35 +02:00
rect_x = ( config . screen_width - max_width ) / / 2
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , ( rect_x , rect_y , max_width , rect_height ) , border_radius = 8 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , ( rect_x , rect_y , max_width , rect_height ) , 1 , border_radius = 8 )
2025-07-06 19:47:21 +02:00
2025-07-06 22:05:20 +02:00
for i , line in enumerate ( wrapped_controls ) :
2025-07-10 22:32:35 +02:00
text_surface = config . small_font . render ( line , True , THEME_COLORS [ " text " ] )
2025-07-06 22:05:20 +02:00
text_rect = text_surface . get_rect ( center = ( config . screen_width / / 2 , rect_y + 10 + i * line_height + line_height / / 2 ) )
screen . blit ( text_surface , text_rect )
2025-07-06 19:47:21 +02:00
2025-07-10 22:32:35 +02:00
# Menu pause
2025-07-06 19:47:21 +02:00
def draw_pause_menu ( screen , selected_option ) :
2025-07-10 22:32:35 +02:00
""" Dessine le menu pause avec un style moderne. """
2025-07-06 21:13:39 +02:00
screen . blit ( OVERLAY , ( 0 , 0 ) )
2025-07-06 19:47:21 +02:00
options = [
" Controls " ,
" Remap controls " ,
2025-07-07 02:48:05 +02:00
" History " ,
2025-07-09 01:13:55 +02:00
" Redownload Games cache " ,
2025-07-06 19:47:21 +02:00
" Quit "
]
2025-07-10 22:32:35 +02:00
menu_width = int ( config . screen_width * 0.8 )
2025-07-06 22:05:20 +02:00
line_height = config . font . get_height ( ) + 10
2025-07-10 22:32:35 +02:00
button_height = int ( config . screen_height * 0.0463 )
2025-07-07 00:02:20 +02:00
margin_top_bottom = 20
2025-07-10 22:32:35 +02:00
menu_height = len ( options ) * ( button_height + 10 ) + 2 * margin_top_bottom
2025-07-06 19:47:21 +02:00
menu_x = ( config . screen_width - menu_width ) / / 2
menu_y = ( config . screen_height - menu_height ) / / 2
2025-07-10 22:32:35 +02:00
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , ( menu_x , menu_y , menu_width , menu_height ) , border_radius = 12 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , ( menu_x , menu_y , menu_width , menu_height ) , 2 , border_radius = 12 )
2025-07-07 00:02:20 +02:00
2025-07-06 19:47:21 +02:00
for i , option in enumerate ( options ) :
2025-07-10 22:32:35 +02:00
draw_stylized_button (
screen ,
option ,
menu_x + 20 ,
menu_y + margin_top_bottom + i * ( button_height + 10 ) ,
menu_width - 40 ,
button_height ,
selected = i == selected_option
)
# Menu aide contrôles
2025-07-06 19:47:21 +02:00
def draw_controls_help ( screen , previous_state ) :
2025-07-10 22:32:35 +02:00
""" Affiche la liste des contrôles avec un style moderne. """
2025-07-06 21:13:39 +02:00
common_controls = {
" confirm " : lambda action : f " { get_control_display ( ' confirm ' , ' Entrée/A ' ) } : { action } " ,
" cancel " : lambda action : f " { get_control_display ( ' cancel ' , ' Échap/B ' ) } : { action } " ,
" start " : lambda : f " { get_control_display ( ' start ' , ' Start ' ) } : Menu " ,
" progress " : lambda action : f " { get_control_display ( ' progress ' , ' X ' ) } : { action } " ,
" up " : lambda action : f " { get_control_display ( ' up ' , ' Flèche Haut ' ) } : { action } " ,
" down " : lambda action : f " { get_control_display ( ' down ' , ' Flèche Bas ' ) } : { action } " ,
" page_up " : lambda action : f " { get_control_display ( ' page_up ' , ' Q/LB ' ) } : { action } " ,
" page_down " : lambda action : f " { get_control_display ( ' page_down ' , ' E/RB ' ) } : { action } " ,
" filter " : lambda action : f " { get_control_display ( ' filter ' , ' Select ' ) } : { action } " ,
2025-07-09 01:13:55 +02:00
" history " : lambda action : f " { get_control_display ( ' history ' , ' H ' ) } : { action } " ,
2025-07-06 21:13:39 +02:00
" delete " : lambda : f " { get_control_display ( ' delete ' , ' Retour Arrière ' ) } : Supprimer " ,
" space " : lambda : f " { get_control_display ( ' space ' , ' Espace ' ) } : Espace "
}
2025-07-06 19:47:21 +02:00
state_controls = {
" error " : [
2025-07-06 21:13:39 +02:00
common_controls [ " confirm " ] ( " Retenter " ) ,
common_controls [ " cancel " ] ( " Quitter " )
2025-07-06 19:47:21 +02:00
] ,
" platform " : [
2025-07-06 21:13:39 +02:00
common_controls [ " confirm " ] ( " Sélectionner " ) ,
common_controls [ " cancel " ] ( " Quitter " ) ,
common_controls [ " start " ] ( ) ,
2025-07-09 01:13:55 +02:00
common_controls [ " history " ] ( " Historique " ) ,
2025-07-06 21:13:39 +02:00
* ( [ common_controls [ " progress " ] ( " Progression " ) ] if config . download_tasks else [ ] )
2025-07-06 19:47:21 +02:00
] ,
" game " : [
2025-07-09 16:56:37 +02:00
common_controls [ " confirm " ] ( f " { ' Selectionner ' if config . search_mode else ' Télécharger ' } " ) ,
common_controls [ " filter " ] ( " Filtrer " ) ,
2025-07-06 21:13:39 +02:00
common_controls [ " cancel " ] ( f " { ' Annuler ' if config . search_mode else ' Retour ' } " ) ,
2025-07-09 01:13:55 +02:00
common_controls [ " history " ] ( " Historique " ) ,
2025-07-06 19:47:21 +02:00
* ( [
2025-07-06 21:13:39 +02:00
common_controls [ " delete " ] ( ) ,
common_controls [ " space " ] ( )
2025-07-06 19:47:21 +02:00
] if config . search_mode and config . is_non_pc else [ ] ) ,
* ( [
2025-07-06 21:13:39 +02:00
f " { common_controls [ ' up ' ] ( ' Naviguer ' ) } / { common_controls [ ' down ' ] ( ' Naviguer ' ) } " ,
f " { common_controls [ ' page_up ' ] ( ' Page ' ) } / { common_controls [ ' page_down ' ] ( ' Page ' ) } " ,
common_controls [ " filter " ] ( " Filtrer " )
2025-07-06 19:47:21 +02:00
] if not config . is_non_pc or not config . search_mode else [ ] ) ,
2025-07-06 21:13:39 +02:00
common_controls [ " start " ] ( ) ,
* ( [ common_controls [ " progress " ] ( " Progression " ) ] if config . download_tasks and not config . search_mode else [ ] )
2025-07-06 19:47:21 +02:00
] ,
" download_progress " : [
2025-07-06 21:13:39 +02:00
common_controls [ " cancel " ] ( " Annuler le téléchargement " ) ,
common_controls [ " progress " ] ( " Arrière plan " ) ,
common_controls [ " start " ] ( )
2025-07-06 19:47:21 +02:00
] ,
" download_result " : [
2025-07-06 21:13:39 +02:00
common_controls [ " confirm " ] ( " Retour " )
2025-07-06 19:47:21 +02:00
] ,
" confirm_exit " : [
2025-07-06 21:13:39 +02:00
common_controls [ " confirm " ] ( " Confirmer " )
2025-07-06 19:47:21 +02:00
] ,
" extension_warning " : [
2025-07-06 21:13:39 +02:00
common_controls [ " confirm " ] ( " Confirmer " )
2025-07-07 02:48:05 +02:00
] ,
" history " : [
common_controls [ " confirm " ] ( " Retélécharger " ) ,
common_controls [ " cancel " ] ( " Retour " ) ,
common_controls [ " progress " ] ( " Vider l ' historique " ) ,
f " { common_controls [ ' up ' ] ( ' Naviguer ' ) } / { common_controls [ ' down ' ] ( ' Naviguer ' ) } " ,
f " { common_controls [ ' page_up ' ] ( ' Page ' ) } / { common_controls [ ' page_down ' ] ( ' Page ' ) } " ,
common_controls [ " start " ] ( )
2025-07-06 19:47:21 +02:00
]
}
controls = state_controls . get ( previous_state , [ ] )
2025-07-06 21:13:39 +02:00
if not controls :
return
2025-07-06 19:47:21 +02:00
2025-07-06 21:13:39 +02:00
screen . blit ( OVERLAY , ( 0 , 0 ) )
2025-07-06 19:47:21 +02:00
max_width = config . screen_width - 80
wrapped_controls = [ ]
current_line = " "
for control in controls :
test_line = f " { current_line } | { control } " if current_line else control
if config . font . size ( test_line ) [ 0 ] < = max_width :
current_line = test_line
else :
wrapped_controls . append ( current_line )
current_line = control
if current_line :
wrapped_controls . append ( current_line )
line_height = config . font . get_height ( ) + 10
popup_width = max_width + 40
popup_height = len ( wrapped_controls ) * line_height + 60
popup_x = ( config . screen_width - popup_width ) / / 2
popup_y = ( config . screen_height - popup_height ) / / 2
2025-07-10 22:32:35 +02:00
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , ( popup_x , popup_y , popup_width , popup_height ) , border_radius = 12 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , ( popup_x , popup_y , popup_width , popup_height ) , 2 , border_radius = 12 )
2025-07-06 19:47:21 +02:00
for i , line in enumerate ( wrapped_controls ) :
2025-07-10 22:32:35 +02:00
text = config . font . render ( line , True , THEME_COLORS [ " text " ] )
2025-07-06 19:47:21 +02:00
text_rect = text . get_rect ( center = ( config . screen_width / / 2 , popup_y + 40 + i * line_height ) )
2025-07-07 02:48:05 +02:00
screen . blit ( text , text_rect )
2025-07-10 22:32:35 +02:00
# Menu Quitter Appli
2025-07-07 02:48:05 +02:00
def draw_confirm_dialog ( screen ) :
""" Affiche la boîte de dialogue de confirmation pour quitter. """
2025-07-07 03:46:28 +02:00
global OVERLAY
if OVERLAY is None or OVERLAY . get_size ( ) != ( config . screen_width , config . screen_height ) :
OVERLAY = pygame . Surface ( ( config . screen_width , config . screen_height ) , pygame . SRCALPHA )
2025-07-10 22:32:35 +02:00
OVERLAY . fill ( ( 0 , 0 , 0 , 150 ) )
2025-07-07 03:46:28 +02:00
logger . debug ( " OVERLAY recréé dans draw_confirm_dialog " )
2025-07-10 22:32:35 +02:00
2025-07-07 02:48:05 +02:00
screen . blit ( OVERLAY , ( 0 , 0 ) )
2025-07-07 03:46:28 +02:00
message = " Quitter l ' application ? "
2025-07-07 02:48:05 +02:00
wrapped_message = wrap_text ( message , config . font , config . screen_width - 80 )
line_height = config . font . get_height ( ) + 5
text_height = len ( wrapped_message ) * line_height
2025-07-10 22:32:35 +02:00
button_height = int ( config . screen_height * 0.0463 )
2025-07-07 02:48:05 +02:00
margin_top_bottom = 20
rect_height = text_height + button_height + 2 * margin_top_bottom
max_text_width = max ( [ config . font . size ( line ) [ 0 ] for line in wrapped_message ] , default = 300 )
2025-07-10 22:32:35 +02:00
rect_width = max_text_width + 150
2025-07-07 02:48:05 +02:00
rect_x = ( config . screen_width - rect_width ) / / 2
rect_y = ( config . screen_height - rect_height ) / / 2
2025-07-10 22:32:35 +02:00
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , ( rect_x , rect_y , rect_width , rect_height ) , border_radius = 12 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , ( rect_x , rect_y , rect_width , rect_height ) , 2 , border_radius = 12 )
2025-07-07 02:48:05 +02:00
for i , line in enumerate ( wrapped_message ) :
2025-07-10 22:32:35 +02:00
text = config . font . render ( line , True , THEME_COLORS [ " text " ] )
2025-07-07 02:48:05 +02:00
text_rect = text . get_rect ( center = ( config . screen_width / / 2 , rect_y + margin_top_bottom + i * line_height + line_height / / 2 ) )
screen . blit ( text , text_rect )
2025-07-10 22:32:35 +02:00
draw_stylized_button ( screen , " Oui " , rect_x + rect_width / / 2 - 180 , rect_y + text_height + margin_top_bottom , 160 , button_height , selected = config . confirm_selection == 1 )
draw_stylized_button ( screen , " Non " , rect_x + rect_width / / 2 + 20 , rect_y + text_height + margin_top_bottom , 160 , button_height , selected = config . confirm_selection == 0 )
# draw_redownload_game_cache_dialog
2025-07-09 01:13:55 +02:00
def draw_redownload_game_cache_dialog ( screen ) :
""" Affiche la boîte de dialogue de confirmation pour retélécharger le cache des jeux. """
global OVERLAY
if OVERLAY is None or OVERLAY . get_size ( ) != ( config . screen_width , config . screen_height ) :
OVERLAY = pygame . Surface ( ( config . screen_width , config . screen_height ) , pygame . SRCALPHA )
2025-07-10 22:32:35 +02:00
OVERLAY . fill ( ( 0 , 0 , 0 , 150 ) )
2025-07-09 01:13:55 +02:00
logger . debug ( " OVERLAY recréé dans draw_redownload_game_cache_dialog " )
2025-07-10 22:32:35 +02:00
2025-07-07 02:48:05 +02:00
screen . blit ( OVERLAY , ( 0 , 0 ) )
2025-07-09 01:13:55 +02:00
message = " Retélécharger le cache des jeux ? "
wrapped_message = wrap_text ( message , config . small_font , config . screen_width - 80 )
line_height = config . small_font . get_height ( ) + 5
2025-07-07 02:48:05 +02:00
text_height = len ( wrapped_message ) * line_height
2025-07-10 22:32:35 +02:00
button_height = int ( config . screen_height * 0.0463 )
2025-07-07 02:48:05 +02:00
margin_top_bottom = 20
rect_height = text_height + button_height + 2 * margin_top_bottom
2025-07-09 01:13:55 +02:00
max_text_width = max ( [ config . small_font . size ( line ) [ 0 ] for line in wrapped_message ] , default = 300 )
2025-07-10 22:32:35 +02:00
rect_width = max_text_width + 80
2025-07-07 02:48:05 +02:00
rect_x = ( config . screen_width - rect_width ) / / 2
rect_y = ( config . screen_height - rect_height ) / / 2
2025-07-10 22:32:35 +02:00
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , ( rect_x , rect_y , rect_width , rect_height ) , border_radius = 12 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , ( rect_x , rect_y , rect_width , rect_height ) , 2 , border_radius = 12 )
2025-07-07 02:48:05 +02:00
for i , line in enumerate ( wrapped_message ) :
2025-07-10 22:32:35 +02:00
text = config . small_font . render ( line , True , THEME_COLORS [ " text " ] )
2025-07-07 02:48:05 +02:00
text_rect = text . get_rect ( center = ( config . screen_width / / 2 , rect_y + margin_top_bottom + i * line_height + line_height / / 2 ) )
screen . blit ( text , text_rect )
2025-07-10 22:32:35 +02:00
draw_stylized_button ( screen , " Oui " , rect_x + rect_width / / 2 - 180 , rect_y + text_height + margin_top_bottom , 160 , button_height , selected = config . redownload_confirm_selection == 1 )
draw_stylized_button ( screen , " Non " , rect_x + rect_width / / 2 + 20 , rect_y + text_height + margin_top_bottom , 160 , button_height , selected = config . redownload_confirm_selection == 0 )
2025-07-09 01:13:55 +02:00
2025-07-10 22:32:35 +02:00
# Popup avec compte à rebours
2025-07-09 01:13:55 +02:00
def draw_popup ( screen ) :
""" Dessine un popup avec un message et un compte à rebours. """
screen . blit ( OVERLAY , ( 0 , 0 ) )
2025-07-10 22:32:35 +02:00
popup_width = int ( config . screen_width * 0.8 )
2025-07-09 01:13:55 +02:00
line_height = config . small_font . get_height ( ) + 10
text_lines = config . popup_message . split ( ' \n ' )
text_height = len ( text_lines ) * line_height
margin_top_bottom = 20
2025-07-10 22:32:35 +02:00
popup_height = text_height + 2 * margin_top_bottom + line_height
2025-07-09 01:13:55 +02:00
popup_x = ( config . screen_width - popup_width ) / / 2
popup_y = ( config . screen_height - popup_height ) / / 2
2025-07-10 22:32:35 +02:00
pygame . draw . rect ( screen , THEME_COLORS [ " button_idle " ] , ( popup_x , popup_y , popup_width , popup_height ) , border_radius = 12 )
pygame . draw . rect ( screen , THEME_COLORS [ " border " ] , ( popup_x , popup_y , popup_width , popup_height ) , 2 , border_radius = 12 )
2025-07-09 01:13:55 +02:00
for i , line in enumerate ( text_lines ) :
2025-07-10 22:32:35 +02:00
text_surface = config . small_font . render ( line , True , THEME_COLORS [ " text " ] )
2025-07-09 01:13:55 +02:00
text_rect = text_surface . get_rect ( center = ( config . screen_width / / 2 , popup_y + margin_top_bottom + i * line_height + line_height / / 2 ) )
screen . blit ( text_surface , text_rect )
2025-07-10 22:32:35 +02:00
remaining_time = max ( 0 , config . popup_timer / / 1000 )
2025-07-09 01:13:55 +02:00
countdown_text = f " Ce message se fermera dans { remaining_time } seconde { ' s ' if remaining_time != 1 else ' ' } "
2025-07-10 22:32:35 +02:00
countdown_surface = config . small_font . render ( countdown_text , True , THEME_COLORS [ " text " ] )
2025-07-09 01:13:55 +02:00
countdown_rect = countdown_surface . get_rect ( center = ( config . screen_width / / 2 , popup_y + margin_top_bottom + len ( text_lines ) * line_height + line_height / / 2 ) )
screen . blit ( countdown_surface , countdown_rect )