diff options
Diffstat (limited to 'BiblioJAM/JAMEntryText.py')
-rw-r--r-- | BiblioJAM/JAMEntryText.py | 512 |
1 files changed, 512 insertions, 0 deletions
diff --git a/BiblioJAM/JAMEntryText.py b/BiblioJAM/JAMEntryText.py new file mode 100644 index 0000000..47dc2da --- /dev/null +++ b/BiblioJAM/JAMEntryText.py @@ -0,0 +1,512 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# BiblioJAM (Versión 2.0) - 18/04/2011 - CeibalJAM! - Uruguay +# JAMEntryText.py por: Flavio Danesse fdanesse@gmail.com +# https://sites.google.com/site/flaviodanesse/ +# https://sites.google.com/site/sugaractivities/ +# http://codigosdeejemplo.blogspot.com/ + +import pygame, gc, sys +from pygame.locals import * +gc.enable() +pygame.font.init() + +import JAMGlobals as VG +from JAMLabel import JAMLabel + +class JAMEntryText(pygame.sprite.OrderedUpdates): + def __init__(self): + pygame.sprite.OrderedUpdates.__init__(self) + self.buffertext= "" + + # teclas + self.handlekey= None + + #self.sensitive= False + + self.texto= {"fondo":VG.get_blanco(), "tipo":pygame.font.get_default_font(), "tamanio": 20, "color":VG.get_negro()} + + self.separador= 5 + self.posicion= (0,0) + + self.label_buffer= None + self.label_promp = None + self.frame= pygame.sprite.Sprite() + + self.JAMObjects= {"base":self.frame, "etiqueta_buffer":self.label_buffer, "promp":self.label_promp, + "buffertext": self.buffertext, "handle_key":self.handlekey} + + self.Reconstruye_JAMEntryText(["todo"]) + + # ------------- GETS ------------------------ + def get_tamanio(self): + return (self.frame.rect.w, self.frame.rect.h) + + # ------------ SETEOS ----------------------- + #def set_mouse_sensitive(self, valor): + # self.sensitive= bool(valor) + + def set_handle_key(self, valor): + ''' Habilita y desabilita la detección de eventos de tecla. + Por defecto no lo hace ya que JAMEntryText está pensado como objeto parte de JAMBoardEntryText. ''' + if bool(valor) == True: + self.handlekey= JAMHandleKeyEvent(self) + else: + self.handlekey= None + + def set_callback_enter(self, callback=None): + ''' Setea una función para ejecutarse cuando el usuario presione enter. + La función debe recibir un string para el buffer de texto de JAMEntryText''' + if self.handlekey: + self.handlekey.callback_enter= callback + + def set_buffer(self, texto): + ''' Setea el buffer de texto de JAMEntryText. ''' + if texto != self.buffertext: + self.buffertext = texto + self.label_buffer.set_text(tipo=self.texto["tipo"], tamanio=self.texto["tamanio"], color=self.texto["color"], texto=self.buffertext) + self.Reconstruye_JAMEntryText(["buffer"]) + + def set_entry(self, tipo_letra=None, tamanio_letra=None, color_texto=None, color_fondo=None): + ''' Setea colores, tamaño y tipo de letra. ''' + cambios= False + if tipo_letra and tipo_letra != self.texto["tipo"]: + self.texto["tipo"]= tipo_letra + cambios= True + if tamanio_letra and tamanio_letra != self.texto["tamanio"]: + self.texto["tamanio"]= tamanio_letra + cambios= True + if color_texto and color_texto != self.texto["color"]: + self.texto["color"]= color_texto + cambios= True + if color_fondo and color_fondo != self.texto["fondo"]: + self.texto["fondo"]= color_fondo + cambios= True + if cambios: + if self.texto["tipo"] and self.texto["tamanio"] and self.texto["color"] and self.texto["fondo"]: + self.label_buffer.set_text(tipo=self.texto["tipo"], tamanio=self.texto["tamanio"], color=self.texto["color"], texto=self.buffertext) + self.Reconstruye_JAMEntryText(["colores"]) + + def set_posicion(self, punto=(0,0)): + ''' Setea la posición de JAMEntryText. ''' + self.posicion= punto + self.frame.rect.x, self.frame.rect.y= self.posicion + x, y= (self.frame.rect.x + self.separador, self.frame.rect.y + self.separador) + self.label_buffer.set_posicion(punto=(x, y)) + x+= self.label_buffer.rect.w + self.label_promp.set_posicion(punto=(x, y)) + + def set_center(self, punto= None): + ''' Centra JAMEntryText en el punto indicado. ''' + w,h= (0,0) + if not punto or type(punto) != tuple or type(punto[0]) != int or type(punto[1]) != int: + w,h= (pygame.display.Info().current_w, pygame.display.Info().current_h) + posicion= (w/2-self.frame.rect.w/2, h/2-self.frame.rect.h/2) + self.set_posicion(punto=posicion) + elif type(punto) == tuple and type(punto[0]) == int and type(punto[1]) == int: + posicion= (punto[0]-self.frame.rect.w/2, punto[1]-self.frame.rect.h/2) + self.set_posicion(punto=posicion) + + # ------------ CONSTRUCCIÓN ----------------------- + def Reconstruye_JAMEntryText(self, cambios): + if "todo" in cambios: + self.label_buffer= JAMLabel(self.buffertext) + self.label_promp = Promp(self) + self.frame.image= self.get_base() + self.frame.rect= self.frame.image.get_rect() + self.add(self.frame) + self.add(self.label_buffer) + self.add(self.label_promp) + self.set_posicion(punto=self.posicion) + + if "colores" in cambios: + self.label_promp.Reconstruye_Promp(["todo"]) + self.frame.image= self.get_base() + self.frame.rect= self.frame.image.get_rect() + self.set_posicion(punto=self.posicion) + + if "buffer" in cambios: + self.frame.image= self.get_base() + self.frame.rect= self.frame.image.get_rect() + self.set_posicion(punto=self.posicion) + + def get_base(self): + ''' Construye el sprite base. ''' + (a,b,c,d)= self.label_buffer.rect + (aa,bb,cc,dd)= self.label_promp.rect + + ancho= c + cc + self.separador*2 + alto= 0 + if d > dd: + alto= d + else: + alto= dd + alto+= self.separador*2 + + frame1= VG.get_Rectangulo(self.texto["fondo"], (ancho,alto)) + return frame1 + + def Describe(self): + ''' Describe la Estructura de Este Control. ''' + estructura = ''' + Estructura JAMEntryText: + + JAMObject: + frame + etiqueta_buffer + promp + buffertext + handle_key + + Detalle Estructural: + frame: es una imagen construida en tiempo de ejecución sobre la cual se pegan las imágenes de las etiquetas + etiqueta_buffer: JAMLabel con el texto que el usuario va escribiendo + promp: Imagen que representa al promp con su efecto intermitente + buffertext: El texto que el usuario va ingresando + handle_key: Detector de eventos de teclado ''' + + print estructura, "\n" + print "Ejemplo, Configuración actual:\n" + print "\t", self.JAMObjects.keys(), "\n" + for k in self.JAMObjects.items(): + print k, "\n" + +class Promp(pygame.sprite.Sprite): + def __init__(self, entry): + pygame.sprite.Sprite.__init__(self) + ''' Es el promp. ''' + self.entry= entry + self.velocidad= 15 + self.contador= 0 + self.image= None + self.rect= None + self.imagen1= None + self.imagen2= None + + self.Reconstruye_Promp(["todo"]) + + def Reconstruye_Promp(self, cambios): + ''' Reconstruye las imágenes para efecto Titilar. ''' + if "todo" in cambios: + self.set_imagenes_promp() + self.image= self.imagen1 + self.rect= self.image.get_rect() + + def set_posicion(self, punto=(0,0)): + ''' Reposiciona el sprite. ''' + self.rect.x= punto[0] + self.rect.y= punto[1] + + def set_imagenes_promp(self): + ''' Construye las imagenes del promp. ''' + self.imagen1= self.get_promp(self.entry.texto["color"]) + self.imagen2= self.get_promp(self.entry.texto["fondo"]) + + def get_promp(self, color): + ''' Devuelve una Superficie con la Imagen del Texto. ''' + fuente = pygame.font.Font(pygame.font.match_font(self.entry.texto["tipo"], True, False), self.entry.texto["tamanio"]) + string_to_render = unicode( str("|".decode("utf-8")) ) + imagen_fuente = fuente.render(string_to_render, 1, (color)) + return imagen_fuente + + def update(self): + ''' Efecto Titilar. ''' + if self.entry.handlekey: + if self.contador == self.velocidad: + if self.image == self.imagen1: + self.image= self.imagen2 + else: + self.image= self.imagen1 + self.contador= 0 + else: + self.contador += 1 + else: + if self.image == self.imagen1: + self.image = self.imagen2 + + # teclas + if self.entry.handlekey: self.entry.handlekey.handle() + +class JAMHandleKeyEvent(): + def __init__(self, objeto_destino): + ''' Detecta eventos de teclado.''' + self.letras= VG.get_letras_down() + self.numeros= VG.get_numeros() + + self.objeto_destino= objeto_destino + self.text_buffer= [] + self.callback_enter= None + + def handle(self): + ''' Trata los eventos del teclado. ''' + eventos= pygame.event.get() + for event in eventos: + if event.type == pygame.KEYDOWN: + letra= pygame.key.name(event.key) + self.gestiona_event(letra) + + for event in eventos: + # Republica los Eventos. Porque se supone que hay un handle general para los eventos del programa mayor. + pygame.event.post(event) + + def gestiona_event(self, texto): + ''' Cuando el usuario presiona una espacio, borrar, enter o tilde. ''' + if texto in self.letras: + self.text_buffer.append( texto ) + return self.set_bufferentry() + + elif texto in self.numeros: + self.text_buffer.append( texto ) + return self.set_bufferentry() + + elif texto== "space": + # agrega un espacio en el buffer + self.text_buffer.append( " " ) + return self.set_bufferentry() + + elif texto== "backspace": + # Borra el último caracter ingresado + if len(self.text_buffer) <= 1: + self.text_buffer= [ " " ] + else: + self.text_buffer= self.text_buffer[0:-1] + return self.set_bufferentry() + + elif texto== "return": + # Llama a la función conectada al click del botón enter, pasandole como parámetro el texto en el buffer + if self.callback_enter: + buf= "" + try: + primercaracter= self.text_buffer[0] + if primercaracter != " ": + buf= primercaracter + else: + buf= "" + + for x in self.text_buffer[1:]: + buf += x + except: + return + if buf: + return self.callback_enter(buf) + + def set_bufferentry(self): + ''' Convierte el buffer en cadena de texto y lo devuelve a la función set_buffer del objeto destino. ''' + buf= "" + for x in self.text_buffer: + buf += x + self.objeto_destino.set_buffer(buf) + +''' +# Ejemplos para tratar los códigos de teclas posteriormente + def handle_key_enter(self): + for event in pygame.event.get(): + if event.type == pygame.KEYDOWN: + letra= pygame.key.name(event.key) + print letra + +teclas = pygame.key.get_pressed() + print teclas.index(1) + +All the keyboard event.key constants: + +Letters: + K_a ... K_z + +Numbers: + K_0 ... K_9 + +Control: + K_TAB + K_RETURN + K_ESCAPE + K_SCROLLOCK + K_SYSREQ + K_BREAK + K_DELETE + K_BACKSPACE + K_CAPSLOCK + K_CLEAR + K_NUMLOCK + +Punctuation: + K_SPACE + K_PERIOD + K_COMMA + K_QUESTION + K_AMPERSAND + K_ASTERISK + K_AT + K_CARET + K_BACKQUOTE + K_DOLLAR + K_EQUALS + K_EURO + K_EXCLAIM + K_SLASH, K_BACKSLASH + K_COLON, K_SEMICOLON + K_QUOTE, K_QUOTEDBL + K_MINUS, K_PLUS + K_GREATER, K_LESS + +Brackets: + K_RIGHTBRACKET, K_LEFTBRACKET + K_RIGHTPAREN, K_LEFTPAREN + +F-Keys: + K_F1 ... K_F15 + +Edit keys: + K_HELP + K_HOME + K_END + K_INSERT + K_PRINT + K_PAGEUP, K_PAGEDOWN + K_FIRST, K_LAST + +Keypad: + K_KP0 ... K_KP9 + K_KP_DIVIDE + K_KP_ENTER + K_KP_EQUALS + K_KP_MINUS + K_KP_MULTIPLY + K_KP_PERIOD + K_KP_PLUS + +SHF,CTL,ALT etc: + K_LALT, K_RALT + K_LCTRL, K_RCTRL + K_LSUPER, K_RSUPER + K_LSHIFT, K_RSHIFT + K_RMETA, K_LMETA + +Arrows: + K_LEFT + K_UP + K_RIGHT + K_DOWN + +Other: + K_MENU + K_MODE + K_PAUSE + K_POWER + K_UNDERSCORE + K_HASH + + K_UNKNOWN ''' + +# ----- FIN DE CLASE JAMEntryText - INICIO DE DEBUG Y EJEMPLO DE LA CLASE ----- +class Ejemplo(object): + def __init__(self): + self.ventana = None + self.reloj = None + self.nivel = "menu_0" + + self.fondo = None + self.widgets = None + + self.resolucion = (400,250) + + self.setup() + self.Run() + + def setup(self): + pygame.init() + pygame.display.set_mode(self.resolucion , 0, 0) + pygame.display.set_caption("Ejemplo") + + self.fondo = self.get_Fondo() + + self.widgets = JAMEntryText() + self.widgets.set_handle_key(True) + #self.widgets.set_mouse_sensitive(True) + self.widgets.set_callback_enter(self.print_buffer) + + self.ventana = pygame.display.get_surface() + self.reloj = pygame.time.Clock() + + pygame.event.set_blocked([JOYAXISMOTION, JOYBALLMOTION, JOYHATMOTION, JOYBUTTONUP, JOYBUTTONDOWN, + USEREVENT, QUIT, ACTIVEEVENT]) + pygame.event.set_allowed([MOUSEMOTION, MOUSEBUTTONUP, MOUSEBUTTONDOWN, KEYDOWN, KEYUP, VIDEORESIZE, VIDEOEXPOSE]) + pygame.mouse.set_visible(True) + + def Run(self): + self.ventana.blit(self.fondo, (0,0)) + self.widgets.draw(self.ventana) + pygame.display.update() + contador = 0 + while self.nivel == "menu_0": + self.reloj.tick(35) + + cambios=[] + self.widgets.clear(self.ventana, self.fondo) + if contador == 15: + # Activa la siguiente línea para provocar cambios de texto en JAMEntryText + #contador= self.ejemplo_cambia_texto_en_buffer() + # Activa la siguiente línea para provocar cambios de color en JAMEntryText + #contador= self.ejemplo_cambia_colors() + # Activa la siguiente línea para provocar cambios de Posición en JAMEntryText + #contador= self.ejemplo_cambia_posicion() + pass + + self.widgets.update() + self.handle_event() + pygame.event.clear() + cambios.extend ( self.widgets.draw(self.ventana) ) + pygame.display.update(cambios) + contador += 1 + + def ejemplo_cambia_posicion(self): + import random + valores= [100,205,130,140,150,180] + x, y= (random.choice(valores), random.choice(valores)) + self.widgets.set_center(punto= (x,y)) + return 0 + + def ejemplo_cambia_texto_en_buffer(self): + texto= "El usuario ingresa texto y el mismo aparece aqui . . ." + x= len(self.widgets.buffertext) + if len(texto) > x: + self.widgets.set_buffer(str(texto[0:x+1])) + else: + self.widgets.set_buffer("") + return 0 + + def ejemplo_cambia_colors(self): + import random + colores= [(128,128,128,255), (255,100,100,255), (255,255,100,255), (255,0,0,255)] + color=random.choice(colores) + self.widgets.set_entry(tipo_letra=None, tamanio_letra=None, color_texto=color, color_fondo=None) + return 0 + + def get_Fondo(self): + superficie = pygame.Surface( self.resolucion, flags=HWSURFACE ) + superficie.fill((128,128,128,255)) + return superficie + + def handle_event(self): + for event in pygame.event.get(): + if event.type == pygame.KEYDOWN: + teclas = pygame.key.get_pressed() + if teclas[pygame.K_ESCAPE]: + self.salir() + pygame.event.clear() + + def print_buffer(self, buffertext): + print self.widgets.buffertext + print buffertext + + def salir(self): + print "\n" + self.widgets.Describe() + pygame.quit() + sys.exit() + + + +if __name__ == "__main__": + Ejemplo() |