示例#1
0
//*****************************************************************************
//
//! Handles pointer events for a rectangular image button.
//!
//! \param pWidget is a pointer to the image button widget.
//! \param ulMsg is the pointer event message.
//! \param lX is the X coordinate of the pointer event.
//! \param lY is the Y coordinate of the pointer event.
//!
//! This function processes pointer event messages for a rectangular push
//! button.  This is called in response to a \b #WIDGET_MSG_PTR_DOWN,
//! \b #WIDGET_MSG_PTR_MOVE, and \b #WIDGET_MSG_PTR_UP messages.
//!
//! If the \b #WIDGET_MSG_PTR_UP message is received with a position within the
//! extents of the image button, the image button's OnClick callback function is
//! called.
//!
//! \return Returns 1 if the coordinates are within the extents of the push
//! button and 0 otherwise.
//
//*****************************************************************************
static long
ImageButtonClick(tWidget *pWidget, unsigned long ulMsg, long lX, long lY)
{
    tImageButtonWidget *pPush;

    //
    // Check the arguments.
    //
    ASSERT(pWidget);

    //
    // Convert the generic widget pointer into a image button widget pointer.
    //
    pPush = (tImageButtonWidget *)pWidget;

    //
    // See if this is a pointer up message.
    //
    if(ulMsg == WIDGET_MSG_PTR_UP)
    {
        //
        // Indicate that this image button is no longer pressed.
        //
        pPush->ulStyle &= ~(IB_STYLE_PRESSED);

        //
        // Redraw the button in the released state.
        //
        ImageButtonPaint(pWidget);

        //
        // If the pointer is still within the button bounds, and it is a
        // release notify button, call the notification function here.
        //
        if(GrRectContainsPoint(&pWidget->sPosition, lX, lY) &&
           (pPush->ulStyle & IB_STYLE_RELEASE_NOTIFY) && pPush->pfnOnClick)
        {
            pPush->pfnOnClick(pWidget);
        }
    }

    //
    // See if the given coordinates are within the extents of the image button.
    //
    if(GrRectContainsPoint(&pWidget->sPosition, lX, lY))
    {
        //
        // See if this is a pointer down message.
        //
        if(ulMsg == WIDGET_MSG_PTR_DOWN)
        {
            //
            // Indicate that this image button is pressed.
            //
            pPush->ulStyle |= IB_STYLE_PRESSED;

            //
            // Draw the button in the pressed state.
            //
            ImageButtonPaint(pWidget);
        }

        //
        // See if there is an OnClick callback for this widget.
        //
        if(pPush->pfnOnClick)
        {
            //
            // If the pointer was just pressed then call the callback.
            //
            if((ulMsg == WIDGET_MSG_PTR_DOWN) &&
               !(pPush->ulStyle & IB_STYLE_RELEASE_NOTIFY))
            {
                pPush->pfnOnClick(pWidget);
            }

            //
            // See if auto-repeat is enabled for this widget.
            //
            if(pPush->ulStyle & IB_STYLE_AUTO_REPEAT)
            {
                //
                // If the pointer was just pressed, reset the auto-repeat
                // count.
                //
                if(ulMsg == WIDGET_MSG_PTR_DOWN)
                {
                    pPush->ulAutoRepeatCount = 0;
                }

                //
                // See if the pointer was moved.
                //
                else if(ulMsg == WIDGET_MSG_PTR_MOVE)
                {
                    //
                    // Increment the auto-repeat count.
                    //
                    pPush->ulAutoRepeatCount++;

                    //
                    // If the auto-repeat count exceeds the auto-repeat delay,
                    // and it is a multiple of the auto-repeat rate, then
                    // call the callback.
                    //
                    if((pPush->ulAutoRepeatCount >=
                        pPush->usAutoRepeatDelay) &&
                       (((pPush->ulAutoRepeatCount -
                          pPush->usAutoRepeatDelay) %
                         pPush->usAutoRepeatRate) == 0))
                    {
                        pPush->pfnOnClick(pWidget);
                    }
                }
            }
        }

        //
        // These coordinates are within the extents of the image button widget.
        //
        return(1);
    }

    //
    // These coordinates are not within the extents of the image button widget.
    //
    return(0);
}
示例#2
0
//*****************************************************************************
//
//! Handles pointer events for a JPEG widget.
//!
//! \param pWidget is a pointer to the JPEG widget.
//! \param ulMsg is the pointer event message.
//! \param lX is the X coordinate of the pointer event.
//! \param lY is the Y coordinate of the pointer event.
//!
//! This function processes pointer event messages for a JPEG widget.
//! This is called in response to a \b WIDGET_MSG_PTR_DOWN,
//! \b WIDGET_MSG_PTR_MOVE, and \b WIDGET_MSG_PTR_UP messages.
//!
//! If the widget has the \b #JW_STYLE_LOCKED flag set, the input is ignored
//! and this function returns immediately.
//!
//! If the widget is a button type (having style flag \b #JW_STYLE_BUTTON set),
//! and the mouse message is within the extent of the widget, the OnClick
//! callback function will be called on \b WIDGET_MSG_PTR_DOWN if style flag
//! \b #JW_STYLE_RELEASE_NOTIFY is not set or on \b WIDGET_MSG_PTR_UP if
//! \b #JW_STYLE_RELEASE_NOTIFY is set.
//!
//! If the widget is a canvas type (style flag \b #JW_STYLE_BUTTON not set),
//! pointer messages are used to control scrolling of the JPEG image within
//! the area of the widget.  In this case, any pointer movement that will cause
//! a change in the image position is reported to the client via the OnScroll
//! callback function.
//!
//! \return Returns 1 if the coordinates are within the extents of the widget
//! and 0 otherwise.
//
//*****************************************************************************
static long
JPEGWidgetClick(tWidget *pWidget, unsigned long ulMsg, long lX, long lY)
{
    tJPEGWidget *pJPEG;
    tBoolean bWithinWidget, bChanged;

    //
    // Check the arguments.
    //
    ASSERT(pWidget);

    //
    // Convert the generic widget pointer into a JPEG widget pointer.
    //
    pJPEG = (tJPEGWidget *)pWidget;

    //
    // Is the widget currently locked?
    //
    if(pJPEG->ulStyle & JW_STYLE_LOCKED)
    {
        //
        // We ignore this message and have the widget manager pass it back
        // up the tree.
        //
        return(0);
    }

    //
    // Does this event occur within the bounds of this widget?
    //
    bWithinWidget = GrRectContainsPoint(&pWidget->sPosition, lX, lY);

    //
    // Is this widget a button type?
    //
    if(pJPEG->ulStyle & JW_STYLE_BUTTON)
    {
        //
        // Yes - it's a button.  In this case, we only look for PTR_UP and
        // PTR_DOWN messages so that we can trigger the OnClick callback.
        //
        if(pJPEG->pfnOnClick)
        {
            //
            // Call the click callback if the screen has been pressed and we
            // are notifying on press or if the screen has been released and
            // we are notifying on release.
            //
            if(((ulMsg == WIDGET_MSG_PTR_UP) &&
               (pJPEG->ulStyle & JW_STYLE_RELEASE_NOTIFY)) ||
               ((ulMsg == WIDGET_MSG_PTR_DOWN) &&
               !(pJPEG->ulStyle & JW_STYLE_RELEASE_NOTIFY)))
            {
                pJPEG->pfnOnClick(pWidget);
            }
        }
    }
    else
    {
        //
        // This is a canvas style JPEG widget so we track mouse movement to
        // allow us to scroll the image based on touchscreen gestures.
        //
        switch(ulMsg)
        {
            //
            // The user has pressed the touchscreen.
            //
            case WIDGET_MSG_PTR_DOWN:
            {
                //
                // Did this event occur within the bounds of this particular
                // widget?
                //
                if(bWithinWidget)
                {
                    //
                    // Yes, it's our press so remember where it occurred and
                    // remember that the touchscreen is pressed.
                    //
                    pJPEG->ulStyle |= JW_STYLE_PRESSED;
                    pJPEG->psJPEGInst->sXStart = (short)lX;
                    pJPEG->psJPEGInst->sYStart = (short)lY;
                }

                break;
            }

            //
            // The touchscreen has been released.
            //
            case WIDGET_MSG_PTR_UP:
            {
                //
                // Remember that the touchscreen is no longer pressed.
                //
                pJPEG->ulStyle &= ~ JW_STYLE_PRESSED;

                //
                // Has the pointer moved since the last time we looked?  If so
                // handle it appropriately.
                //
                bChanged = JPEGWidgetHandlePtrPos(pJPEG, lX, lY);

                //
                // Repaint the widget.
                //
                WidgetPaint(pWidget);
                break;
            }

            //
            // The pointer position has changed.
            //
            case WIDGET_MSG_PTR_MOVE:
            {
                //
                // Calculate the new image offsets based on the new pointer
                // position.
                //
                bChanged = JPEGWidgetHandlePtrPos(pJPEG, lX, lY);

                //
                // If something changed and we were asked to redraw
                // automatically on scrolling, do so here.
                //
                if(bChanged && (pJPEG->ulStyle & JW_STYLE_SCROLL))
                {
                    WidgetPaint(pWidget);
                }
                break;
            }

            default:
                break;
        }
    }

    //
    // Tell the widget manager whether this event occurred within the bounds
    // of this widget.
    //
    return((long)bWithinWidget);
}
示例#3
0
//*****************************************************************************
//
// Handles pointer messages for a listbox widget.
//
// \param pListBox is a pointer to the listbox widget.
// \param ulMsg is the message.
// \param lX is the X coordinate of the pointer.
// \param lY is the Y coordinate of the pointer.
//
// This function receives pointer messages intended for this listbox widget
// and processes them accordingly.
//
// \return Returns a value appropriate to the supplied message.
//
//*****************************************************************************
static long
ListBoxPointer(tListBoxWidget *pListBox, unsigned long ulMsg, long lX, long lY)
{
    long lLineNum, lEntry, lVisible, lMaxUp, lMaxDown, lScroll;

    switch(ulMsg)
    {
        //
        // The touchscreen has been pressed.
        //
        case WIDGET_MSG_PTR_DOWN:
        {
            //
            // Is the pointer press within the bounds of this widget?
            //
            if(!GrRectContainsPoint(&(pListBox->sBase.sPosition), lX, lY))
            {
                //
                // This is not a message for us so return 0 to indicate that
                // we did not process it.
                //
                return(0);
            }
            else
            {
                //
                // The pointer was pressed within this control.  Remember the Y
                // coordinate and reset or scrolling flag.
                //
                pListBox->usScrolled = 0;
                pListBox->lPointerY = lY;

                //
                // Return 1 to indicate to the widget manager that we processed
                // the message.  This widget will now receive all pointer move
                // messages until the pointer is released.
                //
                return(1);
            }
        }

        //
        // The touchscreen has been released.
        //
        case WIDGET_MSG_PTR_UP:
        {
            //
            // If the pointer is still within the bounds of the control and
            // we have not scrolled the contents since the last time the
            // pointer was pressed, we assume that this is a tap rather than
            // a drag and select the element that falls beneath the current
            // pointer position.  If the pointer is outside our control, if
            // we have scrolled already or if the control is locked, don't
            // change the selection.
            //
            if((pListBox->usScrolled == 0) &&
               !(pListBox->ulStyle & LISTBOX_STYLE_LOCKED) &&
                GrRectContainsPoint(&(pListBox->sBase.sPosition), lX, lY))
            {
                //
                // It seems we need to change the selected element. What is
                // the display line number that has been clicked on?
                //
                lLineNum = (lY - (long)pListBox->sBase.sPosition.sYMin) /
                           GrFontHeightGet(pListBox->pFont);

                //
                // We now know the location of the click as a number of text
                // lines from the top of the list box.  Now determine what
                // entry is shown there, remembering that the index may wrap.
                //
                lEntry = ((long)pListBox->usStartEntry + lLineNum) %
                         pListBox->usMaxEntries;

                //
                // If this is an unpopulated entry or the current selection,
                // clear the selection.
                //
                if((lEntry >= (long)pListBox->usPopulated) ||
                   (lEntry == (long)pListBox->sSelected))
                {
                    //
                    // Yes - update the selection and force a repaint.
                    //
                    pListBox->sSelected = (short)0xFFFF;
                }
                else
                {
                    //
                    // The pointer was tapped on a valid entry other than the
                    // current selection so change the selection.
                    //
                    pListBox->sSelected = (short)lEntry;
                }

                //
                // Force a repaint of the widget.
                //
                WidgetPaint((tWidget *)pListBox);

                //
                // Tell the client that the selection changed.
                //
                if(pListBox->pfnOnChange)
                {
                    (pListBox->pfnOnChange)((tWidget *)pListBox,
                                            pListBox->sSelected);
                }
            }

            //
            // We process all pointer up messages so return 1 to tell the
            // widget manager this.
            //
            return(1);
        }

        //
        // The pointer is moving while pressed.
        //
        case WIDGET_MSG_PTR_MOVE:
        {
            //
            // How far has the pointer moved vertically from the point where it
            // was pressed or where we last registered a scroll?  lLineNum will
            // be negative for downward scrolling.
            //
            lLineNum = pListBox->lPointerY - lY;

            //
            // If this distance is greater than or equal to the height of a
            // line of text, we need to check to see if we need to scroll the
            // list box contents.
            //
            if(abs(lLineNum) >= GrFontHeightGet(pListBox->pFont))
            {
                //
                // We have to scroll if this is possible.  How many lines can
                // be visible on the display?
                //
                lVisible = (pListBox->sBase.sPosition.sYMax -
                            pListBox->sBase.sPosition.sYMin) /
                            (long)GrFontHeightGet(pListBox->pFont);

                //
                // If we have fewer strings in the listbox than there are lines
                // on the display, scrolling is not possible so give up now.
                //
                if(lVisible > (long)pListBox->usPopulated)
                {
                    return(1);
                }

                //
                // How many lines of scrolling does the latest pointer position
                // indicate?  A negative value implies downward scrolling (i.e.
                // showing earlier strings).
                //
                lScroll = lLineNum / (long)GrFontHeightGet(pListBox->pFont);

                //
                // What is the farthest we could scroll downwards (i.e. moving
                // the pointer towards the bottom of the screen)?  Note - this
                // will be negative or 0.
                //
                lMaxDown = (pListBox->usStartEntry >= pListBox->usOldestEntry) ?
                           (pListBox->usOldestEntry - pListBox->usStartEntry ) :
                           ((pListBox->usOldestEntry - pListBox->usStartEntry) -
                             pListBox->usMaxEntries);

                //
                // What is the farthest we could scroll upwards?  Note - this
                // will be a positive number.
                //
                lMaxUp = ((long)pListBox->usPopulated - lVisible) + lMaxDown;

                //
                // Determine the actual scroll distance given the maximum
                // distances calculated.
                //
                lScroll = min(lScroll, lMaxUp);
                lScroll = max(lScroll, lMaxDown);

                if(lScroll)
                {
                    //
                    // Adjust the start entry appropriately, taking care to handle
                    // the wrap case.
                    //
                    pListBox->usStartEntry += lScroll;
                    pListBox->usStartEntry %= pListBox->usMaxEntries;

                    //
                    // Remember that we scrolled.
                    //
                    pListBox->usScrolled = 1;

                    //
                    // Adjust the pointer position we record to take into account
                    // the amount we just scrolled.
                    //
                    pListBox->lPointerY -= (lScroll *
                                            GrFontHeightGet(pListBox->pFont));

                    //
                    // Repaint the contents of the widget.
                    //
                    WidgetPaint((tWidget *)pListBox);
                }
            }

            return(1);
        }
    }

    //
    // We don't handle any other messages so return 0 if we get these.
    //
    return(0);
}
示例#4
0
//*****************************************************************************
//
//! Handles pointer events for a rectangular push button.
//!
//! \param psWidget is a pointer to the push button widget.
//! \param ui32Msg is the pointer event message.
//! \param i32X is the X coordinate of the pointer event.
//! \param i32Y is the Y coordinate of the pointer event.
//!
//! This function processes pointer event messages for a rectangular push
//! button.  This is called in response to a \b #WIDGET_MSG_PTR_DOWN,
//! \b #WIDGET_MSG_PTR_MOVE, and \b #WIDGET_MSG_PTR_UP messages.
//!
//! If the \b #WIDGET_MSG_PTR_UP message is received with a position within the
//! extents of the push button, the push button's OnClick callback function is
//! called.
//!
//! \return Returns 1 if the coordinates are within the extents of the push
//! button and 0 otherwise.
//
//*****************************************************************************
static int32_t
RectangularButtonClick(tWidget *psWidget, uint32_t ui32Msg, int32_t i32X,
                       int32_t i32Y)
{
    tPushButtonWidget *pPush;

    //
    // Check the arguments.
    //
    ASSERT(psWidget);

    //
    // Convert the generic widget pointer into a push button widget pointer.
    //
    pPush = (tPushButtonWidget *)psWidget;

    //
    // See if this is a pointer up message.
    //
    if(ui32Msg == WIDGET_MSG_PTR_UP)
    {
        //
        // Indicate that this push button is no longer pressed.
        //
        pPush->ui32Style &= ~(PB_STYLE_PRESSED);

        //
        // If filling is enabled for this push button, or if an image is being
        // used and a pressed button image is provided, then redraw the push
        // button to show it in its non-pressed state.
        //
        if((pPush->ui32Style & PB_STYLE_FILL) ||
           ((pPush->ui32Style & PB_STYLE_IMG) && pPush->pui8PressImage))
        {
            RectangularButtonPaint(psWidget);
        }

        //
        // If the pointer is still within the button bounds, and it is a
        // release notify button, call the notification function here.
        //
        if(GrRectContainsPoint(&psWidget->sPosition, i32X, i32Y) &&
           (pPush->ui32Style & PB_STYLE_RELEASE_NOTIFY) && pPush->pfnOnClick)
        {
            pPush->pfnOnClick(psWidget);
        }
    }

    //
    // See if the given coordinates are within the extents of the push button.
    //
    if(GrRectContainsPoint(&psWidget->sPosition, i32X, i32Y))
    {
        //
        // See if this is a pointer down message.
        //
        if(ui32Msg == WIDGET_MSG_PTR_DOWN)
        {
            //
            // Indicate that this push button is pressed.
            //
            pPush->ui32Style |= PB_STYLE_PRESSED;

            //
            // If filling is enabled for this push button, or if an image is
            // being used and a pressed button image is provided, then redraw
            // the push button to show it in its pressed state.
            //
            if((pPush->ui32Style & PB_STYLE_FILL) ||
               ((pPush->ui32Style & PB_STYLE_IMG) && pPush->pui8PressImage))
            {
                RectangularButtonPaint(psWidget);
            }
        }

        //
        // See if there is an OnClick callback for this widget.
        //
        if(pPush->pfnOnClick)
        {
            //
            // If the pointer was just pressed then call the callback.
            //
            if((ui32Msg == WIDGET_MSG_PTR_DOWN) &&
               !(pPush->ui32Style & PB_STYLE_RELEASE_NOTIFY))
            {
                pPush->pfnOnClick(psWidget);
            }

            //
            // See if auto-repeat is enabled for this widget.
            //
            if(pPush->ui32Style & PB_STYLE_AUTO_REPEAT)
            {
                //
                // If the pointer was just pressed, reset the auto-repeat
                // count.
                //
                if(ui32Msg == WIDGET_MSG_PTR_DOWN)
                {
                    pPush->ui32AutoRepeatCount = 0;
                }

                //
                // See if the pointer was moved.
                //
                else if(ui32Msg == WIDGET_MSG_PTR_MOVE)
                {
                    //
                    // Increment the auto-repeat count.
                    //
                    pPush->ui32AutoRepeatCount++;

                    //
                    // If the auto-repeat count exceeds the auto-repeat delay,
                    // and it is a multiple of the auto-repeat rate, then
                    // call the callback.
                    //
                    if((pPush->ui32AutoRepeatCount >=
                        pPush->ui16AutoRepeatDelay) &&
                       (((pPush->ui32AutoRepeatCount -
                          pPush->ui16AutoRepeatDelay) %
                         pPush->ui16AutoRepeatRate) == 0))
                    {
                        pPush->pfnOnClick(psWidget);
                    }
                }
            }
        }

        //
        // These coordinates are within the extents of the push button widget.
        //
        return(1);
    }

    //
    // These coordinates are not within the extents of the push button widget.
    //
    return(0);
}