📄 tkmacscrlbr.c
字号:
*-------------------------------------------------------------- * * ScrollbarBindProc -- * * This procedure is invoked when the default <ButtonPress> * binding on the Scrollbar bind tag fires. * * Results: * None. * * Side effects: * The event enters a modal loop. * *-------------------------------------------------------------- */static intScrollbarBindProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interp with binding. */ XEvent *eventPtr, /* X event that triggered binding. */ Tk_Window tkwin, /* Target window for event. */ KeySym keySym) /* The KeySym if a key event. */{ TkWindow *winPtr = (TkWindow*)tkwin; TkScrollbar *scrollPtr = (TkScrollbar *) winPtr->instanceData; MacScrollbar *macScrollPtr = (MacScrollbar *) winPtr->instanceData; Tcl_Preserve((ClientData)scrollPtr); macScrollPtr->macFlags |= IN_MODAL_LOOP; if (eventPtr->type == ButtonPress) { Point where; Rect bounds; int part, x, y, dummy; unsigned int state; CGrafPtr saveWorld; GDHandle saveDevice; GWorldPtr destPort; Window window; /* * To call Macintosh control routines we must have the port * set to the window containing the control. We will then test * which part of the control was hit and act accordingly. */ destPort = TkMacGetDrawablePort(Tk_WindowId(scrollPtr->tkwin)); GetGWorld(&saveWorld, &saveDevice); SetGWorld(destPort, NULL); TkMacSetUpClippingRgn(Tk_WindowId(scrollPtr->tkwin)); TkMacWinBounds((TkWindow *) scrollPtr->tkwin, &bounds); where.h = eventPtr->xbutton.x + bounds.left; where.v = eventPtr->xbutton.y + bounds.top; part = TestControl(macScrollPtr->sbHandle, where); if (part == inThumb && scrollPtr->jump == false) { /* * Case 1: In thumb, no jump scrolling. Call track control * with the thumb action proc which will do most of the work. * Set the global activeScrollPtr to the current control * so the callback may have access to it. */ activeScrollPtr = scrollPtr; part = TrackControl(macScrollPtr->sbHandle, where, (ControlActionUPP) thumbActionProc); activeScrollPtr = NULL; } else if (part == inThumb) { /* * Case 2: in thumb with jump scrolling. Call TrackControl * with a NULL action proc. Use the new value of the control * to set update the control. */ part = TrackControl(macScrollPtr->sbHandle, where, NULL); if (part == inThumb) { double newFirstFraction, thumbWidth; Tcl_DString cmdString; char vauleString[TCL_DOUBLE_SPACE]; /* * The following calculation takes the new control * value and maps it to what Tk needs for its variable * thumb size representation. */ thumbWidth = scrollPtr->lastFraction - scrollPtr->firstFraction; newFirstFraction = (1.0 - thumbWidth) * ((double) GetControlValue(macScrollPtr->sbHandle) / 1000.0); sprintf(vauleString, "%g", newFirstFraction); Tcl_DStringInit(&cmdString); Tcl_DStringAppend(&cmdString, scrollPtr->command, strlen(scrollPtr->command)); Tcl_DStringAppendElement(&cmdString, "moveto"); Tcl_DStringAppendElement(&cmdString, vauleString); Tcl_DStringAppend(&cmdString, "; update idletasks", strlen("; update idletasks")); interp = scrollPtr->interp; Tcl_Preserve((ClientData) interp); Tcl_GlobalEval(interp, cmdString.string); Tcl_Release((ClientData) interp); Tcl_DStringFree(&cmdString); } } else if (part != 0) { /* * Case 3: in any other part of the scrollbar. We call * TrackControl with the scrollActionProc which will do * most all the work. */ TrackControl(macScrollPtr->sbHandle, where, scrollActionProc); HiliteControl(macScrollPtr->sbHandle, 0); } /* * The TrackControl call will "eat" the ButtonUp event. We now * generate a ButtonUp event so Tk will unset implicit grabs etc. */ GetMouse(&where); XQueryPointer(NULL, None, &window, &window, &x, &y, &dummy, &dummy, &state); window = Tk_WindowId(scrollPtr->tkwin); TkGenerateButtonEvent(x, y, window, state); SetGWorld(saveWorld, saveDevice); } if (macScrollPtr->sbHandle && (macScrollPtr->macFlags & ALREADY_DEAD)) { DisposeControl(macScrollPtr->sbHandle); macScrollPtr->sbHandle = NULL; } macScrollPtr->macFlags &= ~IN_MODAL_LOOP; Tcl_Release((ClientData)scrollPtr); return TCL_OK;}/* *-------------------------------------------------------------- * * ScrollbarEventProc -- * * This procedure is invoked by the Tk dispatcher for various * events on scrollbars. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get * cleaned up. When it gets exposed, it is redisplayed. * *-------------------------------------------------------------- */static voidScrollbarEventProc( ClientData clientData, /* Information about window. */ XEvent *eventPtr) /* Information about event. */{ TkScrollbar *scrollPtr = (TkScrollbar *) clientData; MacScrollbar *macScrollPtr = (MacScrollbar *) clientData; if (eventPtr->type == UnmapNotify) { TkMacSetScrollbarGrow((TkWindow *) scrollPtr->tkwin, false); } else if (eventPtr->type == ActivateNotify) { macScrollPtr->macFlags |= ACTIVE; TkScrollbarEventuallyRedraw((ClientData) scrollPtr); } else if (eventPtr->type == DeactivateNotify) { macScrollPtr->macFlags &= ~ACTIVE; TkScrollbarEventuallyRedraw((ClientData) scrollPtr); } else { TkScrollbarEventProc(clientData, eventPtr); }}/* *-------------------------------------------------------------- * * UpdateControlValues -- * * This procedure updates the Macintosh scrollbar control * to display the values defined by the Tk scrollbar. * * Results: * None. * * Side effects: * The Macintosh control is updated. * *-------------------------------------------------------------- */static voidUpdateControlValues( MacScrollbar *macScrollPtr) /* Scrollbar data struct. */{ TkScrollbar *scrollPtr = (TkScrollbar *) macScrollPtr; Tk_Window tkwin = scrollPtr->tkwin; MacDrawable * macDraw = (MacDrawable *) Tk_WindowId(scrollPtr->tkwin); WindowRef windowRef = (**macScrollPtr->sbHandle).contrlOwner; double middle; int drawGrowRgn = false; int flushRight = false; int flushBottom = false; /* * We can't use the Macintosh commands SizeControl and MoveControl as these * calls will also cause a redraw which in our case will also cause * flicker. To avoid this we adjust the control record directly. The * Draw1Control command appears to just draw where ever the control says to * draw so this seems right. * * NOTE: changing the control record directly may not work when * Apple releases the Copland version of the MacOS (or when hell is cold). */ (**macScrollPtr->sbHandle).contrlRect.left = macDraw->xOff + scrollPtr->inset; (**macScrollPtr->sbHandle).contrlRect.top = macDraw->yOff + scrollPtr->inset; (**macScrollPtr->sbHandle).contrlRect.right = macDraw->xOff + Tk_Width(tkwin) - scrollPtr->inset; (**macScrollPtr->sbHandle).contrlRect.bottom = macDraw->yOff + Tk_Height(tkwin) - scrollPtr->inset; /* * To make Tk applications look more like Macintosh applications without * requiring additional work by the Tk developer we do some cute tricks. * The first trick plays with the size of the widget to get it to overlap * with the side of the window by one pixel (we don't do this if the placer * is the geometry manager). The second trick shrinks the scrollbar if it * it covers the area of the grow region ao the scrollbar can also draw * the grow region if need be. */ if (!strcmp(macDraw->winPtr->geomMgrPtr->name, "place")) { macScrollPtr->macFlags &= AUTO_ADJUST; } else { macScrollPtr->macFlags |= AUTO_ADJUST; } /* TODO: use accessor function!!! */ if (windowRef->portRect.left == (**macScrollPtr->sbHandle).contrlRect.left) { if (macScrollPtr->macFlags & AUTO_ADJUST) { (**macScrollPtr->sbHandle).contrlRect.left--; } if (!(macScrollPtr->macFlags & FLUSH_LEFT)) { macScrollPtr->macFlags |= FLUSH_LEFT; if (scrollPtr->vertical) { TkpComputeScrollbarGeometry(scrollPtr); } } } else if (macScrollPtr->macFlags & FLUSH_LEFT) { macScrollPtr->macFlags &= ~FLUSH_LEFT; if (scrollPtr->vertical) { TkpComputeScrollbarGeometry(scrollPtr); } } if (windowRef->portRect.top == (**macScrollPtr->sbHandle).contrlRect.top) { if (macScrollPtr->macFlags & AUTO_ADJUST) { (**macScrollPtr->sbHandle).contrlRect.top--; } if (!(macScrollPtr->macFlags & FLUSH_TOP)) { macScrollPtr->macFlags |= FLUSH_TOP; if (! scrollPtr->vertical) { TkpComputeScrollbarGeometry(scrollPtr); } } } else if (macScrollPtr->macFlags & FLUSH_TOP) { macScrollPtr->macFlags &= ~FLUSH_TOP; if (! scrollPtr->vertical) { TkpComputeScrollbarGeometry(scrollPtr); } } if (windowRef->portRect.right == (**macScrollPtr->sbHandle).contrlRect.right) { flushRight = true; if (macScrollPtr->macFlags & AUTO_ADJUST) { (**macScrollPtr->sbHandle).contrlRect.right++; } if (!(macScrollPtr->macFlags & FLUSH_RIGHT)) { macScrollPtr->macFlags |= FLUSH_RIGHT; if (scrollPtr->vertical) { TkpComputeScrollbarGeometry(scrollPtr); } } } else if (macScrollPtr->macFlags & FLUSH_RIGHT) { macScrollPtr->macFlags &= ~FLUSH_RIGHT; if (scrollPtr->vertical) { TkpComputeScrollbarGeometry(scrollPtr); } } if (windowRef->portRect.bottom == (**macScrollPtr->sbHandle).contrlRect.bottom) { flushBottom = true; if (macScrollPtr->macFlags & AUTO_ADJUST) { (**macScrollPtr->sbHandle).contrlRect.bottom++; } if (!(macScrollPtr->macFlags & FLUSH_BOTTOM)) { macScrollPtr->macFlags |= FLUSH_BOTTOM; if (! scrollPtr->vertical) { TkpComputeScrollbarGeometry(scrollPtr); } } } else if (macScrollPtr->macFlags & FLUSH_BOTTOM) { macScrollPtr->macFlags &= ~FLUSH_BOTTOM; if (! scrollPtr->vertical) { TkpComputeScrollbarGeometry(scrollPtr); } } /* * If the scrollbar is flush against the bottom right hand coner then * it may need to draw the grow region for the window so we let the * wm code know about this scrollbar. We don't actually draw the grow * region, however, unless we are currently resizable. */ macScrollPtr->macFlags &= ~DRAW_GROW; if (flushBottom && flushRight) { TkMacSetScrollbarGrow((TkWindow *) tkwin, true); if (TkMacResizable(macDraw->toplevel->winPtr)) { if (scrollPtr->vertical) { (**macScrollPtr->sbHandle).contrlRect.bottom -= 14; } else { (**macScrollPtr->sbHandle).contrlRect.right -= 14; } macScrollPtr->macFlags |= DRAW_GROW; } } else { TkMacSetScrollbarGrow((TkWindow *) tkwin, false); } /* * Given the Tk parameters for the fractions of the start and * end of the thumb, the following calculation determines the * location for the fixed sized Macintosh thumb. */ middle = scrollPtr->firstFraction / (scrollPtr->firstFraction + (1.0 - scrollPtr->lastFraction)); (**macScrollPtr->sbHandle).contrlValue = (short) (middle * 1000); if ((**macScrollPtr->sbHandle).contrlHilite == 0 || (**macScrollPtr->sbHandle).contrlHilite == 255) { if (scrollPtr->firstFraction == 0.0 && scrollPtr->lastFraction == 1.0) { (**macScrollPtr->sbHandle).contrlHilite = 255; } else { (**macScrollPtr->sbHandle).contrlHilite = 0; } } if ((**macScrollPtr->sbHandle).contrlVis != 255) { (**macScrollPtr->sbHandle).contrlVis = 255; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -