#!/usr/bin/env python3 # -*- coding: utf-8 -*- """Input handling for Storm Games. Provides functionality for: - Text input dialogs - Game pause functionality - Exit handling """ import pygame import time from .speech import speak def get_input(prompt="Enter text:", text=""): """Display an accessible text input dialog using pygame. Features: - Speaks each character as typed - Left/Right arrows navigate and speak characters - Up/Down arrows read full text content - Backspace announces deletions - Enter submits, Escape cancels - Fully accessible without screen reader dependency Args: prompt (str): Prompt text to display (default: "Enter text:") text (str): Initial text in input box (default: "") Returns: str: User input text, or None if cancelled """ # Initialize text buffer and cursor text_buffer = list(text) # Use list for easier character manipulation cursor_pos = len(text_buffer) # Start at end of initial text # Announce the prompt and initial text as a single message if text: message = f"{prompt} Default text: {text}" else: message = f"{prompt} Empty text field" speak(message) # Speak initial cursor position if cursor_pos == 0: speak("Beginning of text") elif cursor_pos == len(text_buffer): speak("End of text") else: speak(f"At character: {text_buffer[cursor_pos]}") # Main input loop while True: event = pygame.event.wait() if event.type == pygame.KEYDOWN: if event.key == pygame.K_RETURN: # Submit the input result = ''.join(text_buffer) speak(f"Submitted: {result if result else 'empty'}") return result elif event.key == pygame.K_ESCAPE: # Cancel input speak("Cancelled") return None elif event.key == pygame.K_BACKSPACE: # Delete character before cursor if cursor_pos > 0: deleted_char = text_buffer.pop(cursor_pos - 1) cursor_pos -= 1 speak(f"{deleted_char} deleted") else: speak("Nothing to delete") elif event.key == pygame.K_DELETE: # Delete character at cursor if cursor_pos < len(text_buffer): deleted_char = text_buffer.pop(cursor_pos) speak(f"{deleted_char} deleted") else: speak("Nothing to delete") elif event.key == pygame.K_LEFT: # Move cursor left and speak character if cursor_pos > 0: cursor_pos -= 1 if cursor_pos == 0: speak("Beginning of text") else: speak(text_buffer[cursor_pos]) else: speak("Beginning of text") elif event.key == pygame.K_RIGHT: # Move cursor right and speak character if cursor_pos < len(text_buffer): speak(text_buffer[cursor_pos]) cursor_pos += 1 if cursor_pos == len(text_buffer): speak("End of text") else: speak("End of text") elif event.key == pygame.K_UP or event.key == pygame.K_DOWN: # Read entire text content if text_buffer: speak(''.join(text_buffer)) else: speak("Empty text field") elif event.key == pygame.K_HOME: # Move to beginning cursor_pos = 0 speak("Beginning of text") elif event.key == pygame.K_END: # Move to end cursor_pos = len(text_buffer) speak("End of text") else: # Handle regular character input if event.unicode and event.unicode.isprintable(): char = event.unicode # Insert character at cursor position text_buffer.insert(cursor_pos, char) cursor_pos += 1 # Speak the character name if char == ' ': speak("space") elif char == '\\': speak("backslash") elif char == '/': speak("slash") elif char == '!': speak("exclamation mark") elif char == '"': speak("quotation mark") elif char == '#': speak("hash") elif char == '$': speak("dollar sign") elif char == '%': speak("percent") elif char == '&': speak("ampersand") elif char == "'": speak("apostrophe") elif char == '(': speak("left parenthesis") elif char == ')': speak("right parenthesis") elif char == '*': speak("asterisk") elif char == '+': speak("plus") elif char == ',': speak("comma") elif char == '-': speak("minus") elif char == '.': speak("period") elif char == ':': speak("colon") elif char == ';': speak("semicolon") elif char == '<': speak("less than") elif char == '=': speak("equals") elif char == '>': speak("greater than") elif char == '?': speak("question mark") elif char == '@': speak("at sign") elif char == '[': speak("left bracket") elif char == ']': speak("right bracket") elif char == '^': speak("caret") elif char == '_': speak("underscore") elif char == '`': speak("grave accent") elif char == '{': speak("left brace") elif char == '|': speak("pipe") elif char == '}': speak("right brace") elif char == '~': speak("tilde") else: # For regular letters, numbers, and other characters speak(char) # Allow other events to be processed pygame.event.pump() def pause_game(): """Pauses the game until user presses backspace.""" speak("Game paused, press backspace to resume.") pygame.event.clear() try: pygame.mixer.pause() except: pass try: pygame.mixer.music.pause() except: pass while True: event = pygame.event.wait() if event.type == pygame.KEYDOWN and event.key == pygame.K_BACKSPACE: break try: pygame.mixer.unpause() except: pass try: pygame.mixer.music.unpause() except: pass pygame.event.pump() def check_for_exit(): """Check if user has pressed escape key. Returns: bool: True if escape was pressed, False otherwise """ for event in pygame.event.get(): if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: return True return False pygame.event.pump()