annotate skaapsteker/widgets/text.py @ 632:0675f390653c

Initial port to Python 3 and Pygame 2.
author Simon Cross <hodgestar@gmail.com>
date Fri, 20 Jan 2023 20:01:06 +0100
parents 7d49f698eff7
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
79
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
1 # -*- coding: utf-8 -*-
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
2
45
7f7b4bfbaf0e Trivial text rendering widget
Stefano Rivera <stefano@rivera.za.net>
parents:
diff changeset
3 import pygame
495
a5a57abd5472 Allow K_SPACE wherever we allow K_RETURN.
Jeremy Thurgood <firxen@gmail.com>
parents: 257
diff changeset
4 from pygame.locals import KEYDOWN, K_UP, K_DOWN, K_RETURN, K_SPACE
45
7f7b4bfbaf0e Trivial text rendering widget
Stefano Rivera <stefano@rivera.za.net>
parents:
diff changeset
5
79
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
6 from ..widgets import Widget
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
7 from ..data import filepath
45
7f7b4bfbaf0e Trivial text rendering widget
Stefano Rivera <stefano@rivera.za.net>
parents:
diff changeset
8
7f7b4bfbaf0e Trivial text rendering widget
Stefano Rivera <stefano@rivera.za.net>
parents:
diff changeset
9 fonts = {
7f7b4bfbaf0e Trivial text rendering widget
Stefano Rivera <stefano@rivera.za.net>
parents:
diff changeset
10 'sans': 'DejaVuSans.ttf',
7f7b4bfbaf0e Trivial text rendering widget
Stefano Rivera <stefano@rivera.za.net>
parents:
diff changeset
11 }
7f7b4bfbaf0e Trivial text rendering widget
Stefano Rivera <stefano@rivera.za.net>
parents:
diff changeset
12
7f7b4bfbaf0e Trivial text rendering widget
Stefano Rivera <stefano@rivera.za.net>
parents:
diff changeset
13 loaded_fonts = {}
7f7b4bfbaf0e Trivial text rendering widget
Stefano Rivera <stefano@rivera.za.net>
parents:
diff changeset
14
79
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
15 def load_font(name, size):
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
16 if (name, size) not in loaded_fonts:
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
17 fontfn = filepath('fonts/' + fonts[name])
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
18 fonts[(name, size)] = pygame.font.Font(fontfn, size)
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
19 return fonts[(name, size)]
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
20
134
4713a2a3b0be Initial cutscene screen
Stefano Rivera <stefano@rivera.za.net>
parents: 109
diff changeset
21 # Probably belongs in a utils module
4713a2a3b0be Initial cutscene screen
Stefano Rivera <stefano@rivera.za.net>
parents: 109
diff changeset
22 def unindent_text(text):
4713a2a3b0be Initial cutscene screen
Stefano Rivera <stefano@rivera.za.net>
parents: 109
diff changeset
23 """Reformat docstring-style text blocks."""
4713a2a3b0be Initial cutscene screen
Stefano Rivera <stefano@rivera.za.net>
parents: 109
diff changeset
24 text = text.split('\n')
4713a2a3b0be Initial cutscene screen
Stefano Rivera <stefano@rivera.za.net>
parents: 109
diff changeset
25 while text[0].strip() == '':
4713a2a3b0be Initial cutscene screen
Stefano Rivera <stefano@rivera.za.net>
parents: 109
diff changeset
26 text.pop(0)
4713a2a3b0be Initial cutscene screen
Stefano Rivera <stefano@rivera.za.net>
parents: 109
diff changeset
27 while text[-1].strip() == '':
4713a2a3b0be Initial cutscene screen
Stefano Rivera <stefano@rivera.za.net>
parents: 109
diff changeset
28 text.pop(-1)
4713a2a3b0be Initial cutscene screen
Stefano Rivera <stefano@rivera.za.net>
parents: 109
diff changeset
29 indent = len(text[0]) - len(text[0].lstrip())
4713a2a3b0be Initial cutscene screen
Stefano Rivera <stefano@rivera.za.net>
parents: 109
diff changeset
30 indent_chars = text[0][:indent]
4713a2a3b0be Initial cutscene screen
Stefano Rivera <stefano@rivera.za.net>
parents: 109
diff changeset
31 for index, line in enumerate(text):
4713a2a3b0be Initial cutscene screen
Stefano Rivera <stefano@rivera.za.net>
parents: 109
diff changeset
32 if line.startswith(indent_chars):
4713a2a3b0be Initial cutscene screen
Stefano Rivera <stefano@rivera.za.net>
parents: 109
diff changeset
33 text[index] = line[indent:]
4713a2a3b0be Initial cutscene screen
Stefano Rivera <stefano@rivera.za.net>
parents: 109
diff changeset
34 return '\n'.join(text)
4713a2a3b0be Initial cutscene screen
Stefano Rivera <stefano@rivera.za.net>
parents: 109
diff changeset
35
79
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
36
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
37 class Text(Widget):
136
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
38 def __init__(self, text, pos, font='sans', size=16, color='black',
183
691d2795ae3c Add text shadow
Stefano Rivera <stefano@rivera.za.net>
parents: 182
diff changeset
39 shadow=None, wrap=False):
45
7f7b4bfbaf0e Trivial text rendering widget
Stefano Rivera <stefano@rivera.za.net>
parents:
diff changeset
40 self.text = text
79
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
41 if isinstance(pos, pygame.Rect):
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
42 self.rect = pos
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
43 else:
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
44 self.rect = pygame.Rect(pos, (0, 0))
45
7f7b4bfbaf0e Trivial text rendering widget
Stefano Rivera <stefano@rivera.za.net>
parents:
diff changeset
45 self.font = load_font(font, size)
46
416e40b77924 Multi-line text
Stefano Rivera <stefano@rivera.za.net>
parents: 45
diff changeset
46 self.color = pygame.Color(color)
183
691d2795ae3c Add text shadow
Stefano Rivera <stefano@rivera.za.net>
parents: 182
diff changeset
47 self.shadow = None
691d2795ae3c Add text shadow
Stefano Rivera <stefano@rivera.za.net>
parents: 182
diff changeset
48 if shadow:
691d2795ae3c Add text shadow
Stefano Rivera <stefano@rivera.za.net>
parents: 182
diff changeset
49 self.shadow = pygame.Color(shadow)
136
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
50 if wrap:
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
51 if not isinstance(pos, pygame.Rect):
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
52 raise Exception("Cannot wrap without dimensions")
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
53 self._wrap()
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
54
183
691d2795ae3c Add text shadow
Stefano Rivera <stefano@rivera.za.net>
parents: 182
diff changeset
55 self._lines = []
691d2795ae3c Add text shadow
Stefano Rivera <stefano@rivera.za.net>
parents: 182
diff changeset
56 offset = (0, 0)
691d2795ae3c Add text shadow
Stefano Rivera <stefano@rivera.za.net>
parents: 182
diff changeset
57 for line in self.text.split('\n'):
691d2795ae3c Add text shadow
Stefano Rivera <stefano@rivera.za.net>
parents: 182
diff changeset
58 if shadow is not None:
691d2795ae3c Add text shadow
Stefano Rivera <stefano@rivera.za.net>
parents: 182
diff changeset
59 self._lines.append(((offset[0] + 1, offset[1] + 1),
691d2795ae3c Add text shadow
Stefano Rivera <stefano@rivera.za.net>
parents: 182
diff changeset
60 self.font.render(line, True, self.shadow)))
691d2795ae3c Add text shadow
Stefano Rivera <stefano@rivera.za.net>
parents: 182
diff changeset
61 self._lines.append((offset,
691d2795ae3c Add text shadow
Stefano Rivera <stefano@rivera.za.net>
parents: 182
diff changeset
62 self.font.render(line, True, self.color)))
691d2795ae3c Add text shadow
Stefano Rivera <stefano@rivera.za.net>
parents: 182
diff changeset
63 offset = (offset[0], offset[1] + self.font.get_linesize())
691d2795ae3c Add text shadow
Stefano Rivera <stefano@rivera.za.net>
parents: 182
diff changeset
64 self.rect.width = max(line[1].get_width() for line in self._lines)
691d2795ae3c Add text shadow
Stefano Rivera <stefano@rivera.za.net>
parents: 182
diff changeset
65 self.rect.height = self.font.get_linesize() * len(self._lines)
691d2795ae3c Add text shadow
Stefano Rivera <stefano@rivera.za.net>
parents: 182
diff changeset
66 if shadow is not None:
691d2795ae3c Add text shadow
Stefano Rivera <stefano@rivera.za.net>
parents: 182
diff changeset
67 self.rect.width += 1
691d2795ae3c Add text shadow
Stefano Rivera <stefano@rivera.za.net>
parents: 182
diff changeset
68 self.rect.height += 1
136
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
69
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
70 def _wrap(self):
182
c9a7ab87e0d4 Text: Actually unwrap in unwrapped
Stefano Rivera <stefano@rivera.za.net>
parents: 136
diff changeset
71 unwrapped = [para.replace('\n', ' ')
c9a7ab87e0d4 Text: Actually unwrap in unwrapped
Stefano Rivera <stefano@rivera.za.net>
parents: 136
diff changeset
72 for para in self.text.split('\n\n')]
136
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
73 text = []
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
74 for paragraph in unwrapped:
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
75 words = paragraph.split(' ')
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
76 nwords = len(words)
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
77 from_ = 0
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
78 to = 0
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
79 while to < nwords:
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
80 to += 1
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
81 line = ' '.join(words[from_:to])
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
82 if self.font.size(line)[0] <= self.rect.width:
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
83 continue
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
84 if to - from_ > 1:
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
85 to -= 1
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
86 text.append(' '.join(words[from_:to]))
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
87 from_ = to
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
88 text.append(' '.join(words[from_:to]))
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
89 text.append('')
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
90 if text:
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
91 text.pop(-1)
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
92 self.text = '\n'.join(text)
1e9599e48d7b Simplistic text wrapping
Stefano Rivera <stefano@rivera.za.net>
parents: 134
diff changeset
93
79
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
94 def draw(self, surface):
82
49b25117ebbb rect.copy() is a pygame 1.9 addition. Work around this.
Neil Muller <drnlmuller@gmail.com>
parents: 79
diff changeset
95 pos = self.rect
183
691d2795ae3c Add text shadow
Stefano Rivera <stefano@rivera.za.net>
parents: 182
diff changeset
96 for offset, line in self._lines:
691d2795ae3c Add text shadow
Stefano Rivera <stefano@rivera.za.net>
parents: 182
diff changeset
97 surface.blit(line, pos.move(offset))
45
7f7b4bfbaf0e Trivial text rendering widget
Stefano Rivera <stefano@rivera.za.net>
parents:
diff changeset
98
79
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
99
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
100 class TextChoice(Widget):
109
982f34d0aac0 Add optional data to identify TextChoice options
Stefano Rivera <stefano@rivera.za.net>
parents: 82
diff changeset
101 """Render a list of options, and a selector.
982f34d0aac0 Add optional data to identify TextChoice options
Stefano Rivera <stefano@rivera.za.net>
parents: 82
diff changeset
102 options can be text or a tuple of (text, data).
982f34d0aac0 Add optional data to identify TextChoice options
Stefano Rivera <stefano@rivera.za.net>
parents: 82
diff changeset
103 When selected, calls everything registered in callbacks with (index, data)
982f34d0aac0 Add optional data to identify TextChoice options
Stefano Rivera <stefano@rivera.za.net>
parents: 82
diff changeset
104 """
79
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
105 def __init__(self, options, pos, **kwargs):
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
106 self.options = []
109
982f34d0aac0 Add optional data to identify TextChoice options
Stefano Rivera <stefano@rivera.za.net>
parents: 82
diff changeset
107 self.option_widgets = []
257
3f8ce3452cd6 Add support for selecting dialogue choices (and for moving TextChoice around the screen).
Simon Cross <hodgestar@gmail.com>
parents: 249
diff changeset
108 if isinstance(pos, pygame.Rect):
3f8ce3452cd6 Add support for selecting dialogue choices (and for moving TextChoice around the screen).
Simon Cross <hodgestar@gmail.com>
parents: 249
diff changeset
109 self.rect = pos
3f8ce3452cd6 Add support for selecting dialogue choices (and for moving TextChoice around the screen).
Simon Cross <hodgestar@gmail.com>
parents: 249
diff changeset
110 else:
3f8ce3452cd6 Add support for selecting dialogue choices (and for moving TextChoice around the screen).
Simon Cross <hodgestar@gmail.com>
parents: 249
diff changeset
111 self.rect = pygame.Rect(pos, (0, 0))
3f8ce3452cd6 Add support for selecting dialogue choices (and for moving TextChoice around the screen).
Simon Cross <hodgestar@gmail.com>
parents: 249
diff changeset
112 pos = self.rect
3f8ce3452cd6 Add support for selecting dialogue choices (and for moving TextChoice around the screen).
Simon Cross <hodgestar@gmail.com>
parents: 249
diff changeset
113 self.selector = Text(u'» ', pos.move(0, 0), **kwargs)
79
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
114 self.selected = 0
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
115 self.callbacks = []
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
116
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
117 for option in options:
109
982f34d0aac0 Add optional data to identify TextChoice options
Stefano Rivera <stefano@rivera.za.net>
parents: 82
diff changeset
118 if not isinstance(option, tuple):
982f34d0aac0 Add optional data to identify TextChoice options
Stefano Rivera <stefano@rivera.za.net>
parents: 82
diff changeset
119 option = (option, None)
982f34d0aac0 Add optional data to identify TextChoice options
Stefano Rivera <stefano@rivera.za.net>
parents: 82
diff changeset
120 self.options.append(option)
982f34d0aac0 Add optional data to identify TextChoice options
Stefano Rivera <stefano@rivera.za.net>
parents: 82
diff changeset
121 text, data = option
257
3f8ce3452cd6 Add support for selecting dialogue choices (and for moving TextChoice around the screen).
Simon Cross <hodgestar@gmail.com>
parents: 249
diff changeset
122 t = Text(text, pos.move(0, 0), **kwargs)
109
982f34d0aac0 Add optional data to identify TextChoice options
Stefano Rivera <stefano@rivera.za.net>
parents: 82
diff changeset
123 self.option_widgets.append(t)
982f34d0aac0 Add optional data to identify TextChoice options
Stefano Rivera <stefano@rivera.za.net>
parents: 82
diff changeset
124
982f34d0aac0 Add optional data to identify TextChoice options
Stefano Rivera <stefano@rivera.za.net>
parents: 82
diff changeset
125 self.rect.width = max(line.rect.width for line in self.option_widgets
982f34d0aac0 Add optional data to identify TextChoice options
Stefano Rivera <stefano@rivera.za.net>
parents: 82
diff changeset
126 ) + self.selector.rect.width
982f34d0aac0 Add optional data to identify TextChoice options
Stefano Rivera <stefano@rivera.za.net>
parents: 82
diff changeset
127 self.rect.height = sum(line.rect.height for line in self.option_widgets)
79
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
128
257
3f8ce3452cd6 Add support for selecting dialogue choices (and for moving TextChoice around the screen).
Simon Cross <hodgestar@gmail.com>
parents: 249
diff changeset
129 def _update_rects(self):
3f8ce3452cd6 Add support for selecting dialogue choices (and for moving TextChoice around the screen).
Simon Cross <hodgestar@gmail.com>
parents: 249
diff changeset
130 pos = self.rect.move(self.selector.rect.width, 0)
3f8ce3452cd6 Add support for selecting dialogue choices (and for moving TextChoice around the screen).
Simon Cross <hodgestar@gmail.com>
parents: 249
diff changeset
131 for t in self.option_widgets:
3f8ce3452cd6 Add support for selecting dialogue choices (and for moving TextChoice around the screen).
Simon Cross <hodgestar@gmail.com>
parents: 249
diff changeset
132 t.rect.topleft = pos.topleft
3f8ce3452cd6 Add support for selecting dialogue choices (and for moving TextChoice around the screen).
Simon Cross <hodgestar@gmail.com>
parents: 249
diff changeset
133 pos = pos.move(0, t.rect.height)
3f8ce3452cd6 Add support for selecting dialogue choices (and for moving TextChoice around the screen).
Simon Cross <hodgestar@gmail.com>
parents: 249
diff changeset
134 self.selector.rect.top = self.option_widgets[self.selected].rect.top
3f8ce3452cd6 Add support for selecting dialogue choices (and for moving TextChoice around the screen).
Simon Cross <hodgestar@gmail.com>
parents: 249
diff changeset
135 self.selector.rect.left = self.rect.left
3f8ce3452cd6 Add support for selecting dialogue choices (and for moving TextChoice around the screen).
Simon Cross <hodgestar@gmail.com>
parents: 249
diff changeset
136
79
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
137 def dispatch(self, ev):
632
0675f390653c Initial port to Python 3 and Pygame 2.
Simon Cross <hodgestar@gmail.com>
parents: 611
diff changeset
138 if ev.type == KEYDOWN:
79
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
139 if ev.key == K_UP:
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
140 self.selected -= 1
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
141 elif ev.key == K_DOWN:
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
142 self.selected += 1
495
a5a57abd5472 Allow K_SPACE wherever we allow K_RETURN.
Jeremy Thurgood <firxen@gmail.com>
parents: 257
diff changeset
143 elif ev.key in [K_RETURN, K_SPACE]:
109
982f34d0aac0 Add optional data to identify TextChoice options
Stefano Rivera <stefano@rivera.za.net>
parents: 82
diff changeset
144 for callback in self.callbacks:
982f34d0aac0 Add optional data to identify TextChoice options
Stefano Rivera <stefano@rivera.za.net>
parents: 82
diff changeset
145 callback(self.selected, self.options[self.selected][1])
79
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
146
611
7d49f698eff7 Ensure that self.selected remaings with self.options in ButtonSet. Only wrap self.selected if it might have changed (for both ButtonSet and TextChoice).
Simon Cross <hodgestar@gmail.com>
parents: 495
diff changeset
147 self.selected %= len(self.option_widgets)
79
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
148
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
149 def draw(self, surface):
257
3f8ce3452cd6 Add support for selecting dialogue choices (and for moving TextChoice around the screen).
Simon Cross <hodgestar@gmail.com>
parents: 249
diff changeset
150 self._update_rects()
109
982f34d0aac0 Add optional data to identify TextChoice options
Stefano Rivera <stefano@rivera.za.net>
parents: 82
diff changeset
151 for option in self.option_widgets:
79
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
152 option.draw(surface)
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 46
diff changeset
153 self.selector.draw(surface)
247
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
154
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
155
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
156 class TextButton(Widget):
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
157 def __init__(self, text, pos, margin=10, **kwargs):
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
158 textpos = pygame.Rect((pos[0] + margin, pos[1] + margin), (0, 0))
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
159 self.text = Text(text, textpos, **kwargs)
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
160 self.rect = pygame.Rect(pos, (0, 0))
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
161 self.rect.width = self.text.rect.width + 2 * margin
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
162 self.rect.height = self.text.rect.height + 2 * margin
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
163
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
164 def draw(self, surface, selected=False):
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
165 self.text.draw(surface)
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
166 pygame.draw.rect(surface, self.text.color, self.rect, 1)
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
167
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
168
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
169 class ButtonSet(Widget):
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
170 def __init__(self):
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
171 self.options = []
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
172 self.selected = 0
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
173 self.callbacks = []
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
174
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
175 def append(self, widget, data=None):
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
176 self.options.append((widget, data))
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
177
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
178 def dispatch(self, ev):
632
0675f390653c Initial port to Python 3 and Pygame 2.
Simon Cross <hodgestar@gmail.com>
parents: 611
diff changeset
179 if ev.type == KEYDOWN:
247
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
180 if ev.key == K_UP:
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
181 self.selected -= 1
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
182 elif ev.key == K_DOWN:
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
183 self.selected += 1
495
a5a57abd5472 Allow K_SPACE wherever we allow K_RETURN.
Jeremy Thurgood <firxen@gmail.com>
parents: 257
diff changeset
184 elif ev.key in [K_RETURN, K_SPACE]:
247
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
185 for callback in self.callbacks:
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
186 callback(self.selected, self.options[self.selected][1])
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
187
611
7d49f698eff7 Ensure that self.selected remaings with self.options in ButtonSet. Only wrap self.selected if it might have changed (for both ButtonSet and TextChoice).
Simon Cross <hodgestar@gmail.com>
parents: 495
diff changeset
188 self.selected %= len(self.options)
7d49f698eff7 Ensure that self.selected remaings with self.options in ButtonSet. Only wrap self.selected if it might have changed (for both ButtonSet and TextChoice).
Simon Cross <hodgestar@gmail.com>
parents: 495
diff changeset
189
247
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
190 def draw(self, surface):
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
191 for i, widget in enumerate(self.options):
8c0c132b422f Button widget for cutscene
Stefano Rivera <stefano@rivera.za.net>
parents: 183
diff changeset
192 widget[0].draw(surface, i == self.selected)