1
0
forked from Mirrors/RGSX
- add toggle for hiding premium systems needing an api key
- add new font for better accessibility
This commit is contained in:
skymike03
2025-09-12 03:41:59 +02:00
parent 7a7651e582
commit 3c36dd2e02
10 changed files with 251 additions and 48 deletions

View File

@@ -13,7 +13,7 @@ except Exception:
pygame = None # type: ignore
# Version actuelle de l'application
app_version = "2.2.2.0"
app_version = "2.2.2.1"
def get_application_root():
@@ -173,6 +173,16 @@ batch_download_indices = [] # File d'attente des indices de jeux à traiter en
batch_in_progress = False # Indique qu'un lot est en cours
batch_pending_game = None # Données du jeu en attente de confirmation d'extension
# --- Premium systems filtering ---
# Liste des marqueurs (substrings) indiquant qu'un système/plateforme requiert un compte premium ou une clé API.
# On teste la présence (case-insensitive) de ces marqueurs dans le nom du système (ex: "Microsoft Windows (1Fichier)").
# Ajoutez librement d'autres valeurs (ex: 'RealDebrid', 'AllDebrid') si de futurs systèmes nécessitent un compte.
PREMIUM_HOST_MARKERS = [
"1Fichier",
]
# Flag runtime contrôlant le masquage des systèmes premium dans le menu pause > games.
hide_premium_systems = False
# Indicateurs d'entrée (détectés au démarrage)
joystick = False
keyboard = False
@@ -215,34 +225,71 @@ search_font = None
small_font = None
"""Police pour les petits textes."""
def init_font():
"""Initialise les polices après pygame.init()."""
# Liste des familles de polices disponibles (identifiants logiques)
FONT_FAMILIES = [
"pixel", # police rétro Pixel-UniCode.ttf
"dejavu" # police plus standard lisible petites tailles
]
current_font_family_index = 0 # 0=pixel par défaut
# Après définition de FONT_FAMILIES et current_font_family_index, tenter de charger la famille depuis les settings
try:
from rgsx_settings import get_font_family # import tardif pour éviter dépendances circulaires lors de l'exécution initiale
saved_family = get_font_family()
if saved_family in FONT_FAMILIES:
current_font_family_index = FONT_FAMILIES.index(saved_family)
except Exception as e:
logging.getLogger(__name__).debug(f"Impossible de charger la famille de police sauvegardée: {e}")
def init_font():
"""Initialise les polices après pygame.init() en fonction de la famille choisie."""
global font, progress_font, title_font, search_font, small_font
font_scale = accessibility_settings.get("font_scale", 1.0)
# Déterminer la famille sélectionnée
family_id = FONT_FAMILIES[current_font_family_index] if 0 <= current_font_family_index < len(FONT_FAMILIES) else "pixel"
def load_family(fam: str):
"""Retourne un tuple (font, title_font, search_font, progress_font, small_font)."""
base_size = 36
title_size = 48
search_size = 48
small_size = 28
if fam == "pixel":
path = os.path.join(APP_FOLDER, "assets", "Pixel-UniCode.ttf")
f = pygame.font.Font(path, int(base_size * font_scale))
t = pygame.font.Font(path, int(title_size * font_scale))
s = pygame.font.Font(path, int(search_size * font_scale))
p = pygame.font.Font(path, int(base_size * font_scale))
sm = pygame.font.Font(path, int(small_size * font_scale))
return f, t, s, p, sm
elif fam == "dejavu":
try:
f = pygame.font.SysFont("dejavusans", int(base_size * font_scale))
t = pygame.font.SysFont("dejavusans", int(title_size * font_scale))
s = pygame.font.SysFont("dejavusans", int(search_size * font_scale))
p = pygame.font.SysFont("dejavusans", int(base_size * font_scale))
sm = pygame.font.SysFont("dejavusans", int(small_size * font_scale))
except Exception:
f = pygame.font.SysFont("dejavu sans", int(base_size * font_scale))
t = pygame.font.SysFont("dejavu sans", int(title_size * font_scale))
s = pygame.font.SysFont("dejavu sans", int(search_size * font_scale))
p = pygame.font.SysFont("dejavu sans", int(base_size * font_scale))
sm = pygame.font.SysFont("dejavu sans", int(small_size * font_scale))
return f, t, s, p, sm
try:
font_path = os.path.join(APP_FOLDER, "assets", "Pixel-UniCode.ttf")
font = pygame.font.Font(font_path, int(36 * font_scale))
title_font = pygame.font.Font(font_path, int(48 * font_scale))
search_font = pygame.font.Font(font_path, int(48 * font_scale))
progress_font = pygame.font.Font(font_path, int(36 * font_scale))
small_font = pygame.font.Font(font_path, int(28 * font_scale))
logger.debug(f"Polices Pixel-UniCode initialisées (font_scale: {font_scale})")
font, title_font, search_font, progress_font, small_font = load_family(family_id)
logger.debug(f"Polices initialisées (famille={family_id}, scale={font_scale})")
except Exception as e:
logger.error(f"Erreur chargement famille {family_id}: {e}, fallback dejavu")
try:
font = pygame.font.SysFont("arial", int(48 * font_scale))
title_font = pygame.font.SysFont("arial", int(60 * font_scale))
search_font = pygame.font.SysFont("arial", int(60 * font_scale))
progress_font = pygame.font.SysFont("arial", int(36 * font_scale))
small_font = pygame.font.SysFont("arial", int(28 * font_scale))
logger.debug(f"Polices Arial initialisées (font_scale: {font_scale})")
font, title_font, search_font, progress_font, small_font = load_family("dejavu")
except Exception as e2:
logger.error(f"Erreur lors de l'initialisation des polices : {e2}")
font = None
progress_font = None
title_font = None
search_font = None
small_font = None
logger.error(f"Erreur fallback dejavu: {e2}")
font = title_font = search_font = progress_font = small_font = None
# Indique si une vérification/installation des mises à jour a déjà été effectuée au démarrage
update_checked = False

View File

@@ -1157,7 +1157,7 @@ def handle_controls(event, sources, joystick, screen):
# Sous-menu Display
elif config.menu_state == "pause_display_menu":
sel = getattr(config, 'pause_display_selection', 0)
total = 6 # layout, font, unsupported, unknown, filter, back
total = 8 # layout, font size, font family, unsupported, unknown, hide premium, filter, back
if is_input_matched(event, "up"):
config.pause_display_selection = (sel - 1) % total
config.needs_redraw = True
@@ -1211,8 +1211,43 @@ def handle_controls(event, sources, joystick, screen):
except Exception as e:
logger.error(f"Erreur init polices: {e}")
config.needs_redraw = True
# 2 unsupported toggle
# 2 font family cycle
elif sel == 2 and (is_input_matched(event, "left") or is_input_matched(event, "right") or is_input_matched(event, "confirm")):
try:
from rgsx_settings import get_font_family, set_font_family
families = getattr(config, 'FONT_FAMILIES', ["pixel"]) or ["pixel"]
current = get_font_family()
try:
fam_index = families.index(current)
except ValueError:
fam_index = 0
direction = 1 if (is_input_matched(event, "right") or is_input_matched(event, "confirm")) else -1
fam_index = (fam_index + direction) % len(families)
new_family = families[fam_index]
set_font_family(new_family)
config.current_font_family_index = fam_index
init_font_func = getattr(config, 'init_font', None)
if callable(init_font_func):
init_font_func()
# popup
if _:
try:
# Vérifier proprement la présence de la clé i18n
fmt = _("popup_font_family_changed") if 'popup_font_family_changed' in getattr(_, 'translations', {}) else None
except Exception:
fmt = None
if fmt:
config.popup_message = fmt.format(new_family)
else:
config.popup_message = f"Font: {new_family}"
else:
config.popup_message = f"Font: {new_family}"
config.popup_timer = 2500
config.needs_redraw = True
except Exception as e:
logger.error(f"Erreur changement font family: {e}")
# 3 unsupported toggle
elif sel == 3 and (is_input_matched(event, "left") or is_input_matched(event, "right") or is_input_matched(event, "confirm")):
try:
from rgsx_settings import get_show_unsupported_platforms, set_show_unsupported_platforms
current = get_show_unsupported_platforms()
@@ -1224,8 +1259,8 @@ def handle_controls(event, sources, joystick, screen):
config.needs_redraw = True
except Exception as e:
logger.error(f"Erreur toggle unsupported: {e}")
# 3 allow unknown extensions
elif sel == 3 and (is_input_matched(event, "left") or is_input_matched(event, "right") or is_input_matched(event, "confirm")):
# 4 allow unknown extensions
elif sel == 4 and (is_input_matched(event, "left") or is_input_matched(event, "right") or is_input_matched(event, "confirm")):
try:
from rgsx_settings import get_allow_unknown_extensions, set_allow_unknown_extensions
current = get_allow_unknown_extensions()
@@ -1235,15 +1270,26 @@ def handle_controls(event, sources, joystick, screen):
config.needs_redraw = True
except Exception as e:
logger.error(f"Erreur toggle allow_unknown_extensions: {e}")
# 4 filter platforms
elif sel == 4 and (is_input_matched(event, "confirm") or is_input_matched(event, "right")):
# 5 hide premium systems
elif sel == 5 and (is_input_matched(event, "confirm") or is_input_matched(event, "left") or is_input_matched(event, "right")):
try:
from rgsx_settings import get_hide_premium_systems, set_hide_premium_systems
cur = get_hide_premium_systems()
new_val = set_hide_premium_systems(not cur)
config.popup_message = ("Premium hidden" if new_val else "Premium visible") if _ is None else (_("popup_hide_premium_on") if new_val else _("popup_hide_premium_off"))
config.popup_timer = 2500
config.needs_redraw = True
except Exception as e:
logger.error(f"Erreur toggle hide_premium_systems: {e}")
# 6 filter platforms
elif sel == 6 and (is_input_matched(event, "confirm") or is_input_matched(event, "right")):
config.filter_return_to = "pause_display_menu"
config.menu_state = "filter_platforms"
config.selected_filter_index = 0
config.filter_platforms_scroll_offset = 0
config.needs_redraw = True
# 5 back
elif sel == 5 and (is_input_matched(event, "confirm")):
# 7 back
elif sel == 7 and (is_input_matched(event, "confirm")):
config.menu_state = "pause_menu"
config.last_state_change_time = pygame.time.get_ticks()
config.needs_redraw = True

View File

@@ -475,8 +475,28 @@ def draw_platform_grid(screen):
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)]
# Affichage des indicateurs de page si nécessaire
total_pages = (len(config.platforms) + systems_per_page - 1) // systems_per_page
# Filtrage éventuel des systèmes premium selon réglage
try:
from rgsx_settings import get_hide_premium_systems
hide_premium = get_hide_premium_systems()
except Exception:
hide_premium = False
premium_markers = getattr(config, 'PREMIUM_HOST_MARKERS', [])
if hide_premium and premium_markers:
visible_platforms = [p for p in config.platforms if not any(m.lower() in p.lower() for m in premium_markers)]
else:
visible_platforms = list(config.platforms)
# Ajuster selected_platform et current_platform/page si liste réduite
if config.selected_platform >= len(visible_platforms):
config.selected_platform = max(0, len(visible_platforms) - 1)
# Recalcule la page courante en fonction de selected_platform
systems_per_page = num_cols * num_rows
if systems_per_page <= 0:
systems_per_page = 1
config.current_page = config.selected_platform // systems_per_page if systems_per_page else 0
total_pages = (len(visible_platforms) + systems_per_page - 1) // systems_per_page
if total_pages > 1:
page_indicator_text = _("platform_page").format(config.current_page + 1, total_pages)
page_indicator = config.small_font.render(page_indicator_text, True, THEME_COLORS["text"])
@@ -490,7 +510,7 @@ def draw_platform_grid(screen):
# Pré-calcul des images pour optimiser le rendu
start_idx = config.current_page * systems_per_page
for idx in range(start_idx, start_idx + systems_per_page):
if idx >= len(config.platforms):
if idx >= len(visible_platforms):
break
grid_idx = idx - start_idx
row = grid_idx // num_cols
@@ -504,12 +524,16 @@ def draw_platform_grid(screen):
scale = scale_base + pulse if is_selected else scale_base
# Récupération robuste du dict via nom
display_name = config.platforms[idx]
display_name = visible_platforms[idx]
platform_dict = getattr(config, 'platform_dict_by_name', {}).get(display_name)
if not platform_dict:
# Fallback index brut
if idx < len(config.platform_dicts):
platform_dict = config.platform_dicts[idx]
# Chercher en parcourant platform_dicts pour correspondance nom
for pd in config.platform_dicts:
n = pd.get("platform_name") or pd.get("platform")
if n == display_name:
platform_dict = pd
break
else:
continue
platform_id = platform_dict.get("platform_name") or platform_dict.get("platform") or display_name
@@ -1351,10 +1375,18 @@ def draw_language_menu(screen):
text_rect = text_surface.get_rect(center=(button_x + button_width // 2, button_y + button_height // 2))
screen.blit(text_surface, text_rect)
# Instructions
# Instructions (placer juste au-dessus du footer sans chevauchement)
instruction_text = _("language_select_instruction")
instruction_surface = config.small_font.render(instruction_text, True, THEME_COLORS["text"])
instruction_rect = instruction_surface.get_rect(center=(config.screen_width // 2, config.screen_height - 50))
footer_reserved = 72 # hauteur approximative footer (barre bas) + marge
bottom_margin = 12
instruction_y = config.screen_height - footer_reserved - bottom_margin
# Empêcher un chevauchement avec les derniers boutons si espace réduit
last_button_bottom = start_y + (len(available_languages) - 1) * (button_height + button_spacing) + button_height
min_gap = 16
if instruction_y - last_button_bottom < min_gap:
instruction_y = last_button_bottom + min_gap
instruction_rect = instruction_surface.get_rect(center=(config.screen_width // 2, instruction_y))
screen.blit(instruction_surface, instruction_rect)
def draw_display_menu(screen):
@@ -1499,7 +1531,12 @@ def draw_pause_controls_menu(screen, selected_index):
_draw_submenu_generic(screen, _("menu_controls") if _ else "Controls", options, selected_index)
def draw_pause_display_menu(screen, selected_index):
from rgsx_settings import get_show_unsupported_platforms, get_allow_unknown_extensions
from rgsx_settings import (
get_show_unsupported_platforms,
get_allow_unknown_extensions,
get_hide_premium_systems,
get_font_family
)
# Layout label
layouts = [(3,3),(3,4),(4,3),(4,4)]
try:
@@ -1513,6 +1550,16 @@ def draw_pause_display_menu(screen, selected_index):
cur_idx = getattr(config, 'current_font_scale_index', 1)
font_value = f"{opts[cur_idx]}x"
font_txt = f"{_('submenu_display_font_size') if _ else 'Font Size'}: < {font_value} >"
# Font family
current_family = get_font_family()
# Nom user-friendly
family_map = {
"pixel": "Pixel",
"dejavu": "DejaVu Sans"
}
fam_label = family_map.get(current_family, current_family)
font_family_txt = f"{_('submenu_display_font_family') if _ else 'Font'}: < {fam_label} >"
unsupported = get_show_unsupported_platforms()
status_unsupported = _('status_on') if unsupported else _('status_off')
# Construire label sans statut pour insérer les chevrons proprement
@@ -1527,9 +1574,14 @@ def draw_pause_display_menu(screen, selected_index):
if '{status}' in raw_unknown_label:
raw_unknown_label = raw_unknown_label.split('{status}')[0].rstrip(' :')
unknown_txt = f"{raw_unknown_label}: < {status_unknown} >"
# Hide premium systems
hide_premium = get_hide_premium_systems()
status_hide_premium = _('status_on') if hide_premium else _('status_off')
hide_premium_label = _('menu_hide_premium_systems') if _ else 'Hide Premium systems'
hide_premium_txt = f"{hide_premium_label}: < {status_hide_premium} >"
filter_txt = _("submenu_display_filter_platforms") if _ else "Filter Platforms"
back_txt = _("menu_back") if _ else "Back"
options = [layout_txt, font_txt, unsupported_txt, unknown_txt, filter_txt, back_txt]
options = [layout_txt, font_txt, font_family_txt, unsupported_txt, unknown_txt, hide_premium_txt, filter_txt, back_txt]
_draw_submenu_generic(screen, _("menu_display"), options, selected_index)
def draw_pause_games_menu(screen, selected_index):
@@ -1538,7 +1590,6 @@ def draw_pause_games_menu(screen, selected_index):
source_label = _("games_source_rgsx") if mode == "rgsx" else _("games_source_custom")
source_txt = f"{_('menu_games_source_prefix')}: < {source_label} >"
update_txt = _("menu_redownload_cache")
# Première entrée: Historique des téléchargements (utiliser la clé menu_history)
history_txt = _("menu_history") if _ else "History"
back_txt = _("menu_back") if _ else "Back"
options = [history_txt, source_txt, update_txt, back_txt]

View File

@@ -149,5 +149,10 @@
"api_keys_status_title": "Status der API-Schlüssel",
"menu_games": "Spiele",
"api_keys_hint_manage": "Legen Sie Ihre Schlüssel in {path}",
"api_key_empty_suffix": "leer"
"api_key_empty_suffix": "leer",
"menu_hide_premium_systems": "Premium-Systeme ausblenden",
"popup_hide_premium_on": "Premium-Systeme ausgeblendet",
"popup_hide_premium_off": "Premium-Systeme sichtbar"
,"submenu_display_font_family": "Schrift"
,"popup_font_family_changed": "Schrift geändert: {0}"
}

View File

@@ -149,5 +149,10 @@
"api_keys_status_title": "API Keys Status",
"menu_games": "Games",
"api_keys_hint_manage": "Put your keys in {path}",
"api_key_empty_suffix": "empty"
"api_key_empty_suffix": "empty",
"menu_hide_premium_systems": "Hide Premium systems"
,"popup_hide_premium_on": "Premium systems hidden"
,"popup_hide_premium_off": "Premium systems visible"
,"submenu_display_font_family": "Font"
,"popup_font_family_changed": "Font changed: {0}"
}

View File

@@ -149,5 +149,10 @@
"api_keys_status_title": "Estado de las claves API",
"menu_games": "Juegos",
"api_keys_hint_manage": "Coloca tus claves en {path}",
"api_key_empty_suffix": "vacío"
"api_key_empty_suffix": "vacío",
"menu_hide_premium_systems": "Ocultar sistemas Premium",
"popup_hide_premium_on": "Sistemas Premium ocultos",
"popup_hide_premium_off": "Sistemas Premium visibles"
,"submenu_display_font_family": "Fuente"
,"popup_font_family_changed": "Fuente cambiada: {0}"
}

View File

@@ -149,5 +149,10 @@
"api_keys_status_title": "Statut des clés API",
"menu_games": "Jeux",
"api_keys_hint_manage": "Placez vos clés dans {path}",
"api_key_empty_suffix": "vide"
"api_key_empty_suffix": "vide",
"menu_hide_premium_systems": "Masquer systèmes Premium",
"popup_hide_premium_on": "Systèmes Premium masqués",
"popup_hide_premium_off": "Systèmes Premium visibles"
,"submenu_display_font_family": "Police"
,"popup_font_family_changed": "Police changée : {0}"
}

View File

@@ -149,5 +149,10 @@
"api_keys_status_title": "Stato delle chiavi API",
"menu_games": "Giochi",
"api_keys_hint_manage": "Metti le tue chiavi in {path}",
"api_key_empty_suffix": "vuoto"
"api_key_empty_suffix": "vuoto",
"menu_hide_premium_systems": "Nascondi sistemi Premium",
"popup_hide_premium_on": "Sistemi Premium nascosti",
"popup_hide_premium_off": "Sistemi Premium visibili"
,"submenu_display_font_family": "Font"
,"popup_font_family_changed": "Font cambiato: {0}"
}

View File

@@ -149,5 +149,10 @@
"api_keys_status_title": "Status das chaves API",
"menu_games": "Jogos",
"api_keys_hint_manage": "Coloque suas chaves em {path}",
"api_key_empty_suffix": "vazio"
"api_key_empty_suffix": "vazio",
"menu_hide_premium_systems": "Ocultar sistemas Premium",
"popup_hide_premium_on": "Sistemas Premium ocultos",
"popup_hide_premium_off": "Sistemas Premium visíveis"
,"submenu_display_font_family": "Fonte"
,"popup_font_family_changed": "Fonte alterada: {0}"
}

View File

@@ -56,7 +56,8 @@ def load_rgsx_settings():
"font_scale": 1.0
},
"display": {
"grid": "3x4"
"grid": "3x4",
"font_family": "pixel"
},
"symlink": {
"enabled": False,
@@ -228,6 +229,22 @@ def set_allow_unknown_extensions(enabled: bool) -> bool:
save_rgsx_settings(settings)
return settings["allow_unknown_extensions"]
# ----------------------- Hide premium systems toggle ----------------------- #
def get_hide_premium_systems(settings=None) -> bool:
"""Retourne True si le masquage des systèmes premium est activé."""
if settings is None:
settings = load_rgsx_settings()
return bool(settings.get("hide_premium_systems", False))
def set_hide_premium_systems(enabled: bool) -> bool:
"""Active/désactive le masquage des systèmes premium et sauvegarde."""
settings = load_rgsx_settings()
settings["hide_premium_systems"] = bool(enabled)
save_rgsx_settings(settings)
return settings["hide_premium_systems"]
# ----------------------- Display layout (grid) ----------------------- #
def get_display_grid(settings=None):
@@ -252,3 +269,15 @@ def set_display_grid(cols: int, rows: int):
disp["grid"] = f"{cols}x{rows}"
save_rgsx_settings(settings)
return cols, rows
def get_font_family(settings=None):
if settings is None:
settings = load_rgsx_settings()
return settings.get("display", {}).get("font_family", "pixel")
def set_font_family(family: str):
settings = load_rgsx_settings()
disp = settings.setdefault("display", {})
disp["font_family"] = family
save_rgsx_settings(settings)
return family