Menus LCD TFT

Dependents:   Example_Menu_LCD_TFT

Revision:
0:310ed2337a8f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Menus.h	Tue Mar 15 23:23:51 2011 +0000
@@ -0,0 +1,516 @@
+/*
+   \file Menus.h
+   \version: 1.0
+   
+   \brief Este fichero contiene funciones para creación de Menus es LCD TFT.- 
+   
+   \web www.micros-designs.com.ar
+   \date 15/03/11
+   
+ *- Version Log --------------------------------------------------------------*
+ *   Fecha       Autor                Comentarios                             *
+ *----------------------------------------------------------------------------*
+ * 15/03/11      Suky        Original                                         *
+ *----------------------------------------------------------------------------*/ 
+///////////////////////////////////////////////////////////////////////////
+////                                                                   ////
+////                                                                   ////
+////        (C) Copyright 2011 www.micros-designs.com.ar               ////
+//// Este código puede ser usado, modificado y distribuido libremente  ////
+//// sin eliminar esta cabecera y  sin garantía de ningún tipo.        ////
+////                                                                   ////
+////                                                                   ////
+/////////////////////////////////////////////////////////////////////////// 
+#ifndef __MENUS_H__
+#define __MENUS_H__
+
+#include "mbed.h"
+#include "LCDTFT.h"
+#include "Touch.h"
+#include "GenericTypeDefs.h"
+#include "Images.h"
+
+// ****************************************************************************************
+#define TOUCH_X_MIN 20
+#define TOUCH_X_MAX 230
+#define TOUCH_Y_MIN 15
+#define TOUCH_Y_MAX 240
+// ****************************************************************************************
+#define MENU_FIN                0
+#define MENU_COMANDO            1
+#define MENU_SUBMENU            2
+#define SUBMENU_ANTERIOR        3
+#define MENU_MAIN               4
+// ****************************************************************************************
+#define MENSAJE_ATRAS_OK        1
+#define MENSAJE_NO_SI           2
+#define MENSAJE_ATRAS           3
+
+#define MENSAJE_ACCION_ATRAS    1
+#define MENSAJE_ACCION_OK       2
+#define MENSAJE_ACCION_NO       3
+#define MENSAJE_ACCION_SI       4
+
+#define MODIFICADOR_ACEPTAR     1
+#define MODIFICADOR_CANCELAR    2
+// ****************************************************************************************
+#define IMAGEN_FONDO_MENU       10
+// ****************************************************************************************
+#define BOTON_NORMAL            1
+#define BOTON_PRES_IZQ          2
+#define BOTON_PRES_DER          3
+#define ITEM_NORMAL             4
+#define ITEM_PRES               5
+// ****************************************************************************************
+#define COLOR_LETRA_BOTON       ColorAqua
+#define COLOR_LETRA_BOTON_PRES  ColorWhite
+#define COLOR_FONDO_LETRA       ColorGray
+#define COLOR_MSJ               ColorWhite
+// ****************************************************************************************
+#define JUST_IZQ                1
+#define JUST_DER                2
+#define JUST_CENTRADO           3
+// ****************************************************************************************
+#define AREA_BTN_INF_DER()       (Coordenadas.x<235 && Coordenadas.x>135) && (Coordenadas.y<320 && Coordenadas.y>290)
+#define AREA_BTN_INF_IZQ()       (Coordenadas.x<105 && Coordenadas.x>5) && (Coordenadas.y<320 && Coordenadas.y>290)
+// ****************************************************************************************
+TouchScreenADS7843 MyTouch(p9,p10,p12,p11,p8); // ADS7843-> SDO,SDI,SCK,CS,IRQ
+BusOut    MyBus(p13,p14,p15,p16,p17,p18,p19,p20,p30,p29,p28,p27,p26,p25,p24,p23);
+LCDTFT    MyLCD(p5,p6,p7,p22,p21,&MyBus);
+// ****************************************************************************************
+typedef struct{
+    UINT8 TipoMenu;
+    const UINT8 *TextoMenu;
+    UINT8 *Menu;
+    void (*PtrFuncionSeleccion)(void);
+    const UINT16 *PtrIcono;
+}MENU;
+// ****************************************************************************************
+struct{
+    const MENU *PtrMenu;
+    UINT8 ElementoSeleccionActual; 
+    void (*FuncionActualEjecucion)(void);
+    UINT8 CantElementosMenu;
+}MenuActual;
+// ****************************************************************************************
+struct{
+    float ValorInicial;
+    float ValorActual;
+    UINT8 String[15];
+    UINT8 Ptr;
+    void (*FuncionActualEjecucion)(UINT8,float);
+}ModificadorVariable;
+// ****************************************************************************************
+struct{
+    UINT8 TipoMensajePantalla;
+    void (*MensajeFuncionEjecutar)(UINT8);
+}MensajePantalla;
+// ****************************************************************************************
+TOUCH_DATA Coordenadas;
+volatile bool kbhit_irq=0;
+volatile bool kbhit_tratament=0;
+// ****************************************************************************************
+void vSeteoFuncionEjecutar(void (*PtrNuevaFuncion)(void));
+void vEjecutaEventosMenu(void);
+void vSeleccionarMenuAnterior(void);
+void vSeleccionMenu(const MENU *Menu,UINT8 ElementoMenuSeleccion);
+void vEventosSubMenu(void);
+void vDibujarImagenFondo(UINT8 Seleccion);
+void vDibujarMenuInferior(const UINT8 *TextoIzq,const UINT8 *TextoDer, UINT8 Status);
+void vDibujarElementoMenu(UINT8 NElemento,UINT8 Status);
+void vMensajePantalla(const UINT8 *Mensaje,UINT16 YInicial,UINT8 TipoMensaje,void (*FuncionEjecutar)(UINT8));
+void vEventosPantallaMensaje(void);
+void vModificadorVariables(const UINT8 *NombreVariable,float ValorInicial,void (*PtrFuncion)(UINT8,float));
+void vEventosModificadorVariables(void);
+void vTextoJustificado(const unsigned char *PtrTexto,unsigned short ExtremoIzq, unsigned short ExtremoDer, unsigned short y, unsigned char Just,const char (*Fuente)[5],unsigned char Alto, unsigned short Color);
+void vEscribirMensaje(unsigned short YInicial,const unsigned char *Mensaje,const char (*Fuente)[5],unsigned char Just, unsigned short Color);
+// ****************************************************************************************
+// Rutina de atencion de interrupcion.-
+void vISRTouchIRQ(){
+    UINT_COORDxy Temp;
+    
+    
+    MyTouch.vTestTouchPanel(&Coordenadas);
+    // Coordenadas dentro del rango de pantalla LCD:
+    if((Coordenadas.x>TOUCH_X_MIN && Coordenadas.x<TOUCH_X_MAX) && (Coordenadas.y>TOUCH_Y_MIN && Coordenadas.y<TOUCH_Y_MAX)){
+        if(kbhit_tratament==0){            
+            // Cambio de coordenda y escala:
+            Temp=Coordenadas.y;
+            Coordenadas.y=((float)((255.0-TOUCH_X_MIN)-Coordenadas.x)*(320.0/(TOUCH_X_MAX-TOUCH_X_MIN)));
+            Coordenadas.x=((float)(Temp-TOUCH_Y_MIN)*(240.0/(TOUCH_Y_MAX-TOUCH_Y_MIN)));
+            kbhit_irq=1;
+        }
+    }    
+}
+// ****************************************************************************************
+void vInitLCDTFTAndTouch(void){
+    MyTouch.vInitADS7843(USE_8BITS,&vISRTouchIRQ);
+    MyLCD.vLCDTFTInit();
+    Led1=0;
+    Led2=0;
+}
+// ****************************************************************************************
+// ****************************************************************************************
+/* ** Se carga en puntero la funcion que se ejecutara dentro del while ** */
+void vSeteamosFuncionEjecutar(void (*PtrNuevaFuncion)(void)){    
+    MenuActual.FuncionActualEjecucion = PtrNuevaFuncion;
+}
+/* ** Ejecuta funcion que se encuentra apuntada ** */
+void vEjecutaEventosMenu(void){
+    (*MenuActual.FuncionActualEjecucion)();
+}
+/* ** Selecciona Menu anterior a mostrar despues de un comando ** */
+void vSeleccionarMenuAnterior(void){
+    vSeleccionMenu(MenuActual.PtrMenu,MenuActual.ElementoSeleccionActual);
+}
+    
+/* ** Selecciona y dibuja un submenu, luego carga en puntero funcion que atiende sus eventos ** */
+void vSeleccionMenu(const MENU *Menu,UINT8 ElementoMenuSeleccion){
+UINT8 NElemento;
+
+    /* ** Guardamos el Menu actual que se visualiza y trabaja ** */
+    MenuActual.PtrMenu=Menu;
+    MenuActual.ElementoSeleccionActual=ElementoMenuSeleccion;
+
+    /* ** Borramos pantalla y dibujamos elementos del menu** */
+    vDibujarImagenFondo(IMAGEN_FONDO_MENU);
+    
+    /* ** Dibujamos barra con titulo ** */
+    MyLCD.vLCDTFTDrawImage(0,0,WIDTH_TITULO,HEIGH_TITULO,LENGTH_TITULO,&Titulo[0]);
+    vTextoJustificado(MenuActual.PtrMenu[0].TextoMenu,5,234,4,JUST_CENTRADO,&ARIAL[0],2,ColorAzulMarino);
+    /* ** Dibujamos Items ** */
+    NElemento=1;
+    while(MenuActual.PtrMenu[NElemento].TipoMenu!=MENU_FIN){    
+        vDibujarElementoMenu(NElemento-1,ITEM_NORMAL);
+        NElemento++;
+    }
+    MenuActual.CantElementosMenu=NElemento-1;
+    
+    if(MenuActual.PtrMenu[0].TipoMenu==MENU_MAIN){
+        vDibujarMenuInferior(" ","Menu",BOTON_NORMAL);
+    }else{
+        vDibujarMenuInferior("Atras"," ",BOTON_NORMAL);
+    }
+    /* ** Cargamos en puntero funci&#65533;n que atiende eventos del Submenu (Funci&#65533;n en while del main)** */
+    vSeteamosFuncionEjecutar(vEventosSubMenu);
+}
+
+void vDibujarImagenFondo(UINT8 Seleccion){
+
+    switch(Seleccion){
+        case IMAGEN_FONDO_MENU:
+            for(short k=0;k<320;k+=10){
+                MyLCD.vLCDTFTDrawImage(0,k,WIDTH_FONDO,HEIGH_FONDO,LENGTH_FONDO,&Fondo[0]);
+            }
+        break;
+    }
+}
+/* ** Dibuja barra inferior de botones ** */ 
+void vDibujarMenuInferior(const UINT8 *TextoIzq,const UINT8 *TextoDer, UINT8 Status){
+
+    
+    switch(Status){
+        case BOTON_PRES_IZQ:
+            vTextoJustificado(TextoIzq,5,105,296,JUST_CENTRADO,&ARIAL[0],2,COLOR_LETRA_BOTON_PRES);
+        break;
+        case BOTON_PRES_DER:
+            vTextoJustificado(TextoDer,135,234,296,JUST_CENTRADO,&ARIAL[0],2,COLOR_LETRA_BOTON_PRES);
+        break;
+        case BOTON_NORMAL:
+            MyLCD.vLCDTFTDrawImage(0,289,WIDTH_BOTONES,HEIGH_BOTONES,LENGTH_BOTONES,&Botones[0]);
+            vTextoJustificado(TextoIzq,5,105,296,JUST_CENTRADO,&ARIAL[0],2,COLOR_LETRA_BOTON);
+            vTextoJustificado(TextoDer,135,234,296,JUST_CENTRADO,&ARIAL[0],2,COLOR_LETRA_BOTON);
+        break;
+    }
+}
+/* ** Dibuja elementos del submenu ** */
+void vDibujarElementoMenu(UINT8 NElemento,UINT8 Status){
+
+    if(Status==ITEM_NORMAL){
+        if((NElemento%2)==0){
+            MyLCD.vLCDTFTDrawImage(35,28+((((NElemento+2)/2)-1)*65),WIDTH_ICONO,HEIGH_ICONO,LENGTH_ICONO,MenuActual.PtrMenu[NElemento+1].PtrIcono);
+            MyLCD.vLCDTFTRectangle(5,81+((((NElemento+2)/2)-1)*65),114,90+((((NElemento+2)/2)-1)*65),1,COLOR_FONDO_LETRA);
+            vTextoJustificado(MenuActual.PtrMenu[NElemento+1].TextoMenu,5,114,82+((((NElemento+2)/2)-1)*65),JUST_CENTRADO,&ARIAL[0],1,COLOR_LETRA_BOTON);
+        }else{
+            MyLCD.vLCDTFTDrawImage(155,28+((((NElemento+2)/2)-1)*65),WIDTH_ICONO,HEIGH_ICONO,LENGTH_ICONO,MenuActual.PtrMenu[NElemento+1].PtrIcono);  
+            MyLCD.vLCDTFTRectangle(125,81+((((NElemento+2)/2)-1)*65),234,90+((((NElemento+2)/2)-1)*65),1,COLOR_FONDO_LETRA);
+            vTextoJustificado(MenuActual.PtrMenu[NElemento+1].TextoMenu,125,234,82+((((NElemento+2)/2)-1)*65),JUST_CENTRADO,&ARIAL[0],1,COLOR_LETRA_BOTON);  
+        }
+    }else{
+        if((NElemento%2)==0){
+            vTextoJustificado(MenuActual.PtrMenu[NElemento+1].TextoMenu,5,114,82+((((NElemento+2)/2)-1)*65),JUST_CENTRADO,&ARIAL[0],1,COLOR_LETRA_BOTON_PRES);
+        }else{
+            vTextoJustificado(MenuActual.PtrMenu[NElemento+1].TextoMenu,125,234,82+((((NElemento+2)/2)-1)*65),JUST_CENTRADO,&ARIAL[0],1,COLOR_LETRA_BOTON_PRES);  
+        }
+    }
+}
+// ****************************************************************************************
+// ****************************************************************************************
+void vEventosSubMenu(void){
+    const MENU *SubMenu;
+    void (*PtrComando)(void);
+    
+    if(kbhit_irq==1){
+        kbhit_irq=0;
+        kbhit_tratament=1;
+        
+        if(MenuActual.PtrMenu[0].TipoMenu==MENU_MAIN){
+            if(AREA_BTN_INF_DER()){
+                vDibujarMenuInferior(" ","Menu",BOTON_PRES_DER);
+                wait_ms(300);
+                SubMenu=(MENU *)MenuActual.PtrMenu[0].Menu;
+                vSeleccionMenu(SubMenu,1);
+            }
+            kbhit_tratament=0;
+        }else{
+            for(char k=0;k<MenuActual.CantElementosMenu;k++){
+                if((k%2)==0){
+                    if((Coordenadas.x<85 && Coordenadas.x>35) && (Coordenadas.y<(78+((((k+2)/2)-1)*65)) && Coordenadas.y>(28+((((k+2)/2)-1)*65)))){
+                        vDibujarElementoMenu(k,ITEM_PRES);
+                        wait_ms(300);
+                        MenuActual.ElementoSeleccionActual=k+1;
+                        /* ** Abrimos otro submenu o ejecutamos comando ** */
+                        switch(MenuActual.PtrMenu[k+1].TipoMenu){
+                            case MENU_COMANDO:
+                                PtrComando=(void(*)(void))MenuActual.PtrMenu[k+1].PtrFuncionSeleccion;
+                                kbhit_tratament=0;
+                                if(PtrComando!=NULL) (*PtrComando)();
+                            break;
+                            case MENU_SUBMENU:
+                                SubMenu=(MENU *)MenuActual.PtrMenu[k+1].Menu;
+                                vSeleccionMenu(SubMenu,1);
+                            break;
+                        }
+                    }
+                }else{
+                    if((Coordenadas.x<205 && Coordenadas.x>155) && (Coordenadas.y<(78+((((k+2)/2)-1)*65)) && Coordenadas.y>(28+((((k+2)/2)-1)*65)))){
+                        vDibujarElementoMenu(k,ITEM_PRES);
+                        wait_ms(300);
+                        MenuActual.ElementoSeleccionActual=k+1;
+                        /* ** Abrimos otro submenu o ejecutamos comando ** */
+                        switch(MenuActual.PtrMenu[k+1].TipoMenu){
+                            case MENU_COMANDO:
+                                PtrComando=(void(*)(void))MenuActual.PtrMenu[k+1].PtrFuncionSeleccion;
+                                kbhit_tratament=0; 
+                                if(PtrComando!=NULL) (*PtrComando)();
+                            break;
+                            case MENU_SUBMENU:
+                                SubMenu=(MENU *)MenuActual.PtrMenu[k+1].Menu;
+                                vSeleccionMenu(SubMenu,1);
+                            break;
+                        }
+                    }
+                }                
+            }
+            
+            if(AREA_BTN_INF_IZQ()){
+                vDibujarMenuInferior("Atras"," ",BOTON_PRES_IZQ);
+                wait_ms(300);
+                SubMenu=(MENU *)MenuActual.PtrMenu[0].Menu;
+                vSeleccionMenu(SubMenu,1);
+            }
+            kbhit_tratament=0;        
+        }
+    }    
+} 
+// ********************************************************************************************************************************
+// ****************************************** MENSAJES EN PANTALLA ****************************************************************
+// ********************************************************************************************************************************
+/* ** Se escribe un mensaje en pantalla para elemento del tipo comando, presentando en barra inferior opcion a elegir ** */
+void vMensajePantalla(const UINT8 *Mensaje,UINT16 YInicial,UINT8 TipoMensaje,void (*FuncionEjecutar)(UINT8)){
+
+    MensajePantalla.MensajeFuncionEjecutar=FuncionEjecutar;
+    MensajePantalla.TipoMensajePantalla=TipoMensaje;
+
+    vDibujarImagenFondo(IMAGEN_FONDO_MENU);
+    MyLCD.vLCDTFTDrawImage(0,0,WIDTH_TITULO,HEIGH_TITULO,LENGTH_TITULO,&Titulo[0]);
+    vTextoJustificado(MenuActual.PtrMenu[MenuActual.ElementoSeleccionActual].TextoMenu,5,234,4,JUST_CENTRADO,&ARIAL[0],2,ColorAzulMarino);
+    
+    MyLCD.vLCDTFTRectangle(5,30,234,284,1,ColorGray);
+    MyLCD.vLCDTFTRectangle(5,30,234,31,1,ColorWhite);
+    MyLCD.vLCDTFTRectangle(5,283,234,284,1,ColorBlack);
+    MyLCD.vLCDTFTRectangle(5,30,6,284,1,ColorWhite);
+    MyLCD.vLCDTFTRectangle(233,30,234,284,1,ColorWhite);
+    
+    vEscribirMensaje(YInicial,Mensaje,&ARIAL[0],JUST_CENTRADO,COLOR_MSJ);
+
+    switch(TipoMensaje){
+        case MENSAJE_ATRAS_OK:
+            vDibujarMenuInferior("Atras", "Ok",BOTON_NORMAL);
+        break;        
+        case MENSAJE_NO_SI:
+            vDibujarMenuInferior("No", "Si",BOTON_NORMAL);
+        break;        
+        case MENSAJE_ATRAS:
+            vDibujarMenuInferior("Atras", " ",BOTON_NORMAL);
+        break;
+    }
+    vSeteamosFuncionEjecutar(vEventosPantallaMensaje);
+}
+
+/* ** Se atiende eventos de pantalla con mensaje ** */
+void vEventosPantallaMensaje(void){    
+    UINT8 AccionPulsIzq,AccionPulsDer;
+    const UINT8 *TextDer,*TextIzq;
+
+    switch(MensajePantalla.TipoMensajePantalla){
+        case MENSAJE_ATRAS_OK:
+            AccionPulsIzq = MENSAJE_ACCION_ATRAS;
+            AccionPulsDer = MENSAJE_ACCION_OK;
+            TextDer="Atras";
+            TextIzq="Ok";
+        break;
+
+        case MENSAJE_NO_SI:
+            AccionPulsIzq = MENSAJE_ACCION_NO;
+            AccionPulsDer = MENSAJE_ACCION_SI;
+            TextDer="No";
+            TextIzq="Si";
+        break;
+        
+        default:
+            AccionPulsIzq = MENSAJE_ACCION_ATRAS;
+            AccionPulsDer = MENSAJE_ACCION_ATRAS;
+            TextDer="Atras";
+            TextIzq=" ";
+    }
+    if(kbhit_irq==1){
+        kbhit_irq=0;
+        kbhit_tratament=1;
+        
+        if(AREA_BTN_INF_DER()){
+            vDibujarMenuInferior(TextIzq,TextDer,BOTON_PRES_DER);
+            wait_ms(300);
+            (*MensajePantalla.MensajeFuncionEjecutar)(AccionPulsIzq);
+        }
+        if(AREA_BTN_INF_IZQ()){
+            vDibujarMenuInferior(TextIzq,TextDer,BOTON_PRES_IZQ);
+            wait_ms(300);
+            (*MensajePantalla.MensajeFuncionEjecutar)(AccionPulsDer);
+        }
+        kbhit_tratament=0;
+    }
+}
+
+void vModificadorVariables(const UINT8 *NombreVariable,float ValorInicial,void (*PtrFuncion)(UINT8,float)){
+    const UINT8 PtrLetras[13][2]={"7","8","9","4","5","6","1","2","3",".","0","c"};
+    UINT8 Ptr=0,Fmt[30]; 
+
+    ModificadorVariable.ValorInicial=ValorInicial;
+    ModificadorVariable.ValorActual=0.0;
+    memset(&ModificadorVariable.String[0],0,15);
+    ModificadorVariable.Ptr=0;
+    ModificadorVariable.FuncionActualEjecucion=PtrFuncion;
+    
+    vDibujarImagenFondo(IMAGEN_FONDO_MENU);
+    MyLCD.vLCDTFTDrawImage(0,0,WIDTH_TITULO,HEIGH_TITULO,LENGTH_TITULO,&Titulo[0]);
+    vTextoJustificado(NombreVariable,5,234,4,JUST_CENTRADO,&ARIAL[0],2,ColorAzulMarino);
+    
+    MyLCD.vLCDTFTRectangle(22,122,217,148,1,ColorWhite);
+    MyLCD.vLCDTFTRectangle(20,120,219,121,1,ColorGray);
+    MyLCD.vLCDTFTRectangle(20,120,21,150,1,ColorGray);
+    MyLCD.vLCDTFTRectangle(218,120,219,150,1,ColorGray);
+    MyLCD.vLCDTFTRectangle(20,149,219,150,1,ColorBlack);
+    sprintf((char *)&Fmt[0],"%f",ValorInicial);
+    vTextoJustificado((const UINT8 *)&Fmt[0],20,219,128,JUST_CENTRADO,&ARIAL[0],2,ColorAzulMarino);
+    
+    // Dibuja pad Numerico:
+    for(int k=209;k<289;k+=20){
+        for(int j=0;j<240;j+=80){
+            MyLCD.vLCDTFTDrawImage(j,k,WIDTH_TECLAS,HEIGH_TECLAS,LENGTH_TECLAS,&Teclas[0]);
+            vTextoJustificado(&PtrLetras[Ptr++][0],j,j+79,k+3,JUST_CENTRADO,&ARIAL[0],2,ColorCian);
+        }
+    }
+    vDibujarMenuInferior("Cancelar","Aceptar",BOTON_NORMAL);
+    
+    vSeteamosFuncionEjecutar(vEventosModificadorVariables);
+}
+
+void vEventosModificadorVariables(void){
+    const UINT8 PtrLetras[12][2]={"7","8","9","4","5","6","1","2","3",".","0","c"};
+    UINT8 PtrTecla;
+    float Temp;
+
+    if(kbhit_irq==1){
+        kbhit_irq=0;
+        kbhit_tratament=1;
+        
+        // Testea Pad Numerico.-
+        PtrTecla=0;
+        for(int k=209;k<289;k+=20){
+            for(int j=0;j<240;j+=80){
+                if((Coordenadas.x<(j+74)) && (Coordenadas.x>(j+5)) && (Coordenadas.y<(k+15)) && (Coordenadas.y>(k+5))){
+                    vTextoJustificado(&PtrLetras[PtrTecla][0],j,j+79,k+3,JUST_CENTRADO,&ARIAL[0],2,ColorWhite);
+                    wait_ms(300);
+                    vTextoJustificado(&PtrLetras[PtrTecla][0],j,j+79,k+3,JUST_CENTRADO,&ARIAL[0],2,ColorCian);
+                    // Borrar?
+                    if(PtrTecla==11){
+                        if(ModificadorVariable.Ptr!=0){
+                            ModificadorVariable.Ptr--;
+                            ModificadorVariable.String[ModificadorVariable.Ptr]='\0';
+                        }
+                    }else{
+                        ModificadorVariable.String[ModificadorVariable.Ptr++]=((UINT8)PtrLetras[PtrTecla][0]);
+                    }
+                    MyLCD.vLCDTFTRectangle(22,122,217,148,1,ColorWhite);
+                    vTextoJustificado((const UINT8 *)&ModificadorVariable.String[0],20,219,128,JUST_CENTRADO,&ARIAL[0],2,ColorAzulMarino);
+                    kbhit_tratament=0;
+                    return;
+                }
+                PtrTecla++;
+            }
+        }
+        
+        if(AREA_BTN_INF_DER()){
+            vDibujarMenuInferior("Cancelar","Aceptar",BOTON_PRES_DER);
+            wait_ms(300);
+            Temp=atof((const char *)&ModificadorVariable.String[0]);
+            (*ModificadorVariable.FuncionActualEjecucion)(MODIFICADOR_ACEPTAR,Temp);
+           
+        }
+        if(AREA_BTN_INF_IZQ()){
+            vDibujarMenuInferior("Cancelar","Aceptar",BOTON_PRES_IZQ);
+            wait_ms(300);
+            (*ModificadorVariable.FuncionActualEjecucion)(MODIFICADOR_CANCELAR,0.0);
+        }
+        kbhit_tratament=0;
+    }
+}
+// ************************************************************************************************
+void vTextoJustificado(const unsigned char *PtrTexto,unsigned short ExtremoIzq, unsigned short ExtremoDer, unsigned short y, unsigned char Just,const char (*Fuente)[5],unsigned char Alto, unsigned short Color){
+    unsigned char x,NCaracteres;
+    const unsigned char *Ptr;
+
+    if(Just!=JUST_IZQ){
+        for(Ptr=PtrTexto;*Ptr!='\0';Ptr++);
+        NCaracteres=Ptr - PtrTexto;
+    }
+    switch(Just){
+        case JUST_IZQ:
+            x=ExtremoIzq+5;
+        break;
+        case JUST_DER:
+            x=ExtremoDer-NCaracteres*(5*Alto+1)-4;
+        break;
+        case JUST_CENTRADO:
+            x=((ExtremoIzq+ExtremoDer-NCaracteres*(5*Alto+1))/2);
+        break;
+    }
+    MyLCD.vLCDTFTText(x,y,(const char *)PtrTexto,Fuente,Alto,Color);
+}
+/* ** Escribe mensaje en pantalla multilinea justificado ** */
+void vEscribirMensaje(unsigned short YInicial,const unsigned char *Mensaje,const char (*Fuente)[5],unsigned char Just, unsigned short Color){
+    char Texto[50],k,dy=0;
+    
+    while(*Mensaje!='\0'){
+        k=0;
+        do{
+            Texto[k++]=*Mensaje++;
+        }while(*Mensaje!='\0' && *Mensaje!='\n');
+        if(*Mensaje=='\n') *Mensaje++;
+        if(k<50){while(k<50){Texto[k++]='\0';}}
+        vTextoJustificado((const unsigned char *)&Texto[0],0,239,YInicial+dy,Just,Fuente,1,Color);
+        dy+=11;
+    }
+}
+#endif
\ No newline at end of file