Add header rendering to text component

This commit is contained in:
2023-06-19 12:36:08 +02:00
parent 0549dc6f2f
commit 78724ff4b2
4 changed files with 53 additions and 5 deletions

View File

@@ -5,6 +5,7 @@
from operator import truediv from operator import truediv
from data import MenuText as mt from data import MenuText as mt
import utils.text as Text import utils.text as Text
from utils.text import HeaderStyle
from location.locations import * from location.locations import *
from player import Player from player import Player
from utils.input import Menu, Option from utils.input import Menu, Option
@@ -15,7 +16,7 @@ class Game:
self.player = Player() self.player = Player()
#ToDo: move this out of the main file #ToDo: move this out of the main file
locations = { locations = {
"City": SafeZone(self, "Main city", "You find yourself in the small rural town of Mayberry. \nThe town is quaint and charming, with a population of only a few hundred people. \nIt is surrounded by a thick forest, and the only way to get here is on foot. \nThere are a few shops and businesses around."), "City": SafeZone(self, "Mayberry", "You find yourself in the small rural town of Mayberry. \nThe town is quaint and charming, with a population of only a few hundred people. \nIt is surrounded by a thick forest, and the only way to get here is on foot. \nThere are a few shops and businesses around."),
"Forest": Location(self, "the Forest", "You find yourself in a warm and lush oak forest. \nThe dense trees provide plenty of cover from the sun, and the forest floor is carpeted with a thick layer of leaves. \nYou hear the sound of birdsong all around you, and the occasional rustle of small animals in the undergrowth."), "Forest": Location(self, "the Forest", "You find yourself in a warm and lush oak forest. \nThe dense trees provide plenty of cover from the sun, and the forest floor is carpeted with a thick layer of leaves. \nYou hear the sound of birdsong all around you, and the occasional rustle of small animals in the undergrowth."),
} }
locations["City"].connect_location(locations["Forest"]) locations["City"].connect_location(locations["Forest"])
@@ -30,9 +31,10 @@ class Game:
self.quit = True self.quit = True
def main(self): def main(self):
Text.clear()
Text.print_header("Welcome", HeaderStyle.ROUND)
Text.type(mt.intro_text, delay=0.01, newline_delay=1.0) Text.type(mt.intro_text, delay=0.01, newline_delay=1.0)
while not self.quit: while not self.quit:
print(f"\n[{self.current_location.name}]")
options = [ options = [
Option("Test option", lambda: print("Test option selected\n")), Option("Test option", lambda: print("Test option selected\n")),
Option("Test option no callback", None), Option("Test option no callback", None),

View File

@@ -1,5 +1,6 @@
"""Generic Location""" """Generic Location"""
from utils.input import Option from utils.input import Option
from utils.text import HeaderStyle
import utils.text as Text import utils.text as Text
import time import time
@@ -12,10 +13,12 @@ class Location:
self.game = game self.game = game
def look_around(self) -> None: def look_around(self) -> None:
Text.print_header(self.name, HeaderStyle.ROUND)
Text.type(f"{self.description}\n", 0.01, 0.1) Text.type(f"{self.description}\n", 0.01, 0.1)
time.sleep(0.5) time.sleep(0.5)
def enter(self) -> None: def enter(self) -> None:
Text.print_header(self.name, HeaderStyle.ROUND)
print(f"You enter {self.name}.\n") print(f"You enter {self.name}.\n")
self.game.current_location = self self.game.current_location = self
time.sleep(0.5) time.sleep(0.5)

View File

@@ -2,6 +2,8 @@
Utility to show a seletion menu Utility to show a seletion menu
""" """
import time import time
import utils.text as Text
class Option(object): class Option(object):
def __init__(self, text: str, callback: callable) -> None: def __init__(self, text: str, callback: callable) -> None:
self.text = text self.text = text
@@ -25,7 +27,7 @@ class Menu(object):
time.sleep(0.5) time.sleep(0.5)
self.show() self.show()
else: else:
print("") #Newline for better readability Text.clear()
if self.options[selected-1].callback is not None: if self.options[selected-1].callback is not None:
self.options[selected-1].callback() self.options[selected-1].callback()

View File

@@ -2,7 +2,14 @@
Utilities for text output Utilities for text output
""" """
import time, sys import time, os
from enum import IntEnum
from typing import List, Dict
class HeaderStyle(IntEnum):
LIGHT = 0,
BOLD = 1
ROUND = 2
def type(text: str, delay: float = 0.05, newline_delay: float = 0.0) -> None: def type(text: str, delay: float = 0.05, newline_delay: float = 0.0) -> None:
""" Prints the given text, one character at a time, with a delay between each character. """ Prints the given text, one character at a time, with a delay between each character.
@@ -16,4 +23,38 @@ def type(text: str, delay: float = 0.05, newline_delay: float = 0.0) -> None:
print(char, end="", flush=True) print(char, end="", flush=True)
if (char == "\n"): if (char == "\n"):
time.sleep(newline_delay) time.sleep(newline_delay)
time.sleep(delay) time.sleep(delay)
def clear() -> None:
os.system('cls' if os.name=='nt' else 'clear')
def print_header(title: str, style: HeaderStyle = HeaderStyle.LIGHT, padding: int = 1, length: int = 0):
""" Prints the Title wrapped by a decoration char
Arguments:
title: Title to be printed
style: Changes the viasual style of the header.
Light has single line wraps, bold double lines wraps
Round has single lines with round corners
length: Total length the header has to fill
"""
#If no length is defined, use the terminal width (-2 to avoid any line breaks)
length = length if length > 0 else os.get_terminal_size()[0] - 2
title = f"{' ' * padding}{title}{' ' * padding}"
characters: List[Dict[str, str]] = [
{ 'line': '', 'tj_left': '', 'corner_tl': '', 'corner_tr': '', 'corner_bl': '', 'corner_br': '', 'tj_right': ''},
{ 'line': '', 'tj_left': '', 'corner_tl': '', 'corner_tr': '', 'corner_bl': '', 'corner_br': '', 'tj_right': ''},
{ 'line': '', 'tj_left': '', 'corner_tl': '', 'corner_tr': '', 'corner_bl': '', 'corner_br': '', 'tj_right': ''},
]
title_length: int = len(title)
pre_wrap_length: int = int(length / 2) - int(title_length / 2)
post_wrap_length: int = length - pre_wrap_length - title_length
print(' ' * pre_wrap_length + characters[style]['corner_tl'] + characters[style]['line'] * title_length + characters[style]['corner_tr'])
print(f"{characters[style]['line'] * pre_wrap_length}{characters[style]['tj_left']}{title}{characters[style]['tj_right']}{characters[style]['line'] * post_wrap_length}")
print(' ' * pre_wrap_length + characters[style]['corner_bl'] + characters[style]['line'] * title_length + characters[style]['corner_br'])