Mercurial > skaapsteker
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 |
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 | 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 | 46 self.color = pygame.Color(color) |
183 | 47 self.shadow = None |
48 if shadow: | |
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 | 55 self._lines = [] |
56 offset = (0, 0) | |
57 for line in self.text.split('\n'): | |
58 if shadow is not None: | |
59 self._lines.append(((offset[0] + 1, offset[1] + 1), | |
60 self.font.render(line, True, self.shadow))) | |
61 self._lines.append((offset, | |
62 self.font.render(line, True, self.color))) | |
63 offset = (offset[0], offset[1] + self.font.get_linesize()) | |
64 self.rect.width = max(line[1].get_width() for line in self._lines) | |
65 self.rect.height = self.font.get_linesize() * len(self._lines) | |
66 if shadow is not None: | |
67 self.rect.width += 1 | |
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 | 96 for offset, line in self._lines: |
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) |