v1.9.8.7
- Move accessibility settings loading and saving on accessibility.py - Updated controls to replace old "progress" status button with "clear_history" - Refactored control mappings and descriptions to align with the new naming conventions. - Updated language files - Improved the controls help menu layout for better readability and organization.
This commit is contained in:
@@ -1,13 +1,14 @@
|
||||
import os
|
||||
os.environ["SDL_FBDEV"] = "/dev/fb0"
|
||||
import pygame # type: ignore
|
||||
# type: ignore[reportAttributeAccessIssue]
|
||||
import asyncio
|
||||
import platform
|
||||
import logging
|
||||
import requests
|
||||
import queue
|
||||
import datetime
|
||||
import config
|
||||
|
||||
from display import (
|
||||
init_display, draw_loading_screen, draw_error_screen, draw_platform_grid,
|
||||
draw_progress_screen, draw_controls, draw_virtual_keyboard, draw_popup_result_download,
|
||||
@@ -19,14 +20,14 @@ from display import (
|
||||
from language import handle_language_menu_events, _
|
||||
from network import test_internet, download_rom, is_1fichier_url, download_from_1fichier, check_for_updates
|
||||
from controls import handle_controls, validate_menu_state, process_key_repeats, get_emergency_controls
|
||||
from controls_mapper import load_controls_config, save_controls_config, map_controls, draw_controls_mapping, get_actions
|
||||
from controls_mapper import load_controls_config, map_controls, draw_controls_mapping, get_actions
|
||||
from utils import (
|
||||
detect_non_pc, load_sources, check_extension_before_download, extract_zip_data,
|
||||
play_random_music, load_accessibility_settings, load_music_config
|
||||
play_random_music, load_music_config
|
||||
)
|
||||
from history import load_history, save_history
|
||||
import config
|
||||
from config import OTA_data_ZIP
|
||||
from accessibility import load_accessibility_settings
|
||||
|
||||
# Configuration du logging
|
||||
try:
|
||||
@@ -267,7 +268,15 @@ async def main():
|
||||
|
||||
if config.menu_state == "confirm_clear_history":
|
||||
action = handle_controls(event, sources, joystick, screen)
|
||||
config.needs_redraw = True
|
||||
if action == "confirm":
|
||||
config.history.clear()
|
||||
save_history(config.history)
|
||||
config.menu_state = "history"
|
||||
config.needs_redraw = True
|
||||
logger.debug("Historique effacé")
|
||||
elif action == "cancel":
|
||||
config.menu_state = "history"
|
||||
config.needs_redraw = True
|
||||
continue
|
||||
|
||||
if config.menu_state == "confirm_cancel_download":
|
||||
@@ -314,7 +323,7 @@ async def main():
|
||||
logger.debug("Téléchargement annulé, retour à l'état précédent")
|
||||
continue
|
||||
|
||||
if config.menu_state in ["platform", "game", "error", "confirm_exit", "download_progress", "download_result", "history"]:
|
||||
if config.menu_state in ["platform", "game", "error", "confirm_exit", "download_result", "history"]:
|
||||
action = handle_controls(event, sources, joystick, screen)
|
||||
config.needs_redraw = True
|
||||
if action == "quit":
|
||||
@@ -456,7 +465,13 @@ async def main():
|
||||
config.needs_redraw = True
|
||||
logger.debug(f"Retéléchargement terminé pour {game_name}, succès={success}, message={message}")
|
||||
break
|
||||
|
||||
elif action in ("clear_history", "delete_history") and config.menu_state == "history":
|
||||
# Ouvrir le dialogue de confirmation
|
||||
config.previous_menu_state = config.menu_state
|
||||
config.menu_state = "confirm_clear_history"
|
||||
config.confirm_selection = 0
|
||||
config.needs_redraw = True
|
||||
continue
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,34 @@
|
||||
import pygame #type:ignore
|
||||
import config
|
||||
from utils import save_accessibility_settings
|
||||
import os
|
||||
import json
|
||||
from logging import getLogger
|
||||
from language import _
|
||||
|
||||
logger = getLogger(__name__)
|
||||
|
||||
def load_accessibility_settings():
|
||||
"""Charge les paramètres d'accessibilité depuis accessibility.json."""
|
||||
accessibility_path = os.path.join(config.SAVE_FOLDER, "accessibility.json")
|
||||
try:
|
||||
if os.path.exists(accessibility_path):
|
||||
with open(accessibility_path, 'r', encoding='utf-8') as f:
|
||||
return json.load(f)
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur lors du chargement de accessibility.json: {str(e)}")
|
||||
return {"font_scale": 1.0}
|
||||
|
||||
def save_accessibility_settings(settings):
|
||||
"""Sauvegarde les paramètres d'accessibilité dans accessibility.json."""
|
||||
accessibility_path = os.path.join(config.SAVE_FOLDER, "accessibility.json")
|
||||
try:
|
||||
os.makedirs(config.SAVE_FOLDER, exist_ok=True)
|
||||
with open(accessibility_path, 'w', encoding='utf-8') as f:
|
||||
json.dump(settings, f, indent=2)
|
||||
logger.debug(f"Paramètres d'accessibilité sauvegardés: {settings}")
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur lors de la sauvegarde de accessibility.json: {str(e)}")
|
||||
|
||||
def draw_accessibility_menu(screen):
|
||||
"""Affiche le menu d'accessibilité avec curseur pour la taille de police."""
|
||||
from display import OVERLAY, THEME_COLORS, draw_stylized_button
|
||||
|
||||
@@ -4,7 +4,7 @@ import sys
|
||||
import logging
|
||||
|
||||
# Version actuelle de l'application
|
||||
app_version = "1.9.8.6"
|
||||
app_version = "1.9.8.7"
|
||||
|
||||
def get_application_root():
|
||||
"""Détermine le dossier de l'application de manière portable."""
|
||||
|
||||
@@ -26,7 +26,7 @@ key_states = {} # Dictionnaire pour suivre l'état des touches
|
||||
|
||||
# Liste des états valides
|
||||
VALID_STATES = [
|
||||
"platform", "game", "download_progress", "download_result", "confirm_exit",
|
||||
"platform", "game", "download_result", "confirm_exit",
|
||||
"extension_warning", "pause_menu", "controls_help", "history", "controls_mapping",
|
||||
"redownload_game_cache", "restart_popup", "error", "loading", "confirm_clear_history",
|
||||
"language_select"
|
||||
@@ -52,7 +52,7 @@ def load_controls_config(path=CONTROLS_CONFIG_PATH):
|
||||
"up": {"type": "key", "key": pygame.K_UP},
|
||||
"down": {"type": "key", "key": pygame.K_DOWN},
|
||||
"start": {"type": "key", "key": pygame.K_p},
|
||||
"progress": {"type": "key", "key": pygame.K_x},
|
||||
"clear_history": {"type": "key", "key": pygame.K_x},
|
||||
"history": {"type": "key", "key": pygame.K_h},
|
||||
"page_up": {"type": "key", "key": pygame.K_PAGEUP},
|
||||
"page_down": {"type": "key", "key": pygame.K_PAGEDOWN},
|
||||
@@ -62,17 +62,27 @@ def load_controls_config(path=CONTROLS_CONFIG_PATH):
|
||||
}
|
||||
|
||||
try:
|
||||
with open(path, "r") as f:
|
||||
config_data = json.load(f)
|
||||
# Vérifier et compléter les actions manquantes
|
||||
for action, default_mapping in default_config.items():
|
||||
if action not in config_data:
|
||||
logger.warning(f"Action {action} manquante dans {path}, utilisation de la valeur par défaut")
|
||||
config_data[action] = default_mapping
|
||||
return config_data
|
||||
except (FileNotFoundError, json.JSONDecodeError) as e:
|
||||
logger.error(f"Erreur lors de la lecture de {path} : {e}, utilisation de la configuration par défaut")
|
||||
return default_config
|
||||
if os.path.exists(path):
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
if not isinstance(data, dict):
|
||||
data = {}
|
||||
else:
|
||||
data = {}
|
||||
changed = False
|
||||
for k, v in default_config.items():
|
||||
if k not in data:
|
||||
data[k] = v
|
||||
changed = True
|
||||
if changed:
|
||||
os.makedirs(os.path.dirname(path), exist_ok=True)
|
||||
with open(path, "w", encoding="utf-8") as f:
|
||||
json.dump(data, f, indent=2)
|
||||
logging.getLogger(__name__).debug(f"controls.json complété avec les actions manquantes: {path}")
|
||||
return data
|
||||
except Exception as e:
|
||||
logging.getLogger(__name__).error(f"Erreur load_controls_config: {e}")
|
||||
return default_config.copy()
|
||||
|
||||
# Fonction pour vérifier si un événement correspond à une action
|
||||
def is_input_matched(event, action_name):
|
||||
@@ -254,11 +264,6 @@ def handle_controls(event, sources, joystick, screen):
|
||||
config.repeat_start_time = 0
|
||||
config.repeat_last_action = current_time
|
||||
config.needs_redraw = True
|
||||
elif is_input_matched(event, "progress"):
|
||||
if config.download_tasks:
|
||||
config.menu_state = "download_progress"
|
||||
config.needs_redraw = True
|
||||
logger.debug("Retour à download_progress depuis platform")
|
||||
elif is_input_matched(event, "history"):
|
||||
config.menu_state = "history"
|
||||
config.needs_redraw = True
|
||||
@@ -356,20 +361,20 @@ def handle_controls(event, sources, joystick, screen):
|
||||
config.scroll_offset = 0
|
||||
config.needs_redraw = True
|
||||
logger.debug("Sortie du mode recherche")
|
||||
elif is_input_matched(event, "filter") or is_input_matched(event, "confirm"):
|
||||
elif is_input_matched(event, "filter"):
|
||||
config.search_mode = False
|
||||
config.filter_active = bool(config.search_query)
|
||||
config.needs_redraw = True
|
||||
logger.debug(f"Validation du filtre avec manette: query={config.search_query}, filter_active={config.filter_active}")
|
||||
elif config.search_mode and not config.is_non_pc:
|
||||
# Gestion de la recherche sur PC (clavier et manette)
|
||||
if is_input_matched(event, "filter"):
|
||||
if is_input_matched(event, "confirm"):
|
||||
config.search_mode = False
|
||||
config.filter_active = True
|
||||
config.current_game = 0
|
||||
config.scroll_offset = 0
|
||||
config.needs_redraw = True
|
||||
logger.debug(f"Validation du filtre avec bouton filter sur PC: query={config.search_query}")
|
||||
logger.debug(f"Validation du filtre avec bouton entree sur PC: query={config.search_query}")
|
||||
elif is_input_matched(event, "cancel"):
|
||||
config.search_mode = False
|
||||
config.search_query = ""
|
||||
@@ -397,31 +402,7 @@ def handle_controls(event, sources, joystick, screen):
|
||||
config.scroll_offset = 0
|
||||
config.needs_redraw = True
|
||||
logger.debug(f"Suppression caractère: query={config.search_query}, jeux filtrés={len(config.filtered_games)}")
|
||||
# Gestion de la validation
|
||||
elif is_input_matched(event, "confirm"):
|
||||
config.search_mode = False
|
||||
config.filter_active = True # Conserver le filtre actif
|
||||
config.current_game = 0
|
||||
config.scroll_offset = 0
|
||||
config.needs_redraw = True
|
||||
logger.debug(f"Validation de la recherche: query={config.search_query}, jeux filtrés={len(config.filtered_games)}")
|
||||
# Gestion de l'annulation
|
||||
elif is_input_matched(event, "cancel"):
|
||||
config.search_mode = False
|
||||
config.search_query = ""
|
||||
config.filtered_games = config.games
|
||||
config.current_game = 0
|
||||
config.scroll_offset = 0
|
||||
config.needs_redraw = True
|
||||
logger.debug("Sortie du mode recherche")
|
||||
# Gestion de la validation avec le bouton filter
|
||||
elif is_input_matched(event, "filter"):
|
||||
config.search_mode = False
|
||||
config.filter_active = True
|
||||
config.current_game = 0
|
||||
config.scroll_offset = 0
|
||||
config.needs_redraw = True
|
||||
logger.debug(f"Validation du filtre avec bouton filter: query={config.search_query}, jeux filtrés={len(config.filtered_games)}")
|
||||
|
||||
|
||||
else:
|
||||
if is_input_matched(event, "up"):
|
||||
@@ -462,13 +443,7 @@ def handle_controls(event, sources, joystick, screen):
|
||||
config.scroll_offset = 0
|
||||
config.selected_key = (0, 0)
|
||||
config.needs_redraw = True
|
||||
logger.debug("Entrée en mode recherche")
|
||||
elif is_input_matched(event, "progress"):
|
||||
if config.download_tasks:
|
||||
config.previous_menu_state = config.menu_state
|
||||
config.menu_state = "download_progress"
|
||||
config.needs_redraw = True
|
||||
logger.debug(f"Retour à download_progress depuis {config.previous_menu_state}")
|
||||
logger.debug("Entrée en mode recherche")
|
||||
elif is_input_matched(event, "history"):
|
||||
config.menu_state = "history"
|
||||
config.needs_redraw = True
|
||||
@@ -683,7 +658,9 @@ def handle_controls(event, sources, joystick, screen):
|
||||
config.repeat_last_action = current_time
|
||||
config.needs_redraw = True
|
||||
#logger.debug("Page suivante dans l'historique")
|
||||
elif is_input_matched(event, "progress"):
|
||||
elif (is_input_matched(event, "clear_history")
|
||||
or is_input_matched(event, "delete_history")
|
||||
or is_input_matched(event, "progress")):
|
||||
config.previous_menu_state = validate_menu_state(config.previous_menu_state)
|
||||
config.menu_state = "confirm_clear_history"
|
||||
config.confirm_clear_selection = 0 # 0 pour "Non", 1 pour "Oui"
|
||||
@@ -782,12 +759,12 @@ def handle_controls(event, sources, joystick, screen):
|
||||
elif is_input_matched(event, "cancel"):
|
||||
config.menu_state = "history"
|
||||
config.needs_redraw = True
|
||||
|
||||
# Confirmation vider l'historique"
|
||||
|
||||
# Confirmation vider l'historique
|
||||
elif config.menu_state == "confirm_clear_history":
|
||||
logger.debug(f"État confirm_clear_history, confirm_clear_selection={config.confirm_clear_selection}, événement={event.type}, valeur={getattr(event, 'value', None)}")
|
||||
if is_input_matched(event, "confirm"):
|
||||
logger.debug(f"Action confirm détectée dans confirm_clear_history")
|
||||
# 0 = Non, 1 = Oui
|
||||
if config.confirm_clear_selection == 1: # Oui
|
||||
clear_history()
|
||||
config.history = []
|
||||
@@ -799,38 +776,13 @@ def handle_controls(event, sources, joystick, screen):
|
||||
else: # Non
|
||||
config.menu_state = "history"
|
||||
config.needs_redraw = True
|
||||
logger.debug("Annulation du vidage de l'historique, retour à history")
|
||||
elif is_input_matched(event, "left"):
|
||||
#logger.debug(f"Action left détectée dans confirm_clear_history")
|
||||
config.confirm_clear_selection = 1 # Sélectionner "Non"
|
||||
elif is_input_matched(event, "left") or is_input_matched(event, "right"):
|
||||
config.confirm_clear_selection = 1 - config.confirm_clear_selection
|
||||
config.needs_redraw = True
|
||||
#logger.debug(f"Changement sélection confirm_clear_history: {config.confirm_clear_selection}")
|
||||
elif is_input_matched(event, "right"):
|
||||
#logger.debug(f"Action right détectée dans confirm_clear_history")
|
||||
config.confirm_clear_selection = 0 # Sélectionner "Oui"
|
||||
config.needs_redraw = True
|
||||
#logger.debug(f"Changement sélection confirm_clear_history: {config.confirm_clear_selection}")
|
||||
elif is_input_matched(event, "cancel"):
|
||||
#logger.debug(f"Action cancel détectée dans confirm_clear_history")
|
||||
config.menu_state = "history"
|
||||
config.needs_redraw = True
|
||||
logger.debug("Annulation du vidage de l'historique, retour à history")
|
||||
|
||||
# Progression téléchargement
|
||||
elif config.menu_state == "download_progress":
|
||||
if is_input_matched(event, "cancel"):
|
||||
for task in config.download_tasks:
|
||||
task.cancel()
|
||||
config.download_tasks.clear()
|
||||
config.download_progress.clear()
|
||||
config.pending_download = None
|
||||
config.menu_state = validate_menu_state(config.previous_menu_state)
|
||||
config.needs_redraw = True
|
||||
logger.debug(f"Téléchargement annulé, retour à {config.menu_state}")
|
||||
elif is_input_matched(event, "progress"):
|
||||
config.menu_state = validate_menu_state(config.previous_menu_state)
|
||||
config.needs_redraw = True
|
||||
logger.debug(f"Retour à {config.menu_state} depuis download_progress")
|
||||
|
||||
# Résultat téléchargement
|
||||
elif config.menu_state == "download_result":
|
||||
@@ -958,7 +910,6 @@ def handle_controls(event, sources, joystick, screen):
|
||||
if config.redownload_confirm_selection == 1: # Oui
|
||||
logger.debug("Début du redownload des jeux")
|
||||
config.download_tasks.clear()
|
||||
config.download_progress.clear()
|
||||
config.pending_download = None
|
||||
if os.path.exists(config.APP_FOLDER + "/sources.json"):
|
||||
try:
|
||||
@@ -1151,7 +1102,11 @@ def get_emergency_controls():
|
||||
"left": {"type": "key", "key": pygame.K_LEFT},
|
||||
"right": {"type": "key", "key": pygame.K_RIGHT},
|
||||
"start": {"type": "key", "key": pygame.K_p},
|
||||
# Ajouter aussi les contrôles manette de base si disponible
|
||||
"confirm_joy": {"type": "button", "button": 0}, # A/Croix
|
||||
"cancel_joy": {"type": "button", "button": 1}, # B/Rond
|
||||
"history": {"type": "key", "key": pygame.K_h},
|
||||
"clear_history": {"type": "key", "key": pygame.K_x},
|
||||
"page_up": {"type": "key", "key": pygame.K_PAGEUP},
|
||||
"page_down": {"type": "key", "key": pygame.K_PAGEDOWN},
|
||||
# manette basique
|
||||
"confirm_joy": {"type": "button", "button": 0},
|
||||
"cancel_joy": {"type": "button", "button": 1},
|
||||
}
|
||||
@@ -28,7 +28,7 @@ ACTION_DEFS = [
|
||||
{"name": "page_up"},
|
||||
{"name": "page_down"},
|
||||
{"name": "history"},
|
||||
{"name": "delete_history"},
|
||||
{"name": "clear_history"},
|
||||
{"name": "delete"},
|
||||
{"name": "space"},
|
||||
]
|
||||
@@ -60,14 +60,14 @@ SDL_TO_PYGAME_KEY = {
|
||||
|
||||
# Noms lisibles pour les touches clavier
|
||||
KEY_NAMES = {
|
||||
pygame.K_RETURN: "Entrée",
|
||||
pygame.K_RETURN: "Enter",
|
||||
pygame.K_ESCAPE: "Échap",
|
||||
pygame.K_SPACE: "Espace",
|
||||
pygame.K_UP: "Flèche Haut",
|
||||
pygame.K_DOWN: "Flèche Bas",
|
||||
pygame.K_LEFT: "Flèche Gauche",
|
||||
pygame.K_RIGHT: "Flèche Droite",
|
||||
pygame.K_BACKSPACE: "Retour Arrière",
|
||||
pygame.K_UP: "↑",
|
||||
pygame.K_DOWN: "↓",
|
||||
pygame.K_LEFT: "←",
|
||||
pygame.K_RIGHT: "→",
|
||||
pygame.K_BACKSPACE: "Backspace",
|
||||
pygame.K_TAB: "Tab",
|
||||
pygame.K_LALT: "Alt",
|
||||
pygame.K_RALT: "AltGR",
|
||||
@@ -116,23 +116,23 @@ KEY_NAMES = {
|
||||
pygame.K_7: "7",
|
||||
pygame.K_8: "8",
|
||||
pygame.K_9: "9",
|
||||
pygame.K_KP0: "Pavé 0",
|
||||
pygame.K_KP1: "Pavé 1",
|
||||
pygame.K_KP2: "Pavé 2",
|
||||
pygame.K_KP3: "Pavé 3",
|
||||
pygame.K_KP4: "Pavé 4",
|
||||
pygame.K_KP5: "Pavé 5",
|
||||
pygame.K_KP6: "Pavé 6",
|
||||
pygame.K_KP7: "Pavé 7",
|
||||
pygame.K_KP8: "Pavé 8",
|
||||
pygame.K_KP9: "Pavé 9",
|
||||
pygame.K_KP_PERIOD: "Pavé .",
|
||||
pygame.K_KP_DIVIDE: "Pavé /",
|
||||
pygame.K_KP_MULTIPLY: "Pavé *",
|
||||
pygame.K_KP_MINUS: "Pavé -",
|
||||
pygame.K_KP_PLUS: "Pavé +",
|
||||
pygame.K_KP_ENTER: "Pavé Entrée",
|
||||
pygame.K_KP_EQUALS: "Pavé =",
|
||||
pygame.K_KP0: "Num 0",
|
||||
pygame.K_KP1: "Num 1",
|
||||
pygame.K_KP2: "Num 2",
|
||||
pygame.K_KP3: "Num 3",
|
||||
pygame.K_KP4: "Num 4",
|
||||
pygame.K_KP5: "Num 5",
|
||||
pygame.K_KP6: "Num 6",
|
||||
pygame.K_KP7: "Num 7",
|
||||
pygame.K_KP8: "Num 8",
|
||||
pygame.K_KP9: "Num 9",
|
||||
pygame.K_KP_PERIOD: "Num .",
|
||||
pygame.K_KP_DIVIDE: "Num /",
|
||||
pygame.K_KP_MULTIPLY: "Num *",
|
||||
pygame.K_KP_MINUS: "Num -",
|
||||
pygame.K_KP_PLUS: "Num +",
|
||||
pygame.K_KP_ENTER: "Num Enter",
|
||||
pygame.K_KP_EQUALS: "Num =",
|
||||
pygame.K_F1: "F1",
|
||||
pygame.K_F2: "F2",
|
||||
pygame.K_F3: "F3",
|
||||
@@ -152,9 +152,9 @@ KEY_NAMES = {
|
||||
pygame.K_DELETE: "Suppr",
|
||||
pygame.K_HOME: "Début",
|
||||
pygame.K_END: "Fin",
|
||||
pygame.K_PAGEUP: "Page Haut",
|
||||
pygame.K_PAGEDOWN: "Page Bas",
|
||||
pygame.K_PRINT: "Impr Écran",
|
||||
pygame.K_PAGEUP: "Page+",
|
||||
pygame.K_PAGEDOWN: "Page-",
|
||||
pygame.K_PRINT: "PrintScreen",
|
||||
pygame.K_SYSREQ: "SysReq",
|
||||
pygame.K_BREAK: "Pause",
|
||||
pygame.K_PAUSE: "Pause",
|
||||
@@ -286,17 +286,36 @@ HOLD_DURATION = 1000
|
||||
|
||||
JOYHAT_DEBOUNCE = 200 # Délai anti-rebond pour JOYHATMOTION (ms)
|
||||
|
||||
def load_controls_config():
|
||||
def load_controls_config(path=CONTROLS_CONFIG_PATH):
|
||||
"""Charge la configuration des contrôles depuis controls.json"""
|
||||
try:
|
||||
if os.path.exists(CONTROLS_CONFIG_PATH):
|
||||
with open(CONTROLS_CONFIG_PATH, "r") as f:
|
||||
config_data = json.load(f)
|
||||
logger.debug(f"Configuration des contrôles chargée : {config_data}")
|
||||
return config_data
|
||||
if os.path.exists(path):
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
if not isinstance(data, dict):
|
||||
data = {}
|
||||
else:
|
||||
logger.debug("Aucun fichier controls.json trouvé")
|
||||
return {}
|
||||
data = {}
|
||||
changed = False
|
||||
|
||||
# Normaliser les alias vers l’action canonique "clear_history"
|
||||
# Votre controls.json a "delete_history": mappez-le vers "clear_history"
|
||||
if "delete_history" in data and "clear_history" not in data:
|
||||
data["clear_history"] = data["delete_history"]
|
||||
changed = True
|
||||
# Ancien alias éventuel
|
||||
if "progress" in data and "clear_history" not in data:
|
||||
data["clear_history"] = data["progress"]
|
||||
changed = True
|
||||
|
||||
# Compléter avec des valeurs par défaut si nécessaire (facultatif selon votre implémentation)
|
||||
# ...existing code de complétion si présent...
|
||||
|
||||
if changed:
|
||||
os.makedirs(os.path.dirname(path), exist_ok=True)
|
||||
with open(path, "w", encoding="utf-8") as f:
|
||||
json.dump(data, f, indent=2)
|
||||
return data
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur lors du chargement de controls.json : {e}")
|
||||
return {}
|
||||
|
||||
@@ -248,14 +248,14 @@ def get_control_display(action, default):
|
||||
if control_type == 'key':
|
||||
key_code = control_config.get('key')
|
||||
key_names = {
|
||||
pygame.K_RETURN: "Entrée",
|
||||
pygame.K_RETURN: "Enter",
|
||||
pygame.K_ESCAPE: "Échap",
|
||||
pygame.K_SPACE: "Espace",
|
||||
pygame.K_UP: "Flèche Haut",
|
||||
pygame.K_DOWN: "Flèche Bas",
|
||||
pygame.K_LEFT: "Flèche Gauche",
|
||||
pygame.K_RIGHT: "Flèche Droite",
|
||||
pygame.K_BACKSPACE: "Retour Arrière",
|
||||
pygame.K_UP: "↑",
|
||||
pygame.K_DOWN: "↓",
|
||||
pygame.K_LEFT: "←",
|
||||
pygame.K_RIGHT: "→",
|
||||
pygame.K_BACKSPACE: "Backspace",
|
||||
pygame.K_TAB: "Tab",
|
||||
pygame.K_LALT: "Alt",
|
||||
pygame.K_RALT: "AltGR",
|
||||
@@ -304,23 +304,23 @@ def get_control_display(action, default):
|
||||
pygame.K_7: "7",
|
||||
pygame.K_8: "8",
|
||||
pygame.K_9: "9",
|
||||
pygame.K_KP0: "Pavé 0",
|
||||
pygame.K_KP1: "Pavé 1",
|
||||
pygame.K_KP2: "Pavé 2",
|
||||
pygame.K_KP3: "Pavé 3",
|
||||
pygame.K_KP4: "Pavé 4",
|
||||
pygame.K_KP5: "Pavé 5",
|
||||
pygame.K_KP6: "Pavé 6",
|
||||
pygame.K_KP7: "Pavé 7",
|
||||
pygame.K_KP8: "Pavé 8",
|
||||
pygame.K_KP9: "Pavé 9",
|
||||
pygame.K_KP_PERIOD: "Pavé .",
|
||||
pygame.K_KP_DIVIDE: "Pavé /",
|
||||
pygame.K_KP_MULTIPLY: "Pavé *",
|
||||
pygame.K_KP_MINUS: "Pavé -",
|
||||
pygame.K_KP_PLUS: "Pavé +",
|
||||
pygame.K_KP_ENTER: "Pavé Entrée",
|
||||
pygame.K_KP_EQUALS: "Pavé =",
|
||||
pygame.K_KP0: "Num 0",
|
||||
pygame.K_KP1: "Num 1",
|
||||
pygame.K_KP2: "Num 2",
|
||||
pygame.K_KP3: "Num 3",
|
||||
pygame.K_KP4: "Num 4",
|
||||
pygame.K_KP5: "Num 5",
|
||||
pygame.K_KP6: "Num 6",
|
||||
pygame.K_KP7: "Num 7",
|
||||
pygame.K_KP8: "Num 8",
|
||||
pygame.K_KP9: "Num 9",
|
||||
pygame.K_KP_PERIOD: "Num .",
|
||||
pygame.K_KP_DIVIDE: "Num /",
|
||||
pygame.K_KP_MULTIPLY: "Num *",
|
||||
pygame.K_KP_MINUS: "Num -",
|
||||
pygame.K_KP_PLUS: "Num +",
|
||||
pygame.K_KP_ENTER: "Num Enter",
|
||||
pygame.K_KP_EQUALS: "Num =",
|
||||
pygame.K_F1: "F1",
|
||||
pygame.K_F2: "F2",
|
||||
pygame.K_F3: "F3",
|
||||
@@ -340,9 +340,9 @@ def get_control_display(action, default):
|
||||
pygame.K_DELETE: "Suppr",
|
||||
pygame.K_HOME: "Début",
|
||||
pygame.K_END: "Fin",
|
||||
pygame.K_PAGEUP: "Page Haut",
|
||||
pygame.K_PAGEDOWN: "Page Bas",
|
||||
pygame.K_PRINT: "Impr Écran",
|
||||
pygame.K_PAGEUP: "Page+",
|
||||
pygame.K_PAGEDOWN: "Page-",
|
||||
pygame.K_PRINT: "Printscreen",
|
||||
pygame.K_SYSREQ: "SysReq",
|
||||
pygame.K_BREAK: "Pause",
|
||||
pygame.K_PAUSE: "Pause",
|
||||
@@ -1249,121 +1249,161 @@ def draw_pause_menu(screen, selected_option):
|
||||
|
||||
# Menu aide contrôles
|
||||
def draw_controls_help(screen, previous_state):
|
||||
"""Affiche la liste des contrôles avec un style moderne."""
|
||||
start_text = _("controls_action_start")
|
||||
history_text = _("controls_action_history")
|
||||
delete_text = _("controls_action_delete")
|
||||
space_text = _("controls_action_space")
|
||||
nav_text = _("controls_navigation")
|
||||
pages_text = _("controls_pages")
|
||||
confirm_select_text = _("controls_confirm_select")
|
||||
cancel_back_text = _("controls_cancel_back")
|
||||
clear_history_text = _("controls_action_delete_history")
|
||||
filter_search_text = _("controls_filter_search")
|
||||
|
||||
"""Affiche la liste des contrôles (aide) avec mise en page adaptative."""
|
||||
# Contenu des catégories
|
||||
control_categories = {
|
||||
_("controls_category_navigation"): [
|
||||
f"{get_control_display('up', '↑')} {get_control_display('down', '↓')} {get_control_display('left', '←')} {get_control_display('right', '→')} : {nav_text}",
|
||||
f"{get_control_display('page_up', 'LB')} {get_control_display('page_down', 'RB')} : {pages_text}"
|
||||
f"{get_control_display('up', '↑')} {get_control_display('down', '↓')} {get_control_display('left', '←')} {get_control_display('right', '→')} : {_('controls_navigation')}",
|
||||
f"{get_control_display('page_up', 'LB')} {get_control_display('page_down', 'RB')} : {_('controls_pages')}",
|
||||
],
|
||||
_("controls_category_main_actions"): [
|
||||
f"{get_control_display('confirm', 'A')} : {confirm_select_text}",
|
||||
f"{get_control_display('cancel', 'B')} : {cancel_back_text}",
|
||||
f"{get_control_display('start', 'Start')} : {start_text}"
|
||||
f"{get_control_display('confirm', 'A')} : {_('controls_confirm_select')}",
|
||||
f"{get_control_display('cancel', 'B')} : {_('controls_cancel_back')}",
|
||||
f"{get_control_display('start', 'Start')} : {_('controls_action_start')}",
|
||||
],
|
||||
_("controls_category_downloads"): [
|
||||
f"{get_control_display('history', 'Y')} : {history_text}",
|
||||
f"{get_control_display('progress', 'X')} : {clear_history_text}"
|
||||
f"{get_control_display('history', 'Y')} : {_('controls_action_history')}",
|
||||
f"{get_control_display('clear_history', 'X')} : {_('controls_action_clear_history')}",
|
||||
],
|
||||
_("controls_category_search"): [
|
||||
f"{get_control_display('filter', 'Select')} : {_('controls_filter_search')}",
|
||||
f"{get_control_display('delete', 'Suppr')} : {_('controls_action_delete')}",
|
||||
f"{get_control_display('space', 'Espace')} : {_('controls_action_space')}",
|
||||
],
|
||||
_("controls_category_search"): [
|
||||
f"{get_control_display('filter', 'Select')} : {filter_search_text}",
|
||||
f"{get_control_display('delete', 'Suppr')} : {delete_text}",
|
||||
f"{get_control_display('space', 'Espace')} : {space_text}"
|
||||
]
|
||||
}
|
||||
|
||||
state_controls = {
|
||||
"error": control_categories,
|
||||
"platform": control_categories,
|
||||
"game": control_categories,
|
||||
"download_progress": control_categories,
|
||||
"download_result": control_categories,
|
||||
"confirm_exit": control_categories,
|
||||
"extension_warning": control_categories,
|
||||
"history": control_categories
|
||||
}
|
||||
|
||||
control_columns = state_controls.get(previous_state, {})
|
||||
if not control_columns:
|
||||
|
||||
# États autorisés (même logique qu'avant)
|
||||
allowed_states = {
|
||||
"error", "platform", "game", "download_result", "confirm_exit",
|
||||
"extension_warning", "history", "clear_history"
|
||||
}
|
||||
if previous_state not in allowed_states:
|
||||
return
|
||||
|
||||
screen.blit(OVERLAY, (0, 0))
|
||||
|
||||
# Organisation en 2x2
|
||||
categories = list(control_columns.keys())
|
||||
col1 = [categories[0], categories[2]] # Navigation, Historique/Téléchargements
|
||||
col2 = [categories[1], categories[3]] # Actions principales, Recherche / Filtre
|
||||
|
||||
# Calculer la largeur nécessaire
|
||||
max_text_width = 0
|
||||
for category, controls in control_columns.items():
|
||||
for control in controls:
|
||||
text_width = config.small_font.size(control)[0]
|
||||
max_text_width = max(max_text_width, text_width)
|
||||
|
||||
col_width = max_text_width + 40
|
||||
popup_width = col_width * 2 + 100 # Plus d'espace entre colonnes
|
||||
popup_height = 320
|
||||
popup_x = (config.screen_width - popup_width) // 2
|
||||
popup_y = (config.screen_height - popup_height) // 2
|
||||
# Paramètres d'affichage
|
||||
font = config.small_font
|
||||
title_font = config.title_font
|
||||
section_font = config.font
|
||||
line_spacing = max(4, font.get_height() // 6)
|
||||
section_spacing = font.get_height() // 2
|
||||
title_spacing = font.get_height()
|
||||
padding = 24
|
||||
inter_col_spacing = 48
|
||||
max_panel_width = int(config.screen_width * 0.9)
|
||||
max_panel_height = int(config.screen_height * 0.9)
|
||||
|
||||
# Fond principal
|
||||
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)
|
||||
# Découpage en 2 colonnes (équilibré)
|
||||
categories_list = list(control_categories.items())
|
||||
mid = len(categories_list) // 2
|
||||
col1_categories = categories_list[:mid]
|
||||
col2_categories = categories_list[mid:]
|
||||
|
||||
# Largeur cible par colonne (avant wrapping)
|
||||
target_col_width = (max_panel_width - 2 * padding - inter_col_spacing) // 2
|
||||
|
||||
def wrap_lines_for_column(cat_pairs):
|
||||
wrapped = [] # liste de (is_section_title, surface)
|
||||
max_width = 0
|
||||
total_height = 0
|
||||
for section_title, lines in cat_pairs:
|
||||
# Titre section
|
||||
sec_surf = section_font.render(section_title, True, THEME_COLORS["fond_lignes"])
|
||||
wrapped.append((True, sec_surf))
|
||||
total_height += sec_surf.get_height() + line_spacing
|
||||
|
||||
for raw_line in lines:
|
||||
# Wrap par mots
|
||||
words = raw_line.split()
|
||||
cur = ""
|
||||
for word in words:
|
||||
test = (cur + " " + word).strip()
|
||||
if font.size(test)[0] <= target_col_width:
|
||||
cur = test
|
||||
else:
|
||||
if cur:
|
||||
line_surf = font.render(cur, True, THEME_COLORS["text"])
|
||||
wrapped.append((False, line_surf))
|
||||
total_height += line_surf.get_height() + line_spacing
|
||||
max_width = max(max_width, line_surf.get_width())
|
||||
cur = word
|
||||
if cur:
|
||||
line_surf = font.render(cur, True, THEME_COLORS["text"])
|
||||
wrapped.append((False, line_surf))
|
||||
total_height += line_surf.get_height() + line_spacing
|
||||
max_width = max(max_width, line_surf.get_width())
|
||||
|
||||
total_height += section_spacing # espace après section
|
||||
max_width = max(max_width, sec_surf.get_width())
|
||||
|
||||
if wrapped and not wrapped[-1][0]:
|
||||
total_height -= section_spacing # retirer excédent final
|
||||
return wrapped, max_width, total_height
|
||||
|
||||
col1_wrapped, col1_w, col1_h = wrap_lines_for_column(col1_categories)
|
||||
col2_wrapped, col2_w, col2_h = wrap_lines_for_column(col2_categories)
|
||||
|
||||
col_widths_sum = col1_w + col2_w + inter_col_spacing
|
||||
content_width = min(max_panel_width - 2 * padding, max(col_widths_sum, col1_w + col2_w + inter_col_spacing))
|
||||
panel_width = content_width + 2 * padding
|
||||
|
||||
title_surf = title_font.render(_("controls_help_title"), True, THEME_COLORS["text"])
|
||||
title_height = title_surf.get_height()
|
||||
|
||||
content_height = max(col1_h, col2_h)
|
||||
panel_height = title_height + title_spacing + content_height + 2 * padding
|
||||
if panel_height > max_panel_height:
|
||||
panel_height = max_panel_height
|
||||
enable_clip = True
|
||||
else:
|
||||
enable_clip = False
|
||||
|
||||
panel_x = (config.screen_width - panel_width) // 2
|
||||
panel_y = (config.screen_height - panel_height) // 2
|
||||
|
||||
# Fond panel
|
||||
pygame.draw.rect(screen, THEME_COLORS["button_idle"], (panel_x, panel_y, panel_width, panel_height), border_radius=16)
|
||||
pygame.draw.rect(screen, THEME_COLORS["border"], (panel_x, panel_y, panel_width, panel_height), 2, border_radius=16)
|
||||
|
||||
# Titre
|
||||
title_text = _("controls_help_title")
|
||||
title_surface = config.title_font.render(title_text, True, THEME_COLORS["text"])
|
||||
title_rect = title_surface.get_rect(center=(config.screen_width // 2, popup_y + 25))
|
||||
screen.blit(title_surface, title_rect)
|
||||
title_rect = title_surf.get_rect(center=(panel_x + panel_width // 2, panel_y + padding + title_height // 2))
|
||||
screen.blit(title_surf, title_rect)
|
||||
|
||||
# Zones de colonnes
|
||||
col_top = panel_y + padding + title_height + title_spacing
|
||||
col1_x = panel_x + padding
|
||||
col2_x = panel_x + panel_width - padding - col2_w
|
||||
|
||||
# Clip si nécessaire
|
||||
prev_clip = None
|
||||
if enable_clip:
|
||||
prev_clip = screen.get_clip()
|
||||
clip_rect = pygame.Rect(panel_x + padding, col_top, panel_width - 2 * padding, panel_height - (col_top - panel_y) - padding)
|
||||
screen.set_clip(clip_rect)
|
||||
|
||||
# Dessin colonne 1
|
||||
y1 = col_top
|
||||
last_section = False
|
||||
for is_section, surf in col1_wrapped:
|
||||
if is_section:
|
||||
y1 += 0
|
||||
if y1 + surf.get_height() > panel_y + panel_height - padding:
|
||||
break
|
||||
screen.blit(surf, (col1_x, y1))
|
||||
y1 += surf.get_height() + (section_spacing if is_section else line_spacing)
|
||||
|
||||
# Dessin colonne 2
|
||||
y2 = col_top
|
||||
for is_section, surf in col2_wrapped:
|
||||
if y2 + surf.get_height() > panel_y + panel_height - padding:
|
||||
break
|
||||
screen.blit(surf, (col2_x, y2))
|
||||
y2 += surf.get_height() + (section_spacing if is_section else line_spacing)
|
||||
|
||||
if enable_clip and prev_clip is not None:
|
||||
screen.set_clip(prev_clip)
|
||||
|
||||
# Affichage en colonnes
|
||||
start_y = popup_y + 60
|
||||
|
||||
# Colonne 1
|
||||
current_y = start_y
|
||||
for category in col1:
|
||||
controls = control_columns[category]
|
||||
# Titre
|
||||
cat_surface = config.font.render(category, True, THEME_COLORS["fond_lignes"])
|
||||
cat_rect = cat_surface.get_rect(x=popup_x + 20, y=current_y)
|
||||
screen.blit(cat_surface, cat_rect)
|
||||
current_y += 30 # Plus d'espace après titre
|
||||
# Contrôles
|
||||
for control in controls:
|
||||
ctrl_surface = config.small_font.render(f"• {control}", True, THEME_COLORS["text"])
|
||||
ctrl_rect = ctrl_surface.get_rect(x=popup_x + 30, y=current_y)
|
||||
screen.blit(ctrl_surface, ctrl_rect)
|
||||
current_y += 20
|
||||
current_y += 20 # Plus d'espace entre sections
|
||||
|
||||
# Colonne 2
|
||||
current_y = start_y
|
||||
for category in col2:
|
||||
controls = control_columns[category]
|
||||
# Titre
|
||||
cat_surface = config.font.render(category, True, THEME_COLORS["fond_lignes"])
|
||||
cat_rect = cat_surface.get_rect(x=popup_x + col_width + 40, y=current_y) # Plus d'espace entre colonnes
|
||||
screen.blit(cat_surface, cat_rect)
|
||||
current_y += 30 # Plus d'espace après titre
|
||||
# Contrôles
|
||||
for control in controls:
|
||||
ctrl_surface = config.small_font.render(f"• {control}", True, THEME_COLORS["text"])
|
||||
ctrl_rect = ctrl_surface.get_rect(x=popup_x + col_width + 50, y=current_y) # Plus d'espace entre colonnes
|
||||
screen.blit(ctrl_surface, ctrl_rect)
|
||||
current_y += 20
|
||||
current_y += 20 # Plus d'espace entre sections
|
||||
|
||||
# Menu Quitter Appli
|
||||
def draw_confirm_dialog(screen):
|
||||
|
||||
@@ -28,7 +28,7 @@ def parse_es_input_config():
|
||||
"right": "right",
|
||||
"pageup": "page_up",
|
||||
"pagedown": "page_down",
|
||||
"y": "progress",
|
||||
"y": "clear_history",
|
||||
"x": "history",
|
||||
"select": "filter",
|
||||
"leftshoulder": "delete",
|
||||
@@ -129,7 +129,7 @@ def parse_es_input_config():
|
||||
controls_config["start"] = {"type": "key", "key": pygame.K_p}
|
||||
controls_config["filter"] = {"type": "key", "key": pygame.K_f}
|
||||
controls_config["history"] = {"type": "key", "key": pygame.K_h}
|
||||
controls_config["progress"] = {"type": "key", "key": pygame.K_x}
|
||||
controls_config["clear_history"] = {"type": "key", "key": pygame.K_x}
|
||||
controls_config["page_up"] = {"type": "key", "key": pygame.K_PAGEUP}
|
||||
controls_config["page_down"] = {"type": "key", "key": pygame.K_PAGEDOWN}
|
||||
|
||||
@@ -143,7 +143,7 @@ def parse_es_input_config():
|
||||
"right": {"type": "key", "key": pygame.K_RIGHT},
|
||||
"page_up": {"type": "key", "key": pygame.K_PAGEUP},
|
||||
"page_down": {"type": "key", "key": pygame.K_PAGEDOWN},
|
||||
"progress": {"type": "key", "key": pygame.K_x},
|
||||
"clear_history": {"type": "key", "key": pygame.K_x},
|
||||
"history": {"type": "key", "key": pygame.K_h},
|
||||
"filter": {"type": "key", "key": pygame.K_f},
|
||||
"delete": {"type": "key", "key": pygame.K_DELETE},
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
"controls_action_right": "Rechts",
|
||||
"controls_action_page_up": "Vorherige Seite",
|
||||
"controls_action_page_down": "Nächste Seite",
|
||||
"controls_action_delete_history": "Verlauf leeren",
|
||||
"controls_action_clear_history": "Verlauf leeren",
|
||||
"controls_action_history": "Verlauf",
|
||||
"controls_action_filter": "Filtern",
|
||||
"controls_action_delete": "Löschen",
|
||||
@@ -119,7 +119,7 @@
|
||||
"controls_desc_right": "Nach rechts navigieren",
|
||||
"controls_desc_page_up": "Vorherige Seite/Schnelles Scrollen nach oben (z.B.: BildAuf, LB)",
|
||||
"controls_desc_page_down": "Nächste Seite/Schnelles Scrollen nach unten (z.B.: BildAb, RB)",
|
||||
"controls_desc_delete_history": "Verlauf löschen (z.B.: X)",
|
||||
"controls_desc_clear_history": "Verlauf löschen (z.B.: X)",
|
||||
"controls_desc_history": "Verlauf öffnen (z.B.: H, Y)",
|
||||
"controls_desc_filter": "Filter öffnen (z.B.: F, Select)",
|
||||
"controls_desc_delete": "Zeichen löschen (z.B.: LT, Entf)",
|
||||
@@ -131,7 +131,6 @@
|
||||
"action_quit": "Beenden",
|
||||
"action_select": "Auswählen",
|
||||
"action_history": "Verlauf",
|
||||
"action_progress": "Fortschritt",
|
||||
"action_download": "Herunterladen",
|
||||
"action_filter": "Filtern",
|
||||
"action_cancel": "Abbrechen",
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
"controls_action_right": "Right",
|
||||
"controls_action_page_up": "Previous Page",
|
||||
"controls_action_page_down": "Next Page",
|
||||
"controls_action_delete_history": "Clear History",
|
||||
"controls_action_clear_history": "Clear History",
|
||||
"controls_action_history": "History",
|
||||
"controls_action_filter": "Filter",
|
||||
"controls_action_delete": "Delete",
|
||||
@@ -110,7 +110,7 @@
|
||||
"controls_desc_right": "Navigate right",
|
||||
"controls_desc_page_up": "Previous page/Fast scroll up (e.g. PageUp, LB)",
|
||||
"controls_desc_page_down": "Next page/Fast scroll down (e.g. PageDown, RB)",
|
||||
"controls_desc_delete_history": "Clear History (e.g. X)",
|
||||
"controls_desc_clear_history": "Clear History (e.g. X)",
|
||||
"controls_desc_history": "Open history (e.g. H, Y)",
|
||||
"controls_desc_filter": "Open filter (e.g. F, Select)",
|
||||
"controls_desc_delete": "Delete character (e.g. LT, Delete)",
|
||||
@@ -122,7 +122,6 @@
|
||||
"action_quit": "Quit",
|
||||
"action_select": "Select",
|
||||
"action_history": "History",
|
||||
"action_progress": "Progress",
|
||||
"action_download": "Download",
|
||||
"action_filter": "Filter",
|
||||
"action_cancel": "Cancel",
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
"controls_action_right": "Derecha",
|
||||
"controls_action_page_up": "Página anterior",
|
||||
"controls_action_page_down": "Página siguiente",
|
||||
"controls_action_delete_history": "Vaciar Historial",
|
||||
"controls_action_clear_history": "Vaciar Historial",
|
||||
"controls_action_history": "Historial",
|
||||
"controls_action_filter": "Filtrar",
|
||||
"controls_action_delete": "Eliminar",
|
||||
@@ -121,7 +121,7 @@
|
||||
"controls_desc_right": "Navegar a derecha",
|
||||
"controls_desc_page_up": "Página anterior/Desplazamiento rápido arriba (ej: RePág, LB)",
|
||||
"controls_desc_page_down": "Página siguiente/Desplazamiento rápido abajo (ej: AvPág, RB)",
|
||||
"controls_desc_delete_history": "Borrar Historial (ej: X)",
|
||||
"controls_desc_clear_history": "Borrar Historial (ej: X)",
|
||||
"controls_desc_history": "Abrir historial (ej: H, Y)",
|
||||
"controls_desc_filter": "Abrir filtro (ej: F, Select)",
|
||||
"controls_desc_delete": "Eliminar carácter (ej: LT, Supr)",
|
||||
@@ -133,7 +133,6 @@
|
||||
"action_quit": "Salir",
|
||||
"action_select": "Seleccionar",
|
||||
"action_history": "Historial",
|
||||
"action_progress": "Progreso",
|
||||
"action_download": "Descargar",
|
||||
"action_filter": "Filtrar",
|
||||
"action_cancel": "Cancelar",
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
"controls_action_right": "Droite",
|
||||
"controls_action_page_up": "Page Précédente",
|
||||
"controls_action_page_down": "Page Suivante",
|
||||
"controls_action_delete_history": "Vider Historique",
|
||||
"controls_action_clear_history": "Vider Historique",
|
||||
"controls_action_history": "Historique",
|
||||
"controls_action_filter": "Filtrer",
|
||||
"controls_action_delete": "Supprimer",
|
||||
@@ -117,7 +117,7 @@
|
||||
"controls_desc_page_up": "Défilement Rapide - (ex: PageUp, LB)",
|
||||
"controls_desc_page_down": "Défilement Rapide + (ex: PageDown, RB)",
|
||||
"controls_desc_history": "Ouvrir l'historique (ex: H, Y)",
|
||||
"controls_desc_delete_history": "Effacer Historique (ex: X)",
|
||||
"controls_desc_clear_history": "Effacer Historique (ex: X)",
|
||||
"controls_desc_filter": "Mode Filtre : Ouvrir/Valider (ex: F, Select)",
|
||||
"controls_desc_delete": "Mode Filtre : Supprimer caractère (ex: LT, Suppr)",
|
||||
"controls_desc_space": "Mode Filtre : Ajouter espace (ex: RT, Espace)",
|
||||
@@ -128,7 +128,6 @@
|
||||
"action_quit": "Quitter",
|
||||
"action_select": "Sélectionner",
|
||||
"action_history": "Historique",
|
||||
"action_progress": "Progression",
|
||||
"action_download": "Télécharger",
|
||||
"action_filter": "Filtrer",
|
||||
"action_cancel": "Annuler",
|
||||
|
||||
@@ -12,28 +12,6 @@ import zipfile
|
||||
import time
|
||||
import random
|
||||
from config import JSON_EXTENSIONS, SAVE_FOLDER
|
||||
|
||||
def load_accessibility_settings():
|
||||
"""Charge les paramètres d'accessibilité depuis accessibility.json."""
|
||||
accessibility_path = os.path.join(SAVE_FOLDER, "accessibility.json")
|
||||
try:
|
||||
if os.path.exists(accessibility_path):
|
||||
with open(accessibility_path, 'r', encoding='utf-8') as f:
|
||||
return json.load(f)
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur lors du chargement de accessibility.json: {str(e)}")
|
||||
return {"font_scale": 1.0}
|
||||
|
||||
def save_accessibility_settings(settings):
|
||||
"""Sauvegarde les paramètres d'accessibilité dans accessibility.json."""
|
||||
accessibility_path = os.path.join(SAVE_FOLDER, "accessibility.json")
|
||||
try:
|
||||
os.makedirs(SAVE_FOLDER, exist_ok=True)
|
||||
with open(accessibility_path, 'w', encoding='utf-8') as f:
|
||||
json.dump(settings, f, indent=2)
|
||||
logger.debug(f"Paramètres d'accessibilité sauvegardés: {settings}")
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur lors de la sauvegarde de accessibility.json: {str(e)}")
|
||||
from history import save_history
|
||||
from language import _ # Import de la fonction de traduction
|
||||
from datetime import datetime
|
||||
@@ -59,7 +37,7 @@ def detect_non_pc():
|
||||
except (subprocess.SubprocessError, FileNotFoundError):
|
||||
logger.debug(f"batocera-es-swissknife non disponible, utilisation de platform.machine(): {arch}")
|
||||
|
||||
is_non_pc = arch not in ["x86_64", "amd64"]
|
||||
is_non_pc = arch not in ["x86_64", "amd64", "AMD64"]
|
||||
logger.debug(f"Système détecté: {platform.system()}, architecture: {arch}, is_non_pc={is_non_pc}")
|
||||
return is_non_pc
|
||||
|
||||
|
||||
Reference in New Issue
Block a user