📄 tkmacscrlbr.c
字号:
/* * Adjust the slider so that some piece of it is always * displayed in the scrollbar and so that it has at least * a minimal width (so it can be grabbed with the mouse). */ if (scrollPtr->sliderFirst > (fieldLength - 2*scrollPtr->borderWidth)) { scrollPtr->sliderFirst = fieldLength - 2*scrollPtr->borderWidth; } if (scrollPtr->sliderFirst < 0) { scrollPtr->sliderFirst = 0; } if (scrollPtr->sliderLast < (scrollPtr->sliderFirst + MIN_SLIDER_LENGTH)) { scrollPtr->sliderLast = scrollPtr->sliderFirst + MIN_SLIDER_LENGTH; } if (scrollPtr->sliderLast > fieldLength) { scrollPtr->sliderLast = fieldLength; } scrollPtr->sliderFirst += scrollPtr->arrowLength + scrollPtr->inset; scrollPtr->sliderLast += scrollPtr->arrowLength + scrollPtr->inset; /* * Register the desired geometry for the window (leave enough space * for the two arrows plus a minimum-size slider, plus border around * the whole window, if any). Then arrange for the window to be * redisplayed. */ if (scrollPtr->vertical) { if ((macScrollPtr->macFlags & AUTO_ADJUST) && (macScrollPtr->macFlags & (FLUSH_RIGHT|FLUSH_LEFT))) { adjust--; } Tk_GeometryRequest(scrollPtr->tkwin, scrollPtr->width + 2*scrollPtr->inset + adjust, 2*(scrollPtr->arrowLength + scrollPtr->borderWidth + scrollPtr->inset)); } else { if ((macScrollPtr->macFlags & AUTO_ADJUST) && (macScrollPtr->macFlags & (FLUSH_TOP|FLUSH_BOTTOM))) { adjust--; } Tk_GeometryRequest(scrollPtr->tkwin, 2*(scrollPtr->arrowLength + scrollPtr->borderWidth + scrollPtr->inset), scrollPtr->width + 2*scrollPtr->inset + adjust); } Tk_SetInternalBorder(scrollPtr->tkwin, scrollPtr->inset);}/* *---------------------------------------------------------------------- * * TkpDestroyScrollbar -- * * Free data structures associated with the scrollbar control. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */voidTkpDestroyScrollbar( TkScrollbar *scrollPtr) /* Scrollbar to destroy. */{ MacScrollbar *macScrollPtr = (MacScrollbar *)scrollPtr; if (macScrollPtr->sbHandle != NULL) { if (!(macScrollPtr->macFlags & IN_MODAL_LOOP)) { DisposeControl(macScrollPtr->sbHandle); macScrollPtr->sbHandle = NULL; } } macScrollPtr->macFlags |= ALREADY_DEAD;}/* *-------------------------------------------------------------- * * TkpScrollbarPosition -- * * Determine the scrollbar element corresponding to a * given position. * * Results: * One of TOP_ARROW, TOP_GAP, etc., indicating which element * of the scrollbar covers the position given by (x, y). If * (x,y) is outside the scrollbar entirely, then OUTSIDE is * returned. * * Side effects: * None. * *-------------------------------------------------------------- */intTkpScrollbarPosition( TkScrollbar *scrollPtr, /* Scrollbar widget record. */ int x, int y) /* Coordinates within scrollPtr's * window. */{ MacScrollbar *macScrollPtr = (MacScrollbar *) scrollPtr; GWorldPtr destPort; int length, width, tmp, inactive = false; ControlPartCode part; Point where; Rect bounds; if (scrollPtr->vertical) { length = Tk_Height(scrollPtr->tkwin); width = Tk_Width(scrollPtr->tkwin); } else { tmp = x; x = y; y = tmp; length = Tk_Width(scrollPtr->tkwin); width = Tk_Height(scrollPtr->tkwin); } if ((x < scrollPtr->inset) || (x >= (width - scrollPtr->inset)) || (y < scrollPtr->inset) || (y >= (length - scrollPtr->inset))) { return OUTSIDE; } /* * All of the calculations in this procedure mirror those in * DisplayScrollbar. Be sure to keep the two consistent. On the * Macintosh we use the OS call TestControl to do this mapping. * For TestControl to work, the scrollbar must be active and must * be in the current port. */ destPort = TkMacGetDrawablePort(Tk_WindowId(scrollPtr->tkwin)); SetGWorld(destPort, NULL); UpdateControlValues(macScrollPtr); if ((**macScrollPtr->sbHandle).contrlHilite == 255) { inactive = true; (**macScrollPtr->sbHandle).contrlHilite = 0; } TkMacWinBounds((TkWindow *) scrollPtr->tkwin, &bounds); where.h = x + bounds.left; where.v = y + bounds.top; part = TestControl(((MacScrollbar *) scrollPtr)->sbHandle, where); if (inactive) { (**macScrollPtr->sbHandle).contrlHilite = 255; } switch (part) { case inUpButton: return TOP_ARROW; case inPageUp: return TOP_GAP; case inThumb: return SLIDER; case inPageDown: return BOTTOM_GAP; case inDownButton: return BOTTOM_ARROW; default: return OUTSIDE; }}/* *-------------------------------------------------------------- * * ThumbActionProc -- * * Callback procedure used by the Macintosh toolbox call * TrackControl. This call is used to track the thumb of * the scrollbar. Unlike the ScrollbarActionProc function * this function is called once and basically takes over * tracking the scrollbar from the control. This is done * to avoid conflicts with what the control plans to draw. * * Results: * None. * * Side effects: * May change the display. * *-------------------------------------------------------------- */static pascal voidThumbActionProc(){ register TkScrollbar *scrollPtr = activeScrollPtr; register MacScrollbar *macScrollPtr = (MacScrollbar *) activeScrollPtr; Tcl_DString cmdString; Rect nullRect = {0,0,0,0}; int origValue, trackBarPin; double thumbWidth, newFirstFraction, trackBarSize; char vauleString[40]; Point currentPoint = { 0, 0 }; Point lastPoint = { 0, 0 }; Rect trackRect; Tcl_Interp *interp; if (scrollPtr == NULL) { return; } Tcl_DStringInit(&cmdString); /* * First compute values that will remain constant during the tracking * of the thumb. The variable trackBarSize is the length of the scrollbar * minus the 2 arrows and half the width of the thumb on both sides * (3 * arrowLength). The variable trackBarPin is the lower starting point * of the drag region. * * Note: the arrowLength is equal to the thumb width of a Mac scrollbar. */ origValue = GetControlValue(macScrollPtr->sbHandle); trackRect = (**macScrollPtr->sbHandle).contrlRect; if (scrollPtr->vertical == true) { trackBarSize = (double) (trackRect.bottom - trackRect.top - (scrollPtr->arrowLength * 3)); trackBarPin = trackRect.top + scrollPtr->arrowLength + (scrollPtr->arrowLength / 2); InsetRect(&trackRect, -25, -113); } else { trackBarSize = (double) (trackRect.right - trackRect.left - (scrollPtr->arrowLength * 3)); trackBarPin = trackRect.left + scrollPtr->arrowLength + (scrollPtr->arrowLength / 2); InsetRect(&trackRect, -113, -25); } /* * Track the mouse while the button is held down. If the mouse is moved, * we calculate the value that should be passed to the "command" part of * the scrollbar. */ while (StillDown()) { GetMouse(¤tPoint); if (EqualPt(currentPoint, lastPoint)) { continue; } lastPoint = currentPoint; /* * Calculating this value is a little tricky. We need to calculate a * value for where the thumb would be in a Motif widget (variable * thumb). This value is what the "command" expects and is what will * be resent to the scrollbar to update its value. */ thumbWidth = scrollPtr->lastFraction - scrollPtr->firstFraction; if (PtInRect(currentPoint, &trackRect)) { if (scrollPtr->vertical == true) { newFirstFraction = (1.0 - thumbWidth) * ((double) (currentPoint.v - trackBarPin) / trackBarSize); } else { newFirstFraction = (1.0 - thumbWidth) * ((double) (currentPoint.h - trackBarPin) / trackBarSize); } } else { newFirstFraction = ((double) origValue / 1000.0) * (1.0 - thumbWidth); } sprintf(vauleString, "%g", newFirstFraction); Tcl_DStringSetLength(&cmdString, 0); Tcl_DStringAppend(&cmdString, scrollPtr->command, scrollPtr->commandSize); Tcl_DStringAppendElement(&cmdString, "moveto"); Tcl_DStringAppendElement(&cmdString, vauleString); interp = scrollPtr->interp; Tcl_Preserve((ClientData) interp); Tcl_GlobalEval(interp, cmdString.string); Tcl_Release((ClientData) interp); Tcl_DStringSetLength(&cmdString, 0); Tcl_DStringAppend(&cmdString, "update idletasks", strlen("update idletasks")); Tcl_Preserve((ClientData) interp); Tcl_GlobalEval(interp, cmdString.string); Tcl_Release((ClientData) interp); } /* * This next bit of code is a bit of a hack - but needed. The problem is * that the control wants to draw the drag outline if the control value * changes during the drag (which it does). What we do here is change the * clip region to hide this drawing from the user. */ ClipRect(&nullRect); Tcl_DStringFree(&cmdString); return;}/* *-------------------------------------------------------------- * * ScrollbarActionProc -- * * Callback procedure used by the Macintosh toolbox call * TrackControl. This call will update the display while * the scrollbar is being manipulated by the user. * * Results: * None. * * Side effects: * May change the display. * *-------------------------------------------------------------- */static pascal voidScrollbarActionProc( ControlRef theControl, /* Handle to scrollbat control */ ControlPartCode partCode) /* Part of scrollbar that was "hit" */{ register TkScrollbar *scrollPtr = (TkScrollbar *) GetCRefCon(theControl); Tcl_DString cmdString; Tcl_DStringInit(&cmdString); Tcl_DStringAppend(&cmdString, scrollPtr->command, scrollPtr->commandSize); if (partCode == inUpButton || partCode == inDownButton) { Tcl_DStringAppendElement(&cmdString, "scroll"); Tcl_DStringAppendElement(&cmdString, (partCode == inUpButton ) ? "-1" : "1"); Tcl_DStringAppendElement(&cmdString, "unit"); } else if (partCode == inPageUp || partCode == inPageDown) { Tcl_DStringAppendElement(&cmdString, "scroll"); Tcl_DStringAppendElement(&cmdString, (partCode == inPageUp ) ? "-1" : "1"); Tcl_DStringAppendElement(&cmdString, "page"); } Tcl_Preserve((ClientData) scrollPtr->interp); Tcl_DStringAppend(&cmdString, "; update idletasks", strlen("; update idletasks")); Tcl_GlobalEval(scrollPtr->interp, cmdString.string); Tcl_Release((ClientData) scrollPtr->interp); Tcl_DStringFree(&cmdString);}/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -