comparison src/parpg/gui/spinners.py @ 0:1fd2201f5c36

Initial commit of parpg-core.
author M. George Hansen <technopolitica@gmail.com>
date Sat, 14 May 2011 01:12:35 -0700
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1fd2201f5c36
1 from fife.extensions.pychan.widgets import (ImageButton, TextField, HBox,
2 Spacer)
3 from fife.extensions.pychan.attrs import Attr, IntAttr, BoolAttr
4
5 class ListAttr(Attr):
6 def parse(self, value):
7 list_ = value.split(',')
8 return list_
9
10
11 class 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
185 class 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