//***************************************************************************** // //! Draws a circular push button. //! //! \param psWidget 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 *psWidget) { const uint8_t *pui8Image; tPushButtonWidget *pPush; tContext sCtx; int32_t i32X, i32Y, i32R; // // 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 circular // push button. // GrContextClipRegionSet(&sCtx, &(psWidget->sPosition)); // // Get the radius of the circular push button, along with the X and Y // coordinates for its center. // i32R = (psWidget->sPosition.i16XMax - psWidget->sPosition.i16XMin + 1) / 2; i32X = psWidget->sPosition.i16XMin + i32R; i32Y = psWidget->sPosition.i16YMin + i32R; // // 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)); GrCircleFill(&sCtx, i32X, i32Y, i32R); } // // 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); GrCircleDraw(&sCtx, i32X, i32Y, i32R); } // // See if the push button text or image style is selected. // if(pPush->ui32Style & (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->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 an image button. //! //! \param psWidget 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 *psWidget) { const uint8_t *pui8Image; tImageButtonWidget *psPush; tContext sCtx; int32_t i32X, i32Y; // // Check the arguments. // ASSERT(psWidget); // // Convert the generic widget pointer into a image button widget pointer. // psPush = (tImageButtonWidget *)psWidget; // // Initialize a drawing context. // GrContextInit(&sCtx, psWidget->psDisplay); // // Initialize the clipping region based on the extents of this rectangular // image button. // GrContextClipRegionSet(&sCtx, &(psWidget->sPosition)); // // Compute the center of the image 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)); // // Do we need to fill the widget background with a color? // if(psPush->ui32Style & IB_STYLE_FILL) { // // Yes. Set the appropriate color depending upon whether or not // the widget is currently pressed. // GrContextForegroundSet(&sCtx, ((psPush->ui32Style & IB_STYLE_PRESSED) ? psPush->ui32PressedColor : psPush->ui32BackgroundColor)); GrRectFill(&sCtx, &(psWidget->sPosition)); } // // Set the foreground and background colors to use for 1 BPP // images and text // GrContextForegroundSet(&sCtx, psPush->ui32ForegroundColor); GrContextBackgroundSet(&sCtx, ((psPush->ui32Style & IB_STYLE_PRESSED) ? psPush->ui32PressedColor : psPush->ui32BackgroundColor)); // // Do we need to draw the background image? // if(!(psPush->ui32Style & IB_STYLE_IMAGE_OFF)) { // // Get the background image to be drawn. // pui8Image = ((psPush->ui32Style & IB_STYLE_PRESSED) ? psPush->pui8PressImage : psPush->pui8Image); // // Draw the image centered in the image button. // GrImageDraw(&sCtx, pui8Image, i32X - (GrImageWidthGet(pui8Image) / 2), i32Y - (GrImageHeightGet(pui8Image) / 2)); } // // Adjust the drawing position if the button is pressed. // i32X += ((psPush->ui32Style & IB_STYLE_PRESSED) ? psPush->i16XOffset : 0); i32Y += ((psPush->ui32Style & IB_STYLE_PRESSED) ? psPush->i16YOffset : 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(psPush->pui8KeycapImage && !(psPush->ui32Style & IB_STYLE_KEYCAP_OFF)) { // // Draw the keycap image. // GrImageDraw(&sCtx, psPush->pui8KeycapImage, i32X - (GrImageWidthGet(psPush->pui8KeycapImage) / 2), i32Y - (GrImageHeightGet(psPush->pui8KeycapImage) / 2)); } // // See if the button text style is selected. // if(psPush->ui32Style & IB_STYLE_TEXT) { // // Draw the text centered in the middle of the button with offset // applied if the button is currently pressed. // GrContextFontSet(&sCtx, psPush->psFont); GrStringDrawCentered(&sCtx, psPush->pcText, -1, i32X, i32Y, 0); } }
//***************************************************************************** // //! Draws a slider. //! //! \param psWidget is a pointer to the slider widget to be drawn. //! \param psDirty 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 *psWidget, tRectangle *psDirty) { tRectangle sClipRect, sValueRect, sEmptyRect, sActiveClip; tSliderWidget *pSlider; tContext sCtx; int32_t i32X, i32Y; bool bIntersect; int16_t i16Pos; // // Check the arguments. // ASSERT(psWidget); // // Convert the generic widget pointer into a slider widget pointer. // pSlider = (tSliderWidget *)psWidget; // // Initialize a drawing context. // GrContextInit(&sCtx, psWidget->psDisplay); // // Initialize the clipping region based on the update rectangle passed. // bIntersect = GrRectIntersectGet(psDirty, &(pSlider->sBase.sPosition), &sClipRect); GrContextClipRegionSet(&sCtx, &sClipRect); // // Draw the control outline if necessary. // if(pSlider->ui32Style & SL_STYLE_OUTLINE) { // // Outline the slider with the outline color. // GrContextForegroundSet(&sCtx, pSlider->ui32OutlineColor); GrRectDraw(&sCtx, &(psWidget->sPosition)); // // Adjust the clipping rectangle to prevent the outline from being // corrupted later. // if(sClipRect.i16XMin == psWidget->sPosition.i16XMin) { sClipRect.i16XMin++; } if(sClipRect.i16YMin == psWidget->sPosition.i16YMin) { sClipRect.i16YMin++; } if(sClipRect.i16XMax == psWidget->sPosition.i16XMax) { sClipRect.i16XMax--; } if(sClipRect.i16YMax == psWidget->sPosition.i16YMax) { sClipRect.i16YMax--; } } // // Determine the position associated with the current slider value. // i16Pos = SliderValueToPosition(pSlider, pSlider->i32Value); // // Remember this so that the dirty rectangle code in the click handler // draws the correct thing the first time it is called. // pSlider->i16Pos = i16Pos; // // Determine the rectangles for the active and empty portions of the // widget. // if(pSlider->ui32Style & SL_STYLE_VERTICAL) { // // Determine the rectangle corresponding to the bottom (value) portion // of the slider. // sValueRect.i16XMin = psWidget->sPosition.i16XMin; sValueRect.i16XMax = psWidget->sPosition.i16XMax; sValueRect.i16YMin = i16Pos; sValueRect.i16YMax = psWidget->sPosition.i16YMax; // // Determine the rectangle corresponding to the top (empty) portion // of the slider. // sEmptyRect.i16XMin = psWidget->sPosition.i16XMin; sEmptyRect.i16XMax = psWidget->sPosition.i16XMax; sEmptyRect.i16YMin = psWidget->sPosition.i16YMin; sEmptyRect.i16YMax = max(sEmptyRect.i16YMin, sValueRect.i16YMin - 1); } else { // // Determine the rectangle corresponding to the bottom (value) portion // of the slider. // sValueRect.i16YMin = psWidget->sPosition.i16YMin; sValueRect.i16YMax = psWidget->sPosition.i16YMax; sValueRect.i16XMin = psWidget->sPosition.i16XMin; sValueRect.i16XMax = i16Pos; // // Determine the rectangle corresponding to the top (empty) portion // of the slider. // sEmptyRect.i16YMin = psWidget->sPosition.i16YMin; sEmptyRect.i16YMax = psWidget->sPosition.i16YMax; sEmptyRect.i16XMax = psWidget->sPosition.i16XMax; sEmptyRect.i16XMin = min(sEmptyRect.i16XMax, sValueRect.i16XMax + 1); } // // Compute the center of the slider. This will be needed later if drawing // text or an image. // i32X = (psWidget->sPosition.i16XMin + ((psWidget->sPosition.i16XMax - psWidget->sPosition.i16XMin + 1) / 2)); i32Y = (psWidget->sPosition.i16YMin + ((psWidget->sPosition.i16YMax - psWidget->sPosition.i16YMin + 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->ui32Style & SL_STYLE_FILL) { GrContextForegroundSet(&sCtx, pSlider->ui32FillColor); GrRectFill(&sCtx, &sValueRect); } // // Do we need to draw an image in the active area? // if(pSlider->ui32Style & SL_STYLE_IMG) { GrContextForegroundSet(&sCtx, pSlider->ui32TextColor); GrContextBackgroundSet(&sCtx, pSlider->ui32FillColor); GrImageDraw(&sCtx, pSlider->pui8Image, i32X - (GrImageWidthGet(pSlider->pui8Image) / 2), i32Y - (GrImageHeightGet(pSlider->pui8Image) / 2)); } // // Do we need to render a text string over the top of the active area? // if(pSlider->ui32Style & SL_STYLE_TEXT) { GrContextFontSet(&sCtx, pSlider->psFont); GrContextForegroundSet(&sCtx, pSlider->ui32TextColor); GrContextBackgroundSet(&sCtx, pSlider->ui32FillColor); GrStringDrawCentered(&sCtx, pSlider->pcText, -1, i32X, i32Y, pSlider->ui32Style & 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->ui32Style & SL_STYLE_BACKG_FILL) { GrContextForegroundSet(&sCtx, pSlider->ui32BackgroundFillColor); GrRectFill(&sCtx, &sEmptyRect); } // // Do we need to draw an image in the active area? // if(pSlider->ui32Style & SL_STYLE_BACKG_IMG) { GrContextForegroundSet(&sCtx, pSlider->ui32BackgroundTextColor); GrContextBackgroundSet(&sCtx, pSlider->ui32BackgroundFillColor); GrImageDraw(&sCtx, pSlider->pui8BackgroundImage, i32X - (GrImageWidthGet(pSlider->pui8BackgroundImage) / 2), i32Y - (GrImageHeightGet(pSlider->pui8BackgroundImage) / 2)); } // // Do we need to render a text string over the top of the active area? // if(pSlider->ui32Style & SL_STYLE_BACKG_TEXT) { GrContextFontSet(&sCtx, pSlider->psFont); GrContextForegroundSet(&sCtx, pSlider->ui32BackgroundTextColor); GrContextBackgroundSet(&sCtx, pSlider->ui32BackgroundFillColor); GrStringDrawCentered(&sCtx, pSlider->pcText, -1, i32X, i32Y, pSlider->ui32Style & SL_STYLE_BACKG_TEXT_OPAQUE); } } }
//***************************************************************************** // //! Draws a rectangular push button. //! //! \param pWidget 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 *pWidget) { const unsigned char *pucImage; tPushButtonWidget *pPush; tContext sCtx; long lX, lY; // // 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 rectangular // push button. // GrContextClipRegionSet(&sCtx, &(pWidget->sPosition)); // // 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)); GrRectFill(&sCtx, &(pWidget->sPosition)); } // // 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); GrRectDraw(&sCtx, &(pWidget->sPosition)); } // // See if the push button text or image style is selected. // if(pPush->ulStyle & (PB_STYLE_TEXT | PB_STYLE_IMG)) { // // Compute the center of the push 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)); // // 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); } } }