Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Saludame.activity/gui/window.py
blob: b130dde4cabfd0dc240dd2e3312b29d562f741c1 (plain)
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# -*- coding: utf-8 -*-

import pygame

class Window:
    
    # Una ventana contiene 'n' widgets
    
    def __init__(self, container, rect, frame_rate, windows_controller, register_id, bg_color=None):
        self.container = container
        self.rect = pygame.Rect(container.left + rect.left, container.top + rect.top, rect.width, rect.height)
        self.frame_rate = frame_rate
        self.background = pygame.Surface(rect.size)
        self.bg_color = bg_color
        self.bg_image = None
        self.windows_controller = windows_controller
        self.parent = None
        
        # Register
        self.register_id = register_id
        self.windows_controller.register_new_window(register_id, self)
        
        self.widgets = [] # Lista de widgets que contiene la ventana
        self.windows = [] # Lista de ventanas que contiene la ventana
        self.buttons = [] # Lista de botones que contiene la ventana
        
        self.repaint = True
        
    def get_register_id(self):
        return self.register_id
    
    def set_bg_image(self, image):
        if not isinstance(image, pygame.Surface):
            # Is a path, convert it to a surface
            self.bg_image = pygame.image.load(image).convert_alpha()
        else:
            self.bg_image = image
        
    def set_bg_color(self, color):
        self.bg_color = color
        
    def dispose(self):
        self.windows_controller.unregister_window(self)
    
    # Abstract function.
    def pre_draw(self, screen):
        return []
    
    # Logica de pintado de cualquier ventana
    def draw(self, screen, frames):
        
        changes = []
        
        changes += self.pre_draw(screen)
        
        if self.repaint:    # Solo actualizamos el fondo de la ventana cuando hagamos un 'repaint'
                            # De otra forma solo actualizamos los widgets y subventanas
            
            if self.bg_image != None:
                screen.blit(self.bg_image, self.rect) # Pintamos el "fondo" de la ventana
            else:
                if self.bg_color:
                    screen.fill(self.bg_color, self.rect)
            
            changes.append(self.rect)
            
            self.repaint = False
        
        for win in self.windows:
            if frames % win.frame_rate == 0:
                changes.extend(win.draw(screen, frames)) # Le decimos a cada ventana que se pinte
        
        for widget in self.widgets:
            if frames % widget.frame_rate == 0:
                changes.append(widget.draw(screen)) # Pintamos los widgets que "contiene" la ventana
        
        return changes
    
    def add_child(self, widget):
        self.widgets.append(widget)
        widget.parent = self
        
    def remove_child(self, widget):
        if widget in self.widgets:
            self.widgets.remove(widget)
        
    def add_button(self, button):
        self.add_child(button)
        self.buttons.append(button)
        button.parent = self
        
    def remove_button(self, button):
        if button in self.buttons:
            self.buttons.remove(button)
            self.remove_child(button)
            button.parent = None
    
    def add_window(self, window):
        self.windows.append(window)
        window.parent = self
        
    def remove_window(self, window):
        self.windows.remove(window)
                
    def enable_repaint(self):
        self.repaint = True
        for win in self.windows:
            win.enable_repaint()
    
    def handle_mouse_down(self, (x, y)):
        for button in self.buttons:
            if button.contains_point(x, y):
                # Tooltips
                if button.showing_tooltip:
                    self.windows_controller.hide_active_tooltip()
                    button.showing_tooltip = False
                button.on_mouse_click()
                return # No seguimos buscando el botón
        
        for win in self.windows:
            if win.rect.collidepoint(x, y):
                win.handle_mouse_down((x, y))
    
    def handle_mouse_over(self, (x, y)):
        
        buttons = []
        buttons += self.buttons
        for win in self.windows:
            buttons += win.buttons
       
        for button in buttons:
            if button.contains_point(x, y):
                if not button.over:
                    # Tooltips
                    if button.tooltip: # Si el boton tiene tooltip entonces lo mostramos
                        self.windows_controller.hide_active_tooltip()
                        self.windows_controller.show_tooltip(button.tooltip)
                        button.showing_tooltip = True
                    if button.super_tooltip:
                        self.windows_controller.hide_active_tooltip()
                        self.windows_controller.show_super_tooltip(button.super_tooltip)
                        button.showing_tooltip = True
                    button.on_mouse_over()
                    button.over = True
                    return # No seguimos buscando el botón
            else:
                # Ineficiente! Por ahora lo dejo asi para PROBAR
                # Esta todo el tiempo haciendo esto! Cambiar
                if button.showing_tooltip:
                    # Si estabamos mostrando el tooltip ahora debemos esconderlo
                    self.windows_controller.hide_active_tooltip()
                    button.showing_tooltip = False
                button.over = False
                button.on_mouse_out()
    
    # It will be overridden by cooking challenge or other D&D challenge
    def handle_mouse_motion(self, (x, y)):
        pass

    # It will be overridden by cooking challenge or other D&D challenge
    def handle_mouse_up(self, pos):
        pass
    
    def move(self, (x, y)):
        """ Moves the window the given offset, notifying all its subitems """
        self.rect.move_ip(x, y)
        for win in self.windows:
            win.move(x, y, self.rect)
        
        # Buttons are usually in widget list, so they are not moved
        for widget in self.widgets:
            if not (self.rect is widget.container):
                widget.container.move_ip(x, y)
            widget.rect_absolute.move_ip(x, y)
       
    def get_background_and_owner(self):
        if self.bg_image:
            return (self.bg_image, self)
        elif self.bg_color:
            return (self.bg_color, 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]