Source code for albow.controls

# Albow - Controls
#-# Modified by D.C.-G. for translation purpose

from pygame import Rect, draw, transform

from widget import Widget, overridable_property
from theme import ThemeProperty
import resource
from translate import _, getLang

[docs]class Control(object): highlighted = overridable_property('highlighted') enabled = overridable_property('enabled') value = overridable_property('value') enable = None ref = None _highlighted = False _enabled = True _value = None
[docs] def get_value(self): ref = self.ref if ref: return ref.get() else: return self._value
[docs] def set_value(self, x): ref = self.ref if ref: ref.set(x) else: self._value = x
[docs] def get_highlighted(self): return self._highlighted
[docs] def get_enabled(self): enable = self.enable if enable: return enable() else: return self._enabled
[docs] def set_enabled(self, x): self._enabled = x
[docs]class AttrRef(object): def __init__(self, obj, attr): self.obj = obj self.attr = attr
[docs] def get(self): return getattr(self.obj, self.attr)
[docs] def set(self, x): setattr(self.obj, self.attr, x)
[docs]class ItemRef(object): def __init__(self, obj, item): self.obj = obj self.item = item
[docs] def get(self): return self.obj[self.item]
[docs] def set(self, x): self.obj[self.item] = x
[docs]class Label(Widget): text = overridable_property('text') align = overridable_property('align') hover_color = ThemeProperty('hover_color') highlight_color = ThemeProperty('highlight_color') disabled_color = ThemeProperty('disabled_color') highlight_bg_color = ThemeProperty('highlight_bg_color') hover_bg_color = ThemeProperty('hover_bg_color') enabled_bg_color = ThemeProperty('enabled_bg_color') disabled_bg_color = ThemeProperty('disabled_bg_color') enabled = True highlighted = False _align = 'l' def __init__(self, text, width=None, base_text=None, **kwds): #-# Translation live update preparation # base_text: to be used each time a widget takes a formated string # defaults to 'text'. Widget.__init__(self, **kwds) #-# Translation live update preparation self.fixed_width = width self.base_text = base_text or text self.previous_translation = _(text, doNotTranslate=kwds.get('doNotTranslate', False)) #-# self._text = _(text, doNotTranslate=kwds.get('doNotTranslate', False)) #-# self.calc_size() #-# #-# Translation live update preparation
[docs] def calc_size(self): lines = self._text.split("\n") tw, th = 0, 0 for i in range(len(lines)): line = lines[i] if i == len(lines) - 1: w, h = self.font.size(line) else: w, h = self.font.size(line)[0], self.font.get_linesize() tw = max(tw, w) th += h if self.fixed_width is not None: tw = self.fixed_width else: tw = max(1, tw) d = 2 * self.margin self.size = (tw + d, th + d)
[docs] def get_update_translation(self): return Widget.update_translation(self)
[docs] def set_update_ui(self, v): self.text = self.base_text self.set_text(self.base_text) self.calc_size() Widget.set_update_ui(self, v) #-#
def __repr__(self): return "Label {0}, child of {1}".format(self.text.encode('ascii', errors='backslashreplace'), self.parent)
[docs] def get_text(self): return self._text
[docs] def set_text(self, x, doNotTranslate=False): self._text = _(x, doNotTranslate=doNotTranslate or self.doNotTranslate) self.calc_size()
[docs] def get_align(self): return self._align
[docs] def set_align(self, x): self._align = x
[docs] def draw(self, surface): if not self.enabled: fg = self.disabled_color bg = self.disabled_bg_color else: fg = self.fg_color bg = self.enabled_bg_color if self.is_default: fg = self.default_choice_color or fg bg = self.default_choice_bg_color or bg if self.is_hover: fg = self.hover_color or fg bg = self.hover_bg_color or bg if self.highlighted: fg = self.highlight_color or fg bg = self.highlight_bg_color or bg self.draw_with(surface, fg, bg)
is_default = False
[docs] def draw_with(self, surface, fg, bg=None): if bg: r = surface.get_rect() b = self.border_width if b: e = -2 * b r.inflate_ip(e, e) surface.fill(bg, r) m = self.margin align = self.align width = surface.get_width() y = m lines = self.text.split("\n") font = self.font dy = font.get_linesize() for line in lines: if len(line): size = font.size(line) if size[0] == 0: continue image = font.render(line, True, fg) r = image.get_rect() = y if align == 'l': r.left = m elif align == 'r': r.right = width - m else: r.centerx = width // 2 surface.blit(image, r) y += dy
[docs]class GLLabel(Label): pass
[docs]class SmallLabel(Label): """Small text size. See"""
[docs]class ButtonBase(Control): align = 'c' action = None rightClickAction = None default_choice_color = ThemeProperty('default_choice_color') default_choice_bg_color = ThemeProperty('default_choice_bg_color')
[docs] def mouse_down(self, event): button = event.button if self.enabled and button == 1: self._highlighted = True
[docs] def mouse_drag(self, event): state = event in self if event.buttons[0] == 1 and state != self._highlighted: self._highlighted = state self.invalidate()
[docs] def mouse_up(self, event): button = event.button if event in self and button == 1: if self is event.clicked_widget or (event.clicked_widget and self in event.clicked_widget.all_parents()): self._highlighted = False if self.enabled: self.call_handler('action') if event in self and button == 3 and self.enabled: if self is event.clicked_widget or (event.clicked_widget and self in event.clicked_widget.all_parents()): self.call_handler('rightClickAction') self.get_root().fix_sticky_ctrl()
[docs]class Button(ButtonBase, Label): def __init__(self, text, action=None, enable=None, rightClickAction=None, **kwds): if action: kwds['action'] = action if enable: kwds['enable'] = enable if rightClickAction: kwds['rightClickAction'] = rightClickAction Label.__init__(self, text, **kwds)
[docs]class Image(Widget): # image Image to display highlight_color = ThemeProperty('highlight_color') image = overridable_property('image') highlighted = False def __init__(self, image=None, rect=None, prefix="", **kwds): Widget.__init__(self, rect, **kwds) if image: if isinstance(image, basestring): image = resource.get_image(image, prefix=prefix) w, h = image.get_size() d = 2 * self.margin self.size = w + d, h + d self._image = image
[docs] def get_image(self): return self._image
[docs] def set_image(self, x): self._image = x
[docs] def draw(self, surf): frame = surf.get_rect() if self.highlighted: surf.fill(self.highlight_color) image = self.image r = image.get_rect() = surf.blit(image, r)
[docs]class RotatableImage(Image): def __init__(self, angle=0.0, min_angle=0, max_angle=360, **kwds): super(RotatableImage, self).__init__(**kwds) self._angle = -angle self._min_angle = min_angle self._max_angle = max_angle
[docs] def draw(self, surf): frame = surf.get_rect() if self.highlighted: surf.fill(self.highlight_color) image = self.image image = transform.rotate(image, self._angle) r = image.get_rect() = surf.blit(image, r)
[docs] def get_angle(self): return self._angle
[docs] def set_angle(self, angle): angle = max(min(angle, self._max_angle), self._min_angle) self._angle = angle
[docs] def add_angle(self, angle): self.set_angle(self.get_angle() + (angle * -1))
[docs]class ImageButton(ButtonBase, Image): pass
[docs]class ValueDisplay(Control, Label): format = "%s" align = 'l' def __init__(self, width=100, **kwds): Label.__init__(self, "", **kwds) self.set_size_for_text(width)
[docs] def get_text(self): return self.format_value(_(self.value, self.doNotTranslate))
[docs] def format_value(self, value): if value is not None: return self.format % value else: return ""
[docs]class SmallValueDisplay(ValueDisplay): pass
[docs]class ValueButton(ButtonBase, ValueDisplay): align = 'c'
[docs] def get_text(self): return self.format_value(_(self.value, self.doNotTranslate))
[docs]class CheckControl(Control):
[docs] def mouse_down(self, e): if self.get_enabled(): self.value = not self.value
[docs] def get_highlighted(self): return self.value
[docs]class CheckWidget(Widget): default_size = (16, 16) margin = 4 border_width = 1 check_mark_tweak = 2 smooth = ThemeProperty('smooth') def __init__(self, **kwds): Widget.__init__(self, Rect((0, 0), self.default_size), **kwds)
[docs] def draw(self, surf): if self.highlighted: r = self.get_margin_rect() fg = self.fg_color d = self.check_mark_tweak p1 = (r.left, r.centery - d) p2 = (r.centerx - d, r.bottom) p3 = (r.right, - d) if self.smooth: draw.aalines(surf, fg, False, [p1, p2, p3]) else: draw.lines(surf, fg, False, [p1, p2, p3])
[docs]class CheckBox(CheckControl, CheckWidget): pass
[docs]class RadioControl(Control): setting = None
[docs] def get_highlighted(self): return self.value == self.setting
[docs] def mouse_down(self, e): self.value = self.setting
[docs]class RadioButton(RadioControl, CheckWidget): pass