Allow for centring text buttons and display levels centred.
[tabakrolletjie.git] / tabakrolletjie / widgets.py
1 # Simple widgets
2 # This just unifies some logic.
3 # There is no implied container / window system (yet)
4
5 import pygame.locals as pgl
6
7 from .loader import loader
8 from .constants import FONTS
9 from .transforms import NullTransform, Multiply
10
11
12 class Button(object):
13
14     def __init__(self, size, name=None, pos=None, padding=10):
15         self._size = size
16         self._padding = padding
17         self.position = pos
18         self.name = name
19         self.enabled = True
20
21     def enable(self):
22         self.enabled = True
23
24     def disable(self):
25         self.enabled = False
26
27     @property
28     def position(self):
29         return self._pos
30
31     @position.setter
32     def position(self, pos):
33         self._pos = pos
34         if pos is not None:
35             self._min_x = pos[0] - self._padding
36             self._max_x = pos[0] + self._size[0] + self._padding
37             self._min_y = pos[1] - self._padding
38             self._max_y = pos[1] + self._size[1] + self._padding
39
40     def get_width(self):
41         return self._size[0]
42
43     def get_height(self):
44         return self._size[1]
45
46     def render(self, surface):
47         pass
48
49     def pressed(self, ev):
50         if not self.enabled:
51             return False
52         if self._pos is None:
53             # Unplaced buttons can't be pressed
54             return False
55         if ev.type == pgl.MOUSEBUTTONDOWN and ev.button == 1:
56             if self._min_x < ev.pos[0] < self._max_x:
57                 if self._min_y < ev.pos[1] < self._max_y:
58                     return True
59         return False
60
61
62 class SpacerButton(Button):
63     """ Add a nothing object which can be used to space other things,
64         but is never pressed """
65
66     def pressed(self, ev):
67         return False
68
69
70 class TextButton(Button):
71
72     def __init__(
73             self, text, colour, name=None, pos=None, padding=10, size=24,
74             font='sans', centre=False):
75         font = loader.load_font(FONTS[font], size=size)
76         self._text = font.render(text, True, colour)
77         if centre:
78             w, h = self._text.get_size()
79             pos = pos[0] - (w / 2), pos[1] - (h / 2)
80         self._disabled_text = self._text.copy()
81         Multiply(colour=(80, 80, 80)).apply(self._disabled_text)
82         super(TextButton, self).__init__(self._text.get_size(), name,
83                                          pos, padding)
84
85     def render(self, surface):
86         if self.enabled:
87             surface.blit(self._text, self._pos, None)
88         else:
89             surface.blit(self._disabled_text, self._pos, None)
90
91
92 class ImageButton(Button):
93
94     def __init__(self, *imgparts, **kwargs):
95         transform = kwargs.pop("transform", NullTransform())
96         self._img = kwargs.pop("image", None)
97         if self._img is None:
98             self._img = loader.load_image(*imgparts, transform=transform)
99         name = kwargs.get('name')
100         pos = kwargs.get('pos')
101         padding = kwargs.get('padding', 0)
102         super(ImageButton, self).__init__(self._img.get_size(), name,
103                                           pos, padding)
104
105     def update_image(self, *imgparts, **kwargs):
106         transform = kwargs.pop("transform", NullTransform())
107         self._img = loader.load_image(*imgparts, transform=transform)
108         Multiply((128, 128, 128)).apply(self._disabled_img)
109
110     def render(self, surface):
111         surface.blit(self._img, self._pos, None)