"""Display management module for PygStormGames. Handles text display, navigation, and information presentation including: - Text display with navigation - Instructions display - Credits display - Donation link handling """ import os import webbrowser import pyglet from pyglet.window import key import pyperclip import wx class Display: """Handles display and text navigation systems.""" def __init__(self, game): """Initialize display system. Args: game (PygStormGames): Reference to main game object """ self.game = game self.window = pyglet.window.Window(800, 600, caption=game.gameTitle) self.displayedInstructions = False self.currentText = [] self.currentIndex = 0 self.gameTitle = game.gameTitle def display_text(self, text, speech): """Display and navigate text with speech output. Args: text (list): List of text lines to display speech (Speech): Speech system for audio output """ # Stop bgm if present. self.game.sound.pause_bgm() # Store original text with blank lines for copying self.originalText = text.copy() # Create navigation text by filtering out blank lines self.navText = [line for line in text if line.strip()] # Add instructions at start if not self.displayedInstructions: instructions = ("Press space to read the whole text. Use up and down arrows to navigate " "the text line by line. Press c to copy the current line to the clipboard " "or t to copy the entire text. Press enter or escape when you are done reading.") self.navText.insert(0, instructions) self.displayedInstructions = True # Add end marker self.navText.append("End of text.") self.currentIndex = 0 speech.speak(self.navText[self.currentIndex]) validKeys = [ pyglet.window.key.ESCAPE, pyglet.window.key.RETURN, pyglet.window.key.SPACE, pyglet.window.key.UP, pyglet.window.key.DOWN, pyglet.window.key.W, pyglet.window.key.S, pyglet.window.key.C, pyglet.window.key.T ] while True: key, _ = self.game.wait(validKeys) if key in (pyglet.window.key.ESCAPE, pyglet.window.key.RETURN): break if key in (pyglet.window.key.DOWN, pyglet.window.key.S) and self.currentIndex < len(self.navText) - 1: self.currentIndex += 1 speech.speak(self.navText[self.currentIndex]) if key in (pyglet.window.key.UP, pyglet.window.key.W) and self.currentIndex > 0: self.currentIndex -= 1 speech.speak(self.navText[self.currentIndex]) if key == pyglet.window.key.SPACE: speech.speak('\n'.join(self.originalText[1:-1])) if key == pyglet.window.key.C: try: pyperclip.copy(self.navText[self.currentIndex]) speech.speak("Copied " + self.navText[self.currentIndex] + " to the clipboard.") except: speech.speak("Failed to copy the text to the clipboard.") if key == pyglet.window.key.T: try: pyperclip.copy(''.join(self.originalText[2:-1])) speech.speak("Copied entire message to the clipboard.") except: speech.speak("Failed to copy the text to the clipboard.") def instructions(self, speech): """Display game instructions from file. Args: speech (Speech): Speech system for audio output """ try: with open('files/instructions.txt', 'r') as f: info = f.readlines() except: info = ["Instructions file is missing."] self.display_text(info, speech) def credits(self, speech): """Display game credits from file. Args: speech (Speech): Speech system for audio output """ try: with open('files/credits.txt', 'r') as f: info = f.readlines() # Add the header info.insert(0, f"{self.gameTitle}: brought to you by Storm Dragon") except: info = ["Credits file is missing."] self.display_text(info, speech) def messagebox(self, text): """Display a simple message box with text. Shows a message that can be repeated until the user chooses to continue. Args: text (str): Message to display """ text = text + "\nPress any key to repeat or enter to continue." while True: # Speak the text self.game.speech.speak(text) # Wait for any key key, _ = self.game.wait() # Exit if enter/escape pressed if key in (pyglet.window.key.RETURN, pyglet.window.key.ESCAPE): break def get_input(self, prompt="Enter text:", defaultText=""): """Display a dialog box for text input. Args: prompt (str): Prompt text to display defaultText (str): Initial text in input box Returns: str: User input text, or None if cancelled """ app = wx.App(False) dialog = wx.TextEntryDialog(None, prompt, "Input", defaultText) dialog.SetValue(defaultText) # Bring dialog to front and give it focus dialog.Raise() dialog.SetFocus() if dialog.ShowModal() == wx.ID_OK: userInput = dialog.GetValue() else: userInput = None dialog.Destroy() # Return focus to game window self.window.activate() return userInput def donate(self, speech): """Open the donation webpage.""" speech.speak("Opening donation page. Press space or enter to continue.") webbrowser.open('https://ko-fi.com/stormux') validKeys = [ pyglet.window.key.ESCAPE, pyglet.window.key.RETURN, pyglet.window.key.SPACE ] key, _ = self.game.wait(validKeys)