diff options
Diffstat (limited to 'Saludame.activity/gui/window.py')
-rwxr-xr-x | Saludame.activity/gui/window.py | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/Saludame.activity/gui/window.py b/Saludame.activity/gui/window.py new file mode 100755 index 0000000..1c725c4 --- /dev/null +++ b/Saludame.activity/gui/window.py @@ -0,0 +1,188 @@ +# -*- 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] + |