void window_drawtime(tContext *pContext, long y, uint8_t times[3], uint8_t selected) { char data[3]; data[0] = data[1] = '0'; data[2] = ':'; #define SPACING 3 uint8_t height = GrStringHeightGet(pContext); uint8_t width_all = GrStringWidthGet(pContext, data, 3) + 10; uint8_t width_digit = GrStringWidthGet(pContext, data, 2) + 4; long startx = (LCD_WIDTH - width_all - width_all - width_digit) / 2; if (startx < 0) startx = 0; for(int i = 0; i < 3; i++) { data[0] = '0' + times[i] / 10; data[1] = '0' + times[i] % 10; GrContextForegroundSet(pContext, ClrWhite); GrContextBackgroundSet(pContext, ClrBlack); if (selected & (1 << i)) window_selecttext(pContext, data, 2, startx + SPACING + i * width_all, y); else GrStringDraw(pContext, data, 2, startx + SPACING + i * width_all, y, 0); if (i != 2) { GrContextForegroundSet(pContext, ClrWhite); GrContextBackgroundSet(pContext, ClrBlack); GrStringDraw(pContext, ":", 1, startx + SPACING + width_digit + i * width_all, y, 0); } } }
static void drawItem(tContext *pContext, uint8_t n, char icon, const char* text, const char* value) { if (icon) { #if defined(PRODUCT_W002) || defined(PRODUCT_W004) GrContextFontSet(pContext, (tFont*)&g_sFontExIcons32); GrStringDraw(pContext, &icon, 1, 12, 21 + n * LINEMARGIN, 0); #else GrContextFontSet(pContext, (tFont*)&g_sFontExIcon16); GrStringDraw(pContext, &icon, 1, 3, 12 + n * LINEMARGIN, 0); #endif } // draw text #if defined(PRODUCT_W002) || defined(PRODUCT_W004) GrContextFontSet(pContext, &g_sFontBaby16); GrStringDraw(pContext, text, -1, 57, 24 + n * LINEMARGIN, 0); uint8_t width = GrStringWidthGet(pContext, value, -1); GrStringDraw(pContext, value, -1, 57, 39 + n * LINEMARGIN, 0); #else GrContextFontSet(pContext, &g_sFontGothic24b); GrStringDraw(pContext, text, -1, 20, 10 + n * LINEMARGIN, 0); uint8_t width = GrStringWidthGet(pContext, value, -1); GrStringDraw(pContext, value, -1, LCD_WIDTH - width - 4, 10 + n * LINEMARGIN, 0); #endif }
void window_selecttext(tContext *pContext, const char* pcString, long lLength, long lX, long lY) { int height = GrStringHeightGet(pContext); int width, textwidth; if (lLength == -1) { width = GrStringWidthGet(pContext, pcString, lLength); textwidth = width; } else { char data = '8'; width = GrStringWidthGet(pContext, &data, 1) * lLength; textwidth = GrStringWidthGet(pContext, pcString, lLength); } tRectangle rect = {lX - 2, lY - 2, lX + width + 2, lY + height + 2}; GrContextForegroundSet(pContext, ClrWhite); #if defined(PRODUCT_W002) || defined(PRODUCT_W004) GrRectFillRound(pContext, &rect, 0); #else GrRectFillRound(pContext, &rect, 3); #endif GrContextForegroundSet(pContext, ClrBlack); GrStringDraw(pContext, pcString, lLength, lX + (width - textwidth)/2, lY, 0); GrContextForegroundSet(pContext, ClrWhite); #if defined(PRODUCT_W002) || defined(PRODUCT_W004) #else // there is something more long x = lX + width/2; long y0 = lY - 5 - 6; long y1 = lY + height + 5 + 6; for(int i = 0; i < 6; i++) { GrLineDrawH(pContext, x - i, x + i, y1 - i); GrLineDrawH(pContext, x - i, x + i, y0 + i); } #endif }
static void drawItem(tContext *pContext, uint8_t n, char icon, const char* text, const char* value) { if (icon) { GrContextFontSet(pContext, (tFont*)&g_sFontExIcon16); GrStringDraw(pContext, &icon, 1, 3, 12 + n * LINEMARGIN, 0); } // draw text GrContextFontSet(pContext, &g_sFontGothic24b); GrStringDraw(pContext, text, -1, 20, 10 + n * LINEMARGIN, 0); uint8_t width = GrStringWidthGet(pContext, value, -1); GrStringDraw(pContext, value, -1, LCD_WIDTH - width - 4, 10 + n * LINEMARGIN, 0); }
//***************************************************************************** // //! Draws a container widget. //! //! \param pWidget is a pointer to the container widget to be drawn. //! //! This function draws a container widget on the display. This is called in //! response to a \b #WIDGET_MSG_PAINT message. //! //! \return None. // //***************************************************************************** static void ContainerPaint(tWidget *pWidget) { tContainerWidget *pContainer; long lX1, lX2, lY; tContext sCtx; // // Check the arguments. // ASSERT(pWidget); // // Convert the generic widget pointer into a container widget pointer. // pContainer = (tContainerWidget *)pWidget; // // Initialize a drawing context. // GrContextInit(&sCtx, pWidget->pDisplay); // // Initialize the clipping region based on the extents of this container. // GrContextClipRegionSet(&sCtx, &(pWidget->sPosition)); // // See if the container fill style is selected. // if(pContainer->ulStyle & CTR_STYLE_FILL) { // // Fill the container with the fill color. // GrContextForegroundSet(&sCtx, pContainer->ulFillColor); GrRectFill(&sCtx, &(pWidget->sPosition)); } // // See if the container text style is selected. // if(pContainer->ulStyle & CTR_STYLE_TEXT) { // // Set the font and colors used to draw the container text. // GrContextFontSet(&sCtx, pContainer->pFont); GrContextForegroundSet(&sCtx, pContainer->ulTextColor); GrContextBackgroundSet(&sCtx, pContainer->ulFillColor); // // Get the width of the container text. // lX2 = GrStringWidthGet(&sCtx, pContainer->pcText, -1); // // Determine the position of the text. The position depends on the // the width of the string and if centering is enabled. // if(pContainer->ulStyle & CTR_STYLE_TEXT_CENTER) { lX1 = (pWidget->sPosition.sXMin + ((pWidget->sPosition.sXMax - pWidget->sPosition.sXMin + 1 - lX2 - 8) / 2)); } else { lX1 = pWidget->sPosition.sXMin + 4; } // // Draw the container text. // GrStringDraw(&sCtx, pContainer->pcText, -1, lX1 + 4, pWidget->sPosition.sYMin, pContainer->ulStyle & CTR_STYLE_TEXT_OPAQUE); // // See if the container outline style is selected. // if(pContainer->ulStyle & CTR_STYLE_OUTLINE) { // // Get the position of the right side of the string. // lX2 = lX1 + lX2 + 8; // // Get the position of the vertical center of the text. // lY = (pWidget->sPosition.sYMin + (GrFontBaselineGet(pContainer->pFont) / 2)); // // Set the color to draw the outline. // GrContextForegroundSet(&sCtx, pContainer->ulOutlineColor); // // Draw the outline around the container widget, leaving a gap // where the text reside across the top of the widget. // GrLineDraw(&sCtx, lX1, lY, pWidget->sPosition.sXMin, lY); GrLineDraw(&sCtx, pWidget->sPosition.sXMin, lY, pWidget->sPosition.sXMin, pWidget->sPosition.sYMax); GrLineDraw(&sCtx, pWidget->sPosition.sXMin, pWidget->sPosition.sYMax, pWidget->sPosition.sXMax, pWidget->sPosition.sYMax); GrLineDraw(&sCtx, pWidget->sPosition.sXMax, pWidget->sPosition.sYMax, pWidget->sPosition.sXMax, lY); GrLineDraw(&sCtx, pWidget->sPosition.sXMax, lY, lX2, lY); } } // // Otherwise, see if the container outline style is selected. // else if(pContainer->ulStyle & CTR_STYLE_OUTLINE) { // // Outline the container with the outline color. // GrContextForegroundSet(&sCtx, pContainer->ulOutlineColor); GrRectDraw(&sCtx, &(pWidget->sPosition)); } }
// draw one grid data static void drawGridData(tContext *pContext, uint8_t grid, uint32_t data) { int width; if (grid == 0) { // draw time drawGridTime(pContext); return; } int index = findDataGrid(grid); if (index == -1) { index = 4; // default to distance } struct _datapoints const *d = &datapoints[grid]; char buf[20]; uint32_t tmp = data; const char* unit = window_readconfig()->is_ukuint ? d->unit_uk : d->unit; switch(d->format) { case FORMAT_TIME: sprintf(buf, "%02u:%02u", (uint16_t)(data / 60), (uint16_t)(data % 60)); break; case FORMAT_SPD: tmp = data * 36 / 10; //to km per hour if (window_readconfig()->is_ukuint) tmp = tmp * 621 / 1000; // to mile sprintf(buf, "%u.%01u", (uint16_t)(tmp / 100), (uint16_t)(tmp % 100)); break; case FORMAT_DIST: tmp = tmp / 10; if (window_readconfig()->is_ukuint) tmp = tmp * 621 / 1000; // to mile if (tmp >= 1000) { sprintf(buf, "%u.%02u", (uint16_t)(tmp / 1000), (uint16_t)(tmp % 1000)); } else { if (window_readconfig()->is_ukuint) { tmp = data * 82 / 250; unit = "ft"; } else { unit = "mt"; } sprintf(buf, "%03u", (uint16_t)(tmp % 1000)); } break; case FORMAT_CALS: //kcal if (!window_readconfig()->is_ukuint) tmp = tmp * 21 / 5; //to KJ if (tmp >= 1000) sprintf(buf, "%u", (uint16_t)(tmp / 1000)); else sprintf(buf, "0.%02u", (uint16_t)(tmp % 1000)); break; case FORMAT_ALT: if (window_readconfig()->is_ukuint) tmp = tmp * 82 / 25; sprintf(buf, "%u.%01u", (uint16_t)(tmp / 100), (uint16_t)(tmp % 100)); break; case FORMAT_PACE: if (window_readconfig()->is_ukuint) tmp = tmp * 621 / 1000; sprintf(buf, "%u.%01u", (uint16_t)(tmp / 60), (uint16_t)((tmp % 60) * 5 / 3)); break; default: sprintf(buf, "%d", (uint16_t)data); break; } GrContextForegroundSet(pContext, ClrWhite); // other generic grid data switch(window_readconfig()->sports_grid) { case GRID_3: GrContextFontSet(pContext, &g_sFontGothic18); GrStringDraw(pContext, d->name, -1, region_3grid[index].sXMin + 8, region_3grid[index].sYMin, 0); GrContextFontSet(pContext, &g_sFontGothic28b); GrStringDraw(pContext, buf, -1, region_3grid[index].sXMin + 8, region_3grid[index].sYMin + 20, 0); if (unit) { GrContextFontSet(pContext, &g_sFontGothic18); GrStringDraw(pContext, unit, -1, region_3grid[index].sXMin + 8, region_3grid[index].sYMin + 50, 0); } break; case GRID_4: GrContextFontSet(pContext, &g_sFontGothic18); GrStringDrawWrap(pContext, d->name, region_4grid[index].sXMin + 8, region_4grid[index].sYMin + 8, (region_4grid[index].sXMax - region_4grid[index].sXMin) / 3, 1); GrContextFontSet(pContext, &g_sFontGothic28b); width = GrStringWidthGet(pContext, buf, -1); GrStringDraw(pContext, buf, -1, (region_4grid[index].sXMax - region_4grid[index].sXMin) * 3 / 4 - width, region_4grid[index].sYMin + 10, 0); if (unit) { GrContextFontSet(pContext, &g_sFontGothic18); GrStringDraw(pContext, unit, -1, (region_4grid[index].sXMax - region_4grid[index].sXMin) * 3 / 4 + 8, region_4grid[index].sYMin + 20, 0); } break; case GRID_5: GrContextFontSet(pContext, &g_sFontGothic18); GrStringDraw(pContext, d->name, -1, region_5grid[index].sXMin + 8, region_5grid[index].sYMin, 0); GrContextFontSet(pContext, &g_sFontGothic28b); width = GrStringWidthGet(pContext, buf, -1); GrStringDraw(pContext, buf, -1, region_5grid[index].sXMax - 4 - width, region_5grid[index].sYMin + 15, 0); if (unit) { GrContextFontSet(pContext, &g_sFontGothic18); GrStringDraw(pContext, unit, -1, region_5grid[index].sXMin + 8, region_5grid[index].sYMin + 40, 0); } break; } }
//***************************************************************************** // // Handles wrapping a string within an area. // // \param psContext is the context of the area to update. // \param pcString is the string to print out. // \param i32LineHeight is the height of a character in the currrent font. // \param i32X is the x position to start printing this string. // \param i32Y is the y position to start printing this string. // \param bSplitOnSpace is true if strings in the current language must be // split only on space characters or false if they may be split between any // two characters. // // \return Returns the number of lines that were printed due to this string. // //***************************************************************************** uint32_t DrawStringWrapped(tContext *psContext, char *pcString, int32_t i32LineHeight, int32_t i32X, int32_t i32Y, bool bSplitOnSpace) { uint32_t ui32Width, ui32CharWidth, ui32StrWidth, ui32Char; uint32_t ui32Lines, ui32Skip; char *pcStart, *pcEnd; char *pcLastSpace; ui32Lines = 0; // // Get the number of pixels we have to fit the string into across the // screen. // ui32Width = GrContextDpyWidthGet(psContext) - 16 - i32X; // // Get a pointer to the terminating zero. // pcEnd = pcString; while(*pcEnd) { pcEnd++; } // // The first substring we draw will start at the beginning of the string. // pcStart = pcString; pcLastSpace = pcString; ui32StrWidth = 0; // // Keep processing until we have no more characters to display. // do { // // Get the next character in the string. // ui32Char = GrStringNextCharGet(psContext, pcString, (pcEnd - pcString), &ui32Skip); // // Did we reach the end of the string? // if(ui32Char) { // // No - how wide is this character? // ui32CharWidth = GrStringWidthGet(psContext, pcString, ui32Skip); // // Have we run off the edge of the display? // if((ui32StrWidth + ui32CharWidth) > ui32Width) { // // If we are splitting on spaces, rewind the string pointer to // the byte after the last space. // if(bSplitOnSpace) { pcString = pcLastSpace; } // // Yes - draw the substring. // GrStringDraw(psContext, pcStart, (pcString - pcStart), i32X, i32Y, 0); // // Increment the line count and move the y position down by the // current font's line height. // ui32Lines++; i32Y += i32LineHeight; ui32StrWidth = 0; // // The next string we draw will start at the current position. // pcStart = pcString; } else { // // No - update the width and move on to the next character. // ui32StrWidth += ui32CharWidth; pcString += ui32Skip; // // If this is a space, remember where we are. // if(ui32Char == SPACE_CHAR) { pcLastSpace = pcString; } } } else { // // Do we have any remaining chunk of string to draw? // if(pcStart != pcString) { // // Yes - draw the last section of string. // GrStringDraw(psContext, pcStart, -1, i32X, i32Y, 0); ui32Lines++; } } } while(ui32Char); return(ui32Lines); }
//***************************************************************************** // //! Draws the contents of a canvas. //! //! \param pWidget is a pointer to the canvas widget to be drawn. //! //! This function draws the contents of a canvas on the display. This is //! called in response to a \b #WIDGET_MSG_PAINT message. //! //! \return None. // //***************************************************************************** static void CanvasPaint(tWidget *pWidget) { tCanvasWidget *pCanvas; tContext sCtx; long lX, lY, lSize; // // Check the arguments. // ASSERT(pWidget); // // Convert the generic widget pointer into a canvas widget pointer. // pCanvas = (tCanvasWidget *)pWidget; // // Initialize a drawing context. // GrContextInit(&sCtx, pWidget->pDisplay); // // Initialize the clipping region based on the extents of this canvas. // GrContextClipRegionSet(&sCtx, &(pWidget->sPosition)); // // See if the canvas fill style is selected. // if(pCanvas->ulStyle & CANVAS_STYLE_FILL) { // // Fill the canvas with the fill color. // GrContextForegroundSet(&sCtx, pCanvas->ulFillColor); GrRectFill(&sCtx, &(pWidget->sPosition)); } // // See if the canvas outline style is selected. // if(pCanvas->ulStyle & CANVAS_STYLE_OUTLINE) { // // Outline the canvas with the outline color. // GrContextForegroundSet(&sCtx, pCanvas->ulOutlineColor); GrRectDraw(&sCtx, &(pWidget->sPosition)); } // // See if the canvas text or image style is selected. // if(pCanvas->ulStyle & (CANVAS_STYLE_TEXT | CANVAS_STYLE_IMG)) { // // Compute the center of the canvas. // lX = (pWidget->sPosition.sXMin + ((pWidget->sPosition.sXMax - pWidget->sPosition.sXMin + 1) / 2)); lY = (pWidget->sPosition.sYMin + ((pWidget->sPosition.sYMax - pWidget->sPosition.sYMin + 1) / 2)); // // If the canvas outline style is selected then shrink the clipping // region by one pixel on each side so that the outline is not // overwritten by the text or image. // if(pCanvas->ulStyle & CANVAS_STYLE_OUTLINE) { sCtx.sClipRegion.sXMin++; sCtx.sClipRegion.sYMin++; sCtx.sClipRegion.sXMax--; sCtx.sClipRegion.sYMax--; } // // See if the canvas image style is selected. // if(pCanvas->ulStyle & CANVAS_STYLE_IMG) { // // Set the foreground and background colors to use for 1 BPP // images. // GrContextForegroundSet(&sCtx, pCanvas->ulTextColor); GrContextBackgroundSet(&sCtx, pCanvas->ulFillColor); // // Draw the image centered in the canvas. // GrImageDraw(&sCtx, pCanvas->pucImage, lX - (GrImageWidthGet(pCanvas->pucImage) / 2), lY - (GrImageHeightGet(pCanvas->pucImage) / 2)); } // // See if the canvas text style is selected. // if(pCanvas->ulStyle & CANVAS_STYLE_TEXT) { // // Set the relevant font and colors. // GrContextFontSet(&sCtx, pCanvas->pFont); GrContextForegroundSet(&sCtx, pCanvas->ulTextColor); GrContextBackgroundSet(&sCtx, pCanvas->ulFillColor); // // Determine the drawing position for the string based on the // text alignment style. First consider the horizontal case. We // enter this section with lX set to the center of the widget. // // // How wide is the string? // lSize = GrStringWidthGet(&sCtx, pCanvas->pcText, -1); if(pCanvas->ulStyle & CANVAS_STYLE_TEXT_LEFT) { // // The string is to be aligned with the left edge of // the widget. Use the clipping rectangle as reference // since this will ensure that the string doesn't // encroach on any border that is set. // lX = sCtx.sClipRegion.sXMin; } else { if(pCanvas->ulStyle & CANVAS_STYLE_TEXT_RIGHT) { // // The string is to be aligned with the right edge of // the widget. Use the clipping rectangle as reference // since this will ensure that the string doesn't // encroach on any border that is set. // lX = sCtx.sClipRegion.sXMax - lSize; } else { // // We are centering the string horizontally so adjust // the position accordingly to take into account the // width of the string. // lX -= (lSize / 2); } } // // Now consider the horizontal case. We enter this section with lY // set to the center of the widget. // // How tall is the string? // lSize = GrStringHeightGet(&sCtx); if(pCanvas->ulStyle & CANVAS_STYLE_TEXT_TOP) { // // The string is to be aligned with the top edge of // the widget. Use the clipping rectangle as reference // since this will ensure that the string doesn't // encroach on any border that is set. // lY = sCtx.sClipRegion.sYMin; } else { if(pCanvas->ulStyle & CANVAS_STYLE_TEXT_BOTTOM) { // // The string is to be aligned with the bottom edge of // the widget. Use the clipping rectangle as reference // since this will ensure that the string doesn't // encroach on any border that is set. // lY = sCtx.sClipRegion.sYMax - lSize; } else { // // We are centering the string vertically so adjust // the position accordingly to take into account the // height of the string. // lY -= (lSize / 2); } } // // Now draw the string. // GrStringDraw(&sCtx, pCanvas->pcText, -1, lX, lY, pCanvas->ulStyle & CANVAS_STYLE_TEXT_OPAQUE); } } // // See if the application-drawn style is selected. // if(pCanvas->ulStyle & CANVAS_STYLE_APP_DRAWN) { // // Call the application-supplied function to draw the canvas. // pCanvas->pfnOnPaint(pWidget, &sCtx); } }
//***************************************************************************** // //! Draws the contents of a listbox. //! //! \param pWidget is a pointer to the listbox widget to be drawn. //! //! This function draws the contents of a listbox on the display. This is //! called in response to a \b #WIDGET_MSG_PAINT message. //! //! \return None. // //***************************************************************************** static void ListBoxPaint(tWidget *pWidget) { tListBoxWidget *pListBox; tContext sCtx; tRectangle sWidgetRect, sLineRect; short sHeight; long lWidth; unsigned short usCount, usString; // // Check the arguments. // ASSERT(pWidget); // // Convert the generic widget pointer into a listbox widget pointer. // pListBox = (tListBoxWidget *)pWidget; // // Initialize a drawing context. // GrContextInit(&sCtx, pWidget->pDisplay); GrContextFontSet(&sCtx, pListBox->pFont); // // Initialize the clipping region based on the extents of this listbox. // sWidgetRect = pWidget->sPosition; GrContextClipRegionSet(&sCtx, &sWidgetRect); // // See if the listbox outline style is selected. // if(pListBox->ulStyle & LISTBOX_STYLE_OUTLINE) { // // Outline the listbox with the outline color. // GrContextForegroundSet(&sCtx, pListBox->ulOutlineColor); GrRectDraw(&sCtx, &(pWidget->sPosition)); // // Shrink the widget region by one pixel on each side and draw another // rectangle, this time in the background color. This ensures that the // text will not interfere with the colored border. // sWidgetRect.sXMin++; sWidgetRect.sYMin++; sWidgetRect.sXMax--; sWidgetRect.sYMax--; GrContextForegroundSet(&sCtx, pListBox->ulBackgroundColor); GrRectDraw(&sCtx, &sWidgetRect); // // Reduce the size of the rectangle by another pixel to get the final // area into which we will put the text. // sWidgetRect.sXMin++; sWidgetRect.sYMin++; sWidgetRect.sXMax--; sWidgetRect.sYMax--; GrContextClipRegionSet(&sCtx, &sWidgetRect); } // // Start drawing at the top of the widget. // sLineRect = sWidgetRect; usCount = 0; usString = pListBox->usStartEntry; sHeight = GrFontHeightGet(pListBox->pFont); // // Keep drawing until we reach the bottom of the listbox or run out of // strings to draw. // while((sLineRect.sYMin < sWidgetRect.sYMax) && (usCount < pListBox->usPopulated)) { // // Calculate the rectangle that will enclose this line of text. // sLineRect.sYMax = sLineRect.sYMin + sHeight - 1; // // Set foreground and background colors appropriately. // GrContextBackgroundSet(&sCtx, ((usString == pListBox->sSelected) ? pListBox->ulSelectedBackgroundColor : pListBox->ulBackgroundColor)); GrContextForegroundSet(&sCtx, ((usString == pListBox->sSelected) ? pListBox->ulSelectedTextColor : pListBox->ulTextColor)); // // Draw the text. // GrStringDraw(&sCtx, pListBox->ppcText[usString], -1, sLineRect.sXMin, sLineRect.sYMin, 1); // // Determine the width of the string we just rendered. // lWidth = GrStringWidthGet(&sCtx, pListBox->ppcText[usString], -1); // // Do we need to clear the area to the right of the string? // if(lWidth < (sLineRect.sXMax - sLineRect.sXMin + 1)) { // // Yes - we need to fill the right side of this string with // background color. // GrContextForegroundSet(&sCtx, ((usString == pListBox->sSelected) ? pListBox->ulSelectedBackgroundColor : pListBox->ulBackgroundColor)); sLineRect.sXMin += lWidth; GrRectFill(&sCtx, &sLineRect); sLineRect.sXMin = sWidgetRect.sXMin; } // // Move on to the next string. // usCount++; usString++; if(usString == pListBox->usMaxEntries) { usString = 0; } sLineRect.sYMin += sHeight; } // // Fill the remainder of the listbox area with the background color. // if(sLineRect.sYMin < sWidgetRect.sYMax) { // // Determine the rectangle to be filled. // sLineRect.sYMax = sWidgetRect.sYMax; // // Fill the rectangle with the background color. // GrContextForegroundSet(&sCtx, pListBox->ulBackgroundColor); GrRectFill(&sCtx, &sLineRect); } }
//***************************************************************************** // //! Draws the contents of a listbox. //! //! \param psWidget is a pointer to the listbox widget to be drawn. //! //! This function draws the contents of a listbox on the display. This is //! called in response to a \b #WIDGET_MSG_PAINT message. //! //! \return None. // //***************************************************************************** static void ListBoxPaint(tWidget *psWidget) { tListBoxWidget *pListBox; tContext sCtx; tRectangle sWidgetRect, sLineRect; int16_t i16Height; int32_t i32Width; uint16_t ui16String; // // Check the arguments. // ASSERT(psWidget); // // Convert the generic widget pointer into a listbox widget pointer. // pListBox = (tListBoxWidget *)psWidget; // // Initialize a drawing context. // GrContextInit(&sCtx, psWidget->psDisplay); GrContextFontSet(&sCtx, pListBox->psFont); // // Initialize the clipping region based on the extents of this listbox. // sWidgetRect = psWidget->sPosition; GrContextClipRegionSet(&sCtx, &sWidgetRect); // // See if the listbox outline style is selected. // if(pListBox->ui32Style & LISTBOX_STYLE_OUTLINE) { // // Outline the listbox with the outline color. // GrContextForegroundSet(&sCtx, pListBox->ui32OutlineColor); GrRectDraw(&sCtx, &(psWidget->sPosition)); // // Shrink the widget region by one pixel on each side and draw another // rectangle, this time in the background color. This ensures that the // text will not interfere with the colored border. // sWidgetRect.i16XMin++; sWidgetRect.i16YMin++; sWidgetRect.i16XMax--; sWidgetRect.i16YMax--; GrContextForegroundSet(&sCtx, pListBox->ui32BackgroundColor); GrRectDraw(&sCtx, &sWidgetRect); // // Reduce the size of the rectangle by another pixel to get the final // area into which we will put the text. // sWidgetRect.i16XMin++; sWidgetRect.i16YMin++; sWidgetRect.i16XMax--; sWidgetRect.i16YMax--; GrContextClipRegionSet(&sCtx, &sWidgetRect); } // // Start drawing at the top of the widget. // sLineRect = sWidgetRect; ui16String = pListBox->ui16StartEntry; i16Height = GrFontHeightGet(pListBox->psFont); // // Keep drawing until we reach the bottom of the listbox or run out of // strings to draw. // while((sLineRect.i16YMin < sWidgetRect.i16YMax) && (ui16String < pListBox->ui16Populated)) { // // Calculate the rectangle that will enclose this line of text. // sLineRect.i16YMax = sLineRect.i16YMin + i16Height - 1; // // Set foreground and background colors appropriately. // GrContextBackgroundSet(&sCtx, ((ui16String == pListBox->i16Selected) ? pListBox->ui32SelectedBackgroundColor : pListBox->ui32BackgroundColor)); GrContextForegroundSet(&sCtx, ((ui16String == pListBox->i16Selected) ? pListBox->ui32SelectedTextColor : pListBox->ui32TextColor)); // // Draw the text. // GrStringDraw(&sCtx, pListBox->ppcText[ui16String], -1, sLineRect.i16XMin, sLineRect.i16YMin, 1); // // Determine the width of the string we just rendered. // i32Width = GrStringWidthGet(&sCtx, pListBox->ppcText[ui16String], -1); // // Do we need to clear the area to the right of the string? // if(i32Width < (sLineRect.i16XMax - sLineRect.i16XMin + 1)) { // // Yes - we need to fill the right side of this string with // background color. // GrContextForegroundSet(&sCtx, ((ui16String == pListBox->i16Selected) ? pListBox->ui32SelectedBackgroundColor : pListBox->ui32BackgroundColor)); sLineRect.i16XMin += i32Width; GrRectFill(&sCtx, &sLineRect); sLineRect.i16XMin = sWidgetRect.i16XMin; } // // Move on to the next string, wrapping if necessary. // ui16String++; if(ui16String == pListBox->ui16MaxEntries) { ui16String = 0; } sLineRect.i16YMin += i16Height; // // If we are wrapping and got back at the oldest entry, we drop out. // if(ui16String == pListBox->ui16OldestEntry) { break; } } // // Fill the remainder of the listbox area with the background color. // if(sLineRect.i16YMin < sWidgetRect.i16YMax) { // // Determine the rectangle to be filled. // sLineRect.i16YMax = sWidgetRect.i16YMax; // // Fill the rectangle with the background color. // GrContextForegroundSet(&sCtx, pListBox->ui32BackgroundColor); GrRectFill(&sCtx, &sLineRect); } }
static void onDraw(tContext *pContext) { // draw circles onDrawTitleBar(pContext); GrContextClipRegionSet(pContext, &contentrect); GrContextForegroundSet(pContext, ClrWhite); GrRectFill(pContext, &fullscreen_clip); GrContextForegroundSet(pContext, ClrBlack); long starty = 12 - skip; if (message_icon && message_date) { // draw the title bar // draw icon if (message_icon) { GrContextFontSet(pContext, (tFont*)&g_sFontExIcon16); GrStringDraw(pContext, &message_icon, 1, 8, starty, 0); } if (message_date) { char buffer[20]; strcpy(buffer, message_date); #if defined(PRODUCT_W002) || defined(PRODUCT_W004) GrContextFontSet(pContext, (tFont*)&g_sFontRonda12); #else GrContextFontSet(pContext, (tFont*)&g_sFontGothic14); #endif const char* text = parse_date(buffer); int16_t width = GrStringWidthGet(pContext, text, -1); GrStringDraw(pContext, text, -1, LCD_WIDTH - 10 - width, starty, 0); } starty += 16; } const tFont *titleFont; const tFont *contentFont; titleFont = get_titlefont(); contentFont = get_contentfont(); GrContextFontSet(pContext, titleFont); // draw title if (message_title && (*message_title != '\0')) { starty = GrStringDrawWrap(pContext, message_title, 1, starty, LCD_WIDTH - 1, 0); } if (message_subtitle && (*message_subtitle != '\0')) starty = GrStringDrawWrap(pContext, message_subtitle, 1, starty, LCD_WIDTH - 1, 0); GrContextFontSet(pContext, contentFont); //draw message if (message && *message != '\0') { if (GrStringDrawWrap(pContext, message, 1, starty, LCD_WIDTH - 1, 0) == -1) { state |= STATE_MORE; for(int i = 0; i < 6; i++) { GrLineDrawH(pContext, 130 - i, 130 + i, 160 - i); } } else { state &= ~STATE_MORE; } } }
//***************************************************************************** // // Handles when a key is pressed on the keyboard. // //***************************************************************************** void KeyEvent(tWidget *psWidget, uint32_t ui32Key, uint32_t ui32Event) { switch(ui32Key) { // // Look for a backspace key press. // case UNICODE_BACKSPACE: { if(ui32Event == KEYBOARD_EVENT_PRESS) { if(g_ui32StringIdx != 0) { g_ui32StringIdx--; g_pcKeyStr[g_ui32StringIdx] = 0; } WidgetPaint((tWidget *)&g_sKeyboardText); // // Save the pixel width of the current string. // g_i32StringWidth = GrStringWidthGet(&g_sContext, g_pcKeyStr, 40); } break; } // // Look for an enter/return key press. This will exit the keyboard and // return to the current active screen. // case UNICODE_RETURN: { if(ui32Event == KEYBOARD_EVENT_RELEASE) { // // Get rid of the keyboard widget. // WidgetRemove(g_sScreens[g_i32ScreenIdx].psWidget); // // Switch back to the previous screen and add its widget back. // g_i32ScreenIdx = g_i32ScreenIdx; WidgetAdd(WIDGET_ROOT, g_sScreens[g_i32ScreenIdx].psWidget); // // If returning to the main screen then re-draw the frame to // indicate the main screen. // if(g_i32ScreenIdx == SCREEN_DETAILS) { FrameDraw(&g_sContext, "nfc-p2p-demo : Details"); WidgetPaint(g_sScreens[g_i32ScreenIdx].psWidget); } else if(g_i32ScreenIdx == SCREEN_TI) { // // Returning to the settings screen. // FrameDraw(&g_sContext, "nfc-p2p-demo : TI"); WidgetPaint(g_sScreens[g_i32ScreenIdx].psWidget); AnimateButtons(true); WidgetMessageQueueProcess(); } // // Assumed Screen = SCREEN_SUMMARY // else { FrameDraw(&g_sContext, "nfc-p2p-demo : Summary"); WidgetPaint(g_sScreens[g_i32ScreenIdx].psWidget); } // // Enable gestures. // g_sSwipe.bEnable = true; } break; } // // If the key is not special then update the text string. // default: { if(ui32Event == KEYBOARD_EVENT_PRESS) { // // Set the string to the current string to be updated. // if(g_ui32StringIdx == 0) { CanvasTextSet(&g_sKeyboardText, g_pcKeyStr); } g_pcKeyStr[g_ui32StringIdx] = (char)ui32Key; g_ui32StringIdx++; g_pcKeyStr[g_ui32StringIdx] = 0; WidgetPaint((tWidget *)&g_sKeyboardText); // // Save the pixel width of the current string. // g_i32StringWidth = GrStringWidthGet(&g_sContext, g_pcKeyStr, 40); } break; } } }
void window_button(tContext *pContext, uint8_t key, uint8_t icon_type, const char* text) { int width; int i; long forecolor, backcolor; uint8_t upshift = 0; if (key & 0x80) { forecolor = ClrBlack; backcolor = ClrWhite; key &= ~(0x80); } else { forecolor = ClrWhite; backcolor = ClrBlack; } const tRectangle *rect= &button_rect[key]; if((icon_type&0x80) == 0x80) upshift = 13; //Draw button text GrContextFontSet(pContext, &g_sFontBaby16); if (text) { GrContextForegroundSet(pContext, backcolor); if(key == KEY_EXIT) GrStringDraw(pContext, text, -1, rect->sXMax+3, rect->sYMin - upshift , 0); else { width = GrStringWidthGet(pContext, text, -1); if(icon_type == BUTTON_NO_ICON) GrStringDraw(pContext, text, -1, (rect->sXMax - width ), rect->sYMin- upshift , 0); else GrStringDraw(pContext, text, -1, (rect->sXMin - width - 3), rect->sYMin- upshift , 0); } } //Draw button icon image switch(icon_type&0x0f) { case TRIANGLE_UP: for(i=0; i<7;i++) { GrLineDrawH(pContext, rect->sXMin+i, rect->sXMax-i, rect->sYMax - 2 - upshift - i); } break; case TRIANGLE_DOWN: for(i=0; i<7;i++) { GrLineDrawH(pContext, rect->sXMin+i, rect->sXMax-i, rect->sYMin + 2 - upshift + i); } break; case TRIANGLE_RIGHT: for(i=0; i<7;i++) { GrLineDrawV(pContext, rect->sXMin+i, rect->sYMin - upshift +i , rect->sYMax - upshift -i); } break; case TRIANGLE_LEFT: for(i=0; i<7;i++) { GrLineDrawV(pContext, rect->sXMax-i, rect->sYMin - upshift +i , rect->sYMax - upshift -i); } break; case MUSIC_PAUSE: { tRectangle rect1 = {rect->sXMin, rect->sYMin - upshift , rect->sXMin + 3 , rect->sYMax - upshift}; GrRectFill(pContext, &rect1); tRectangle rect2 = {rect->sXMin+6 , rect->sYMin - upshift , rect->sXMin + 9 , rect->sYMax - upshift}; GrRectFill(pContext, &rect2); } break; case MUSIC_NEXT: for(i=0; i<7;i++) { GrLineDrawV(pContext, rect->sXMin+i, rect->sYMin - upshift + i , rect->sYMax - upshift - i); } GrLineDrawV(pContext, rect->sXMax+2, rect->sYMin - upshift , rect->sYMax - upshift ); break; case MUSIC_PREVIOUS: for(i=0; i<7;i++) { GrLineDrawV(pContext, rect->sXMax-i, rect->sYMin- upshift + i , rect->sYMax - upshift -i); } GrLineDrawV(pContext, rect->sXMin-2, rect->sYMin - upshift , rect->sYMax - upshift); break; case BUTTON_NO_ICON: default: break; } }