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
Diff: UI.cpp
- Revision:
- 3:ecf7f1f8d749
- Parent:
- 2:80026d18fcf3
- Child:
- 5:13c70bcde7f6
--- a/UI.cpp Thu Oct 29 12:59:54 2015 +0000 +++ b/UI.cpp Thu Oct 29 18:09:31 2015 +0000 @@ -1,6 +1,6 @@ #include "WakeupLight.h" -#define CLIENT_COLOR_BG ((uint32_t)0xFF602020) +#define CLIENT_COLOR_BG ((uint32_t)0xFF000000) #define CLIENT_COLOR_FG ((uint32_t)0xFFD0D0D0) #define HEADER_HEIGHT 25 @@ -12,10 +12,25 @@ #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; -int32_t uiCounter=0; +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 @@ -26,6 +41,33 @@ 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 // @@ -33,14 +75,81 @@ { 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) { - // detect at which block was clicked + 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; + } + } } // @@ -57,7 +166,12 @@ 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); } // @@ -66,6 +180,8 @@ void UI_ShowClock(bool initial) { char buffer[100]; + struct tm *tmStruct; + time_t timeValue; if (initial==true) { @@ -78,14 +194,16 @@ uiLcd.SetFont(&display_font_12x22); uiLcd.SetBackColor(CLOCK_COLOR_BG); uiLcd.SetTextColor(CLOCK_COLOR_FG); - snprintf(buffer,sizeof(buffer),"ABC %u",uiCounter); - uiCounter++; + 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); } // @@ -122,6 +240,7 @@ void UI_ClickClockInWords(uint16_t x,uint16_t y) { // exit view + UI_Show(&uiMain); } // @@ -138,7 +257,12 @@ 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); } // @@ -148,6 +272,9 @@ { uiCurrent=NULL; + uiLastTouchX=0; + uiLastTouchY=0; + uiLcd.Init(); uiLcd.Clear(COLOR_BG); @@ -155,11 +282,27 @@ 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) { @@ -172,48 +315,61 @@ uiLcd.SetFont(&display_font_12x22); uiLcd.SetBackColor(HEADER_COLOR_BG); uiLcd.SetTextColor(HEADER_COLOR_FG); - snprintf(buffer,sizeof(buffer),"ABC %u",uiCounter); - uiCounter++; + 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); - if ((uiCurrent->flags & UI_FLAG_TYPE_BOX_LIST)!=0) + typeFlag=uiCurrent->flags & ~UI_FLAG_NEEDS_CHROME; + if ((typeFlag & UI_FLAG_TYPE_BOX_LIST)!=0) UI_ShowBoxList(initial); - else if ((uiCurrent->flags & UI_FLAG_TYPE_MESSAGE_BOX)!=0) + else if ((typeFlag & UI_FLAG_TYPE_MESSAGE_BOX)!=0) UI_ShowMessageBox(initial); - else if ((uiCurrent->flags & UI_FLAG_TYPE_CLOCK)!=0) + else if ((typeFlag & UI_FLAG_TYPE_CLOCK)!=0) UI_ShowClock(initial); - else if ((uiCurrent->flags & UI_FLAG_TYPE_CLOCK_IN_WORDS)!=0) + else if ((typeFlag & UI_FLAG_TYPE_CLOCK_IN_WORDS)!=0) UI_ShowClockInWords(initial); - else if ((uiCurrent->flags & UI_FLAG_TYPE_TIMER_ADJUST)!=0) + 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) { - if ((uiCurrent->flags & UI_FLAG_TYPE_BOX_LIST)!=0) + uint8_t typeFlag; + + typeFlag=uiCurrent->flags & ~UI_FLAG_NEEDS_CHROME; + if ((typeFlag & UI_FLAG_TYPE_BOX_LIST)!=0) UI_ClickBoxList(x,y); - else if ((uiCurrent->flags & UI_FLAG_TYPE_MESSAGE_BOX)!=0) + else if ((typeFlag & UI_FLAG_TYPE_MESSAGE_BOX)!=0) UI_ClickMessageBox(x,y); - else if ((uiCurrent->flags & UI_FLAG_TYPE_CLOCK)!=0) + else if ((typeFlag & UI_FLAG_TYPE_CLOCK)!=0) UI_ClickClock(x,y); - else if ((uiCurrent->flags & UI_FLAG_TYPE_CLOCK_IN_WORDS)!=0) + else if ((typeFlag & UI_FLAG_TYPE_CLOCK_IN_WORDS)!=0) UI_ClickClockInWords(x,y); - else if ((uiCurrent->flags & UI_FLAG_TYPE_TIMER_ADJUST)!=0) + else if ((typeFlag & UI_FLAG_TYPE_TIMER_ADJUST)!=0) UI_ClickTimerAdjust(x,y); } @@ -224,10 +380,26 @@ uiTs.GetState(&tsState); if (tsState.touchDetected>0) { - DPrintf("UI_Poll: #%u - %ux%u.\r\n",tsState.touchDetected,tsState.touchX[0],tsState.touchY[0]); - UI_Click(tsState.touchX[0],tsState.touchY[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); + } }