1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
# -*- coding: utf-8 -*-
import pygame
class Widget:
""" A widget represents anything drawable on the screen """
def __init__(self, container, rect_in_container, frame_rate, surface=None, tooltip=None):
self.container = container # Rect, containing the widget
self.set_rect_in_container(rect_in_container)
self.frame_rate = frame_rate
self.background = surface
self.parent = None
# Tooltip
self.tooltip = tooltip
self.super_tooltip = None
self.showing_tooltip = False
# Click Sound
self.click_sound_path = None
self.visible = True
self.over = False
# A widget it's dirty when it changes somehow, for example an animation will be dirty after every new sprite
# A widget should change in the update method (before draw)
self.dirty = True
# When this flag it's on, the widget it's always dirty, unless the update method is overriden
self.keep_dirty = False
def update(self, frames):
""" Abstract. This method is called before draw, the purpose is to override it to alter the widget and let
know the application that the widget became dirty, for example when an animation changes its image or its position."""
if self.keep_dirty:
self.set_dirty()
def draw(self, screen):
self.dirty = False
if self.visible:
if self.background:
screen.blit(self.background, self.rect_absolute)
return self.rect_absolute
def set_image(self, image):
self.background = image
def get_image(self):
return self.background
def set_rect_in_container(self, rect):
# Rect del widget (relativo al container)
self.rect_in_container = rect
# Rect del widget (absoluto al screen)
self.rect_absolute = pygame.Rect((self.container.left + self.rect_in_container.left, self.container.top + self.rect_in_container.top), (self.rect_in_container.size))
def set_rect_size(self, size):
# Rect del widget (relativo al container)
self.rect_in_container.size = size
# Rect del widget (absoluto al screen)
self.rect_absolute.size = size
def set_click_sound_path(self, path):
self.click_sound_path = path
def set_tooltip(self, text):
self.tooltip = text
def set_super_tooltip(self, text):
self.super_tooltip = text
def handle_mouse_down(self, (x, y)):
self.on_mouse_click()
def on_mouse_click(self):
if self.click_sound_path:
sound = pygame.mixer.Sound(self.click_sound_path)
sound.play()
def on_mouse_over(self):
self.over = True
def on_mouse_out(self):
self.over = False
def set_dirty(self):
self.dirty = True
if self.parent:
self.parent.set_dirty()
def get_background_and_owner(self):
if self.background:
return (self.background, self)
elif self.parent:
return self.parent.get_background_and_owner()
else:
return (None, None)
def get_background(self):
return self.get_background_and_owner()[0]
def get_background_rect(self):
background, owner = self.get_background_and_owner()
if background:
if self is owner:
return background.copy()
else:
parents_relative_pos = self.rect_absolute.x - owner.rect.x, self.rect_absolute.y - owner.rect.y
rect = pygame.Rect(parents_relative_pos, self.rect_absolute.size)
return background.subsurface(rect)
return pygame.Surface(self.rect_absolute.size)
def contains_point(self, x, y):
return self.rect_absolute.collidepoint(x, y)
|