194 lines
6.4 KiB
Python
194 lines
6.4 KiB
Python
"""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)
|