Menus LCD TFT
Dependents: Example_Menu_LCD_TFT
Menus.h
- Committer:
- Suky
- Date:
- 2011-03-15
- Revision:
- 0:310ed2337a8f
File content as of revision 0:310ed2337a8f:
/* \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�n que atiende eventos del Submenu (Funci�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