Dropped wxpython because of stability issues.
This commit is contained in:
190
input.py
190
input.py
@ -10,11 +10,18 @@ Provides functionality for:
|
|||||||
|
|
||||||
import pygame
|
import pygame
|
||||||
import time
|
import time
|
||||||
import wx
|
|
||||||
from .speech import speak
|
from .speech import speak
|
||||||
|
|
||||||
def get_input(prompt="Enter text:", text=""):
|
def get_input(prompt="Enter text:", text=""):
|
||||||
"""Display a dialog box for text input.
|
"""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:
|
Args:
|
||||||
prompt (str): Prompt text to display (default: "Enter text:")
|
prompt (str): Prompt text to display (default: "Enter text:")
|
||||||
@ -23,15 +30,178 @@ def get_input(prompt="Enter text:", text=""):
|
|||||||
Returns:
|
Returns:
|
||||||
str: User input text, or None if cancelled
|
str: User input text, or None if cancelled
|
||||||
"""
|
"""
|
||||||
app = wx.App(False)
|
|
||||||
dialog = wx.TextEntryDialog(None, prompt, "Input", text)
|
# Initialize text buffer and cursor
|
||||||
dialog.SetValue(text)
|
text_buffer = list(text) # Use list for easier character manipulation
|
||||||
if dialog.ShowModal() == wx.ID_OK:
|
cursor_pos = len(text_buffer) # Start at end of initial text
|
||||||
userInput = dialog.GetValue()
|
|
||||||
|
# Announce the prompt and initial text
|
||||||
|
speak(prompt)
|
||||||
|
if text:
|
||||||
|
speak(f"Default text: {text}")
|
||||||
else:
|
else:
|
||||||
userInput = None
|
speak("Empty text field")
|
||||||
dialog.Destroy()
|
|
||||||
return userInput
|
# 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():
|
def pause_game():
|
||||||
"""Pauses the game until user presses backspace."""
|
"""Pauses the game until user presses backspace."""
|
||||||
|
6
menu.py
6
menu.py
@ -485,6 +485,12 @@ def exit_game(fade=0):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Warning: Could not handle music during exit: {e}")
|
print(f"Warning: Could not handle music during exit: {e}")
|
||||||
|
|
||||||
|
# Clean up pygame mixer first
|
||||||
|
try:
|
||||||
|
pygame.mixer.quit()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Warning: Error during pygame.mixer.quit(): {e}")
|
||||||
|
|
||||||
# Clean up pygame
|
# Clean up pygame
|
||||||
try:
|
try:
|
||||||
pygame.quit()
|
pygame.quit()
|
||||||
|
@ -5,4 +5,3 @@ pyxdg>=0.27
|
|||||||
setproctitle>=1.2.0
|
setproctitle>=1.2.0
|
||||||
numpy>=1.19.0
|
numpy>=1.19.0
|
||||||
accessible-output2>=0.14
|
accessible-output2>=0.14
|
||||||
wxpython
|
|
||||||
|
Reference in New Issue
Block a user