static void onDraw(tContext *pContext) { // first draw the datetime uint8_t totalgrid = window_readconfig()->sports_grid + 3; GrContextForegroundSet(pContext, ClrWhite); switch(window_readconfig()->sports_grid) { case GRID_3: GrRectFill(pContext, ®ion_3grid[0]); GrLineDrawV(pContext, region_3grid[1].sXMax, region_3grid[1].sYMin, region_3grid[1].sYMax); break; case GRID_4: GrRectFill(pContext, ®ion_4grid[0]); GrLineDrawH(pContext, region_4grid[1].sXMin, region_4grid[1].sXMax, region_4grid[1].sYMax); GrLineDrawH(pContext, region_4grid[2].sXMin, region_4grid[2].sXMax, region_4grid[2].sYMax); break; case GRID_5: GrRectFill(pContext, ®ion_5grid[0]); GrLineDrawH(pContext, region_5grid[1].sXMin, region_5grid[2].sXMax, region_5grid[1].sYMax); GrLineDrawV(pContext, region_5grid[1].sXMax, region_5grid[1].sYMin, region_5grid[3].sYMax); break; } GrContextForegroundSet(pContext, ClrWhite); for(uint8_t g = 0; g < totalgrid; g++) { drawGridData(pContext, window_readconfig()->sports_grid_data[g] , grid_data[g]); } }
//***************************************************************************** // //! Draws a rectangle. //! //! \param pContext is a pointer to the drawing context to use. //! \param pRect is a pointer to the structure containing the extents of the //! rectangle. //! //! This function draws a rectangle. The rectangle will extend from \e i32XMin //! to \e i32XMax and \e i32YMin to \e i32YMax, inclusive. //! //! \return None. // //***************************************************************************** void GrRectDraw(const tContext *pContext, const tRectangle *pRect) { // // Check the arguments. // ASSERT(pContext); ASSERT(pRect); // // Draw a line across the top of the rectangle. // GrLineDrawH(pContext, pRect->i16XMin, pRect->i16XMax, pRect->i16YMin); // // Return if the rectangle is one pixel tall. // if(pRect->i16YMin == pRect->i16YMax) { return; } // // Draw a line down the right side of the rectangle. // GrLineDrawV(pContext, pRect->i16XMax, pRect->i16YMin + 1, pRect->i16YMax); // // Return if the rectangle is one pixel wide. // if(pRect->i16XMin == pRect->i16XMax) { return; } // // Draw a line across the bottom of the rectangle. // GrLineDrawH(pContext, pRect->i16XMax - 1, pRect->i16XMin, pRect->i16YMax); // // Return if the rectangle is two pixels tall. // if((pRect->i16YMin + 1) == pRect->i16YMax) { return; } // // Draw a line up the left side of the rectangle. // GrLineDrawV(pContext, pRect->i16XMin, pRect->i16YMax - 1, pRect->i16YMin + 1); }
void window_button(tContext *pContext, uint8_t key, const char* text) { long forecolor, backcolor; if (key & 0x80) { forecolor = ClrBlack; backcolor = ClrWhite; key &= ~(0x80); } else { forecolor = ClrWhite; backcolor = ClrBlack; } GrContextFontSet(pContext, &g_sFontGothic18); // draw black box if (text) { const tRectangle *rect = &button_rect[key]; GrContextForegroundSet(pContext, forecolor); GrRectFill(pContext, rect); // draw triagle for(int i = 0; i <= (rect->sYMax - rect->sYMin) /2 ; i++) { if (rect->sXMin < 20) { GrLineDrawH(pContext, rect->sXMin - i, rect->sXMin, rect->sYMin + i); GrLineDrawH(pContext, rect->sXMin - i, rect->sXMin, rect->sYMax - i); } else { GrLineDrawH(pContext, rect->sXMax, rect->sXMax + i, rect->sYMin + i); GrLineDrawH(pContext, rect->sXMax, rect->sXMax + i, rect->sYMax - i); } } GrContextForegroundSet(pContext, backcolor); GrStringDrawCentered(pContext, text, -1, (rect->sXMin + rect->sXMax) /2, (rect->sYMin + rect->sYMax) /2, 0); } else { GrContextForegroundSet(pContext, backcolor); GrRectFill(pContext, &button_rect[key]); } }
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 }
//***************************************************************************** // //! Draws a line. //! //! \param pContext is a pointer to the drawing context to use. //! \param i32X1 is the X coordinate of the start of the line. //! \param i32Y1 is the Y coordinate of the start of the line. //! \param i32X2 is the X coordinate of the end of the line. //! \param i32Y2 is the Y coordinate of the end of the line. //! //! This function draws a line, utilizing GrLineDrawH() and GrLineDrawV() to //! draw the line as efficiently as possible. The line is clipped to the //! clippping rectangle using the Cohen-Sutherland clipping algorithm, and then //! scan converted using Bresenham's line drawing algorithm. //! //! \return None. // //***************************************************************************** void GrLineDraw(const tContext *pContext, int32_t i32X1, int32_t i32Y1, int32_t i32X2, int32_t i32Y2) { int32_t i32Error, i32DeltaX, i32DeltaY, i32YStep, bSteep; // // Check the arguments. // ASSERT(pContext); // // See if this is a vertical line. // if(i32X1 == i32X2) { // // It is more efficient to avoid Bresenham's algorithm when drawing a // vertical line, so use the vertical line routine to draw this line. // GrLineDrawV(pContext, i32X1, i32Y1, i32Y2); // // The line has ben drawn, so return. // return; } // // See if this is a horizontal line. // if(i32Y1 == i32Y2) { // // It is more efficient to avoid Bresenham's algorithm when drawing a // horizontal line, so use the horizontal line routien to draw this // line. // GrLineDrawH(pContext, i32X1, i32X2, i32Y1); // // The line has ben drawn, so return. // return; } // // Clip this line if necessary, and return without drawing anything if the // line does not cross the clipping region. // if(GrLineClip(pContext, &i32X1, &i32Y1, &i32X2, &i32Y2) == 0) { return; } // // Determine if the line is steep. A steep line has more motion in the Y // direction than the X direction. // if(((i32Y2 > i32Y1) ? (i32Y2 - i32Y1) : (i32Y1 - i32Y2)) > ((i32X2 > i32X1) ? (i32X2 - i32X1) : (i32X1 - i32X2))) { bSteep = 1; } else { bSteep = 0; } // // If the line is steep, then swap the X and Y coordinates. // if(bSteep) { i32Error = i32X1; i32X1 = i32Y1; i32Y1 = i32Error; i32Error = i32X2; i32X2 = i32Y2; i32Y2 = i32Error; } // // If the starting X coordinate is larger than the ending X coordinate, // then swap the start and end coordinates. // if(i32X1 > i32X2) { i32Error = i32X1; i32X1 = i32X2; i32X2 = i32Error; i32Error = i32Y1; i32Y1 = i32Y2; i32Y2 = i32Error; } // // Compute the difference between the start and end coordinates in each // axis. // i32DeltaX = i32X2 - i32X1; i32DeltaY = (i32Y2 > i32Y1) ? (i32Y2 - i32Y1) : (i32Y1 - i32Y2); // // Initialize the error term to negative half the X delta. // i32Error = -i32DeltaX / 2; // // Determine the direction to step in the Y axis when required. // if(i32Y1 < i32Y2) { i32YStep = 1; } else { i32YStep = -1; } // // Loop through all the points along the X axis of the line. // for(; i32X1 <= i32X2; i32X1++) { // // See if this is a steep line. // if(bSteep) { // // Plot this point of the line, swapping the X and Y coordinates. // DpyPixelDraw(pContext->psDisplay, i32Y1, i32X1, pContext->ui32Foreground); } else { // // Plot this point of the line, using the coordinates as is. // DpyPixelDraw(pContext->psDisplay, i32X1, i32Y1, pContext->ui32Foreground); } // // Increment the error term by the Y delta. // i32Error += i32DeltaY; // // See if the error term is now greater than zero. // if(i32Error > 0) { // // Take a step in the Y axis. // i32Y1 += i32YStep; // // Decrement the error term by the X delta. // i32Error -= i32DeltaX; } } }
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; } } }
//***************************************************************************** // //! Draws a filled circle. //! //! \param pContext is a pointer to the drawing context to use. //! \param lX is the X coordinate of the center of the circle. //! \param lY is the Y coordinate of the center of the circle. //! \param lRadius is the radius of the circle. //! //! This function draws a filled circle, utilizing the Bresenham circle drawing //! algorithm. The extent of the circle is from \e lX - \e lRadius to \e lX + //! \e lRadius and \e lY - \e lRadius to \e lY + \e lRadius, inclusive. //! //! \return None. // //***************************************************************************** void GrCircleFill(const tContext *pContext, long lX, long lY, long lRadius) { long lA, lB, lD, lX1, lX2, lY1; // // Check the arguments. // ASSERT(pContext); // // Initialize the variables that control the Bresenham circle drawing // algorithm. // lA = 0; lB = lRadius; lD = 3 - (2 * lRadius); // // Loop until the A delta is greater than the B delta, meaning that the // entire circle has been filled. // while(lA <= lB) { // // Determine the row when subtracting the A delta. // lY1 = lY - lA; // // See if this row is within the clipping region. // if((lY1 >= pContext->sClipRegion.sYMin) && (lY1 <= pContext->sClipRegion.sYMax)) { // // Determine the column when subtracting the B delta, and move it // to the left edge of the clipping region if it is to the left of // the clipping region. // lX1 = lX - lB; if(lX1 < pContext->sClipRegion.sXMin) { lX1 = pContext->sClipRegion.sXMin; } // // Determine the column when adding the B delta, and move it to the // right edge of the clipping region if it is to the right of the // clipping region. // lX2 = lX + lB; if(lX2 > pContext->sClipRegion.sXMax) { lX2 = pContext->sClipRegion.sXMax; } // // Draw a horizontal line if this portion of the circle is within // the clipping region. // if(lX1 <= lX2) { GrLineDrawH(pContext, lX1, lX2, lY1); } } // // Determine the row when adding the A delta. // lY1 = lY + lA; // // See if this row is within the clipping region, and the A delta is // not zero (otherwise, this describes the same row of the circle). // if((lY1 >= pContext->sClipRegion.sYMin) && (lY1 <= pContext->sClipRegion.sYMax) && (lA != 0)) { // // Determine the column when subtracting the B delta, and move it // to the left edge of the clipping region if it is to the left of // the clipping region. // lX1 = lX - lB; if(lX1 < pContext->sClipRegion.sXMin) { lX1 = pContext->sClipRegion.sXMin; } // // Determine the column when adding the B delta, and move it to the // right edge of the clipping region if it is to the right of the // clipping region. // lX2 = lX + lB; if(lX2 > pContext->sClipRegion.sXMax) { lX2 = pContext->sClipRegion.sXMax; } // // Draw a horizontal line if this portion of the circle is within // the clipping region. // if(lX1 <= lX2) { GrLineDrawH(pContext, lX1, lX2, lY1); } } // // Only draw the complementary lines if the B delta is about to change // and the A and B delta are different (otherwise, they describe the // same set of pixels). // if((lD >= 0) && (lA != lB)) { // // Determine the row when subtracting the B delta. // lY1 = lY - lB; // // See if this row is within the clipping region. // if((lY1 >= pContext->sClipRegion.sYMin) && (lY1 <= pContext->sClipRegion.sYMax)) { // // Determine the column when subtracting the A delta, and move // it to the left edge of the clipping regino if it is to the // left of the clipping region. // lX1 = lX - lA; if(lX1 < pContext->sClipRegion.sXMin) { lX1 = pContext->sClipRegion.sXMin; } // // Determine the column when adding the A delta, and move it to // the right edge of the clipping region if it is to the right // of the clipping region. // lX2 = lX + lA; if(lX2 > pContext->sClipRegion.sXMax) { lX2 = pContext->sClipRegion.sXMax; } // // Draw a horizontal line if this portion of the circle is // within the clipping region. // if(lX1 <= lX2) { GrLineDrawH(pContext, lX1, lX2, lY1); } } // // Determine the row when adding the B delta. // lY1 = lY + lB; // // See if this row is within the clipping region. // if((lY1 >= pContext->sClipRegion.sYMin) && (lY1 <= pContext->sClipRegion.sYMax)) { // // Determine the column when subtracting the A delta, and move // it to the left edge of the clipping region if it is to the // left of the clipping region. // lX1 = lX - lA; if(lX1 < pContext->sClipRegion.sXMin) { lX1 = pContext->sClipRegion.sXMin; } // // Determine the column when adding the A delta, and move it to // the right edge of the clipping region if it is to the right // of the clipping region. // lX2 = lX + lA; if(lX2 > pContext->sClipRegion.sXMax) { lX2 = pContext->sClipRegion.sXMax; } // // Draw a horizontal line if this portion of the circle is // within the clipping region. // if(lX1 <= lX2) { GrLineDrawH(pContext, lX1, lX2, lY1); } } } // // See if the error term is negative. // if(lD < 0) { // // Since the error term is negative, adjust it based on a move in // only the A delta. // lD += (4 * lA) + 6; } else { // // Since the error term is non-negative, adjust it based on a move // in both the A and B deltas. // lD += (4 * (lA - lB)) + 10; // // Decrement the B delta. // lB -= 1; } // // Increment the A delta. // lA++; } }
static void OnDraw(tContext* pContext) { // clear the region GrContextForegroundSet(pContext, ClrBlack); GrRectFill(pContext, &status_clip); GrContextForegroundSet(pContext, ClrWhite); GrLineDrawH(pContext, 0, pContext->pDisplay->usWidth, 16); GrContextFontSet(pContext, (tFont*)&g_sFontExIcon16); char icon; int x = CHARGE_X; switch(status & 0x03) { case BATTERY_EMPTY: icon = ICON_BATTERY_EMPTY; break; case BATTERY_LESS: icon = ICON_BATTERY_LESS; break; case BATTERY_MORE: icon = ICON_BATTERY_MORE; break; case BATTERY_FULL: icon = ICON_BATTERY_FULL; break; default: icon = 0; } if (status & BATTERY_CHARGING) { GrStringDraw(pContext, &icon, 1, 120, 0, 0); icon = ICON_CHARGING; GrStringDraw(pContext, &icon, 1, 137, 0, 0); } else { GrStringDraw(pContext, &icon, 1, 127, 0, 0); } x = 2; if (status & ALARM_STATUS) { icon = ICON_ALARM; GrStringDraw(pContext, &icon, 1, x, 0, 0); x += 15; } if (status & BLUETOOTH_STATUS) { icon = ICON_BT; GrStringDraw(pContext, &icon, 1, x, 0, 0); } if (status & MID_STATUS) { char icon = ICON_RUN; // draw activity GrContextFontSet(pContext, (tFont*)&g_sFontExIcon16); GrStringDraw(pContext, &icon, 1, 48, 0, 0); uint16_t part = window_readconfig()->goal_steps / 5; uint16_t steps = ped_get_steps(); for(int i = 0; i < 5; i++) { if (i * part + part / 2 <= steps) { GrCircleFill(pContext, 68 + i*6, 7, 2); } else { GrCircleDraw(pContext, 68 + i*6, 7, 2); } } } else { uint8_t hour, minute; char buf[20]; uint8_t ispm; rtc_readtime(&hour, &minute, NULL); adjustAMPM(hour, &hour, &ispm); sprintf(buf, "%02d:%02d %s", hour, minute, ispm?"PM":"AM"); #if defined(PRODUCT_W002) || defined(PRODUCT_W004) GrContextFontSet(pContext, (tFont*)&g_sFontRonda12); #else GrContextFontSet(pContext, &g_sFontGothic14); #endif GrStringDrawCentered(pContext, buf, -1, pContext->pDisplay->usWidth/2, 8, 0); } }
//***************************************************************************** // //! Draws the strip chart into a drawing context, off-screen buffer. //! //! \param psChartWidget points at the StripsChartWidget being processed. //! \param psContext points to the context where all drawing should be done. //! //! This function renders a strip chart into a drawing context. //! It assumes that the drawing context is an off-screen buffer, and that //! the entire buffer belongs to this widget. //! //! \return None. // //***************************************************************************** void StripChartDraw(tStripChartWidget *psChartWidget, tContext *psContext) { tStripChartAxis *psAxisY; int32_t i32Y; int32_t i32Ygrid; int32_t i32X; int32_t i32GridRange; int32_t i32DispRange; int32_t i32GridMin; int32_t i32DispMax; tStripChartSeries *psSeries; // // Check the parameters // ASSERT(psChartWidget); ASSERT(psContext); ASSERT(psChartWidget->psAxisY); // // Get handy pointer to Y axis // psAxisY = psChartWidget->psAxisY; // // Find the range of Y axis in Y axis units // i32GridRange = psAxisY->i32Max - psAxisY->i32Min; // // Find the range of the Y axis in display units (pixels) // i32DispRange = (psContext->sClipRegion.i16YMax - psContext->sClipRegion.i16YMin); // // Find the minimum Y units value to be shown, and the maximum of the // clipping region. // i32GridMin = psAxisY->i32Min; i32DispMax = psContext->sClipRegion.i16YMax; // // Set the fg color for the rectangle fill to match what we want as the // chart background. // GrContextForegroundSet(psContext, psChartWidget->ui32BackgroundColor); GrRectFill(psContext, &psContext->sClipRegion); // // Draw vertical grid lines // GrContextForegroundSet(psContext, psChartWidget->ui32GridColor); for(i32X = psChartWidget->i32GridX; i32X < psContext->sClipRegion.i16XMax; i32X += psChartWidget->psAxisX->i32GridInterval) { GrLineDrawV(psContext, psContext->sClipRegion.i16XMax - i32X, psContext->sClipRegion.i16YMin, psContext->sClipRegion.i16YMax); } // // Draw horizontal grid lines // for(i32Ygrid = psAxisY->i32Min; i32Ygrid < psAxisY->i32Max; i32Ygrid += psAxisY->i32GridInterval) { i32Y = ((i32Ygrid - i32GridMin) * i32DispRange) / i32GridRange; i32Y = i32DispMax - i32Y; GrLineDrawH(psContext, psContext->sClipRegion.i16XMin, psContext->sClipRegion.i16XMax, i32Y); } // // Compute location of Y=0 line, and draw it // i32Y = ((-i32GridMin) * i32DispRange) / i32GridRange; i32Y = i32DispMax - i32Y; GrLineDrawH(psContext, psContext->sClipRegion.i16XMin, psContext->sClipRegion.i16XMax, i32Y); // // Iterate through each series to draw it // psSeries = psChartWidget->psSeries; while(psSeries) { int idx = 0; // // Find the starting X position on the display for this series. // If the series has less data points than can fit on the display // then starting X can be somewhere in the middle of the screen. // i32X = 1 + psContext->sClipRegion.i16XMax - psSeries->ui16NumItems; // // If the starting X is off the left side of the screen, then the // staring index (idx) for reading data needs to be adjusted to the // first value in the series that will be visible on the screen // if(i32X < psContext->sClipRegion.i16XMin) { idx = psContext->sClipRegion.i16XMin - i32X; i32X = psContext->sClipRegion.i16XMin; } // // Set the drawing color for this series // GrContextForegroundSet(psContext, psSeries->ui32Color); // // Scan through all possible X values, find the Y value, and draw the // pixel. // for(; i32X <= psContext->sClipRegion.i16XMax; i32X++) { // // Find the Y value at each position in the data series. Take into // account the data size and the stride // if(psSeries->ui8DataTypeSize == 1) { i32Y = ((int8_t *)psSeries->pvData)[idx * psSeries->ui8Stride]; } else if(psSeries->ui8DataTypeSize == 2) { i32Y = ((int16_t *)psSeries->pvData)[idx * psSeries->ui8Stride]; } else if(psSeries->ui8DataTypeSize == 4) { i32Y = ((int32_t *)psSeries->pvData)[idx * psSeries->ui8Stride]; } else { // // If there is an invalid data size, then just force Y value // to be off the display // i32Y = i32DispMax + 1; break; } // // Advance to the next position in the data series. // idx++; // // Now scale the Y value according to the axis scaling // i32Y = ((i32Y - i32GridMin) * i32DispRange) / i32GridRange; i32Y = i32DispMax - i32Y; // // Draw the pixel on the display // GrPixelDraw(psContext, i32X, i32Y); } // // Advance to the next series until there are no more. // psSeries = psSeries->psNextSeries; } // // Draw a frame around the entire chart. // GrContextForegroundSet(psContext, psChartWidget->ui32Y0Color); GrRectDraw(psContext, &psContext->sClipRegion); // // Draw titles // GrContextForegroundSet(psContext, psChartWidget->ui32TextColor); GrContextFontSet(psContext, psChartWidget->psFont); // // Draw the chart title, if there is one // if(psChartWidget->pcTitle) { GrStringDrawCentered(psContext, psChartWidget->pcTitle, -1, psContext->sClipRegion.i16XMax / 2, GrFontHeightGet(psChartWidget->psFont), 0); } // // Draw the Y axis max label, if there is one // if(psChartWidget->psAxisY->pcMaxLabel) { GrStringDraw(psContext, psChartWidget->psAxisY->pcMaxLabel, -1, psContext->sClipRegion.i16XMin + GrFontMaxWidthGet(psChartWidget->psFont) / 2, GrFontHeightGet(psChartWidget->psFont) / 2, 0); } // // Draw the Y axis min label, if there is one // if(psChartWidget->psAxisY->pcMinLabel) { GrStringDraw(psContext, psChartWidget->psAxisY->pcMinLabel, -1, psContext->sClipRegion.i16XMin + GrFontMaxWidthGet(psChartWidget->psFont) / 2, psContext->sClipRegion.i16YMax - (GrFontHeightGet(psChartWidget->psFont) + (GrFontHeightGet(psChartWidget->psFont) / 2)), 0); } // // Draw a label for the name of the Y axis, if there is one // if(psChartWidget->psAxisY->pcName) { GrStringDraw(psContext, psChartWidget->psAxisY->pcName, -1, psContext->sClipRegion.i16XMin + 1, (psContext->sClipRegion.i16YMax / 2) - (GrFontHeightGet(psChartWidget->psFont) / 2), 1); } }
//***************************************************************************** // // Handle the animation when switching between screens. // //***************************************************************************** void AnimatePanel(uint32_t ui32Color) { int32_t i32Idx; GrContextForegroundSet(&g_sContext, ui32Color); if(g_i32ScreenIdx == SCREEN_DETAILS) { for(i32Idx = BG_MAX_Y; i32Idx >= BG_MIN_Y; i32Idx--) { GrLineDrawH(&g_sContext, BG_MIN_X, BG_MAX_X, i32Idx); if(i32Idx == 40) { WidgetPaint((tWidget *)&g_sHeaderTitle); WidgetMessageQueueProcess(); } else if(i32Idx == 70) { WidgetPaint((tWidget *)&g_sHeaderLine1); WidgetMessageQueueProcess(); } else if(i32Idx == 100) { WidgetPaint((tWidget *)&g_sHeaderLine2); WidgetMessageQueueProcess(); } else if(i32Idx == 130) { WidgetPaint((tWidget *)&g_sHeaderLine3); WidgetMessageQueueProcess(); } else if(i32Idx == 160) { WidgetPaint((tWidget *)&g_sHeaderLine4); WidgetMessageQueueProcess(); } else if(i32Idx == 190) { WidgetPaint((tWidget *)&g_sHeaderLine5); WidgetMessageQueueProcess(); } SysCtlDelay(SCREEN_ANIMATE_DELAY); } } else if(g_i32ScreenIdx == SCREEN_SUMMARY) { for(i32Idx = BG_MAX_Y; i32Idx >= BG_MIN_Y; i32Idx--) { GrLineDrawH(&g_sContext, BG_MIN_X, BG_MAX_X, i32Idx); if(i32Idx == 210) { WidgetPaint((tWidget *)&g_sPayloadLine8); WidgetMessageQueueProcess(); } else if(i32Idx == 195) { WidgetPaint((tWidget *)&g_sPayloadLine7); WidgetMessageQueueProcess(); } else if(i32Idx == 180) { WidgetPaint((tWidget *)&g_sPayloadLine6); WidgetMessageQueueProcess(); } else if(i32Idx == 165) { WidgetPaint((tWidget *)&g_sPayloadLine5); WidgetMessageQueueProcess(); } else if(i32Idx == 150) { WidgetPaint((tWidget *)&g_sPayloadLine4); WidgetMessageQueueProcess(); } else if(i32Idx == 135) { WidgetPaint((tWidget *)&g_sPayloadLine3); WidgetMessageQueueProcess(); } else if(i32Idx == 120) { WidgetPaint((tWidget *)&g_sPayloadLine2); WidgetMessageQueueProcess(); } else if(i32Idx == 105) { WidgetPaint((tWidget *)&g_sPayloadLine1); WidgetMessageQueueProcess(); } else if(i32Idx == 75) { WidgetPaint((tWidget *)&g_sPayloadTitle); WidgetMessageQueueProcess(); } else if(i32Idx == 40) { WidgetPaint((tWidget *)&g_sTag); WidgetMessageQueueProcess(); WidgetPaint((tWidget *)&g_sTagTitle); WidgetMessageQueueProcess(); } SysCtlDelay(SCREEN_ANIMATE_DELAY); } } else if(g_i32ScreenIdx == SCREEN_TI) { for(i32Idx = BG_MIN_Y; i32Idx < BG_MAX_Y; i32Idx++) { GrLineDrawH(&g_sContext, BG_MIN_X, BG_MAX_X, i32Idx); if (i32Idx == 100) { GrImageDraw(&g_sContext, g_pui8TILogo, BG_MIN_X, BG_MIN_Y); } else if(i32Idx == 140) { WidgetPaint((tWidget *)&g_sStatusLine1); WidgetMessageQueueProcess(); GrContextForegroundSet(&g_sContext, ui32Color); } else if(i32Idx == 170) { //DrawToggle(&sProxyToggle, g_sConfig.bProxyEnabled); WidgetPaint((tWidget *)&g_sStatusLine2); GrContextForegroundSet(&g_sContext, ui32Color); WidgetMessageQueueProcess(); } else if(i32Idx == 230) { WidgetPaint((tWidget *)&g_sTINFCButton); WidgetPaint((tWidget *)&g_sEchoNFCButton); GrContextForegroundSet(&g_sContext, ui32Color); WidgetMessageQueueProcess(); } SysCtlDelay(SCREEN_ANIMATE_DELAY); } } }
//***************************************************************************** // // Draw the pop up buttons on the screen. // //***************************************************************************** static void DrawButtons(int32_t i32Offset, bool bClear) { static const tRectangle sRectTop = { 140, BG_MIN_Y, 171, BG_MIN_Y + 10, }; static const tRectangle sRectRight = { BG_MAX_X - 11, BG_MIN_Y - 20 + ((BG_MAX_Y - BG_MIN_Y) / 2), BG_MAX_X, BG_MIN_Y - 20 + ((BG_MAX_Y - BG_MIN_Y) / 2) + 40, }; static const tRectangle sRectLeft = { BG_MIN_X, BG_MIN_Y - 20 + ((BG_MAX_Y - BG_MIN_Y) / 2), BG_MIN_X + 10, BG_MIN_Y - 20 + ((BG_MAX_Y - BG_MIN_Y) / 2) + 40, }; // // Only draw if they are enabled. // if(g_sButtons.bEnabled == false) { return; } // // Draw the three pop up buttons. // if(g_i32ScreenIdx == SCREEN_SUMMARY || g_i32ScreenIdx == SCREEN_DETAILS) { GrContextForegroundSet(&g_sContext, ClrBlack); GrContextBackgroundSet(&g_sContext, ClrGray); GrRectFill(&g_sContext, &sRectRight); GrRectFill(&g_sContext, &sRectLeft); if(bClear == false) { GrLineDrawH(&g_sContext, 140, 171, BG_MIN_Y + 10 + i32Offset); GrImageDraw(&g_sContext, g_pui8DownTabImage, 140, BG_MIN_Y + i32Offset); GrTransparentImageDraw(&g_sContext, g_pui8RightImage, BG_MAX_X - 10 + i32Offset, BG_MIN_Y - 20 + ((BG_MAX_Y - BG_MIN_Y) / 2), 1); GrTransparentImageDraw(&g_sContext, g_pui8LeftImage, BG_MIN_X - i32Offset, BG_MIN_Y - 20 + ((BG_MAX_Y - BG_MIN_Y) / 2), 1); } else { GrRectFill(&g_sContext, &sRectTop); } } else if(g_i32ScreenIdx == SCREEN_TI) { GrContextForegroundSet(&g_sContext, ClrGray); GrContextBackgroundSet(&g_sContext, ClrWhite); if(bClear == false) { GrLineDrawH(&g_sContext, 140, 171, BG_MAX_Y - 11 - i32Offset); GrImageDraw(&g_sContext, g_pui8UpTabImage, 140, BG_MAX_Y - 10 - i32Offset); } } }
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; } }
static void OnDraw(tContext *pContext) { char buf[20]; // clear screen GrContextForegroundSet(pContext, ClrBlack); GrContextBackgroundSet(pContext, ClrWhite); GrRectFill(pContext, &fullscreen_clip); // draw table title GrContextForegroundSet(pContext, ClrWhite); GrContextBackgroundSet(pContext, ClrBlack); const tRectangle rect = {0, 27, 255, 41}; GrRectFill(pContext, &rect); // draw the title bar GrContextFontSet(pContext, &g_sFontGothic18b); sprintf(buf, "%s %d", toMonthName(month, 1), year); GrStringDrawCentered(pContext, buf, -1, LCD_WIDTH / 2, 15, 0); GrContextForegroundSet(pContext, ClrBlack); GrContextBackgroundSet(pContext, ClrWhite); GrContextFontSet(pContext, &g_sFontGothic18); for(int i = 0; i < 7; i++) { GrStringDrawCentered( pContext, week_shortname[i], -1, i * 20 + 11, 35, 0); // draw line in title bar GrLineDrawV(pContext, i * 20, 28, 42); } GrContextFontSet(pContext, &g_sFontGothic18); GrContextForegroundSet(pContext, ClrWhite); GrContextBackgroundSet(pContext, ClrBlack); // get the start point of this month uint8_t weekday = rtc_getweekday(year, month, 1) - 1; // use 0 as index uint8_t maxday = rtc_getmaxday(year, month); uint8_t y = 50; for(int day = 1; day <= maxday; day++) { sprintf(buf, "%d", day); uint8_t today = now_year == year && now_month == month && now_day == day; if (today) { const tRectangle rect = {weekday * 20 + 1, y - 7, 20 + weekday * 20 - 1, y + 7}; GrRectFill(pContext, &rect); GrContextForegroundSet(pContext, ClrBlack); GrContextBackgroundSet(pContext, ClrWhite); } GrStringDrawCentered( pContext, buf, -1, weekday * 20 + 11, y, 0); if (today) { const tRectangle rect2 = {weekday * 20 + 16, y - 5, weekday * 20 + 17, y - 4}; GrRectFill(pContext, &rect2); GrContextForegroundSet(pContext, ClrWhite); GrContextBackgroundSet(pContext, ClrBlack); } if (weekday != 6) GrLineDrawV(pContext, (weekday + 1 ) * 20, 42, y + 7); weekday++; if (weekday == 7) { GrLineDrawH(pContext, 0, LCD_WIDTH, y + 8); weekday = 0; y += 20; } } GrLineDrawH(pContext, 0, weekday * 20, y + 8); // draw the buttons if (month == 1) sprintf(buf, "%s %d", toMonthName(12, 0), year - 1); else sprintf(buf, "%s %d", toMonthName(month - 1, 0), year); window_button(pContext, KEY_ENTER, buf); if (month == 12) sprintf(buf, "%s %d", toMonthName(1, 0), year + 1); else sprintf(buf, "%s %d", toMonthName(month + 1, 0), year); window_button(pContext, KEY_DOWN, buf); }
//***************************************************************************** // //! Draws a line. //! //! \param pContext is a pointer to the drawing context to use. //! \param lX1 is the X coordinate of the start of the line. //! \param lY1 is the Y coordinate of the start of the line. //! \param lX2 is the X coordinate of the end of the line. //! \param lY2 is the Y coordinate of the end of the line. //! //! This function draws a line, utilizing GrLineDrawH() and GrLineDrawV() to //! draw the line as efficiently as possible. The line is clipped to the //! clippping rectangle using the Cohen-Sutherland clipping algorithm, and then //! scan converted using Bresenham's line drawing algorithm. //! //! \return None. // //***************************************************************************** void GrLineFill(const tContext *pContext, long lX1, long lY1, long lX2, long lY2, long width) { long lError, lDeltaX, lDeltaY, lYStep, bSteep; long lWStart, lWEnd; lWEnd = width/2; lWStart = lWEnd - width; // // Check the arguments. // ASSERT(pContext); GrCircleFill(pContext, lX1, lY1, width/2); GrCircleFill(pContext, lX2, lY2, width/2); // // See if this is a vertical line. // if(lX1 == lX2) { // // It is more efficient to avoid Bresenham's algorithm when drawing a // vertical line, so use the vertical line routine to draw this line. // for(long i = lWStart; i <= lWEnd; i++) GrLineDrawV(pContext, lX1 + i, lY1, lY2); // // The line has ben drawn, so return. // return; } // // See if this is a horizontal line. // if(lY1 == lY2) { // // It is more efficient to avoid Bresenham's algorithm when drawing a // horizontal line, so use the horizontal line routien to draw this // line. // for(long i = lWStart; i <= lWEnd; i++) GrLineDrawH(pContext, lX1, lX2, lY1+i); // // The line has ben drawn, so return. // return; } // // Clip this line if necessary, and return without drawing anything if the // line does not cross the clipping region. // if(GrLineClip(pContext, &lX1, &lY1, &lX2, &lY2) == 0) { return; } // // Determine if the line is steep. A steep line has more motion in the Y // direction than the X direction. // if(((lY2 > lY1) ? (lY2 - lY1) : (lY1 - lY2)) > ((lX2 > lX1) ? (lX2 - lX1) : (lX1 - lX2))) { bSteep = 1; } else { bSteep = 0; } // // If the line is steep, then swap the X and Y coordinates. // if(bSteep) { lError = lX1; lX1 = lY1; lY1 = lError; lError = lX2; lX2 = lY2; lY2 = lError; } // // If the starting X coordinate is larger than the ending X coordinate, // then swap the start and end coordinates. // if(lX1 > lX2) { lError = lX1; lX1 = lX2; lX2 = lError; lError = lY1; lY1 = lY2; lY2 = lError; } // // Compute the difference between the start and end coordinates in each // axis. // lDeltaX = lX2 - lX1; lDeltaY = (lY2 > lY1) ? (lY2 - lY1) : (lY1 - lY2); // // Initialize the error term to negative half the X delta. // lError = -lDeltaX / 2; // // Determine the direction to step in the Y axis when required. // if(lY1 < lY2) { lYStep = 1; } else { lYStep = -1; } // // Loop through all the points along the X axis of the line. // for(; lX1 <= lX2; lX1++) { // // See if this is a steep line. // if(bSteep) { // // Plot this point of the line, swapping the X and Y coordinates. // //DpyPixelDraw(pContext->pDisplay, lY1, lX1, pContext->ulForeground); GrLineDrawH(pContext, lY1 + lWStart, lY1 + lWEnd, lX1); } else { // // Plot this point of the line, using the coordinates as is. // //DpyPixelDraw(pContext->pDisplay, lX1, lY1, pContext->ulForeground); GrLineDrawV(pContext, lX1, lY1 + lWStart, lY1 + lWEnd); } // // Increment the error term by the Y delta. // lError += lDeltaY; // // See if the error term is now greater than zero. // if(lError > 0) { // // Take a step in the Y axis. // lY1 += lYStep; // // Decrement the error term by the X delta. // lError -= lDeltaX; } } }