Last active
March 11, 2022 10:15
-
-
Save wkta/ad44c2b2be079e906aad661c1f41a880 to your computer and use it in GitHub Desktop.
example to show how one can manage text blocks (->GUI building) in a convenient way
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
how can we manage text blocks (->GUI building) in a convenient way? | |
This may be an answer. Contributors: .wkta-tom#7412 | S_P_Y#1331 | |
""" | |
import pygame | |
def create_txtblock_surf(text, ft_obj, color=(0, 0, 0), bg_color=(255, 255, 255), alignment_f=0.0, debug=0): | |
""" | |
goal = to produce a pygame surface | |
append a pair (lbl, textRect) to render_list,one per line | |
""" | |
render_list = list() | |
mw = mh = -1 | |
toth = 0 | |
for line in text.split('\n'): | |
text_lbl = ft_obj.render(line, True, color) | |
w, h = text_lbl.get_size() | |
if w > mw: | |
mw = w | |
if h > mh: | |
mh = h | |
toth += h | |
render_list.append(text_lbl) | |
# create surf, that represents txtblock | |
surf = pygame.Surface((mw, toth)) | |
surf.fill(bg_color) | |
# stack labels, to gen the txt block | |
target_y = 0 | |
for lbl in render_list: | |
curr_w = lbl.get_width() | |
surf.blit(lbl, (alignment_f * (mw - curr_w), target_y)) | |
target_y += mh | |
if debug: | |
pygame.draw.rect(surf, 'red', ((0, 0), (mw - 1, toth - 1)), 1) | |
return surf | |
class TextBlock(pygame.sprite.Sprite): | |
ALIGN_LEFT, ALIGN_CENTER = 0, 1 | |
def __init__(self, ft_name, ft_size, text='', color=(0, 0, 0), bg_color=(255, 255, 255)): | |
super().__init__() | |
self.ft_obj = pygame.font.Font(ft_name, ft_size) | |
self._color = color | |
self._bg_color = bg_color | |
self._align = self.ALIGN_CENTER | |
self._debug = 0 | |
self.rect = None # no position for now | |
if '' == text: | |
self._text = '' | |
self.image = None | |
else: | |
self._text = text | |
self._refresh_img() | |
def _refresh_img(self): | |
if self.rect: # has a position | |
prev_pos = self.rect.center | |
else: | |
prev_pos = None | |
if self._align == self.ALIGN_CENTER: | |
ts = create_txtblock_surf(self._text, self.ft_obj, self._color, self._bg_color, 0.5, self.debug) | |
else: | |
ts = create_txtblock_surf(self._text, self.ft_obj, self._color, self._bg_color, 0.0, self.debug) | |
self.image = ts | |
self.rect = self.image.get_rect() | |
# restore previous position | |
if prev_pos: | |
self.rect.center = prev_pos | |
@property | |
def debug(self): | |
return self._debug | |
@debug.setter | |
def debug(self, v): | |
self._debug = 1 if v else 0 | |
self._refresh_img() | |
@property | |
def text_align(self): | |
return self._align | |
@text_align.setter | |
def text_align(self, v): | |
if v in (self.ALIGN_LEFT, self.ALIGN_CENTER): | |
self._align = v | |
self._refresh_img() | |
else: | |
raise ValueError | |
@property | |
def text(self): | |
return self._text | |
@text.setter | |
def text(self, val): | |
self._text = val | |
self._refresh_img() | |
def draw(self, scr): | |
if self.image: | |
pos = self.rect.topleft | |
scr.blit(self.image, pos) | |
# - program body v - | |
pygame.init() | |
screen = pygame.display.set_mode((640, 480)) | |
width, height = screen.get_size() | |
INIT_TXT = 'hello user this\nis\nsome\ndope\ntext' | |
ALT_TXT = 'i\nunderstand that\nyou watch the console' | |
block = TextBlock('pixel_font2.ttf', 32, INIT_TXT, (0, 0, 0)) | |
block.rect.center = (width // 2, height // 2) # lets center the text block | |
# - debug if needed, comment this line when you're done debugging | |
block.debug = 1 | |
print('*~*~*\npress and hold the space bar ; press ENTER to change alignment') | |
ended = False | |
while not ended: | |
for ev in pygame.event.get(): | |
if ev.type == pygame.QUIT: | |
ended = True | |
elif ev.type == pygame.KEYDOWN: | |
if ev.key == pygame.K_RETURN: | |
block.text_align = (block.text_align + 1) % 2 # switch text align | |
elif ev.key == pygame.K_SPACE: | |
block.text = ALT_TXT | |
elif ev.type == pygame.KEYUP: | |
if not pygame.key.get_pressed()[pygame.K_SPACE]: | |
block.text = INIT_TXT | |
screen.fill('white') | |
block.draw(screen) | |
pygame.display.update() | |
pygame.quit() | |
# - program body ^ - |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment