source: branches/active/character_customization/game/parpg/gui/spinners.py @ 833

Revision 785, 8.3 KB checked in by technomage, 8 years ago (diff)

Patch by Technomage

  • Mostly finished the character creation GUI in gui/character_screen.xml - still needs a few cosmetic touch-ups and it hasn't been tested with stats, traits, and skills lists yet;
  • Added a new CharacterCreationView? class in parpg/gui/charactercreationview.py which should be used by the CharacterCreationController? to display the character creation GUI. It is mostly a skeleton at this point, however, and it hasn't been integrated with the controller yet;
  • Fixed a few graphical glitches in the Spinner widget in parpg/gui/spinners.py that caused the text field to be positioned incorrectly;
  • Added a few new properties to the Spinner widget, including background_color, min_size and max_size, which override the inherited properties. Spinner widgets that uses these properties should now behave in a much more intuitive way;
  • Re-sized the gui/notebook/notebook_background.png background image to 800x600 to accommodate tab-buttons on the edges of the notebook;
  • Added a new widget, TabWidget?, which consists of a view that has tabs which can switch between the various views. Views in a TabWidget? can be added in XML as child tags whose name attribute ends up as the tab text;
  • Added two new size fonts to fonts/oldtypewriter.fontdef, 9 pt and 10 pt;
Line 
1from fife.extensions.pychan.widgets import (ImageButton, TextField, HBox,
2    Spacer)
3from fife.extensions.pychan.attrs import Attr, IntAttr, BoolAttr
4
5class ListAttr(Attr):
6    def parse(self, value):
7        list_ = value.split(',')
8        return list_
9
10
11class Spinner(HBox):
12    ATTRIBUTES = HBox.ATTRIBUTES + [
13        ListAttr('items'),
14        IntAttr('default_item_n'),
15        BoolAttr('circular'),
16    ]
17   
18    def default_item_n():
19        def fget(self):
20            return self._default_item_n
21       
22        def fset(self, index):
23            if len(self.items) -1 >= index:
24                self._default_item_n = index
25                self.text_field.text = self.items[index]
26            else:
27                error_message = \
28                    'default_item_n exceeds number of items in spinner'
29                raise ValueError(error_message)
30       
31        return locals()
32    default_item_n = property(**default_item_n())
33   
34    def items():
35        def fget(self):
36            return self._items
37       
38        def fset(self, items):
39            self._items = map(unicode, items)
40            if self.default_item_n > len(items) - 1:
41                self.default_item_n = 0
42            self.text_field.text = self.items[self.default_item_n] if \
43                                   len(self.items) > 0 else u''
44       
45        return locals()
46    items = property(**items())
47   
48    def background_color():
49        def fget(self):
50            return self.text_field.background_color
51       
52        def fset(self, background_color):
53            self.text_field.background_color = background_color
54       
55        return locals()
56    background_color = property(**background_color())
57   
58    def font():
59        def fget(self):
60            return self.text_field.font
61       
62        def fset(self, font):
63            self.text_field.font = font
64       
65        return locals()
66    font = property(**font())
67   
68    def background_color():
69        def fget(self):
70            return self.text_field.background_color
71       
72        def fset(self, background_color):
73            self.text_field.background_color = background_color
74       
75        return locals()
76    background_color = property(**background_color())
77   
78    def min_size():
79        def fget(self):
80            return self._min_size
81       
82        def fset(self, min_size):
83            self._min_size = min_size
84            self.decrease_button.capture(self.previousItem)
85            increase_button_width, increase_button_height = \
86                self.increase_button.size
87            decrease_button_width, decrease_button_height = \
88                self.decrease_button.size
89            text_field_width = min_size[0] - (2 * self.padding) - \
90                               (increase_button_width + decrease_button_width)
91            self.text_field.min_width = text_field_width
92            self.text_field.max_width = text_field_width
93            self.text_field.min_height = min_size[1]
94       
95        return locals()
96    min_size = property(**min_size())
97   
98   
99    def max_size():
100        def fget(self):
101            return self._max_size
102       
103        def fset(self, max_size):
104            self._max_size = max_size
105            self.decrease_button.capture(self.previousItem)
106            increase_button_width, increase_button_height = \
107                self.increase_button.size
108            decrease_button_width, decrease_button_height = \
109                self.decrease_button.size
110            text_field_width = max_size[0] - (2 * self.padding) - \
111                               (increase_button_width + decrease_button_width)
112            self.text_field.max_width = text_field_width
113            self.text_field.max_height = max_size[1]
114       
115        return locals()
116    max_size = property(**max_size())
117   
118    def __init__(self, items=None, default_item_n=0, circular=True,
119                 min_size=(50, 14), max_size=(50, 14), font=None, background_color=None, **kwargs):
120        self._current_index = 0
121        self._items = map(unicode, items) if items is not None else []
122        self._default_item_n = default_item_n
123        self._min_size = min_size
124        self.circular = circular
125        padding = 1
126        self.text_field = TextField(background_color=background_color)
127        self.decrease_button = ImageButton(
128            up_image='gui/buttons/left_arrow_up.png',
129            down_image='gui/buttons/left_arrow_down.png',
130            hover_image='gui/buttons/left_arrow_hover.png',
131        )
132        # FIXME Technomage 2011-03-05: This is a hack to prevent the button
133        #     from expanding width-wise and skewing the TextField orientation.
134        #     Max size shouldn't be hard-coded like this though...
135        self.decrease_button.max_size = (12, 12)
136        self.decrease_button.capture(self.previousItem)
137        self.increase_button = ImageButton(
138            up_image='gui/buttons/right_arrow_up.png',
139            down_image='gui/buttons/right_arrow_down.png',
140            hover_image='gui/buttons/right_arrow_hover.png',
141        )
142        self.increase_button.capture(self.nextItem)
143        increase_button_width, increase_button_height = \
144            self.increase_button.size
145        decrease_button_width, decrease_button_height = \
146            self.decrease_button.size
147        self.text_field = TextField(font=font)
148        text_field_width = min_size[0] - (2 * padding) - \
149                           (increase_button_width + decrease_button_width)
150        self.text_field.min_width = text_field_width
151        self.text_field.max_width = text_field_width
152        self.text_field.min_height = min_size[1]
153        self.text_field.text = self.items[default_item_n] if \
154                               len(self.items) > 0 else u''
155        HBox.__init__(self, **kwargs)
156        self.opaque = 0
157        self.padding = padding
158        self.margins = (0, 0)
159        self.addChildren(self.decrease_button, self.text_field,
160                         self.increase_button)
161   
162    def nextItem(self, event, widget):
163        if self.circular:
164            if self._current_index < len(self.items) - 1:
165                self._current_index += 1
166            else:
167                self._current_index = 0
168            self.text_field.text = self.items[self._current_index]
169        elif self._current_index < len(self.items) - 1:
170            self._current_index += 1
171            self.text_field.text = self.items[self._current_index]
172   
173    def previousItem(self, event, widget):
174        if self.circular:
175            if self._current_index > 0:
176                self._current_index -= 1
177            else:
178                self._current_index = len(self.items) - 1
179            self.text_field.text = self.items[self._current_index]
180        elif self._current_index > 0:
181            self._current_index -= 1
182            self.text_field.text = self.items[self._current_index]
183
184
185class IntSpinner(Spinner):
186    ATTRIBUTES = Spinner.ATTRIBUTES + [
187        IntAttr('lower_limit'),
188        IntAttr('upper_limit'),
189        IntAttr('step_size'),
190    ]
191   
192    def lower_limit():
193        def fget(self):
194            return self._lower_limit
195       
196        def fset(self, lower_limit):
197            self._lower_limit = lower_limit
198            integers = range(lower_limit, self.upper_limit + 1, self.step_size)
199            self.items = integers
200       
201        return locals()
202    lower_limit = property(**lower_limit())
203   
204    def upper_limit():
205        def fget(self):
206            return self._upper_limit
207       
208        def fset(self, upper_limit):
209            self._upper_limit = upper_limit
210            integers = range(self.lower_limit, upper_limit + 1, self.step_size)
211            self.items = integers
212       
213        return locals()
214    upper_limit = property(**upper_limit())
215   
216    def step_size():
217        def fget(self):
218            return self._step_size
219       
220        def fset(self, step_size):
221            self._step_size = step_size
222            integers = range(self.lower_limit, self.upper_limit + 1, step_size)
223            self.items = integers
224       
225        return locals()
226    step_size = property(**step_size())
227   
228    def __init__(self, lower_limit=0, upper_limit=100, step_size=1, **kwargs):
229        self._lower_limit = lower_limit
230        self._upper_limit = upper_limit
231        self._step_size = step_size
232        integers = range(lower_limit, upper_limit + 1, step_size)
233        Spinner.__init__(self, items=integers, **kwargs)
234
Note: See TracBrowser for help on using the repository browser.