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

168 lines
5.1 KiB

#!/usr/bin/env python3
"""
User Profile Manager for Games
A PySDL2-based profile management system with gamepad-only controls
Refactored with separated UI and business logic components
Features:
- Create new user profiles
- Edit existing profiles
- Delete profiles
- Select active profile
- JSON-based storage
- Gamepad navigation only
- Modular UI components
"""
import time
from typing import Dict, Optional
import sdl2
import sdl2.ext
# Import separated components
from ui_components import UIRenderer, GamepadInputHandler
from profile_data import ProfileDataManager, SettingsManager
from screens import ModularScreenManager
class ProfileManager:
"""Main profile management system with separated UI and business logic"""
def __init__(self, profiles_file: str = "user_profiles.json"):
# Business logic components
self.data_manager = ProfileDataManager(profiles_file)
# Input handling
self.input_handler = GamepadInputHandler()
# SDL2 components
self.window = None
self.renderer = None
self.ui_renderer = None
self.running = True
# NEW: Modular screen manager (will be initialized after SDL setup)
self.screen_manager = None
def init_sdl(self):
"""Initialize SDL2 components"""
sdl2.ext.init(joystick=True)
# Create window
self.window = sdl2.ext.Window(
title="Profile Manager",
size=(640, 480)
)
self.window.show()
# Create renderer
self.renderer = sdl2.ext.Renderer(
self.window,
flags=sdl2.SDL_RENDERER_ACCELERATED | sdl2.SDL_RENDERER_PRESENTVSYNC
)
# Initialize UI renderer
self.ui_renderer = UIRenderer(self.renderer, (640, 480))
# NEW: Initialize modular screen manager
self.screen_manager = ModularScreenManager(self.data_manager, self.ui_renderer)
def handle_input(self):
"""Handle all input (simplified with screen delegation)"""
# Handle SDL events for keyboard
events = sdl2.ext.get_events()
for event in events:
if event.type == sdl2.SDL_QUIT:
self.running = False
elif event.type == sdl2.SDL_KEYDOWN:
action = self._keyboard_to_action(event.key.keysym.sym)
if action:
result = self.screen_manager.handle_input(action)
if not result:
self.running = False
# Handle gamepad input
gamepad_input = self.input_handler.get_gamepad_input()
for action, pressed in gamepad_input.items():
if pressed:
gamepad_action = self._gamepad_to_action(action)
if gamepad_action:
result = self.screen_manager.handle_input(gamepad_action)
if not result:
self.running = False
def _keyboard_to_action(self, key) -> str:
"""Convert keyboard input to action"""
key_map = {
sdl2.SDLK_UP: 'up',
sdl2.SDLK_DOWN: 'down',
sdl2.SDLK_LEFT: 'left',
sdl2.SDLK_RIGHT: 'right',
sdl2.SDLK_RETURN: 'confirm',
sdl2.SDLK_SPACE: 'confirm',
sdl2.SDLK_ESCAPE: 'back',
sdl2.SDLK_DELETE: 'delete',
sdl2.SDLK_BACKSPACE: 'delete'
}
return key_map.get(key, '')
def _gamepad_to_action(self, gamepad_action: str) -> str:
"""Convert gamepad input to action"""
gamepad_map = {
'up': 'up',
'down': 'down',
'left': 'left',
'right': 'right',
'button_3': 'confirm', # A/X button
'button_4': 'back', # B/Circle button
'button_9': 'delete' # X/Square button
}
return gamepad_map.get(gamepad_action, '')
def render(self):
"""Simplified rendering (delegated to screen manager)"""
# Clear and draw background
self.ui_renderer.clear_screen('black')
self.ui_renderer.draw_background_pattern('gradient')
# Delegate all screen rendering to screen manager
self.screen_manager.render()
self.ui_renderer.present()
def run(self):
"""Main application loop (unchanged)"""
self.init_sdl()
target_fps = 30
frame_time = 1000 // target_fps
while self.running:
frame_start = sdl2.SDL_GetTicks()
# Handle input
self.handle_input()
# Render
self.render()
# Frame timing
frame_elapsed = sdl2.SDL_GetTicks() - frame_start
if frame_elapsed < frame_time:
sdl2.SDL_Delay(frame_time - frame_elapsed)
# Cleanup
self.input_handler.cleanup()
sdl2.ext.quit()
# Entry point
def main():
"""Main entry point"""
manager = ProfileManager()
manager.run()
if __name__ == "__main__":
main()