OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [tk/] [win/] [tkWinScrlbr.c] - Diff between revs 578 and 1765

Only display areas with differences | Details | Blame | View Log

Rev 578 Rev 1765
/*
/*
 * tkWinScrollbar.c --
 * tkWinScrollbar.c --
 *
 *
 *      This file implements the Windows specific portion of the scrollbar
 *      This file implements the Windows specific portion of the scrollbar
 *      widget.
 *      widget.
 *
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 *
 *
 * See the file "license.terms" for information on usage and redistribution
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 *
 * RCS: @(#) $Id: tkWinScrlbr.c,v 1.1.1.1 2002-01-16 10:26:03 markom Exp $
 * RCS: @(#) $Id: tkWinScrlbr.c,v 1.1.1.1 2002-01-16 10:26:03 markom Exp $
 */
 */
 
 
#include "tkWinInt.h"
#include "tkWinInt.h"
#include "tkScrollbar.h"
#include "tkScrollbar.h"
 
 
 
 
/*
/*
 * The following constant is used to specify the maximum scroll position.
 * The following constant is used to specify the maximum scroll position.
 * This value is limited by the Win32 API to either 16-bits or 32-bits,
 * This value is limited by the Win32 API to either 16-bits or 32-bits,
 * depending on the context.  For now we'll just use a value small
 * depending on the context.  For now we'll just use a value small
 * enough to fit in 16-bits, but which gives us 4-digits of precision.
 * enough to fit in 16-bits, but which gives us 4-digits of precision.
 */
 */
 
 
#define MAX_SCROLL 10000
#define MAX_SCROLL 10000
 
 
/*
/*
 * Declaration of Windows specific scrollbar structure.
 * Declaration of Windows specific scrollbar structure.
 */
 */
 
 
typedef struct WinScrollbar {
typedef struct WinScrollbar {
    TkScrollbar info;           /* Generic scrollbar info. */
    TkScrollbar info;           /* Generic scrollbar info. */
    WNDPROC oldProc;            /* Old window procedure. */
    WNDPROC oldProc;            /* Old window procedure. */
    int lastVertical;           /* 1 if was vertical at last refresh. */
    int lastVertical;           /* 1 if was vertical at last refresh. */
    HWND hwnd;                  /* Current window handle. */
    HWND hwnd;                  /* Current window handle. */
    int winFlags;               /* Various flags; see below. */
    int winFlags;               /* Various flags; see below. */
} WinScrollbar;
} WinScrollbar;
 
 
/*
/*
 * Flag bits for native scrollbars:
 * Flag bits for native scrollbars:
 *
 *
 * IN_MODAL_LOOP:               Non-zero means this scrollbar is in the middle
 * IN_MODAL_LOOP:               Non-zero means this scrollbar is in the middle
 *                              of a modal loop.
 *                              of a modal loop.
 * ALREADY_DEAD:                Non-zero means this scrollbar has been
 * ALREADY_DEAD:                Non-zero means this scrollbar has been
 *                              destroyed, but has not been cleaned up.
 *                              destroyed, but has not been cleaned up.
 */
 */
 
 
#define IN_MODAL_LOOP   1
#define IN_MODAL_LOOP   1
#define ALREADY_DEAD    2
#define ALREADY_DEAD    2
 
 
/*
/*
 * Cached system metrics used to determine scrollbar geometry.
 * Cached system metrics used to determine scrollbar geometry.
 */
 */
 
 
static int initialized = 0;
static int initialized = 0;
static int hArrowWidth, hThumb; /* Horizontal control metrics. */
static int hArrowWidth, hThumb; /* Horizontal control metrics. */
static int vArrowWidth, vArrowHeight, vThumb; /* Vertical control metrics. */
static int vArrowWidth, vArrowHeight, vThumb; /* Vertical control metrics. */
 
 
/*
/*
 * This variable holds the default width for a scrollbar in string
 * This variable holds the default width for a scrollbar in string
 * form for use in a Tk_ConfigSpec.
 * form for use in a Tk_ConfigSpec.
 */
 */
 
 
static char defWidth[8];
static char defWidth[8];
 
 
/*
/*
 * Declarations for functions defined in this file.
 * Declarations for functions defined in this file.
 */
 */
 
 
static Window           CreateProc _ANSI_ARGS_((Tk_Window tkwin,
static Window           CreateProc _ANSI_ARGS_((Tk_Window tkwin,
                            Window parent, ClientData instanceData));
                            Window parent, ClientData instanceData));
static void             ModalLoopProc _ANSI_ARGS_((Tk_Window tkwin,
static void             ModalLoopProc _ANSI_ARGS_((Tk_Window tkwin,
                            XEvent *eventPtr));
                            XEvent *eventPtr));
static int              ScrollbarBindProc _ANSI_ARGS_((ClientData clientData,
static int              ScrollbarBindProc _ANSI_ARGS_((ClientData clientData,
                            Tcl_Interp *interp, XEvent *eventPtr,
                            Tcl_Interp *interp, XEvent *eventPtr,
                            Tk_Window tkwin, KeySym keySym));
                            Tk_Window tkwin, KeySym keySym));
static LRESULT CALLBACK ScrollbarProc _ANSI_ARGS_((HWND hwnd, UINT message,
static LRESULT CALLBACK ScrollbarProc _ANSI_ARGS_((HWND hwnd, UINT message,
                            WPARAM wParam, LPARAM lParam));
                            WPARAM wParam, LPARAM lParam));
static void             UpdateScrollbar _ANSI_ARGS_((
static void             UpdateScrollbar _ANSI_ARGS_((
                            WinScrollbar *scrollPtr));
                            WinScrollbar *scrollPtr));
static void             UpdateScrollbarMetrics _ANSI_ARGS_((void));
static void             UpdateScrollbarMetrics _ANSI_ARGS_((void));
 
 
/*
/*
 * The class procedure table for the scrollbar widget.
 * The class procedure table for the scrollbar widget.
 */
 */
 
 
TkClassProcs tkpScrollbarProcs = {
TkClassProcs tkpScrollbarProcs = {
    CreateProc,                 /* createProc */
    CreateProc,                 /* createProc */
    NULL,                       /* geometryProc */
    NULL,                       /* geometryProc */
    ModalLoopProc,              /* modalProc */
    ModalLoopProc,              /* modalProc */
};
};
 
 


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * TkpCreateScrollbar --
 * TkpCreateScrollbar --
 *
 *
 *      Allocate a new TkScrollbar structure.
 *      Allocate a new TkScrollbar structure.
 *
 *
 * Results:
 * Results:
 *      Returns a newly allocated TkScrollbar structure.
 *      Returns a newly allocated TkScrollbar structure.
 *
 *
 * Side effects:
 * Side effects:
 *      Registers an event handler for the widget.
 *      Registers an event handler for the widget.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
TkScrollbar *
TkScrollbar *
TkpCreateScrollbar(tkwin)
TkpCreateScrollbar(tkwin)
    Tk_Window tkwin;
    Tk_Window tkwin;
{
{
    WinScrollbar *scrollPtr;
    WinScrollbar *scrollPtr;
    TkWindow *winPtr = (TkWindow *)tkwin;
    TkWindow *winPtr = (TkWindow *)tkwin;
 
 
    if (!initialized) {
    if (!initialized) {
        UpdateScrollbarMetrics();
        UpdateScrollbarMetrics();
        initialized = 1;
        initialized = 1;
    }
    }
 
 
    scrollPtr = (WinScrollbar *) ckalloc(sizeof(WinScrollbar));
    scrollPtr = (WinScrollbar *) ckalloc(sizeof(WinScrollbar));
    scrollPtr->winFlags = 0;
    scrollPtr->winFlags = 0;
    scrollPtr->hwnd = NULL;
    scrollPtr->hwnd = NULL;
 
 
    Tk_CreateEventHandler(tkwin,
    Tk_CreateEventHandler(tkwin,
            ExposureMask|StructureNotifyMask|FocusChangeMask,
            ExposureMask|StructureNotifyMask|FocusChangeMask,
            TkScrollbarEventProc, (ClientData) scrollPtr);
            TkScrollbarEventProc, (ClientData) scrollPtr);
 
 
    if (!Tcl_GetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL)) {
    if (!Tcl_GetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL)) {
        Tcl_SetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL,
        Tcl_SetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL,
                (ClientData)1);
                (ClientData)1);
        TkCreateBindingProcedure(winPtr->mainPtr->interp,
        TkCreateBindingProcedure(winPtr->mainPtr->interp,
                winPtr->mainPtr->bindingTable,
                winPtr->mainPtr->bindingTable,
                (ClientData)Tk_GetUid("Scrollbar"), "<ButtonPress>",
                (ClientData)Tk_GetUid("Scrollbar"), "<ButtonPress>",
                ScrollbarBindProc, NULL, NULL);
                ScrollbarBindProc, NULL, NULL);
    }
    }
 
 
    return (TkScrollbar*) scrollPtr;
    return (TkScrollbar*) scrollPtr;
}
}


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * UpdateScrollbar --
 * UpdateScrollbar --
 *
 *
 *      This function updates the position and size of the scrollbar
 *      This function updates the position and size of the scrollbar
 *      thumb based on the current settings.
 *      thumb based on the current settings.
 *
 *
 * Results:
 * Results:
 *      None.
 *      None.
 *
 *
 * Side effects:
 * Side effects:
 *      Moves the thumb.
 *      Moves the thumb.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
static void
static void
UpdateScrollbar(scrollPtr)
UpdateScrollbar(scrollPtr)
    WinScrollbar *scrollPtr;
    WinScrollbar *scrollPtr;
{
{
    SCROLLINFO scrollInfo;
    SCROLLINFO scrollInfo;
    double thumbSize;
    double thumbSize;
 
 
    /*
    /*
     * Update the current scrollbar position and shape.
     * Update the current scrollbar position and shape.
     */
     */
 
 
    scrollInfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
    scrollInfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
    scrollInfo.cbSize = sizeof(scrollInfo);
    scrollInfo.cbSize = sizeof(scrollInfo);
    scrollInfo.nMin = 0;
    scrollInfo.nMin = 0;
    scrollInfo.nMax = MAX_SCROLL;
    scrollInfo.nMax = MAX_SCROLL;
    thumbSize = (scrollPtr->info.lastFraction - scrollPtr->info.firstFraction);
    thumbSize = (scrollPtr->info.lastFraction - scrollPtr->info.firstFraction);
    if (tkpIsWin32s) {
    if (tkpIsWin32s) {
        scrollInfo.nPage = 0;
        scrollInfo.nPage = 0;
    } else {
    } else {
        scrollInfo.nPage = ((UINT) (thumbSize * (double) MAX_SCROLL)) + 1;
        scrollInfo.nPage = ((UINT) (thumbSize * (double) MAX_SCROLL)) + 1;
    }
    }
    if (thumbSize < 1.0) {
    if (thumbSize < 1.0) {
        scrollInfo.nPos = (int)
        scrollInfo.nPos = (int)
            ((scrollPtr->info.firstFraction / (1.0-thumbSize))
            ((scrollPtr->info.firstFraction / (1.0-thumbSize))
                    * (MAX_SCROLL - (scrollInfo.nPage - 1)));
                    * (MAX_SCROLL - (scrollInfo.nPage - 1)));
    } else {
    } else {
        scrollInfo.nPos = 0;
        scrollInfo.nPos = 0;
    }
    }
    SetScrollInfo(scrollPtr->hwnd, SB_CTL, &scrollInfo, TRUE);
    SetScrollInfo(scrollPtr->hwnd, SB_CTL, &scrollInfo, TRUE);
}
}


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * CreateProc --
 * CreateProc --
 *
 *
 *      This function creates a new Scrollbar control, subclasses
 *      This function creates a new Scrollbar control, subclasses
 *      the instance, and generates a new Window object.
 *      the instance, and generates a new Window object.
 *
 *
 * Results:
 * Results:
 *      Returns the newly allocated Window object, or None on failure.
 *      Returns the newly allocated Window object, or None on failure.
 *
 *
 * Side effects:
 * Side effects:
 *      Causes a new Scrollbar control to come into existence.
 *      Causes a new Scrollbar control to come into existence.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
static Window
static Window
CreateProc(tkwin, parentWin, instanceData)
CreateProc(tkwin, parentWin, instanceData)
    Tk_Window tkwin;            /* Token for window. */
    Tk_Window tkwin;            /* Token for window. */
    Window parentWin;           /* Parent of new window. */
    Window parentWin;           /* Parent of new window. */
    ClientData instanceData;    /* Scrollbar instance data. */
    ClientData instanceData;    /* Scrollbar instance data. */
{
{
    DWORD style;
    DWORD style;
    Window window;
    Window window;
    HWND parent;
    HWND parent;
    TkWindow *winPtr;
    TkWindow *winPtr;
    WinScrollbar *scrollPtr = (WinScrollbar *)instanceData;
    WinScrollbar *scrollPtr = (WinScrollbar *)instanceData;
 
 
    parent = Tk_GetHWND(parentWin);
    parent = Tk_GetHWND(parentWin);
 
 
    if (scrollPtr->info.vertical) {
    if (scrollPtr->info.vertical) {
        style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
        style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
            | SBS_VERT | SBS_RIGHTALIGN;
            | SBS_VERT | SBS_RIGHTALIGN;
    } else {
    } else {
        style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
        style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
            | SBS_HORZ | SBS_BOTTOMALIGN;
            | SBS_HORZ | SBS_BOTTOMALIGN;
    }
    }
 
 
    scrollPtr->hwnd = CreateWindow("SCROLLBAR", NULL, style,
    scrollPtr->hwnd = CreateWindow("SCROLLBAR", NULL, style,
            Tk_X(tkwin), Tk_Y(tkwin), Tk_Width(tkwin), Tk_Height(tkwin),
            Tk_X(tkwin), Tk_Y(tkwin), Tk_Width(tkwin), Tk_Height(tkwin),
            parent, NULL, Tk_GetHINSTANCE(), NULL);
            parent, NULL, Tk_GetHINSTANCE(), NULL);
 
 
    /*
    /*
     * Ensure new window is inserted into the stacking order at the correct
     * Ensure new window is inserted into the stacking order at the correct
     * place.
     * place.
     */
     */
 
 
    SetWindowPos(scrollPtr->hwnd, HWND_TOP, 0, 0, 0, 0,
    SetWindowPos(scrollPtr->hwnd, HWND_TOP, 0, 0, 0, 0,
                    SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
                    SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
 
 
    for (winPtr = ((TkWindow*)tkwin)->nextPtr; winPtr != NULL;
    for (winPtr = ((TkWindow*)tkwin)->nextPtr; winPtr != NULL;
         winPtr = winPtr->nextPtr) {
         winPtr = winPtr->nextPtr) {
        if ((winPtr->window != None) && !(winPtr->flags & TK_TOP_LEVEL)) {
        if ((winPtr->window != None) && !(winPtr->flags & TK_TOP_LEVEL)) {
            TkWinSetWindowPos(scrollPtr->hwnd, Tk_GetHWND(winPtr->window),
            TkWinSetWindowPos(scrollPtr->hwnd, Tk_GetHWND(winPtr->window),
                    Below);
                    Below);
            break;
            break;
        }
        }
    }
    }
 
 
    scrollPtr->lastVertical = scrollPtr->info.vertical;
    scrollPtr->lastVertical = scrollPtr->info.vertical;
    scrollPtr->oldProc = (WNDPROC)SetWindowLong(scrollPtr->hwnd, GWL_WNDPROC,
    scrollPtr->oldProc = (WNDPROC)SetWindowLong(scrollPtr->hwnd, GWL_WNDPROC,
            (DWORD) ScrollbarProc);
            (DWORD) ScrollbarProc);
    window = Tk_AttachHWND(tkwin, scrollPtr->hwnd);
    window = Tk_AttachHWND(tkwin, scrollPtr->hwnd);
 
 
    UpdateScrollbar(scrollPtr);
    UpdateScrollbar(scrollPtr);
    return window;
    return window;
}
}


/*
/*
 *--------------------------------------------------------------
 *--------------------------------------------------------------
 *
 *
 * TkpDisplayScrollbar --
 * TkpDisplayScrollbar --
 *
 *
 *      This procedure redraws the contents of a scrollbar window.
 *      This procedure redraws the contents of a scrollbar window.
 *      It is invoked as a do-when-idle handler, so it only runs
 *      It is invoked as a do-when-idle handler, so it only runs
 *      when there's nothing else for the application to do.
 *      when there's nothing else for the application to do.
 *
 *
 * Results:
 * Results:
 *      None.
 *      None.
 *
 *
 * Side effects:
 * Side effects:
 *      Information appears on the screen.
 *      Information appears on the screen.
 *
 *
 *--------------------------------------------------------------
 *--------------------------------------------------------------
 */
 */
 
 
void
void
TkpDisplayScrollbar(clientData)
TkpDisplayScrollbar(clientData)
    ClientData clientData;      /* Information about window. */
    ClientData clientData;      /* Information about window. */
{
{
    WinScrollbar *scrollPtr = (WinScrollbar *) clientData;
    WinScrollbar *scrollPtr = (WinScrollbar *) clientData;
    Tk_Window tkwin = scrollPtr->info.tkwin;
    Tk_Window tkwin = scrollPtr->info.tkwin;
 
 
    scrollPtr->info.flags &= ~REDRAW_PENDING;
    scrollPtr->info.flags &= ~REDRAW_PENDING;
    if ((tkwin == NULL) || !Tk_IsMapped(tkwin)) {
    if ((tkwin == NULL) || !Tk_IsMapped(tkwin)) {
        return;
        return;
    }
    }
 
 
    /*
    /*
     * Destroy and recreate the scrollbar control if the orientation
     * Destroy and recreate the scrollbar control if the orientation
     * has changed.
     * has changed.
     */
     */
 
 
    if (scrollPtr->lastVertical != scrollPtr->info.vertical) {
    if (scrollPtr->lastVertical != scrollPtr->info.vertical) {
        HWND hwnd = Tk_GetHWND(Tk_WindowId(tkwin));
        HWND hwnd = Tk_GetHWND(Tk_WindowId(tkwin));
 
 
        SetWindowLong(hwnd, GWL_WNDPROC, (DWORD) scrollPtr->oldProc);
        SetWindowLong(hwnd, GWL_WNDPROC, (DWORD) scrollPtr->oldProc);
        DestroyWindow(hwnd);
        DestroyWindow(hwnd);
 
 
        CreateProc(tkwin, Tk_WindowId(Tk_Parent(tkwin)),
        CreateProc(tkwin, Tk_WindowId(Tk_Parent(tkwin)),
                (ClientData) scrollPtr);
                (ClientData) scrollPtr);
    } else {
    } else {
        UpdateScrollbar(scrollPtr);
        UpdateScrollbar(scrollPtr);
    }
    }
}
}


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * TkpDestroyScrollbar --
 * TkpDestroyScrollbar --
 *
 *
 *      Free data structures associated with the scrollbar control.
 *      Free data structures associated with the scrollbar control.
 *
 *
 * Results:
 * Results:
 *      None.
 *      None.
 *
 *
 * Side effects:
 * Side effects:
 *      Restores the default control state.
 *      Restores the default control state.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
void
void
TkpDestroyScrollbar(scrollPtr)
TkpDestroyScrollbar(scrollPtr)
    TkScrollbar *scrollPtr;
    TkScrollbar *scrollPtr;
{
{
    WinScrollbar *winScrollPtr = (WinScrollbar *)scrollPtr;
    WinScrollbar *winScrollPtr = (WinScrollbar *)scrollPtr;
    HWND hwnd = winScrollPtr->hwnd;
    HWND hwnd = winScrollPtr->hwnd;
    if (hwnd) {
    if (hwnd) {
        SetWindowLong(hwnd, GWL_WNDPROC, (DWORD) winScrollPtr->oldProc);
        SetWindowLong(hwnd, GWL_WNDPROC, (DWORD) winScrollPtr->oldProc);
        if (winScrollPtr->winFlags & IN_MODAL_LOOP) {
        if (winScrollPtr->winFlags & IN_MODAL_LOOP) {
            ((TkWindow *)scrollPtr->tkwin)->flags |= TK_DONT_DESTROY_WINDOW;
            ((TkWindow *)scrollPtr->tkwin)->flags |= TK_DONT_DESTROY_WINDOW;
            SetParent(hwnd, NULL);
            SetParent(hwnd, NULL);
        }
        }
    }
    }
    winScrollPtr->winFlags |= ALREADY_DEAD;
    winScrollPtr->winFlags |= ALREADY_DEAD;
}
}


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * UpdateScrollbarMetrics --
 * UpdateScrollbarMetrics --
 *
 *
 *      This function retrieves the current system metrics for a
 *      This function retrieves the current system metrics for a
 *      scrollbar.
 *      scrollbar.
 *
 *
 * Results:
 * Results:
 *      None.
 *      None.
 *
 *
 * Side effects:
 * Side effects:
 *      Updates the geometry cache info for all scrollbars.
 *      Updates the geometry cache info for all scrollbars.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
void
void
UpdateScrollbarMetrics()
UpdateScrollbarMetrics()
{
{
    Tk_ConfigSpec *specPtr;
    Tk_ConfigSpec *specPtr;
 
 
    hArrowWidth = GetSystemMetrics(SM_CXHSCROLL);
    hArrowWidth = GetSystemMetrics(SM_CXHSCROLL);
    hThumb = GetSystemMetrics(SM_CXHTHUMB);
    hThumb = GetSystemMetrics(SM_CXHTHUMB);
    vArrowWidth = GetSystemMetrics(SM_CXVSCROLL);
    vArrowWidth = GetSystemMetrics(SM_CXVSCROLL);
    vArrowHeight = GetSystemMetrics(SM_CYVSCROLL);
    vArrowHeight = GetSystemMetrics(SM_CYVSCROLL);
    vThumb = GetSystemMetrics(SM_CYVTHUMB);
    vThumb = GetSystemMetrics(SM_CYVTHUMB);
 
 
    sprintf(defWidth, "%d", vArrowWidth);
    sprintf(defWidth, "%d", vArrowWidth);
    for (specPtr = tkpScrollbarConfigSpecs; specPtr->type != TK_CONFIG_END;
    for (specPtr = tkpScrollbarConfigSpecs; specPtr->type != TK_CONFIG_END;
            specPtr++) {
            specPtr++) {
        if (specPtr->offset == Tk_Offset(TkScrollbar, width)) {
        if (specPtr->offset == Tk_Offset(TkScrollbar, width)) {
            specPtr->defValue = defWidth;
            specPtr->defValue = defWidth;
        }
        }
    }
    }
}
}


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * TkpComputeScrollbarGeometry --
 * TkpComputeScrollbarGeometry --
 *
 *
 *      After changes in a scrollbar's size or configuration, this
 *      After changes in a scrollbar's size or configuration, this
 *      procedure recomputes various geometry information used in
 *      procedure recomputes various geometry information used in
 *      displaying the scrollbar.
 *      displaying the scrollbar.
 *
 *
 * Results:
 * Results:
 *      None.
 *      None.
 *
 *
 * Side effects:
 * Side effects:
 *      The scrollbar will be displayed differently.
 *      The scrollbar will be displayed differently.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
void
void
TkpComputeScrollbarGeometry(scrollPtr)
TkpComputeScrollbarGeometry(scrollPtr)
    register TkScrollbar *scrollPtr;    /* Scrollbar whose geometry may
    register TkScrollbar *scrollPtr;    /* Scrollbar whose geometry may
                                         * have changed. */
                                         * have changed. */
{
{
    int fieldLength, minThumbSize;
    int fieldLength, minThumbSize;
 
 
    /*
    /*
     * Windows doesn't use focus rings on scrollbars, but we still
     * Windows doesn't use focus rings on scrollbars, but we still
     * perform basic sanity checks to appease backwards compatibility.
     * perform basic sanity checks to appease backwards compatibility.
     */
     */
 
 
    if (scrollPtr->highlightWidth < 0) {
    if (scrollPtr->highlightWidth < 0) {
        scrollPtr->highlightWidth = 0;
        scrollPtr->highlightWidth = 0;
    }
    }
 
 
    if (scrollPtr->vertical) {
    if (scrollPtr->vertical) {
        scrollPtr->arrowLength = vArrowHeight;
        scrollPtr->arrowLength = vArrowHeight;
        fieldLength = Tk_Height(scrollPtr->tkwin);
        fieldLength = Tk_Height(scrollPtr->tkwin);
        minThumbSize = vThumb;
        minThumbSize = vThumb;
    } else {
    } else {
        scrollPtr->arrowLength = hArrowWidth;
        scrollPtr->arrowLength = hArrowWidth;
        fieldLength = Tk_Width(scrollPtr->tkwin);
        fieldLength = Tk_Width(scrollPtr->tkwin);
        minThumbSize = hThumb;
        minThumbSize = hThumb;
    }
    }
    fieldLength -= 2*scrollPtr->arrowLength;
    fieldLength -= 2*scrollPtr->arrowLength;
    if (fieldLength < 0) {
    if (fieldLength < 0) {
        fieldLength = 0;
        fieldLength = 0;
    }
    }
    scrollPtr->sliderFirst = (int) ((double)fieldLength
    scrollPtr->sliderFirst = (int) ((double)fieldLength
            * scrollPtr->firstFraction);
            * scrollPtr->firstFraction);
    scrollPtr->sliderLast = (int) ((double)fieldLength
    scrollPtr->sliderLast = (int) ((double)fieldLength
            * scrollPtr->lastFraction);
            * scrollPtr->lastFraction);
 
 
    /*
    /*
     * Adjust the slider so that some piece of it is always
     * Adjust the slider so that some piece of it is always
     * displayed in the scrollbar and so that it has at least
     * displayed in the scrollbar and so that it has at least
     * a minimal width (so it can be grabbed with the mouse).
     * a minimal width (so it can be grabbed with the mouse).
     */
     */
 
 
    if (scrollPtr->sliderFirst > fieldLength) {
    if (scrollPtr->sliderFirst > fieldLength) {
        scrollPtr->sliderFirst = fieldLength;
        scrollPtr->sliderFirst = fieldLength;
    }
    }
    if (scrollPtr->sliderFirst < 0) {
    if (scrollPtr->sliderFirst < 0) {
        scrollPtr->sliderFirst = 0;
        scrollPtr->sliderFirst = 0;
    }
    }
    if (scrollPtr->sliderLast < (scrollPtr->sliderFirst
    if (scrollPtr->sliderLast < (scrollPtr->sliderFirst
            + minThumbSize)) {
            + minThumbSize)) {
        scrollPtr->sliderLast = scrollPtr->sliderFirst + minThumbSize;
        scrollPtr->sliderLast = scrollPtr->sliderFirst + minThumbSize;
    }
    }
    if (scrollPtr->sliderLast > fieldLength) {
    if (scrollPtr->sliderLast > fieldLength) {
        scrollPtr->sliderLast = fieldLength;
        scrollPtr->sliderLast = fieldLength;
    }
    }
    scrollPtr->sliderFirst += scrollPtr->arrowLength;
    scrollPtr->sliderFirst += scrollPtr->arrowLength;
    scrollPtr->sliderLast += scrollPtr->arrowLength;
    scrollPtr->sliderLast += scrollPtr->arrowLength;
 
 
    /*
    /*
     * Register the desired geometry for the window (leave enough space
     * Register the desired geometry for the window (leave enough space
     * for the two arrows plus a minimum-size slider, plus border around
     * for the two arrows plus a minimum-size slider, plus border around
     * the whole window, if any).  Then arrange for the window to be
     * the whole window, if any).  Then arrange for the window to be
     * redisplayed.
     * redisplayed.
     */
     */
 
 
    if (scrollPtr->vertical) {
    if (scrollPtr->vertical) {
        Tk_GeometryRequest(scrollPtr->tkwin,
        Tk_GeometryRequest(scrollPtr->tkwin,
                scrollPtr->width, 2*scrollPtr->arrowLength + minThumbSize);
                scrollPtr->width, 2*scrollPtr->arrowLength + minThumbSize);
    } else {
    } else {
        Tk_GeometryRequest(scrollPtr->tkwin,
        Tk_GeometryRequest(scrollPtr->tkwin,
                2*scrollPtr->arrowLength + minThumbSize, scrollPtr->width);
                2*scrollPtr->arrowLength + minThumbSize, scrollPtr->width);
    }
    }
    Tk_SetInternalBorder(scrollPtr->tkwin, 0);
    Tk_SetInternalBorder(scrollPtr->tkwin, 0);
}
}


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * ScrollbarProc --
 * ScrollbarProc --
 *
 *
 *      This function is call by Windows whenever an event occurs on
 *      This function is call by Windows whenever an event occurs on
 *      a scrollbar control created by Tk.
 *      a scrollbar control created by Tk.
 *
 *
 * Results:
 * Results:
 *      Standard Windows return value.
 *      Standard Windows return value.
 *
 *
 * Side effects:
 * Side effects:
 *      May generate events.
 *      May generate events.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
static LRESULT CALLBACK
static LRESULT CALLBACK
ScrollbarProc(hwnd, message, wParam, lParam)
ScrollbarProc(hwnd, message, wParam, lParam)
    HWND hwnd;
    HWND hwnd;
    UINT message;
    UINT message;
    WPARAM wParam;
    WPARAM wParam;
    LPARAM lParam;
    LPARAM lParam;
{
{
    LRESULT result;
    LRESULT result;
    POINT point;
    POINT point;
    WinScrollbar *scrollPtr;
    WinScrollbar *scrollPtr;
    Tk_Window tkwin = Tk_HWNDToWindow(hwnd);
    Tk_Window tkwin = Tk_HWNDToWindow(hwnd);
 
 
    if (tkwin == NULL) {
    if (tkwin == NULL) {
        panic("ScrollbarProc called on an invalid HWND");
        panic("ScrollbarProc called on an invalid HWND");
    }
    }
    scrollPtr = (WinScrollbar *)((TkWindow*)tkwin)->instanceData;
    scrollPtr = (WinScrollbar *)((TkWindow*)tkwin)->instanceData;
 
 
    switch(message) {
    switch(message) {
        case WM_HSCROLL:
        case WM_HSCROLL:
        case WM_VSCROLL: {
        case WM_VSCROLL: {
            Tcl_Interp *interp;
            Tcl_Interp *interp;
            Tcl_DString cmdString;
            Tcl_DString cmdString;
            int command = LOWORD(wParam);
            int command = LOWORD(wParam);
            int code;
            int code;
 
 
            GetCursorPos(&point);
            GetCursorPos(&point);
            Tk_TranslateWinEvent(NULL, WM_MOUSEMOVE, 0,
            Tk_TranslateWinEvent(NULL, WM_MOUSEMOVE, 0,
                    MAKELPARAM(point.x, point.y), &result);
                    MAKELPARAM(point.x, point.y), &result);
 
 
            if (command == SB_ENDSCROLL) {
            if (command == SB_ENDSCROLL) {
                return 0;
                return 0;
            }
            }
 
 
            /*
            /*
             * Bail out immediately if there isn't a command to invoke.
             * Bail out immediately if there isn't a command to invoke.
             */
             */
 
 
            if (scrollPtr->info.commandSize == 0) {
            if (scrollPtr->info.commandSize == 0) {
                Tcl_ServiceAll();
                Tcl_ServiceAll();
                return 0;
                return 0;
            }
            }
 
 
            Tcl_DStringInit(&cmdString);
            Tcl_DStringInit(&cmdString);
            Tcl_DStringAppend(&cmdString, scrollPtr->info.command,
            Tcl_DStringAppend(&cmdString, scrollPtr->info.command,
                    scrollPtr->info.commandSize);
                    scrollPtr->info.commandSize);
 
 
            if (command == SB_LINELEFT || command == SB_LINERIGHT) {
            if (command == SB_LINELEFT || command == SB_LINERIGHT) {
                Tcl_DStringAppendElement(&cmdString, "scroll");
                Tcl_DStringAppendElement(&cmdString, "scroll");
                Tcl_DStringAppendElement(&cmdString,
                Tcl_DStringAppendElement(&cmdString,
                        (command == SB_LINELEFT ) ? "-1" : "1");
                        (command == SB_LINELEFT ) ? "-1" : "1");
                Tcl_DStringAppendElement(&cmdString, "units");
                Tcl_DStringAppendElement(&cmdString, "units");
            } else if (command == SB_PAGELEFT || command == SB_PAGERIGHT) {
            } else if (command == SB_PAGELEFT || command == SB_PAGERIGHT) {
                Tcl_DStringAppendElement(&cmdString, "scroll");
                Tcl_DStringAppendElement(&cmdString, "scroll");
                Tcl_DStringAppendElement(&cmdString,
                Tcl_DStringAppendElement(&cmdString,
                        (command == SB_PAGELEFT ) ? "-1" : "1");
                        (command == SB_PAGELEFT ) ? "-1" : "1");
                Tcl_DStringAppendElement(&cmdString, "pages");
                Tcl_DStringAppendElement(&cmdString, "pages");
            } else {
            } else {
                char valueString[TCL_DOUBLE_SPACE];
                char valueString[TCL_DOUBLE_SPACE];
                double pos = 0.0;
                double pos = 0.0;
                switch (command) {
                switch (command) {
                    case SB_THUMBPOSITION:
                    case SB_THUMBPOSITION:
                        pos = ((double)HIWORD(wParam)) / MAX_SCROLL;
                        pos = ((double)HIWORD(wParam)) / MAX_SCROLL;
                        break;
                        break;
 
 
                    case SB_THUMBTRACK:
                    case SB_THUMBTRACK:
                        pos = ((double)HIWORD(wParam)) / MAX_SCROLL;
                        pos = ((double)HIWORD(wParam)) / MAX_SCROLL;
                        break;
                        break;
 
 
                    case SB_TOP:
                    case SB_TOP:
                        pos = 0.0;
                        pos = 0.0;
                        break;
                        break;
 
 
                    case SB_BOTTOM:
                    case SB_BOTTOM:
                        pos = 1.0;
                        pos = 1.0;
                        break;
                        break;
                }
                }
                sprintf(valueString, "%g", pos);
                sprintf(valueString, "%g", pos);
                Tcl_DStringAppendElement(&cmdString, "moveto");
                Tcl_DStringAppendElement(&cmdString, "moveto");
                Tcl_DStringAppendElement(&cmdString, valueString);
                Tcl_DStringAppendElement(&cmdString, valueString);
            }
            }
 
 
            interp = scrollPtr->info.interp;
            interp = scrollPtr->info.interp;
            code = Tcl_GlobalEval(interp, cmdString.string);
            code = Tcl_GlobalEval(interp, cmdString.string);
            if (code != TCL_OK && code != TCL_CONTINUE && code != TCL_BREAK) {
            if (code != TCL_OK && code != TCL_CONTINUE && code != TCL_BREAK) {
                Tcl_AddErrorInfo(interp, "\n    (scrollbar command)");
                Tcl_AddErrorInfo(interp, "\n    (scrollbar command)");
                Tcl_BackgroundError(interp);
                Tcl_BackgroundError(interp);
            }
            }
            Tcl_DStringFree(&cmdString);
            Tcl_DStringFree(&cmdString);
 
 
            Tcl_ServiceAll();
            Tcl_ServiceAll();
            return 0;
            return 0;
        }
        }
 
 
        default:
        default:
            if (Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
            if (Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
                return result;
                return result;
            }
            }
    }
    }
    return CallWindowProc(scrollPtr->oldProc, hwnd, message, wParam, lParam);
    return CallWindowProc(scrollPtr->oldProc, hwnd, message, wParam, lParam);
}
}


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * TkpConfigureScrollbar --
 * TkpConfigureScrollbar --
 *
 *
 *      This procedure is called after the generic code has finished
 *      This procedure is called after the generic code has finished
 *      processing configuration options, in order to configure
 *      processing configuration options, in order to configure
 *      platform specific options.
 *      platform specific options.
 *
 *
 * Results:
 * Results:
 *      None.
 *      None.
 *
 *
 * Side effects:
 * Side effects:
 *      None.
 *      None.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
void
void
TkpConfigureScrollbar(scrollPtr)
TkpConfigureScrollbar(scrollPtr)
    register TkScrollbar *scrollPtr;    /* Information about widget;  may or
    register TkScrollbar *scrollPtr;    /* Information about widget;  may or
                                         * may not already have values for
                                         * may not already have values for
                                         * some fields. */
                                         * some fields. */
{
{
}
}


/*
/*
 *--------------------------------------------------------------
 *--------------------------------------------------------------
 *
 *
 * ScrollbarBindProc --
 * ScrollbarBindProc --
 *
 *
 *      This procedure is invoked when the default <ButtonPress>
 *      This procedure is invoked when the default <ButtonPress>
 *      binding on the Scrollbar bind tag fires.
 *      binding on the Scrollbar bind tag fires.
 *
 *
 * Results:
 * Results:
 *      None.
 *      None.
 *
 *
 * Side effects:
 * Side effects:
 *      The event enters a modal loop.
 *      The event enters a modal loop.
 *
 *
 *--------------------------------------------------------------
 *--------------------------------------------------------------
 */
 */
 
 
static int
static int
ScrollbarBindProc(clientData, interp, eventPtr, tkwin, keySym)
ScrollbarBindProc(clientData, interp, eventPtr, tkwin, keySym)
    ClientData clientData;
    ClientData clientData;
    Tcl_Interp *interp;
    Tcl_Interp *interp;
    XEvent *eventPtr;
    XEvent *eventPtr;
    Tk_Window tkwin;
    Tk_Window tkwin;
    KeySym keySym;
    KeySym keySym;
{
{
    TkWindow *winPtr = (TkWindow*)tkwin;
    TkWindow *winPtr = (TkWindow*)tkwin;
    if (eventPtr->type == ButtonPress) {
    if (eventPtr->type == ButtonPress) {
        winPtr->flags |= TK_DEFER_MODAL;
        winPtr->flags |= TK_DEFER_MODAL;
    }
    }
    return TCL_OK;
    return TCL_OK;
}
}


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * ModalLoopProc --
 * ModalLoopProc --
 *
 *
 *      This function is invoked at the end of the event processing
 *      This function is invoked at the end of the event processing
 *      whenever the ScrollbarBindProc has been invoked for a ButtonPress
 *      whenever the ScrollbarBindProc has been invoked for a ButtonPress
 *      event.
 *      event.
 *
 *
 * Results:
 * Results:
 *      None.
 *      None.
 *
 *
 * Side effects:
 * Side effects:
 *      Enters a modal loop.
 *      Enters a modal loop.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
static void
static void
ModalLoopProc(tkwin, eventPtr)
ModalLoopProc(tkwin, eventPtr)
    Tk_Window tkwin;
    Tk_Window tkwin;
    XEvent *eventPtr;
    XEvent *eventPtr;
{
{
    TkWindow *winPtr = (TkWindow*)tkwin;
    TkWindow *winPtr = (TkWindow*)tkwin;
    WinScrollbar *scrollPtr = (WinScrollbar *) winPtr->instanceData;
    WinScrollbar *scrollPtr = (WinScrollbar *) winPtr->instanceData;
    int oldMode;
    int oldMode;
 
 
    Tcl_Preserve((ClientData)scrollPtr);
    Tcl_Preserve((ClientData)scrollPtr);
    scrollPtr->winFlags |= IN_MODAL_LOOP;
    scrollPtr->winFlags |= IN_MODAL_LOOP;
    oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
    oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
    TkWinResendEvent(scrollPtr->oldProc, scrollPtr->hwnd, eventPtr);
    TkWinResendEvent(scrollPtr->oldProc, scrollPtr->hwnd, eventPtr);
    (void) Tcl_SetServiceMode(oldMode);
    (void) Tcl_SetServiceMode(oldMode);
    scrollPtr->winFlags &= ~IN_MODAL_LOOP;
    scrollPtr->winFlags &= ~IN_MODAL_LOOP;
    if (scrollPtr->hwnd && scrollPtr->winFlags & ALREADY_DEAD) {
    if (scrollPtr->hwnd && scrollPtr->winFlags & ALREADY_DEAD) {
        DestroyWindow(scrollPtr->hwnd);
        DestroyWindow(scrollPtr->hwnd);
    }
    }
    Tcl_Release((ClientData)scrollPtr);
    Tcl_Release((ClientData)scrollPtr);
}
}


/*
/*
 *--------------------------------------------------------------
 *--------------------------------------------------------------
 *
 *
 * TkpScrollbarPosition --
 * TkpScrollbarPosition --
 *
 *
 *      Determine the scrollbar element corresponding to a
 *      Determine the scrollbar element corresponding to a
 *      given position.
 *      given position.
 *
 *
 * Results:
 * Results:
 *      One of TOP_ARROW, TOP_GAP, etc., indicating which element
 *      One of TOP_ARROW, TOP_GAP, etc., indicating which element
 *      of the scrollbar covers the position given by (x, y).  If
 *      of the scrollbar covers the position given by (x, y).  If
 *      (x,y) is outside the scrollbar entirely, then OUTSIDE is
 *      (x,y) is outside the scrollbar entirely, then OUTSIDE is
 *      returned.
 *      returned.
 *
 *
 * Side effects:
 * Side effects:
 *      None.
 *      None.
 *
 *
 *--------------------------------------------------------------
 *--------------------------------------------------------------
 */
 */
 
 
int
int
TkpScrollbarPosition(scrollPtr, x, y)
TkpScrollbarPosition(scrollPtr, x, y)
    register TkScrollbar *scrollPtr;    /* Scrollbar widget record. */
    register TkScrollbar *scrollPtr;    /* Scrollbar widget record. */
    int x, y;                           /* Coordinates within scrollPtr's
    int x, y;                           /* Coordinates within scrollPtr's
                                         * window. */
                                         * window. */
{
{
    int length, width, tmp;
    int length, width, tmp;
 
 
    if (scrollPtr->vertical) {
    if (scrollPtr->vertical) {
        length = Tk_Height(scrollPtr->tkwin);
        length = Tk_Height(scrollPtr->tkwin);
        width = Tk_Width(scrollPtr->tkwin);
        width = Tk_Width(scrollPtr->tkwin);
    } else {
    } else {
        tmp = x;
        tmp = x;
        x = y;
        x = y;
        y = tmp;
        y = tmp;
        length = Tk_Width(scrollPtr->tkwin);
        length = Tk_Width(scrollPtr->tkwin);
        width = Tk_Height(scrollPtr->tkwin);
        width = Tk_Height(scrollPtr->tkwin);
    }
    }
 
 
    if ((x < scrollPtr->inset) || (x >= (width - scrollPtr->inset))
    if ((x < scrollPtr->inset) || (x >= (width - scrollPtr->inset))
            || (y < scrollPtr->inset) || (y >= (length - scrollPtr->inset))) {
            || (y < scrollPtr->inset) || (y >= (length - scrollPtr->inset))) {
        return OUTSIDE;
        return OUTSIDE;
    }
    }
 
 
    /*
    /*
     * All of the calculations in this procedure mirror those in
     * All of the calculations in this procedure mirror those in
     * TkpDisplayScrollbar.  Be sure to keep the two consistent.
     * TkpDisplayScrollbar.  Be sure to keep the two consistent.
     */
     */
 
 
    if (y < (scrollPtr->inset + scrollPtr->arrowLength)) {
    if (y < (scrollPtr->inset + scrollPtr->arrowLength)) {
        return TOP_ARROW;
        return TOP_ARROW;
    }
    }
    if (y < scrollPtr->sliderFirst) {
    if (y < scrollPtr->sliderFirst) {
        return TOP_GAP;
        return TOP_GAP;
    }
    }
    if (y < scrollPtr->sliderLast) {
    if (y < scrollPtr->sliderLast) {
        return SLIDER;
        return SLIDER;
    }
    }
    if (y >= (length - (scrollPtr->arrowLength + scrollPtr->inset))) {
    if (y >= (length - (scrollPtr->arrowLength + scrollPtr->inset))) {
        return BOTTOM_ARROW;
        return BOTTOM_ARROW;
    }
    }
    return BOTTOM_GAP;
    return BOTTOM_GAP;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.