Mercurial > parpg-core
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parpg/gui/spinners.py Sat May 14 01:12:35 2011 -0700 @@ -0,0 +1,234 @@ +from fife.extensions.pychan.widgets import (ImageButton, TextField, HBox, + Spacer) +from fife.extensions.pychan.attrs import Attr, IntAttr, BoolAttr + +class ListAttr(Attr): + def parse(self, value): + list_ = value.split(',') + return list_ + + +class Spinner(HBox): + ATTRIBUTES = HBox.ATTRIBUTES + [ + ListAttr('items'), + IntAttr('default_item_n'), + BoolAttr('circular'), + ] + + def default_item_n(): + def fget(self): + return self._default_item_n + + def fset(self, index): + if len(self.items) -1 >= index: + self._default_item_n = index + self.text_field.text = self.items[index] + else: + error_message = \ + 'default_item_n exceeds number of items in spinner' + raise ValueError(error_message) + + return locals() + default_item_n = property(**default_item_n()) + + def items(): + def fget(self): + return self._items + + def fset(self, items): + self._items = map(unicode, items) + if self.default_item_n > len(items) - 1: + self.default_item_n = 0 + self.text_field.text = self.items[self.default_item_n] if \ + len(self.items) > 0 else u'' + + return locals() + items = property(**items()) + + def background_color(): + def fget(self): + return self.text_field.background_color + + def fset(self, background_color): + self.text_field.background_color = background_color + + return locals() + background_color = property(**background_color()) + + def font(): + def fget(self): + return self.text_field.font + + def fset(self, font): + self.text_field.font = font + + return locals() + font = property(**font()) + + def background_color(): + def fget(self): + return self.text_field.background_color + + def fset(self, background_color): + self.text_field.background_color = background_color + + return locals() + background_color = property(**background_color()) + + def min_size(): + def fget(self): + return self._min_size + + def fset(self, min_size): + self._min_size = min_size + self.decrease_button.capture(self.previousItem) + increase_button_width, increase_button_height = \ + self.increase_button.size + decrease_button_width, decrease_button_height = \ + self.decrease_button.size + text_field_width = min_size[0] - (2 * self.padding) - \ + (increase_button_width + decrease_button_width) + self.text_field.min_width = text_field_width + self.text_field.max_width = text_field_width + self.text_field.min_height = min_size[1] + + return locals() + min_size = property(**min_size()) + + + def max_size(): + def fget(self): + return self._max_size + + def fset(self, max_size): + self._max_size = max_size + self.decrease_button.capture(self.previousItem) + increase_button_width, increase_button_height = \ + self.increase_button.size + decrease_button_width, decrease_button_height = \ + self.decrease_button.size + text_field_width = max_size[0] - (2 * self.padding) - \ + (increase_button_width + decrease_button_width) + self.text_field.max_width = text_field_width + self.text_field.max_height = max_size[1] + + return locals() + max_size = property(**max_size()) + + def __init__(self, items=None, default_item_n=0, circular=True, + min_size=(50, 14), max_size=(50, 14), font=None, background_color=None, **kwargs): + self._current_index = 0 + self._items = map(unicode, items) if items is not None else [] + self._default_item_n = default_item_n + self._min_size = min_size + self.circular = circular + padding = 1 + self.text_field = TextField(background_color=background_color) + self.decrease_button = ImageButton( + up_image='gui/buttons/left_arrow_up.png', + down_image='gui/buttons/left_arrow_down.png', + hover_image='gui/buttons/left_arrow_hover.png', + ) + # FIXME Technomage 2011-03-05: This is a hack to prevent the button + # from expanding width-wise and skewing the TextField orientation. + # Max size shouldn't be hard-coded like this though... + self.decrease_button.max_size = (12, 12) + self.decrease_button.capture(self.previousItem) + self.increase_button = ImageButton( + up_image='gui/buttons/right_arrow_up.png', + down_image='gui/buttons/right_arrow_down.png', + hover_image='gui/buttons/right_arrow_hover.png', + ) + self.increase_button.capture(self.nextItem) + increase_button_width, increase_button_height = \ + self.increase_button.size + decrease_button_width, decrease_button_height = \ + self.decrease_button.size + self.text_field = TextField(font=font) + text_field_width = min_size[0] - (2 * padding) - \ + (increase_button_width + decrease_button_width) + self.text_field.min_width = text_field_width + self.text_field.max_width = text_field_width + self.text_field.min_height = min_size[1] + self.text_field.text = self.items[default_item_n] if \ + len(self.items) > 0 else u'' + HBox.__init__(self, **kwargs) + self.opaque = 0 + self.padding = padding + self.margins = (0, 0) + self.addChildren(self.decrease_button, self.text_field, + self.increase_button) + + def nextItem(self, event, widget): + if self.circular: + if self._current_index < len(self.items) - 1: + self._current_index += 1 + else: + self._current_index = 0 + self.text_field.text = self.items[self._current_index] + elif self._current_index < len(self.items) - 1: + self._current_index += 1 + self.text_field.text = self.items[self._current_index] + + def previousItem(self, event, widget): + if self.circular: + if self._current_index > 0: + self._current_index -= 1 + else: + self._current_index = len(self.items) - 1 + self.text_field.text = self.items[self._current_index] + elif self._current_index > 0: + self._current_index -= 1 + self.text_field.text = self.items[self._current_index] + + +class IntSpinner(Spinner): + ATTRIBUTES = Spinner.ATTRIBUTES + [ + IntAttr('lower_limit'), + IntAttr('upper_limit'), + IntAttr('step_size'), + ] + + def lower_limit(): + def fget(self): + return self._lower_limit + + def fset(self, lower_limit): + self._lower_limit = lower_limit + integers = range(lower_limit, self.upper_limit + 1, self.step_size) + self.items = integers + + return locals() + lower_limit = property(**lower_limit()) + + def upper_limit(): + def fget(self): + return self._upper_limit + + def fset(self, upper_limit): + self._upper_limit = upper_limit + integers = range(self.lower_limit, upper_limit + 1, self.step_size) + self.items = integers + + return locals() + upper_limit = property(**upper_limit()) + + def step_size(): + def fget(self): + return self._step_size + + def fset(self, step_size): + self._step_size = step_size + integers = range(self.lower_limit, self.upper_limit + 1, step_size) + self.items = integers + + return locals() + step_size = property(**step_size()) + + def __init__(self, lower_limit=0, upper_limit=100, step_size=1, **kwargs): + self._lower_limit = lower_limit + self._upper_limit = upper_limit + self._step_size = step_size + integers = range(lower_limit, upper_limit + 1, step_size) + Spinner.__init__(self, items=integers, **kwargs) +