Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/pilas/actores/menu.py
blob: d488118eed403c97386568d2b8fc6a8fb735c78a (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
# -*- encoding: utf-8 -*-
# Pilas engine - A video game framework.
#
# Copyright 2010 - Hugo Ruscitti
# License: LGPLv3 (see http://www.gnu.org/licenses/lgpl.html)
#
# Website - http://www.pilas-engine.com.ar

from pilas.actores import Actor
from pilas.grupo import Grupo
import pilas

DEMORA = 14

class Menu(Actor):
    "Representa un bloque que tiene fisica como una caja."

    def __init__(self, opciones, x=0, y=0):
        self.opciones_como_actores = []
        self.demora_al_responder = 0
        Actor.__init__(self, "invisible.png", x=x, y=y)
        self._verificar_opciones(opciones)
        self.crear_texto_de_las_opciones(opciones)
        self.opciones = opciones
        self.seleccionar_primer_opcion()
        self.opcion_actual = 0
        # contador para evitar la repeticion de teclas
        self.activar()

    def activar(self):
        pilas.eventos.mueve_mouse.conectar(self.cuando_mueve_el_mouse)
        pilas.eventos.click_de_mouse.conectar(self.cuando_hace_click_con_el_mouse)

    def desactivar(self):
        pilas.eventos.mueve_mouse.desconectar(self.cuando_mueve_el_mouse)
        pilas.eventos.click_de_mouse.desconectar(self.cuando_hace_click_con_el_mouse)

    def crear_texto_de_las_opciones(self, opciones):
        "Genera un actor por cada opcion del menu."

        for indice, (texto, funcion) in enumerate(opciones):
            y = self.y - indice * 50
            opciones = pilas.actores.Opcion(texto, x=0, y=y, funcion_a_invocar=funcion)

            self.opciones_como_actores.append(opciones)

    def seleccionar_primer_opcion(self):
        if self.opciones_como_actores:
            self.opciones_como_actores[0].resaltar()

    def _verificar_opciones(self, opciones):
        "Se asegura de que la lista este bien definida."

        for x in opciones:
            if not isinstance(x, tuple) or len(x) != 2:
                raise Exception("Opciones incorrectas, cada opcion tiene que ser una tupla.")

    def actualizar(self):
        "Se ejecuta de manera periodica."

        if self.demora_al_responder < 0:
            if pilas.mundo.control.boton:
                self.seleccionar_opcion_actual()
                self.demora_al_responder = DEMORA

            if pilas.mundo.control.abajo:
                self.mover_cursor(1)
                self.demora_al_responder = DEMORA
            elif pilas.mundo.control.arriba:
                self.mover_cursor(-1)
                self.demora_al_responder = DEMORA

        self.demora_al_responder -= 1

    def seleccionar_opcion_actual(self):
        opcion = self.opciones_como_actores[self.opcion_actual]
        opcion.seleccionar()

    def mover_cursor(self, delta):
        # Deja como no-seleccionada la opcion actual.
        self._deshabilitar_opcion_actual()
        
        # Se asegura que las opciones esten entre 0 y 'cantidad de opciones'.
        self.opcion_actual += delta
        self.opcion_actual %= len(self.opciones_como_actores)

        # Selecciona la opcion nueva.
        self.opciones_como_actores[self.opcion_actual].resaltar()
    
    def __setattr__(self, atributo, valor):
        # Intenta propagar la accion a los actores del grupo.
        try:
            for x in self.opciones_como_actores:
                setattr(x, atributo, valor)
        except AttributeError:
            pass

        Actor.__setattr__(self, atributo, valor)

    def cuando_mueve_el_mouse(self, evento):
        "Permite cambiar la opcion actual moviendo el mouse. Retorna True si el mouse esta sobre alguna opcion."
        for indice, opcion in enumerate(self.opciones_como_actores):
            if opcion.colisiona_con_un_punto(evento.x, evento.y):
                if indice != self.opcion_actual:
                    self._deshabilitar_opcion_actual()
                    self.opcion_actual = indice
                    self.opciones_como_actores[indice].resaltar()
                return True
                    
    def _deshabilitar_opcion_actual(self):
        self.opciones_como_actores[self.opcion_actual].resaltar(False)

    def cuando_hace_click_con_el_mouse(self, evento):
        if self.cuando_mueve_el_mouse(evento):
            self.seleccionar_opcion_actual()