static void run_window_events(windowproc window, struct _event *events) { struct _event *ev = events; PROCESS_CONTEXT_BEGIN(ui_process); int ret = window(ev->event, ev->lparam, ev->rparam); //GrContextFontSet(&context, (const tFont*)NULL); if (ret != 0x80) { status_process(EVENT_WINDOW_PAINT, 0, &context); GrContextClipRegionSet(&context, &client_clip); } else GrContextClipRegionSet(&context, &fullscreen_clip); ev++; for(; ev->delta != -1; ev++) { window(ev->event, ev->lparam, ev->rparam); if (ev->event == EVENT_WINDOW_PAINT) { GrFlush(&context); } } PROCESS_CONTEXT_END(); }
//***************************************************************************** // //! Paints a menu, menu items on a display. //! //! \param psWidget is a pointer to the slide menu widget to be drawn. //! //! This function draws the contents of a slide menu on the display. This is //! called in response to a \b WIDGET_MSG_PAINT message. //! //! \return None. // //***************************************************************************** static void SlideMenuPaint(tWidget *psWidget) { tSlideMenuWidget *psMenuWidget; tContext sContext; // // Check the arguments. // ASSERT(psWidget); // // If this widget has a child widget, that means that the menu has // slid off the screen and the child widget is in control. Therefore // there is nothing to paint here. Just exit and the child widget will // be painted. // if(psWidget->psChild) { return; } // // Convert the generic widget pointer into a slide menu widget pointer, // and get a pointer to its context. // psMenuWidget = (tSlideMenuWidget *)psWidget; // // Initialize a context for the primary off-screen drawing buffer. // Clip region is set to entire display by default, which is what we want. // GrContextInit(&sContext, psMenuWidget->psDisplayA); // // Render the menu into the off-screen buffer, using normal vertical // position. // SlideMenuDraw(psMenuWidget, &sContext, 0); // // Initialize a drawing context for the display where the widget is to be // drawn. This is the physical display, not an off-screen buffer. // GrContextInit(&sContext, psWidget->psDisplay); // // Initialize the clipping region on the physical display, based on the // extents of this widget. // GrContextClipRegionSet(&sContext, &(psWidget->sPosition)); // // Now copy the rendered menu into the physical display. This will show // the menu on the display. // GrImageDraw(&sContext, psMenuWidget->psDisplayA->pvDisplayData, psWidget->sPosition.i16XMin, psWidget->sPosition.i16YMin); }
void TestControl(CuTest* tc) { GrContextClipRegionSet(&context, &client_clip); GrContextForegroundSet(&context, ClrBlack); GrRectFill(&context, &client_clip); GrContextForegroundSet(&context, ClrWhite); window_volume(&context, 20, 100, 8, 4); GrFlush(&context); }
static void test_window_stopwatch(windowproc window, void* data) { window(EVENT_WINDOW_CREATED, 0, data); // GrContextClipRegionSet(&context, &status_clip); // status_process(EVENT_WINDOW_PAINT, 0, &context); for(int i = 3; i >= 0; i--) window(EVENT_KEY_PRESSED, KEY_ENTER, (void*)0); GrContextClipRegionSet(&context, &client_clip); GrContextForegroundSet(&context, ClrWhite); window(EVENT_WINDOW_PAINT, 0, &context); GrFlush(&context); window(EVENT_WINDOW_CLOSING, 0, 0); }
//***************************************************************************** // // Draw a string of text centered within an outlined rectangle. // // \param pszText is a pointer to the zero-terminated ASCII string which will // be displayed within the given rectangle. // \param prectOutline points to the rectangle within which the test is to be // displayed. // \param psColors points to a structure defining the colors to be used for // the background, outline and text. // // This function draws a text string centered within a given rectangle. The // rectangle is filled with a given color and outlined in another color prior // to drawing the text. // // \return None. // //***************************************************************************** void DrawTextBox(const char *pszText, tRectangle *prectOutline, tOutlineTextColors *psColors) { // // Set the clipping region to guard against text strings that are too // long for the supplied rectangle. // GrContextClipRegionSet(&g_sContext, prectOutline); // // Draw the background area // GrContextForegroundSet(&g_sContext, psColors->ulBackground); GrRectFill(&g_sContext, prectOutline); // // Draw the border // GrContextForegroundSet(&g_sContext, psColors->ulBorder); GrRectDraw(&g_sContext, prectOutline); // // Draw the text // GrContextForegroundSet(&g_sContext, psColors->ulText); GrStringDrawCentered(&g_sContext, (char *)pszText, strlen(pszText), (prectOutline->sXMax + prectOutline->sXMin) / 2, (prectOutline->sYMax + prectOutline->sYMin) / 2, false); // // Remove our clipping area. // GrContextClipRegionSet(&g_sContext, &g_sRectDisplay); }
//***************************************************************************** // //! Paints the strip chart on the display. //! //! \param psWidget is a pointer to the strip chart widget to be drawn. //! //! This function draws the contents of a strip chart on the display. This is //! called in response to a \b WIDGET_MSG_PAINT message. //! //! \return None. // //***************************************************************************** static void StripChartPaint(tWidget *psWidget) { tStripChartWidget *psChartWidget; tContext sContext; // // Check the arguments. // ASSERT(psWidget); ASSERT(psWidget->psDisplay); // // Convert the generic widget pointer into a strip chart widget pointer. // psChartWidget = (tStripChartWidget *)psWidget; // // Initialize a context for the primary off-screen drawing buffer. // Clip region is set to entire display by default, which is what we want. // ASSERT(psChartWidget->psOffscreenDisplay); GrContextInit(&sContext, psChartWidget->psOffscreenDisplay); // // Render the strip chart into the off-screen buffer // StripChartDraw(psChartWidget, &sContext); // // Initialize a drawing context for the display where the widget is to be // drawn. This is the physical display, not an off-screen buffer. // GrContextInit(&sContext, psWidget->psDisplay); // // Initialize the clipping region on the physical display, based on the // extents of this widget. // GrContextClipRegionSet(&sContext, &(psWidget->sPosition)); // // Now copy the rendered strip chart into the physical display // GrImageDraw(&sContext, psChartWidget->psOffscreenDisplay->pvDisplayData, psWidget->sPosition.i16XMin, psWidget->sPosition.i16YMin); }
static void onDrawTitleBar(tContext *pContext) { // draw the title bar of circles const tRectangle rect = {0, 0, LCD_WIDTH, 12}; GrContextForegroundSet(pContext, ClrBlack); GrContextClipRegionSet(pContext, &rect); GrRectFill(pContext, &rect); GrContextForegroundSet(pContext, ClrWhite); long startx = LCD_WIDTH/2 - num_uids * 4; for(int i = 0; i < num_uids; i++) { if (i == selectidx) GrCircleFill(pContext, startx + i * 10, 4, 3); else GrCircleDraw(pContext, startx + i * 10, 4, 3); } }
//***************************************************************************** // //! Draws a the full keyboard. //! //! \param psWidget is a pointer to the keyboard widget to be drawn. //! //! This function draws a the full keyboard. This is called whenever //! the full keyboard needs to be updated. //! //! \return None. // //***************************************************************************** static void KeyboardPaint(tWidget *psWidget) { int32_t i32Key; tKeyboardWidget *psKeyboardWidget; const tKeyboard *psKeyboard; tContext sCtx; // // Convert the generic widget pointer into a keyboard widget pointer. // psKeyboardWidget = (tKeyboardWidget *)psWidget; psKeyboard = &psKeyboardWidget->psKeyboards[psKeyboardWidget->ui32Active]; // // Initialize a drawing context. // GrContextInit(&sCtx, psWidget->psDisplay); // // Initialize the clipping region based on the extents of this keyboard. // GrContextClipRegionSet(&sCtx, &(psWidget->sPosition)); // // Fill the keyboard with the fill color. // if(psKeyboardWidget->ui32Style & KEYBOARD_STYLE_BG) { GrContextForegroundSet(&sCtx, psKeyboardWidget->ui32BackgroundColor); GrRectFill(&sCtx, &psWidget->sPosition); } for(i32Key = 0; i32Key < psKeyboard->ui16NumKeys; i32Key++) { ButtonPaintText(psWidget, &psKeyboard->uKeys.psKeysText[i32Key]); } }
//***************************************************************************** // //! 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; } } }
//***************************************************************************** // // Paint the blocks in the game play area. // //***************************************************************************** void OnGameAreaPaint(tWidget *pWidget, tContext *pContext) { static const struct shape *psLastShape; static tBoolean bLastMsgShown = false; unsigned long ulIndex, ulRow, ulCol; tRectangle rectBlock; // // Update the score if necessary. // if (score != g_iCurScore) { usnprintf(g_pcScore, MAX_SCORE_LEN, " %d ", score); WidgetPaint((tWidget *)&g_sScore); g_iCurScore = score; } // // Draw a preview of the next shape if it is different // if (nextshape != psLastShape) { WidgetPaint((tWidget *)&g_sNextPiece); psLastShape = nextshape; } // // Has the screen just been cleared? If so, we fill the whole background // in a single operation rather than doing it cell-by-cell. // if(g_bScreenCleared) { // // Draw the logo into the background of the game area. // GrImageDraw(&g_sScreenContext, g_pucTILogo240x120, GAME_AREA_LEFT, GAME_AREA_TOP); } // // Loop through the rows (which are actually columns in our implementation // since we've rotated the board). // for (ulRow = D_FIRST; ulRow < (D_LAST - 1); ulRow++) { // // Get the index of the first block in this row. // ulIndex = ulRow * B_COLS; // // Loop through all the displayed colums (rows in our implementation) // for (ulCol = 1; ulCol < (B_COLS - 1); ulCol++) { // // If the block on the screen is different from the one we have been // asked to draw, draw it. We also force a redraw of everything if // we had a message displayed last time we repainted but it has // since been removed. // if ((board[ulIndex + ulCol] != g_psCurScreen[ulIndex + ulCol]) || (bLastMsgShown && !g_bMsgShown)) { // // Calculate the coordinates of this block. // rectBlock.sXMin = GAME_AREA_LEFT + ((ulRow - D_FIRST) * GAME_BLOCK_SIZE); rectBlock.sYMin = GAME_AREA_TOP + ((ulCol - 1) * GAME_BLOCK_SIZE); rectBlock.sXMax = rectBlock.sXMin + (GAME_BLOCK_SIZE - 1); rectBlock.sYMax = rectBlock.sYMin + (GAME_BLOCK_SIZE - 1); // // Remember what we are about to draw into the current cell. // g_psCurScreen[ulIndex + ulCol] = board[ulIndex + ulCol]; // // Draw this block of the shape. We use either an image if one // is defined or black otherwise. // if(g_ppucBlockImages[board[ulIndex + ulCol]]) { // // If we just cleared the whole background, there is no // need to reblit the background blocks. // if(!g_bScreenCleared) { GrImageDraw(&g_sScreenContext, g_ppucBlockImages[board[ulIndex + ulCol]], (long)rectBlock.sXMin, (long)rectBlock.sYMin); } } else { tRectangle sRect; // // Draw the block from the background image. First save // the existing clipping region. // sRect = g_sScreenContext.sClipRegion; // // Set the new clipping region to the block we are about // to draw. // GrContextClipRegionSet(&g_sScreenContext, &rectBlock); // // Draw the background image into the clipping region. // GrImageDraw(&g_sScreenContext, g_pucTILogo240x120, GAME_AREA_LEFT, GAME_AREA_TOP); // // Restore the previous clip region. // GrContextClipRegionSet(&g_sScreenContext, &sRect); } } } } // // If there is a message to show, draw it on top of the game area. // if(g_bMsgShown) { // // Determine the center of the game area. // rectBlock.sXMin = GAME_AREA_LEFT + (GAME_BLOCK_SIZE * ((D_LAST - 1) - D_FIRST)) / 2; rectBlock.sYMin = GAME_AREA_TOP + ((GAME_BLOCK_SIZE * (B_COLS - 2)) / 2); // // Render the required message centered in the game area. // GrContextFontSet(&g_sScreenContext, g_pFontCmss20b); GrContextForegroundSet(&g_sScreenContext, MESSAGE_COLOR); GrContextBackgroundSet(&g_sScreenContext, BACKGROUND_COLOR); GrStringDrawCentered(&g_sScreenContext, g_pcMessage, -1, rectBlock.sXMin, rectBlock.sYMin, true); } // // Remember whether we displayed the message or not. // bLastMsgShown = g_bMsgShown; // // Clear the flag that we use to indicate the first redraw in a new game. // g_bScreenCleared = false; }
//***************************************************************************** // //! Performs the sliding menu operation, in response to the "left" button. //! //! \param psWidget is a pointer to the slide menu widget to move to the left. //! //! This function will respond to the "left" key/button event. The left //! button is used to ascend to the next menu up in the menu tree. The effect //! is that the current menu, or active widget, slides off to the right, while //! the parent menu slides in from the left. //! //! This function repeatedly draws the menu onto the display until the sliding //! animation is finished and will not return to the caller until then. This //! function is usually called from the thread context of //! WidgetMessageQueueProcess(). //! //! \return Returns a non-zero value if the menu was moved or was not moved //! because it is already at the last position. If a child widget is active //! then this function does nothing and returns a 0. // //***************************************************************************** static int32_t SlideMenuLeft(tWidget *psWidget) { tSlideMenuWidget *psMenuWidget; tSlideMenu *psMenu; tSlideMenu *psParentMenu; tContext sContext; uint32_t ui32X; uint32_t ui32MenuWidth; // // Get handy pointers to the menu widget and active menu, and the parent // menu if there is one. // psMenuWidget = (tSlideMenuWidget *)psWidget; psMenu = psMenuWidget->psSlideMenu; psParentMenu = psMenu->psParent; // // Initialize a context for the primary off-screen drawing buffer. // Clip region is set to entire display by default, which is what we want. // GrContextInit(&sContext, psMenuWidget->psDisplayB); // // If this widget has a child, that means that the child widget is in // control, and we are requested to go back to the previous menu item. // Process the child widget. // if(psWidget->psChild) { // // Call the widget de-activated callback function. This notifies the // application that the widget is being deactivated. // if(psMenuWidget->pfnActive) { psMenuWidget->pfnActive(psWidget->psChild, &psMenu->psSlideMenuItems[psMenu->ui32FocusIndex], 0); } // // Unlink the child widget from the slide menu widget. The menu // widget will now no longer have a child widget. // psWidget->psChild->psParent = 0; psWidget->psChild = 0; // // Fill a rectangle with the child widget background color. This will // erase everything else that is shown on the widget but leave the // background, which will make the change visually less jarring. // This is done in off-screen buffer B, which is the buffer that is // going to be slid off the screen. // GrContextForegroundSet( &sContext, psMenu->psSlideMenuItems[psMenu->ui32FocusIndex].ui32ChildWidgetColor); GrRectFill(&sContext, &sContext.sClipRegion); } // // Otherwise there is not a child widget in control, so process the parent // menu, if there is one. // else if(psParentMenu) { // // Render the current menu into the off-screen buffer B. This will be // the same menu appearance that is currently on the display. // SlideMenuDraw(psMenuWidget, &sContext, 0); // // Now switch the widget to the parent menu // psMenuWidget->psSlideMenu = psParentMenu; } // // Otherwise, we are already at the top level menu and there is nothing // else to do. // else { return(1); } // // Draw the new menu in the second offscreen buffer. This is the menu // that will be on the display when the animation is over. // GrContextInit(&sContext, psMenuWidget->psDisplayA); SlideMenuDraw(psMenuWidget, &sContext, 0); // // Initialize a drawing context for the display where the widget is to be // drawn. This is the physical display, not an off-screen buffer. // GrContextInit(&sContext, psWidget->psDisplay); // // Initialize the clipping region on the physical display, based on the // extents of this widget. // GrContextClipRegionSet(&sContext, &(psWidget->sPosition)); // // Get the width of the menu widget. // ui32MenuWidth = psMenuWidget->psDisplayA->ui16Width; // // The following loop draws the two off-screen buffers onto the physical // display using a left-to-right. This will provide an appearance // of sliding to the right. The parent menu will slide in from the left. // The "old" child menu is being held in off-screen buffer B and the new // one is in buffer A. So when we are done, the correct image will be in // buffer A. // for(ui32X = 0; ui32X <= ui32MenuWidth; ui32X += 8) { GrImageDraw(&sContext, psMenuWidget->psDisplayB->pvDisplayData, psWidget->sPosition.i16XMin + ui32X, psWidget->sPosition.i16YMin); GrImageDraw(&sContext, psMenuWidget->psDisplayA->pvDisplayData, psWidget->sPosition.i16XMin + ui32X - ui32MenuWidth, psWidget->sPosition.i16YMin); } // // Return indication that we handled the key event. // return(1); }
//***************************************************************************** // //! Draws a key on the keyboard. //! //! \param psWidget is a pointer to the keyboard widget to be drawn. //! \param psKey is a pointer to the key to draw. //! //! This function draws a single key on the display. This is called whenever //! a key on the keyboard needs to be updated. //! //! \return None. // //***************************************************************************** static void ButtonPaintText(tWidget *psWidget, const tKeyText *psKey) { tKeyboardWidget *psKeyboard; tContext sCtx; int32_t i32X, i32Y; uint32_t ui32Range, ui32Size; tRectangle sRect; char pcKeyCap[4]; // // Check the arguments. // ASSERT(psWidget); // // Convert the generic widget pointer into a keyboard widget pointer. // psKeyboard = (tKeyboardWidget *)psWidget; // // Initialize a drawing context. // GrContextInit(&sCtx, psWidget->psDisplay); // // Initialize the clipping region based on the extents of this keyboard. // GrContextClipRegionSet(&sCtx, &(psWidget->sPosition)); // // Calculate a keys bounding box. // ui32Range = psWidget->sPosition.i16XMax - psWidget->sPosition.i16XMin + 1; sRect.i16XMin = psWidget->sPosition.i16XMin + 1; sRect.i16XMin += (ui32Range * (uint32_t)psKey->ui16XPos) / 10000; sRect.i16XMax = sRect.i16XMin - 3 + ((ui32Range * (uint32_t)psKey->ui16Width) / 10000); ui32Range = psWidget->sPosition.i16YMax - psWidget->sPosition.i16YMin + 1; sRect.i16YMin = psWidget->sPosition.i16YMin + 1; sRect.i16YMin += (ui32Range * (uint32_t)psKey->ui16YPos) / 10000; sRect.i16YMax = sRect.i16YMin - 3 + ((ui32Range * (uint32_t)psKey->ui16Height) / 10000); // // See if the keyboard fill style is selected. // if(psKeyboard->ui32Style & KEYBOARD_STYLE_FILL) { // // Fill the key with the fill color. // GrContextForegroundSet(&sCtx, ((psKeyboard->ui32Flags & FLAG_KEY_PRESSED) ? psKeyboard->ui32PressFillColor : psKeyboard->ui32FillColor)); GrRectFill(&sCtx, &sRect); } // // See if the keyboard outline style is selected. // if(psKeyboard->ui32Style & KEYBOARD_STYLE_OUTLINE) { // // Outline the key with the outline color. // GrContextForegroundSet(&sCtx, psKeyboard->ui32OutlineColor); GrRectDraw(&sCtx, &sRect); } // // Compute the center of the key. // i32X = (sRect.i16XMin + ((sRect.i16XMax - sRect.i16XMin + 1) / 2)); i32Y = (sRect.i16YMin + ((sRect.i16YMax - sRect.i16YMin + 1) / 2)); // // If the keyboard 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(psKeyboard->ui32Style & KEYBOARD_STYLE_OUTLINE) { sCtx.sClipRegion.i16XMin++; sCtx.sClipRegion.i16YMin++; sCtx.sClipRegion.i16XMax--; sCtx.sClipRegion.i16YMax--; } // // Draw the text centered in the middle of the key. // GrContextFontSet(&sCtx, psKeyboard->psFont); GrContextForegroundSet(&sCtx, psKeyboard->ui32TextColor); GrContextBackgroundSet(&sCtx, ((psKeyboard->ui32Flags & FLAG_KEY_PRESSED) ? psKeyboard->ui32PressFillColor : psKeyboard->ui32FillColor)); ui32Size = 0; if(psKey->ui32Code == UNICODE_BACKSPACE) { pcKeyCap[0] = 'B'; pcKeyCap[1] = 'S'; ui32Size = 2; } else if(psKey->ui32Code == UNICODE_RETURN) { pcKeyCap[0] = 'E'; pcKeyCap[1] = 'n'; pcKeyCap[2] = 't'; ui32Size = 3; } else if(psKey->ui32Code == UNICODE_CUSTOM_SHIFT) { pcKeyCap[0] = 'C'; pcKeyCap[1] = 'a'; pcKeyCap[2] = 'p'; ui32Size = 3; } else if(psKey->ui32Code == UNICODE_CUSTOM_MODE_TOG) { pcKeyCap[0] = '1'; pcKeyCap[1] = '2'; pcKeyCap[2] = '3'; ui32Size = 3; } else { ui32Size = 1; pcKeyCap[0] = (char)psKey->ui32Code; } GrStringDrawCentered(&sCtx, (const char *)pcKeyCap, ui32Size, i32X, i32Y, psKeyboard->ui32Style & KEYBOARD_STYLE_TEXT_OPAQUE); }
void TestNotification(CuTest *tc) { GrContextClipRegionSet(&context, &fullscreen_clip); handle_message('S', "+8615618273349", "hey KREYOS, how are you doing today? I will be dropping by later at CES to check out the Meteor!"); window_current()(EVENT_WINDOW_PAINT, 0, &context); GrFlush(&context); window_current()(EVENT_KEY_PRESSED, KEY_DOWN, NULL); window_current()(EVENT_WINDOW_PAINT, 0, &context); GrFlush(&context); window_close(); handle_message('S', "+8615618273349", "testing 123"); window_current()(EVENT_WINDOW_PAINT, 0, &context); GrFlush(&context); window_close(); window_notify("Facebook", "Tom Paker\nOur schedule is crazy next a few days unfortunately.", NOTIFY_OK, 'a'); window_current()(EVENT_WINDOW_PAINT, 0, &context); GrFlush(&context); window_close(); window_notify("Facebook", "Tom Paker\nOurscheduleiscrazynextafewdaysunfortunately.", NOTIFY_OK, 'a'); window_current()(EVENT_WINDOW_PAINT, 0, &context); GrFlush(&context); window_close(); window_notify("SMS", chinesedata, NOTIFY_OK, 'a'); window_current()(EVENT_WINDOW_PAINT, 0, &context); GrFlush(&context); window_close(); window_notify_ancs(0, 9, 1, 1); window_notify_ancs(0, 10, 1, 1); window_notify_ancs(0, 11, 1, 1); window_notify_ancs(2, 9, 1, 1); window_notify_ancs(0, 12, 1, 1); window_current()(EVENT_WINDOW_PAINT, 0, &context); GrFlush(&context); window_current()(EVENT_KEY_PRESSED, KEY_DOWN, NULL); window_current()(EVENT_WINDOW_PAINT, 0, &context); GrFlush(&context); window_current()(EVENT_KEY_PRESSED, KEY_DOWN, NULL); window_current()(EVENT_WINDOW_PAINT, 0, &context); GrFlush(&context); window_current()(EVENT_KEY_PRESSED, KEY_DOWN, NULL); window_current()(EVENT_WINDOW_PAINT, 0, &context); GrFlush(&context); window_current()(EVENT_KEY_PRESSED, KEY_DOWN, NULL); window_current()(EVENT_WINDOW_PAINT, 0, &context); GrFlush(&context); window_current()(EVENT_KEY_PRESSED, KEY_DOWN, NULL); window_current()(EVENT_WINDOW_PAINT, 0, &context); GrFlush(&context); window_close(); window_messagebox(ICON_LARGE_WARNING, "Please Pair your Smartphone to the meteor.", 0); window_current()(EVENT_WINDOW_PAINT, 0, &context); GrFlush(&context); window_close(); }
//***************************************************************************** // //! Draws a slider. //! //! \param pWidget is a pointer to the slider widget to be drawn. //! \param pDirty is the subrectangle of the widget which is to be redrawn. //! This is expressed in screen coordinates. //! //! This function draws a slider on the display. This is called in response to //! a \b #WIDGET_MSG_PAINT message or when the slider position changes. //! //! \return None. // //***************************************************************************** static void SliderPaint(tWidget *pWidget, tRectangle *pDirty) { tRectangle sClipRect, sValueRect, sEmptyRect, sActiveClip; tSliderWidget *pSlider; tContext sCtx; long lX, lY, bIntersect; short sPos; // // Check the arguments. // ASSERT(pWidget); // // Convert the generic widget pointer into a slider widget pointer. // pSlider = (tSliderWidget *)pWidget; // // Initialize a drawing context. // GrContextInit(&sCtx, pWidget->pDisplay); // // Initialize the clipping region based on the update rectangle passed. // bIntersect = GrRectIntersectGet(pDirty, &(pSlider->sBase.sPosition), &sClipRect); GrContextClipRegionSet(&sCtx, &sClipRect); // // Draw the control outline if necessary. // if(pSlider->ulStyle & SL_STYLE_OUTLINE) { // // Outline the slider with the outline color. // GrContextForegroundSet(&sCtx, pSlider->ulOutlineColor); GrRectDraw(&sCtx, &(pWidget->sPosition)); // // Adjust the clipping rectangle to prevent the outline from being // corrupted later. // if(sClipRect.sXMin == pWidget->sPosition.sXMin) { sClipRect.sXMin++; } if(sClipRect.sYMin == pWidget->sPosition.sYMin) { sClipRect.sYMin++; } if(sClipRect.sXMax == pWidget->sPosition.sXMax) { sClipRect.sXMax--; } if(sClipRect.sYMax == pWidget->sPosition.sYMax) { sClipRect.sYMax--; } } // // Determine the position associated with the current slider value. // sPos = SliderValueToPosition(pSlider, pSlider->lValue); // // Remember this so that the dirty rectangle code in the click handler // draws the correct thing the first time it is called. // pSlider->sPos = sPos; // // Determine the rectangles for the active and empty portions of the // widget. // if(pSlider->ulStyle & SL_STYLE_VERTICAL) { // // Determine the rectangle corresponding to the bottom (value) portion // of the slider. // sValueRect.sXMin = pWidget->sPosition.sXMin; sValueRect.sXMax = pWidget->sPosition.sXMax; sValueRect.sYMin = sPos; sValueRect.sYMax = pWidget->sPosition.sYMax; // // Determine the rectangle corresponding to the top (empty) portion // of the slider. // sEmptyRect.sXMin = pWidget->sPosition.sXMin; sEmptyRect.sXMax = pWidget->sPosition.sXMax; sEmptyRect.sYMin = pWidget->sPosition.sYMin; sEmptyRect.sYMax = max(sEmptyRect.sYMin, sValueRect.sYMin - 1); } else { // // Determine the rectangle corresponding to the bottom (value) portion // of the slider. // sValueRect.sYMin = pWidget->sPosition.sYMin; sValueRect.sYMax = pWidget->sPosition.sYMax; sValueRect.sXMin = pWidget->sPosition.sXMin; sValueRect.sXMax = sPos; // // Determine the rectangle corresponding to the top (empty) portion // of the slider. // sEmptyRect.sYMin = pWidget->sPosition.sYMin; sEmptyRect.sYMax = pWidget->sPosition.sYMax; sEmptyRect.sXMax = pWidget->sPosition.sXMax; sEmptyRect.sXMin = min(sEmptyRect.sXMax, sValueRect.sXMax + 1); } // // Compute the center of the slider. This will be needed later if drawing // text or an image. // lX = (pWidget->sPosition.sXMin + ((pWidget->sPosition.sXMax - pWidget->sPosition.sXMin + 1) / 2)); lY = (pWidget->sPosition.sYMin + ((pWidget->sPosition.sYMax - pWidget->sPosition.sYMin + 1) / 2)); // // Get the required clipping rectangle for the active/value part of // the slider. // bIntersect = GrRectIntersectGet(&sClipRect, &sValueRect, &sActiveClip); // // Does any part of the value rectangle intersect with the region we are // supposed to be redrawing? // if(bIntersect) { // // Yes - we have something to draw. // // // Set the new clipping rectangle. // GrContextClipRegionSet(&sCtx, &sActiveClip); // // Do we need to fill the active area with a color? // if(pSlider->ulStyle & SL_STYLE_FILL) { GrContextForegroundSet(&sCtx, pSlider->ulFillColor); GrRectFill(&sCtx, &sValueRect); } // // Do we need to draw an image in the active area? // if(pSlider->ulStyle & SL_STYLE_IMG) { GrContextForegroundSet(&sCtx, pSlider->ulTextColor); GrContextBackgroundSet(&sCtx, pSlider->ulFillColor); GrImageDraw(&sCtx, pSlider->pucImage, lX - (GrImageWidthGet(pSlider->pucImage) / 2), lY - (GrImageHeightGet(pSlider->pucImage) / 2)); } // // Do we need to render a text string over the top of the active area? // if(pSlider->ulStyle & SL_STYLE_TEXT) { GrContextFontSet(&sCtx, pSlider->pFont); GrContextForegroundSet(&sCtx, pSlider->ulTextColor); GrContextBackgroundSet(&sCtx, pSlider->ulFillColor); GrStringDrawCentered(&sCtx, pSlider->pcText, -1, lX, lY, pSlider->ulStyle & SL_STYLE_TEXT_OPAQUE); } } // // Now get the required clipping rectangle for the background portion of // the slider. // bIntersect = GrRectIntersectGet(&sClipRect, &sEmptyRect, &sActiveClip); // // Does any part of the background rectangle intersect with the region we // are supposed to be redrawing? // if(bIntersect) { // // Yes - we have something to draw. // // // Set the new clipping rectangle. // GrContextClipRegionSet(&sCtx, &sActiveClip); // // Do we need to fill the active area with a color? // if(pSlider->ulStyle & SL_STYLE_BACKG_FILL) { GrContextForegroundSet(&sCtx, pSlider->ulBackgroundFillColor); GrRectFill(&sCtx, &sEmptyRect); } // // Do we need to draw an image in the active area? // if(pSlider->ulStyle & SL_STYLE_BACKG_IMG) { GrContextForegroundSet(&sCtx, pSlider->ulBackgroundTextColor); GrContextBackgroundSet(&sCtx, pSlider->ulBackgroundFillColor); GrImageDraw(&sCtx, pSlider->pucBackgroundImage, lX - (GrImageWidthGet(pSlider->pucBackgroundImage) / 2), lY - (GrImageHeightGet(pSlider->pucBackgroundImage) / 2)); } // // Do we need to render a text string over the top of the active area? // if(pSlider->ulStyle & SL_STYLE_BACKG_TEXT) { GrContextFontSet(&sCtx, pSlider->pFont); GrContextForegroundSet(&sCtx, pSlider->ulBackgroundTextColor); GrContextBackgroundSet(&sCtx, pSlider->ulBackgroundFillColor); GrStringDrawCentered(&sCtx, pSlider->pcText, -1, lX, lY, pSlider->ulStyle & SL_STYLE_BACKG_TEXT_OPAQUE); } } }
//***************************************************************************** // //! 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 a JPEG widget. // // \param pWidget is a pointer to the JPEG widget to be drawn. // // This function draws a JPEG widget on the display. This is called in // response to a \b WIDGET_MSG_PAINT message. // // \return None. // //***************************************************************************** static void JPEGWidgetPaint(tWidget *pWidget) { tRectangle sRect; tJPEGWidget *pJPEG; tContext sCtx; unsigned short usWidth, usHeight, usRow; unsigned short *pusRow; short sSrcX, sSrcY, sDstX, sDstY; // // Check the arguments. // ASSERT(pWidget); // // Convert the generic widget pointer into a JPEG widget pointer. // pJPEG = (tJPEGWidget *)pWidget; // // Initialize a drawing context. // GrContextInit(&sCtx, pWidget->pDisplay); // // Initialize the clipping region based on the extents of this rectangular // JPEG widget. // GrContextClipRegionSet(&sCtx, &(pWidget->sPosition)); // // Take a copy of the current widget position. // sRect=pWidget->sPosition; // // See if the JPEG widget outline style is selected. // if(pJPEG->ulStyle & JW_STYLE_OUTLINE) { unsigned long ulLoop; GrContextForegroundSet(&sCtx, pJPEG->ulOutlineColor); // // Outline the JPEG widget with the outline color. // for(ulLoop = 0; ulLoop < (unsigned long)pJPEG->ucBorderWidth; ulLoop++) { GrRectDraw(&sCtx, &sRect); sRect.sXMin++; sRect.sYMin++; sRect.sXMax--; sRect.sYMax--; } } // // If the fill style is selected fill the widget with the appropriate color. // if(pJPEG->ulStyle & JW_STYLE_FILL) { // // Fill the JPEG widget with the fill color. // GrContextForegroundSet(&sCtx, pJPEG->ulFillColor); GrRectFill(&sCtx, &(pWidget->sPosition)); } // // Does the widget had a decompressed image to draw? // if(pJPEG->psJPEGInst->pusImage) { // // What is the size of the image area of the widget? // usWidth = (sRect.sXMax - sRect.sXMin) + 1; usHeight = (sRect.sYMax - sRect.sYMin) + 1; // // Is the display window wider than the image? // if(usWidth > pJPEG->psJPEGInst->usWidth) { // // The display window is wider so we need to center the image // within the window. // sDstX = sRect.sXMin + (short)(usWidth - pJPEG->psJPEGInst->usWidth) / 2; sSrcX = 0; usWidth = pJPEG->psJPEGInst->usWidth; } else { // // The image is wider so we will fill the window (in the x // direction) and clip the image accordingly. // sDstX = sRect.sXMin; sSrcX = (pJPEG->psJPEGInst->usWidth - usWidth) / 2 - pJPEG->psJPEGInst->sXOffset; // // Ensure we don't wrap the image due to an offset that is too // large. // sSrcX = (sSrcX < 0) ? 0 : sSrcX; } // // Is the image highter than the display window? // if(usHeight > pJPEG->psJPEGInst->usHeight) { // // The display window is higher so we need to center the image // within the window. // sDstY = sRect.sYMin + (short)(usHeight - pJPEG->psJPEGInst->usHeight) / 2; sSrcY = 0; usHeight = pJPEG->psJPEGInst->usHeight; } else { // // The image is higher so we will fill the window (in the y // direction) and clip the image accordingly. // sDstY = sRect.sYMin; sSrcY = (pJPEG->psJPEGInst->usHeight - usHeight) / 2 - pJPEG->psJPEGInst->sYOffset; // // Ensure we don't wrap the image due to an offset that is too // large. // sSrcY = (sSrcY < 0) ? 0 : sSrcY; } // // Start at the top left of the visible portion of the image (based on the // slider settings). // pusRow = pJPEG->psJPEGInst->pusImage + sSrcX + (sSrcY * pJPEG->psJPEGInst->usWidth); // // Draw the rows of image data using direct calls to the display driver. // for(usRow = 0; usRow < usHeight; usRow++) { sCtx.pDisplay->pfnPixelDrawMultiple( sCtx.pDisplay->pvDisplayData, sDstX, sDstY + usRow, 0, usWidth, 16, (unsigned char *)pusRow, 0); pusRow += pJPEG->psJPEGInst->usWidth; } } // // See if the JPEG widget text style is selected. // if(pJPEG->ulStyle & JW_STYLE_TEXT) { // // Compute the center of the JPEG widget. // sDstX = (sRect.sXMin + ((sRect.sXMax - sRect.sXMin + 1) / 2)); sDstY = (sRect.sYMin + ((sRect.sYMax - sRect.sYMin + 1) / 2)); // // Draw the text centered in the middle of the JPEG widget. // GrContextFontSet(&sCtx, pJPEG->pFont); GrContextForegroundSet(&sCtx, pJPEG->ulTextColor); GrStringDrawCentered(&sCtx, pJPEG->pcText, -1, sDstX, sDstY, 0); } }
//***************************************************************************** // //! Draws a circular push button. //! //! \param pWidget is a pointer to the push button widget to be drawn. //! //! This function draws a circular push button on the display. This is called //! in response to a \b #WIDGET_MSG_PAINT message. //! //! \return None. // //***************************************************************************** static void CircularButtonPaint(tWidget *pWidget) { const unsigned char *pucImage; tPushButtonWidget *pPush; tContext sCtx; long lX, lY, lR; // // Check the arguments. // ASSERT(pWidget); // // Convert the generic widget pointer into a push button widget pointer. // pPush = (tPushButtonWidget *)pWidget; // // Initialize a drawing context. // GrContextInit(&sCtx, pWidget->pDisplay); // // Initialize the clipping region based on the extents of this circular // push button. // GrContextClipRegionSet(&sCtx, &(pWidget->sPosition)); // // Get the radius of the circular push button, along with the X and Y // coordinates for its center. // lR = (pWidget->sPosition.sXMax - pWidget->sPosition.sXMin + 1) / 2; lX = pWidget->sPosition.sXMin + lR; lY = pWidget->sPosition.sYMin + lR; // // See if the push button fill style is selected. // if(pPush->ulStyle & PB_STYLE_FILL) { // // Fill the push button with the fill color. // GrContextForegroundSet(&sCtx, ((pPush->ulStyle & PB_STYLE_PRESSED) ? pPush->ulPressFillColor : pPush->ulFillColor)); GrCircleFill(&sCtx, lX, lY, lR); } // // See if the push button outline style is selected. // if(pPush->ulStyle & PB_STYLE_OUTLINE) { // // Outline the push button with the outline color. // GrContextForegroundSet(&sCtx, pPush->ulOutlineColor); GrCircleDraw(&sCtx, lX, lY, lR); } // // See if the push button text or image style is selected. // if(pPush->ulStyle & (PB_STYLE_TEXT | PB_STYLE_IMG)) { // // If the push button 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(pPush->ulStyle & PB_STYLE_OUTLINE) { sCtx.sClipRegion.sXMin++; sCtx.sClipRegion.sYMin++; sCtx.sClipRegion.sXMax--; sCtx.sClipRegion.sYMax--; } // // See if the push button image style is selected. // if(pPush->ulStyle & PB_STYLE_IMG) { // // Set the foreground and background colors to use for 1 BPP // images. // GrContextForegroundSet(&sCtx, pPush->ulTextColor); GrContextBackgroundSet(&sCtx, ((pPush->ulStyle & PB_STYLE_PRESSED) ? pPush->ulPressFillColor : pPush->ulFillColor)); // // Get the image to be drawn. // pucImage = (((pPush->ulStyle & PB_STYLE_PRESSED) && pPush->pucPressImage) ? pPush->pucPressImage : pPush->pucImage); // // Draw the image centered in the push button. // GrImageDraw(&sCtx, pucImage, lX - (GrImageWidthGet(pucImage) / 2), lY - (GrImageHeightGet(pucImage) / 2)); } // // See if the push button text style is selected. // if(pPush->ulStyle & PB_STYLE_TEXT) { // // Draw the text centered in the middle of the push button. // GrContextFontSet(&sCtx, pPush->pFont); GrContextForegroundSet(&sCtx, pPush->ulTextColor); GrContextBackgroundSet(&sCtx, ((pPush->ulStyle & PB_STYLE_PRESSED) ? pPush->ulPressFillColor : pPush->ulFillColor)); GrStringDrawCentered(&sCtx, pPush->pcText, -1, lX, lY, pPush->ulStyle & PB_STYLE_TEXT_OPAQUE); } } }
//***************************************************************************** // //! Draws a rectangular push button. //! //! \param psWidget is a pointer to the push button widget to be drawn. //! //! This function draws a rectangular push button on the display. This is //! called in response to a \b #WIDGET_MSG_PAINT message. //! //! \return None. // //***************************************************************************** static void RectangularButtonPaint(tWidget *psWidget) { const uint8_t *pui8Image; tPushButtonWidget *pPush; tContext sCtx; int32_t i32X, i32Y; // // Check the arguments. // ASSERT(psWidget); // // Convert the generic widget pointer into a push button widget pointer. // pPush = (tPushButtonWidget *)psWidget; // // Initialize a drawing context. // GrContextInit(&sCtx, psWidget->psDisplay); // // Initialize the clipping region based on the extents of this rectangular // push button. // GrContextClipRegionSet(&sCtx, &(psWidget->sPosition)); // // See if the push button fill style is selected. // if(pPush->ui32Style & PB_STYLE_FILL) { // // Fill the push button with the fill color. // GrContextForegroundSet(&sCtx, ((pPush->ui32Style & PB_STYLE_PRESSED) ? pPush->ui32PressFillColor : pPush->ui32FillColor)); GrRectFill(&sCtx, &(psWidget->sPosition)); } // // See if the push button outline style is selected. // if(pPush->ui32Style & PB_STYLE_OUTLINE) { // // Outline the push button with the outline color. // GrContextForegroundSet(&sCtx, pPush->ui32OutlineColor); GrRectDraw(&sCtx, &(psWidget->sPosition)); } // // See if the push button text or image style is selected. // if(pPush->ui32Style & (PB_STYLE_TEXT | PB_STYLE_IMG)) { // // Compute the center of the push button. // i32X = (psWidget->sPosition.i16XMin + ((psWidget->sPosition.i16XMax - psWidget->sPosition.i16XMin + 1) / 2)); i32Y = (psWidget->sPosition.i16YMin + ((psWidget->sPosition.i16YMax - psWidget->sPosition.i16YMin + 1) / 2)); // // If the push button 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(pPush->ui32Style & PB_STYLE_OUTLINE) { sCtx.sClipRegion.i16XMin++; sCtx.sClipRegion.i16YMin++; sCtx.sClipRegion.i16XMax--; sCtx.sClipRegion.i16YMax--; } // // See if the push button image style is selected. // if(pPush->ui32Style & PB_STYLE_IMG) { // // Set the foreground and background colors to use for 1 BPP // images. // GrContextForegroundSet(&sCtx, pPush->ui32TextColor); GrContextBackgroundSet(&sCtx, ((pPush->ui32Style & PB_STYLE_PRESSED) ? pPush->ui32PressFillColor : pPush->ui32FillColor)); // // Get the image to be drawn. // pui8Image = (((pPush->ui32Style & PB_STYLE_PRESSED) && pPush->pui8PressImage) ? pPush->pui8PressImage : pPush->pui8Image); // // Draw the image centered in the push button. // GrImageDraw(&sCtx, pui8Image, i32X - (GrImageWidthGet(pui8Image) / 2), i32Y - (GrImageHeightGet(pui8Image) / 2)); } // // See if the push button text style is selected. // if(pPush->ui32Style & PB_STYLE_TEXT) { // // Draw the text centered in the middle of the push button. // GrContextFontSet(&sCtx, pPush->psFont); GrContextForegroundSet(&sCtx, pPush->ui32TextColor); GrContextBackgroundSet(&sCtx, ((pPush->ui32Style & PB_STYLE_PRESSED) ? pPush->ui32PressFillColor : pPush->ui32FillColor)); GrStringDrawCentered(&sCtx, pPush->pcText, -1, i32X, i32Y, pPush->ui32Style & PB_STYLE_TEXT_OPAQUE); } } }
//***************************************************************************** // //! 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 an image button. //! //! \param pWidget is a pointer to the image button widget to be drawn. //! //! This function draws a rectangular image button on the display. This is //! called in response to a \b #WIDGET_MSG_PAINT message. //! //! \return None. // //***************************************************************************** static void ImageButtonPaint(tWidget *pWidget) { const unsigned char *pucImage; tImageButtonWidget *pPush; tContext sCtx; long lX, lY; // // Check the arguments. // ASSERT(pWidget); // // Convert the generic widget pointer into a image button widget pointer. // pPush = (tImageButtonWidget *)pWidget; // // Initialize a drawing context. // GrContextInit(&sCtx, pWidget->pDisplay); // // Initialize the clipping region based on the extents of this rectangular // image button. // GrContextClipRegionSet(&sCtx, &(pWidget->sPosition)); // // Compute the center of the image button. // lX = (pWidget->sPosition.sXMin + ((pWidget->sPosition.sXMax - pWidget->sPosition.sXMin + 1) / 2)); lY = (pWidget->sPosition.sYMin + ((pWidget->sPosition.sYMax - pWidget->sPosition.sYMin + 1) / 2)); // // Do we need to fill the widget background with a color? // if(pPush->ulStyle & IB_STYLE_FILL) { // // Yes. Set the appropriate color depending upon whether or not // the widget is currently pressed. // GrContextForegroundSet(&sCtx, ((pPush->ulStyle & IB_STYLE_PRESSED) ? pPush->ulPressedColor : pPush->ulBackgroundColor)); GrRectFill(&sCtx, &(pWidget->sPosition)); } // // Set the foreground and background colors to use for 1 BPP // images and text // GrContextForegroundSet(&sCtx, pPush->ulForegroundColor); GrContextBackgroundSet(&sCtx, ((pPush->ulStyle & IB_STYLE_PRESSED) ? pPush->ulPressedColor : pPush->ulBackgroundColor)); // // Do we need to draw the background image? // if(!(pPush->ulStyle & IB_STYLE_IMAGE_OFF)) { // // Get the background image to be drawn. // pucImage = ((pPush->ulStyle & IB_STYLE_PRESSED) ? pPush->pucPressImage : pPush->pucImage); // // Draw the image centered in the image button. // GrImageDraw(&sCtx, pucImage, lX - (GrImageWidthGet(pucImage) / 2), lY - (GrImageHeightGet(pucImage) / 2)); } // // Adjust the drawing position if the button is pressed. // lX += ((pPush->ulStyle & IB_STYLE_PRESSED) ? pPush->sXOffset : 0); lY += ((pPush->ulStyle & IB_STYLE_PRESSED) ? pPush->sYOffset : 0); // // If there is a keycap image and it is not disabled, center this on the // top of the button, applying any offset defined if the button is // currently pressed. // if(pPush->pucKeycapImage && !(pPush->ulStyle & IB_STYLE_KEYCAP_OFF)) { // // Draw the keycap image. // GrImageDraw(&sCtx, pPush->pucKeycapImage, lX - (GrImageWidthGet(pPush->pucKeycapImage) / 2), lY - (GrImageHeightGet(pPush->pucKeycapImage) / 2)); } // // See if the button text style is selected. // if(pPush->ulStyle & IB_STYLE_TEXT) { // // Draw the text centered in the middle of the button with offset // applied if the button is currently pressed. // GrContextFontSet(&sCtx, pPush->pFont); GrStringDrawCentered(&sCtx, pPush->pcText, -1, lX, lY, 0); } }
//***************************************************************************** // //! Paints the clock set widget on the display. //! //! \param psWidget is a pointer to the clock setting widget to be drawn. //! //! This function draws the date and time fields of the clock setting widget //! onto the display. One of the fields can be highlighted. This is //! called in response to a \b WIDGET_MSG_PAINT message. //! //! \return None. // //***************************************************************************** static void ClockSetPaint(tWidget *psWidget) { tClockSetWidget *psClockWidget; tContext sContext; tRectangle sRect, sRectSel; struct tm *psTime; char pcBuf[8]; int32_t i32X, i32Y, i32Width, i32Height; uint32_t ui32Idx, ui32FontHeight, ui32FontWidth, ui32SelWidth; // // Check the arguments. // ASSERT(psWidget); ASSERT(psWidget->psDisplay); // // Convert the generic widget pointer into a clock set widget pointer. // psClockWidget = (tClockSetWidget *)psWidget; ASSERT(psClockWidget->psTime); // // Get pointer to the time structure // psTime = psClockWidget->psTime; // // Initialize a drawing context. // GrContextInit(&sContext, psWidget->psDisplay); // // Initialize the clipping region based on the extents of this widget. // GrContextClipRegionSet(&sContext, &(psWidget->sPosition)); // // Set the font for the context, and get font height and width - they // are used a lot later. // GrContextFontSet(&sContext, psClockWidget->psFont); ui32FontHeight = GrFontHeightGet(psClockWidget->psFont); ui32FontWidth = GrFontMaxWidthGet(psClockWidget->psFont); // // Fill the widget with the background color. // GrContextForegroundSet(&sContext, psClockWidget->ui32BackgroundColor); GrRectFill(&sContext, &sContext.sClipRegion); // // Draw a border around the widget // GrContextForegroundSet(&sContext, psClockWidget->ui32ForegroundColor); GrContextBackgroundSet(&sContext, psClockWidget->ui32BackgroundColor); GrRectDraw(&sContext, &sContext.sClipRegion); // // Compute a rectangle for the screen title. Put it at the top of // the widget display, and sized to be the height of the font, plus // a few pixels of space. // sRect.i16XMin = sContext.sClipRegion.i16XMin; sRect.i16XMax = sContext.sClipRegion.i16XMax; sRect.i16YMin = sContext.sClipRegion.i16YMin; sRect.i16YMax = ui32FontHeight * 2; GrRectDraw(&sContext, &sRect); // // Print a title for the widget // GrContextFontSet(&sContext, psClockWidget->psFont); GrStringDrawCentered(&sContext, "CLOCK SET", -1, (1 + sRect.i16XMax - sRect.i16XMin) / 2, (1 + sRect.i16YMax - sRect.i16YMin) / 2, 1); // // Reset the rectangle to cover the non-title area of the display // sRect.i16YMin = sRect.i16YMax + 1; sRect.i16YMax = sContext.sClipRegion.i16YMax; // // Compute the width and height of the area remaining for showing the // clock fields. // i32Width = 1 + (sRect.i16XMax - sRect.i16XMin); i32Height = 1 + (sRect.i16YMax - sRect.i16YMin); // // Compute the X and Y starting point for the row that will show the // date. // i32X = sRect.i16XMin + (i32Width - (ui32FontWidth * 10)) / 2; i32Y = sRect.i16YMin + ((i32Height * 1) / 6) - (ui32FontHeight / 2); // // Draw the date field separators on the date row. // GrStringDraw(&sContext, "/", -1, i32X + (ui32FontWidth * 4), i32Y, 0); GrStringDraw(&sContext, "/", -1, i32X + (ui32FontWidth * 7), i32Y, 0); // // Compute the X and Y starting point for the row that will show the // time. // i32X = sRect.i16XMin + (i32Width - (ui32FontWidth * 5)) / 2; i32Y = sRect.i16YMin + ((i32Height * 3) / 6) - (ui32FontHeight / 2); // // Draw the time field separators on the time row. // GrStringDraw(&sContext, ":", -1, i32X + (ui32FontWidth * 2), i32Y, 0); // // Process each of the fields to be shown on the widget // for(ui32Idx = 0; ui32Idx < NUM_FIELDS; ui32Idx++) { // // Compute the X and Y for the text for each field, and print the // text into a buffer. // switch(ui32Idx) { // // Year // case FIELD_YEAR: { usnprintf(pcBuf, sizeof(pcBuf), "%4u", psTime->tm_year+1900); i32X = sRect.i16XMin + (i32Width - (ui32FontWidth * 10)) / 2; i32Y = sRect.i16YMin + ((i32Height * 1) / 6) - (ui32FontHeight / 2); ui32SelWidth = 4; break; } // // Month // case FIELD_MONTH: { usnprintf(pcBuf, sizeof(pcBuf), "%02u", psTime->tm_mon + 1); i32X += ui32FontWidth * 5; ui32SelWidth = 2; break; } // // Day // case FIELD_DAY: { usnprintf(pcBuf, sizeof(pcBuf), "%02u", psTime->tm_mday); i32X += ui32FontWidth * 3; ui32SelWidth = 2; break; } // // Hour // case FIELD_HOUR: { usnprintf(pcBuf, sizeof(pcBuf), "%02u", psTime->tm_hour); i32X = sRect.i16XMin + (i32Width - (ui32FontWidth * 5)) / 2; i32Y = sRect.i16YMin + ((i32Height * 3) / 6) - (ui32FontHeight / 2); ui32SelWidth = 2; break; } // // Minute // case FIELD_MINUTE: { usnprintf(pcBuf, sizeof(pcBuf), "%02u", psTime->tm_min); i32X += ui32FontWidth * 3; ui32SelWidth = 2; break; } // // OK // case FIELD_OK: { usnprintf(pcBuf, sizeof(pcBuf), "OK"); i32X = (i32Width - (ui32FontWidth * 9)) / 2; i32X += sRect.i16XMin; i32Y = ((i32Height * 5) / 6) - (ui32FontHeight / 2); i32Y += sRect.i16YMin; ui32SelWidth = 2; break; } // // CANCEL (default case is purely to keep the compiler from // issuing a warning that ui32SelWidth may be used ininitialized). // case FIELD_CANCEL: default: { usnprintf(pcBuf, sizeof(pcBuf), "CANCEL"); i32X += ui32FontWidth * 3; ui32SelWidth = 6; break; } } // // If the current field index is the highlighted field, then this // text field will be drawn with highlighting. // if(ui32Idx == psClockWidget->ui32Highlight) { // // Compute a rectangle for the highlight area. // sRectSel.i16XMin = i32X; sRectSel.i16XMax = (ui32SelWidth * ui32FontWidth) + i32X; sRectSel.i16YMin = i32Y - 2; sRectSel.i16YMax = ui32FontHeight + i32Y + 2; // // Set the foreground color to the text color, and then fill the // highlight rectangle. The text field will be highlighted by // inverting the normal colors. // Then draw the highlighting rectangle. // GrContextForegroundSet(&sContext, psClockWidget->ui32ForegroundColor); GrRectFill(&sContext, &sRectSel); // // Change the foreground color to the normal background color. // This will be used for drawing the text for the highlighted // field, which has the colors inverted (FG <--> BG) // GrContextForegroundSet(&sContext, psClockWidget->ui32BackgroundColor); } else { // // This text field is not highlighted so just set the normal // foreground color. // GrContextForegroundSet(&sContext, psClockWidget->ui32ForegroundColor); } // // Print the text from the buffer to the display at the computed // location. // GrStringDraw(&sContext, pcBuf, -1, i32X, i32Y, 0); } }
//***************************************************************************** // //! Draws a check box widget. //! //! \param pWidget is a pointer to the check box widget to be drawn. //! \param bClick is a boolean that is \b true if the paint request is a result //! of a pointer click and \b false if not. //! //! This function draws a check box widget on the display. This is called in //! response to a \b #WIDGET_MSG_PAINT message. //! //! \return None. // //***************************************************************************** static void CheckBoxPaint(tWidget *pWidget, unsigned long bClick) { tCheckBoxWidget *pCheck; tRectangle sRect; tContext sCtx; long lY; // // Check the arguments. // ASSERT(pWidget); // // Convert the generic widget pointer into a check box widget pointer. // pCheck = (tCheckBoxWidget *)pWidget; // // Initialize a drawing context. // GrContextInit(&sCtx, pWidget->pDisplay); // // Initialize the clipping region based on the extents of this check box. // GrContextClipRegionSet(&sCtx, &(pWidget->sPosition)); // // See if the check box fill style is selected. // if((pCheck->usStyle & CB_STYLE_FILL) && !bClick) { // // Fill the check box with the fill color. // GrContextForegroundSet(&sCtx, pCheck->ulFillColor); GrRectFill(&sCtx, &(pWidget->sPosition)); } // // See if the check box outline style is selected. // if((pCheck->usStyle & CB_STYLE_OUTLINE) && !bClick) { // // Outline the check box with the outline color. // GrContextForegroundSet(&sCtx, pCheck->ulOutlineColor); GrRectDraw(&sCtx, &(pWidget->sPosition)); } // // Draw the check box. // sRect.sXMin = pWidget->sPosition.sXMin + 2; sRect.sYMin = (pWidget->sPosition.sYMin + ((pWidget->sPosition.sYMax - pWidget->sPosition.sYMin - pCheck->usBoxSize + 1) / 2)); sRect.sXMax = sRect.sXMin + pCheck->usBoxSize - 1; sRect.sYMax = sRect.sYMin + pCheck->usBoxSize - 1; if(!bClick) { GrContextForegroundSet(&sCtx, pCheck->ulOutlineColor); GrRectDraw(&sCtx, &sRect); } // // Select the foreground color based on whether or not the check box is // selected. // if(pCheck->usStyle & CB_STYLE_SELECTED) { GrContextForegroundSet(&sCtx, pCheck->ulOutlineColor); } else { GrContextForegroundSet(&sCtx, pCheck->ulFillColor); } // // Draw an "X" in the check box. // GrLineDraw(&sCtx, sRect.sXMin + 1, sRect.sYMin + 1, sRect.sXMax - 1, sRect.sYMax - 1); GrLineDraw(&sCtx, sRect.sXMin + 1, sRect.sYMax - 1, sRect.sXMax - 1, sRect.sYMin + 1); // // See if the check box text or image style is selected. // if((pCheck->usStyle & (CB_STYLE_TEXT | CB_STYLE_IMG)) && !bClick) { // // Shrink the clipping region by the size of the check box so that it // is not overwritten by further "decorative" portions of the widget. // sCtx.sClipRegion.sXMin += pCheck->usBoxSize + 4; // // If the check box 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(pCheck->usStyle & CB_STYLE_OUTLINE) { sCtx.sClipRegion.sYMin++; sCtx.sClipRegion.sXMax--; sCtx.sClipRegion.sYMax--; } // // See if the check box image style is selected. // if(pCheck->usStyle & CB_STYLE_IMG) { // // Determine where along the Y extent of the widget to draw the // image. It is drawn at the top if it takes all (or more than // all) of the Y extent of the widget, and it is drawn centered if // it takes less than the Y extent. // if(GrImageHeightGet(pCheck->pucImage) > (sCtx.sClipRegion.sYMax - sCtx.sClipRegion.sYMin)) { lY = sCtx.sClipRegion.sYMin; } else { lY = (sCtx.sClipRegion.sYMin + ((sCtx.sClipRegion.sYMax - sCtx.sClipRegion.sYMin - GrImageHeightGet(pCheck->pucImage) + 1) / 2)); } // // Set the foreground and background colors to use for 1 BPP // images. // GrContextForegroundSet(&sCtx, pCheck->ulTextColor); GrContextBackgroundSet(&sCtx, pCheck->ulFillColor); // // Draw the image next to the check box. // GrImageDraw(&sCtx, pCheck->pucImage, sCtx.sClipRegion.sXMin, lY); } // // See if the check box text style is selected. // if(pCheck->usStyle & CB_STYLE_TEXT) { // // Determine where along the Y extent of the widget to draw the // string. It is drawn at the top if it takes all (or more than // all) of the Y extent of the widget, and it is drawn centered if // it takes less than the Y extent. // if(GrFontHeightGet(pCheck->pFont) > (sCtx.sClipRegion.sYMax - sCtx.sClipRegion.sYMin)) { lY = sCtx.sClipRegion.sYMin; } else { lY = (sCtx.sClipRegion.sYMin + ((sCtx.sClipRegion.sYMax - sCtx.sClipRegion.sYMin - GrFontHeightGet(pCheck->pFont) + 1) / 2)); } // // Draw the text next to the check box. // GrContextFontSet(&sCtx, pCheck->pFont); GrContextForegroundSet(&sCtx, pCheck->ulTextColor); GrContextBackgroundSet(&sCtx, pCheck->ulFillColor); GrStringDraw(&sCtx, pCheck->pcText, -1, sCtx.sClipRegion.sXMin, lY, pCheck->usStyle & CB_STYLE_TEXT_OPAQUE); } } }
//***************************************************************************** // //! Draws a radio button widget. //! //! \param psWidget is a pointer to the radio button widget to be drawn. //! \param bClick is a boolean that is \b true if the paint request is a result //! of a pointer click and \b false if not. //! //! This function draws a radio button widget on the display. This is called //! in response to a \b #WIDGET_MSG_PAINT message. //! //! \return None. // //***************************************************************************** static void RadioButtonPaint(tWidget *psWidget, uint32_t bClick) { tRadioButtonWidget *pRadio; tContext sCtx; int32_t i32X, i32Y; // // Check the arguments. // ASSERT(psWidget); // // Convert the generic widget pointer into a radio button widget pointer. // pRadio = (tRadioButtonWidget *)psWidget; // // Initialize a drawing context. // GrContextInit(&sCtx, psWidget->psDisplay); // // Initialize the clipping region based on the extents of this radio // button. // GrContextClipRegionSet(&sCtx, &(psWidget->sPosition)); // // See if the radio button fill style is selected. // if((pRadio->ui16Style & RB_STYLE_FILL) && !bClick) { // // Fill the radio button with the fill color. // GrContextForegroundSet(&sCtx, pRadio->ui32FillColor); GrRectFill(&sCtx, &(psWidget->sPosition)); } // // See if the radio button outline style is selected. // if((pRadio->ui16Style & RB_STYLE_OUTLINE) && !bClick) { // // Outline the radio button with the outline color. // GrContextForegroundSet(&sCtx, pRadio->ui32OutlineColor); GrRectDraw(&sCtx, &(psWidget->sPosition)); } // // Draw the radio button. // i32X = psWidget->sPosition.i16XMin + (pRadio->ui16CircleSize / 2) + 2; i32Y = (psWidget->sPosition.i16YMin + ((psWidget->sPosition.i16YMax - psWidget->sPosition.i16YMin) / 2)); if(!bClick) { GrContextForegroundSet(&sCtx, pRadio->ui32OutlineColor); GrCircleDraw(&sCtx, i32X, i32Y, pRadio->ui16CircleSize / 2); } // // Select the foreground color based on whether or not the radio button is // selected. // if(pRadio->ui16Style & RB_STYLE_SELECTED) { GrContextForegroundSet(&sCtx, pRadio->ui32OutlineColor); } else { GrContextForegroundSet(&sCtx, pRadio->ui32FillColor); } // // Fill in the radio button. // GrCircleFill(&sCtx, i32X, i32Y, (pRadio->ui16CircleSize / 2) - 2); // // See if the radio button text or image style is selected. // if((pRadio->ui16Style & (RB_STYLE_TEXT | RB_STYLE_IMG)) && !bClick) { // // Shrink the clipping region by the size of the radio button so that // it is not overwritten by further "decorative" portions of the // widget. // sCtx.sClipRegion.i16XMin += pRadio->ui16CircleSize + 4; // // If the radio button 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(pRadio->ui16Style & RB_STYLE_OUTLINE) { sCtx.sClipRegion.i16YMin++; sCtx.sClipRegion.i16XMax--; sCtx.sClipRegion.i16YMax--; } // // See if the radio button image style is selected. // if(pRadio->ui16Style & RB_STYLE_IMG) { // // Determine where along the Y extent of the widget to draw the // image. It is drawn at the top if it takes all (or more than // all) of the Y extent of the widget, and it is drawn centered if // it takes less than the Y extent. // if(GrImageHeightGet(pRadio->pui8Image) > (sCtx.sClipRegion.i16YMax - sCtx.sClipRegion.i16YMin)) { i32Y = sCtx.sClipRegion.i16YMin; } else { i32Y = (sCtx.sClipRegion.i16YMin + ((sCtx.sClipRegion.i16YMax - sCtx.sClipRegion.i16YMin - GrImageHeightGet(pRadio->pui8Image) + 1) / 2)); } // // Set the foreground and background colors to use for 1 BPP // images. // GrContextForegroundSet(&sCtx, pRadio->ui32TextColor); GrContextBackgroundSet(&sCtx, pRadio->ui32FillColor); // // Draw the image next to the radio button. // GrImageDraw(&sCtx, pRadio->pui8Image, sCtx.sClipRegion.i16XMin, i32Y); } // // See if the radio button text style is selected. // if(pRadio->ui16Style & RB_STYLE_TEXT) { // // Determine where along the Y extent of the widget to draw the // string. It is drawn at the top if it takes all (or more than // all) of the Y extent of the widget, and it is drawn centered if // it takes less than the Y extent. // if(GrFontHeightGet(pRadio->psFont) > (sCtx.sClipRegion.i16YMax - sCtx.sClipRegion.i16YMin)) { i32Y = sCtx.sClipRegion.i16YMin; } else { i32Y = (sCtx.sClipRegion.i16YMin + ((sCtx.sClipRegion.i16YMax - sCtx.sClipRegion.i16YMin - GrFontHeightGet(pRadio->psFont) + 1) / 2)); } // // Draw the text next to the radio button. // GrContextFontSet(&sCtx, pRadio->psFont); GrContextForegroundSet(&sCtx, pRadio->ui32TextColor); GrContextBackgroundSet(&sCtx, pRadio->ui32FillColor); GrStringDraw(&sCtx, pRadio->pcText, -1, sCtx.sClipRegion.i16XMin, i32Y, pRadio->ui16Style & RB_STYLE_TEXT_OPAQUE); } } }
//***************************************************************************** // //! Performs the sliding menu operation, in response to the "up" button. //! //! \param psWidget is a pointer to the slide menu widget to move up. //! //! This function will respond to the "up" key/button event. The up //! button is used to select the previous menu item down the list, and the //! effect is that the menu itself slides down, leaving the highlighted menu //! item in the middle of the screen. //! //! This function repeatedly draws the menu onto the display until the sliding //! animation is finished and will not return to the caller until then. This //! function is usually called from the thread context of //! WidgetMessageQueueProcess(). //! //! \return Returns a non-zero value if the menu was moved or was not moved //! because it is already at the first position. If a child widget is active //! then this function does nothing and returns a 0. // //***************************************************************************** static int32_t SlideMenuUp(tWidget *psWidget) { tSlideMenuWidget *psMenuWidget; tSlideMenu *psMenu; tContext sContext; uint32_t ui32MenuHeight; uint32_t ui32Y; // // If this menu widget has a child widget, that means the child widget // is in control of the display, and there is nothing to do here. // if(psWidget->psChild) { return(0); } // // Get handy pointers to the menu widget, and the menu that is currently // displayed. // psMenuWidget = (tSlideMenuWidget *)psWidget; psMenu = psMenuWidget->psSlideMenu; // // If we are already at the start of the list of menu items, then there // is nothing else to do. // if(psMenu->ui32FocusIndex == 0) { return(1); } // // Decrement the focus menu item. This has the effect of selecting the // previous menu item in the list. // psMenu->ui32FocusIndex--; // // Initialize a context for the primary off-screen drawing buffer. // Clip region is set to entire display by default, which is what we want. // GrContextInit(&sContext, psMenuWidget->psDisplayA); // // Render the menu into the off-screen buffer. This will be the same // menu appearance as before, except the highlighted item has changed // to the previous menu item up. // SlideMenuDraw(psMenuWidget, &sContext, 0); // // Draw a continuation of this menu in the second offscreen buffer. // This is the part of the menu that would be drawn above this menu if the // display were twice as tall. We are effectively creating a virtual // display that is twice as tall as the physical display. // GrContextInit(&sContext, psMenuWidget->psDisplayB); SlideMenuDraw(psMenuWidget, &sContext, (psMenuWidget->sBase.sPosition.i16YMax - psMenuWidget->sBase.sPosition.i16YMin)); // // Initialize a drawing context for the display where the widget is to be // drawn. This is the physical display, not an off-screen buffer. // GrContextInit(&sContext, psWidget->psDisplay); // // Initialize the clipping region on the physical display, based on the // extents of this widget. // GrContextClipRegionSet(&sContext, &(psWidget->sPosition)); // // Get the height of the displayed part of the menu. // ui32MenuHeight = psMenuWidget->psDisplayA->ui16Height; // // Now copy the rendered menu into the physical display // // Iterate over the Y displacement of one menu item cell. This loop // will repeatedly draw both off screen buffers to the physical display, // adjusting the position of each by one pixel each time it is drawn. Each // time the offset is changed so that both buffers are drawn one lower // than the previous time. This will have the effect of "sliding" the // entire menu down by the height of one menu item cell. // The speed of the animation is controlled entirely by the speed of the // processor and the speed of the interface to the physical display. // for(ui32Y = 0; ui32Y <= psMenuWidget->ui32MenuItemHeight; ui32Y++) { GrImageDraw(&sContext, psMenuWidget->psDisplayB->pvDisplayData, psWidget->sPosition.i16XMin, psWidget->sPosition.i16YMin + ui32Y - ui32MenuHeight); GrImageDraw(&sContext, psMenuWidget->psDisplayA->pvDisplayData, psWidget->sPosition.i16XMin, psWidget->sPosition.i16YMin + ui32Y); } // // Decrement the centered menu item. This will now match the menu item // with the focus. When the menu is repainted again, the newly selected // menu item will be centered and highlighted. // psMenu->ui32CenterIndex = psMenu->ui32FocusIndex; // // Initialize a context for the primary off-screen drawing buffer. // Clip region is set to entire display by default, which is what we want. // GrContextInit(&sContext, psMenuWidget->psDisplayA); // // Render the menu into the off-screen buffer. This will be the same // menu appearance as before, except the highlighted item has changed // to the next menu item up. Now when a repaint occurs the menu // will be redrawn with the newly highlighted menu item. // SlideMenuDraw(psMenuWidget, &sContext, 0); // // Return indication that we handled the key event. // return(1); }
//***************************************************************************** // //! 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)); } }
//***************************************************************************** // //! Performs the sliding menu operation, in response to the "right" button. //! //! \param psWidget is a pointer to the slide menu widget to move to the right. //! //! This function will respond to the "right" key/button event. The right //! button is used to select the next menu level below the current menu item, //! or a widget that is activated by the menu item. The effect is that the //! menu itself slides off to the left, and the new menu or widget slides in //! from the right. //! //! This function repeatedly draws the menu onto the display until the sliding //! animation is finished and will not return to the caller until then. This //! function is usually called from the thread context of //! WidgetMessageQueueProcess(). //! //! \return Returns a non-zero value if the menu was moved or was not moved //! because it is already at the last position. If a child widget is active //! then this function does nothing and returns a 0. // //***************************************************************************** static int32_t SlideMenuRight(tWidget *psWidget) { tSlideMenuWidget *psMenuWidget; tSlideMenu *psMenu; tSlideMenu *psChildMenu; tContext sContext; tWidget *psChildWidget; uint32_t ui32X; uint32_t ui32MenuWidth; // // If this menu widget has a child widget, that means the child widget // is in control of the display, and there is nothing to do here. // if(psWidget->psChild) { return(0); } // // Get handy pointers to the menu widget, and the current menu, and the // child menu and widget if they exist. // psMenuWidget = (tSlideMenuWidget *)psWidget; psMenu = psMenuWidget->psSlideMenu; psChildMenu = psMenu->psSlideMenuItems[psMenu->ui32FocusIndex].psChildMenu; psChildWidget = psMenu->psSlideMenuItems[psMenu->ui32FocusIndex].psChildWidget; // // Initialize a context for the secondary off-screen drawing buffer. // Clip region is set to entire display by default, which is what we want. // GrContextInit(&sContext, psMenuWidget->psDisplayB); // // Render the current menu into off-screen buffer B. This // will be the same menu appearance as is already being shown. // SlideMenuDraw(psMenuWidget, &sContext, 0); // // Now set up context for drawing into off-screen buffer A // GrContextInit(&sContext, psMenuWidget->psDisplayA); // // Process child menu of this menu item // if(psChildMenu) { // // Switch the active menu for this SlideMenuWidget to be the child // menu // psMenuWidget->psSlideMenu = psChildMenu; // // Draw the new (child) menu into off-screen buffer A // SlideMenuDraw(psMenuWidget, &sContext, 0); } // // Process child widget of this menu item. This only happens if there // is no child menu. // else if(psChildWidget) { // // Call the widget activated callback function. This will notify // the application that a child widget has been activated by the // menu system. // if(psMenuWidget->pfnActive) { psMenuWidget->pfnActive(psChildWidget, &psMenu->psSlideMenuItems[psMenu->ui32FocusIndex], 1); } // // Link the new child widget into this SlideMenuWidget so // it appears as a child to this widget. Normally the menu widget // has no child widget. // psWidget->psChild = psChildWidget; psChildWidget->psParent = psWidget; // // Fill a rectangle with the new child widget background color. // This is done in off-screen buffer A. When the menu slides off, // it will be replaced by a blank background that will then be // controlled by the new child widget. // GrContextForegroundSet( &sContext, psMenu->psSlideMenuItems[psMenu->ui32FocusIndex].ui32ChildWidgetColor); GrRectFill(&sContext, &sContext.sClipRegion); // // Request a repaint for the child widget so it can draw itself once // the menu slide is done. // WidgetPaint(psChildWidget); } // // There is no child menu or child widget, so there is nothing to change // on the display. // else { return(1); } // // Initialize a drawing context for the display where the widget is to be // drawn. This is the physical display, not an off-screen buffer. // GrContextInit(&sContext, psWidget->psDisplay); // // Initialize the clipping region on the physical display, based on the // extents of this widget. // GrContextClipRegionSet(&sContext, &(psWidget->sPosition)); // // Get the width of the menu widget which is used in calculations below // ui32MenuWidth = psMenuWidget->psDisplayA->ui16Width; // // The following loop draws the two off-screen buffers onto the physical // display using a right-to-left-wipe. This will provide an appearance // of sliding to the left. The new child menu, or child widget background // will slide in from the right. The "old" menu is being held in // off-screen buffer B and the new one is in buffer A. So when we are // done, the correct image will be in buffer A. // for(ui32X = 0; ui32X <= ui32MenuWidth; ui32X += 8) { GrImageDraw(&sContext, psMenuWidget->psDisplayB->pvDisplayData, psWidget->sPosition.i16XMin - ui32X, psWidget->sPosition.i16YMin); GrImageDraw(&sContext, psMenuWidget->psDisplayA->pvDisplayData, psWidget->sPosition.i16XMin + ui32MenuWidth - ui32X, psWidget->sPosition.i16YMin); } // // Return indication that we handled the key event. // return(1); }