Wakeup Light with touch user interface, anti-aliased Font, SD card access and RTC usage on STM32F746NG-DISCO board
Dependencies: BSP_DISCO_F746NG_patch_fixed LCD_DISCO_F746NG TS_DISCO_F746NG FATFileSystem TinyJpgDec_interwork mbed-src
UI.cpp
- Committer:
- the_sz
- Date:
- 2015-10-29
- Revision:
- 3:ecf7f1f8d749
- Parent:
- 2:80026d18fcf3
- Child:
- 5:13c70bcde7f6
File content as of revision 3:ecf7f1f8d749:
#include "WakeupLight.h" #define CLIENT_COLOR_BG ((uint32_t)0xFF000000) #define CLIENT_COLOR_FG ((uint32_t)0xFFD0D0D0) #define HEADER_HEIGHT 25 #define HEADER_COLOR_BG ((uint32_t)0xFF404040) #define HEADER_COLOR_FG ((uint32_t)0xFFD3D3D3) #define CLOCK_COLOR_BG ((uint32_t)0xFF000000) #define CLOCK_COLOR_FG ((uint32_t)0xFF707070) #define COLOR_BG ((uint32_t)0xFF000000) #define MAX_BOXES_PER_LINE 3 #define BOX_SPACING 10 #define BOX_TEXT_SPACING 10 #define BOX_COLOR_BG ((uint32_t)0xFF808080) #define BOX_COLOR_FG CLIENT_COLOR_FG LCD_DISCO_F746NG uiLcd; TS_DISCO_F746NG uiTs; uint16_t uiLastTouchX; uint16_t uiLastTouchY; UI_STRUCT *uiCurrent=NULL; UI_STRUCT uiClock; UI_STRUCT uiClockInWords; UI_STRUCT uiWakeup; UI_STRUCT uiMain; UI_BOX_LIST_ITEM_STRUCT uiMainItems[]= { { "Clock" }, { "Clock\nWith Words" }, { "Adjust\nTimers" }, { "Lights On" }, { "Lights Off" } }; // // helper function // void UI_ShowClearClientRect(void) { uiLcd.SetTextColor(CLIENT_COLOR_BG); uiLcd.FillRect(0,HEADER_HEIGHT,uiLcd.GetXSize()-1,uiLcd.GetYSize()-1); } void UI_ShowDisplayText(int16_t x,int16_t y,char *text) { int16_t xStart; int16_t charWidth; int16_t charHeight; xStart=x; charHeight=uiLcd.GetFont()->Height+3; charWidth=uiLcd.GetFont()->Width; while ((*text)!='\0') { if ((*text)=='\n') { y+=charHeight; x=xStart; } else { uiLcd.DisplayChar(x,y,*text); x+=charWidth; } text++; } } // // box list // void UI_ShowBoxList(bool initial) { if (initial==true) { int8_t lines; int8_t columns; int8_t box; int16_t width; int16_t height; int16_t startX; int16_t startY; // fill background UI_ShowClearClientRect(); // paint boxes if (uiCurrent->data.boxList.count<=MAX_BOXES_PER_LINE) lines=1; else lines=2; columns=((uiCurrent->data.boxList.count + (lines-1)) / lines); width=(uiLcd.GetXSize() - BOX_SPACING) / columns; height=(uiLcd.GetYSize() - HEADER_HEIGHT - BOX_SPACING) / lines; for (box=0;box<uiCurrent->data.boxList.count;box++) { startX=BOX_SPACING+(width*(box % columns)); startY=HEADER_HEIGHT+BOX_SPACING+(height*(box/columns)); // paint box background uiLcd.SetTextColor(BOX_COLOR_BG); uiLcd.FillRect(startX,startY,width-BOX_SPACING,height-BOX_SPACING); // paint box text uiLcd.SetFont(&display_font_12x22); uiLcd.SetBackColor(BOX_COLOR_BG); uiLcd.SetTextColor(BOX_COLOR_FG); UI_ShowDisplayText(startX+BOX_TEXT_SPACING,startY+BOX_TEXT_SPACING,uiCurrent->data.boxList.items[box].name); } } } void UI_ClickBoxList(uint16_t x,uint16_t y) { int8_t lines; int8_t columns; int8_t box; int16_t width; int16_t height; int16_t startX; int16_t startY; // detect at which box was clicked if (uiCurrent->data.boxList.count<=MAX_BOXES_PER_LINE) lines=1; else lines=2; columns=((uiCurrent->data.boxList.count + (lines-1)) / lines); width=(uiLcd.GetXSize() - BOX_SPACING) / columns; height=(uiLcd.GetYSize() - HEADER_HEIGHT - BOX_SPACING) / lines; for (box=0;box<uiCurrent->data.boxList.count;box++) { startX=BOX_SPACING+(width*(box % columns)); startY=HEADER_HEIGHT+BOX_SPACING+(height*(box/columns)); if ( (x>=startX) && (x<(startX+width-BOX_SPACING)) && (y>=startY) && (y<(startY+height-BOX_SPACING)) ) { uiCurrent->handler(UR_CLICK,box,uiCurrent); break; } } } // // message box // void UI_ShowMessageBox(bool initial) { if (initial==true) { // fill background UI_ShowClearClientRect(); } } void UI_ClickMessageBox(uint16_t x,uint16_t y) { uint32_t index; // detect at which button was clicked index=0; uiCurrent->handler(UR_CLICK,index,uiCurrent); } // // clock // void UI_ShowClock(bool initial) { char buffer[100]; struct tm *tmStruct; time_t timeValue; if (initial==true) { // fill background uiLcd.SetTextColor(CLOCK_COLOR_BG); uiLcd.FillRect(0,0,uiLcd.GetXSize()-1,uiLcd.GetYSize()-1); } // show clock uiLcd.SetFont(&display_font_12x22); uiLcd.SetBackColor(CLOCK_COLOR_BG); uiLcd.SetTextColor(CLOCK_COLOR_FG); timeValue=time(NULL); tmStruct=localtime(&timeValue); snprintf(buffer,sizeof(buffer),"%u:%02u:%02u",tmStruct->tm_hour,tmStruct->tm_min,tmStruct->tm_sec); uiLcd.DisplayStringAt(0,100,(uint8_t *)buffer,CENTER_MODE); } void UI_ClickClock(uint16_t x,uint16_t y) { // exit view UI_Show(&uiMain); } // // clock in words // void UI_ShowClockInWords(bool initial) { if (initial==true) { // fill background UI_ShowClearClientRect(); } // show clock in words uiLcd.SetFont(&display_font_12x22); uiLcd.SetBackColor(CLIENT_COLOR_BG); uiLcd.SetTextColor(CLIENT_COLOR_FG); uiLcd.DisplayStringAt(5,30,(uint8_t *)"UM F\x9ANF ZEHN VIERTEL HALB",LEFT_MODE); uiLcd.DisplayStringAt(5,60,(uint8_t *)"NACH VOR",LEFT_MODE); uiLcd.DisplayStringAt(5,90,(uint8_t *)"EINS ZWEI DREI VIER",LEFT_MODE); uiLcd.DisplayStringAt(5,120,(uint8_t *)"F\x9ANF SECHS SIEBEN ACHT",LEFT_MODE); uiLcd.DisplayStringAt(5,150,(uint8_t *)"NEUN ZEHN ELF ZW\x99LF",LEFT_MODE); // draw charset /* int x; for (x=0x80;x<=0xFF;x++) { uiLcd.DisplayChar(1+(((x-0x80) % 16)*14),30+(((x-0x80)/16)*20),x); } */ } void UI_ClickClockInWords(uint16_t x,uint16_t y) { // exit view UI_Show(&uiMain); } // // timer adjust // void UI_ShowTimerAdjust(bool initial) { if (initial==true) { // fill background UI_ShowClearClientRect(); } } void UI_ClickTimerAdjust(uint16_t x,uint16_t y) { uint32_t index; // detect at which button was clicked index=0; uiCurrent->handler(UR_CLICK,index,uiCurrent); } // // common // void UI_Init(void) { uiCurrent=NULL; uiLastTouchX=0; uiLastTouchY=0; uiLcd.Init(); uiLcd.Clear(COLOR_BG); if (uiTs.Init(uiLcd.GetXSize(),uiLcd.GetYSize())==TS_OK) DPrintf("UI_Init: Size: %ux%u.\r\n",uiLcd.GetXSize(),uiLcd.GetYSize()); else DPrintf("UI_Init: Can't init touch screen.\r\n"); // setup ui structs uiClock.flags=UI_FLAG_TYPE_CLOCK; uiClock.handler=NULL; uiClockInWords.flags=UI_FLAG_TYPE_CLOCK_IN_WORDS; uiClockInWords.handler=NULL; uiWakeup.flags=UI_FLAG_TYPE_BOX_LIST; uiWakeup.handler=UI_WakeupHandler; uiMain.flags=UI_FLAG_TYPE_BOX_LIST; uiMain.handler=UI_MainHandler; uiMain.data.boxList.items=uiMainItems; uiMain.data.boxList.count=COUNT_OF(uiMainItems); UI_Show(&uiMain); } void UI_ShowChrome(bool initial) { char buffer[100]; struct tm *tmStruct; time_t timeValue; if (initial==true) { // fill background uiLcd.SetTextColor(HEADER_COLOR_BG); uiLcd.FillRect(0,0,uiLcd.GetXSize()-1,HEADER_HEIGHT); } // show clock uiLcd.SetFont(&display_font_12x22); uiLcd.SetBackColor(HEADER_COLOR_BG); uiLcd.SetTextColor(HEADER_COLOR_FG); timeValue=time(NULL); tmStruct=localtime(&timeValue); snprintf(buffer,sizeof(buffer),"%u:%02u",tmStruct->tm_hour,tmStruct->tm_min); uiLcd.DisplayStringAt(0,3,(uint8_t *)buffer,CENTER_MODE); // show next alarm //XXX } void UI_Update(bool initial) { uint8_t typeFlag; if ((uiCurrent->flags & UI_FLAG_NEEDS_CHROME)!=0) UI_ShowChrome(initial); typeFlag=uiCurrent->flags & ~UI_FLAG_NEEDS_CHROME; if ((typeFlag & UI_FLAG_TYPE_BOX_LIST)!=0) UI_ShowBoxList(initial); else if ((typeFlag & UI_FLAG_TYPE_MESSAGE_BOX)!=0) UI_ShowMessageBox(initial); else if ((typeFlag & UI_FLAG_TYPE_CLOCK)!=0) UI_ShowClock(initial); else if ((typeFlag & UI_FLAG_TYPE_CLOCK_IN_WORDS)!=0) UI_ShowClockInWords(initial); else if ((typeFlag & UI_FLAG_TYPE_TIMER_ADJUST)!=0) UI_ShowTimerAdjust(initial); } void UI_Show(UI_STRUCT *ui) { DPrintf("UI_Show: 0x%X.\r\n",ui->flags); uiCurrent=ui; if (uiCurrent->handler!=NULL) uiCurrent->handler(UR_SHOW,0,uiCurrent); UI_Update(true); } void UI_Click(uint16_t x,uint16_t y) { uint8_t typeFlag; typeFlag=uiCurrent->flags & ~UI_FLAG_NEEDS_CHROME; if ((typeFlag & UI_FLAG_TYPE_BOX_LIST)!=0) UI_ClickBoxList(x,y); else if ((typeFlag & UI_FLAG_TYPE_MESSAGE_BOX)!=0) UI_ClickMessageBox(x,y); else if ((typeFlag & UI_FLAG_TYPE_CLOCK)!=0) UI_ClickClock(x,y); else if ((typeFlag & UI_FLAG_TYPE_CLOCK_IN_WORDS)!=0) UI_ClickClockInWords(x,y); else if ((typeFlag & UI_FLAG_TYPE_TIMER_ADJUST)!=0) UI_ClickTimerAdjust(x,y); } void UI_Poll(void) { TS_StateTypeDef tsState; uiTs.GetState(&tsState); if (tsState.touchDetected>0) { if ( (ABS(uiLastTouchX-tsState.touchX[0])>4) || (ABS(uiLastTouchY-tsState.touchY[0])>4) ) { DPrintf("UI_Poll: #%u - %ux%u.\r\n",tsState.touchDetected,tsState.touchX[0],tsState.touchY[0]); uiLastTouchX=tsState.touchX[0]; uiLastTouchY=tsState.touchY[0]; if (uiCurrent!=NULL) UI_Click(tsState.touchX[0],tsState.touchY[0]); } } if (uiCurrent!=NULL) { if (uiCurrent->handler!=NULL) uiCurrent->handler(UR_TIMER,0,uiCurrent); UI_Update(false); } }