📄 tkplot.c
字号:
/* initialize colormap */ colormap_init(interp, plotPtr); Tk_SetClass(plotPtr->tkwin, Plot_class); Tk_CreateEventHandler(plotPtr->tkwin,/* ExposureMask|StructureNotifyMask|FocusChangeMask, */ ExposureMask | StructureNotifyMask, PlotEventProc, (ClientData) plotPtr); Tk_CreateEventHandler(plotPtr->tkwin, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask, PlotBindProc, (ClientData) plotPtr);/* Tk_CreateSelHandler(plotPtr->tkwin, XA_PRIMARY, XA_STRING, PlotFetchSelection, (ClientData) plotPtr, XA_STRING);*/ if (ConfigurePlot(interp, plotPtr, argc - 2, argv + 2, 0) != TCL_OK) { Tk_DestroyWindow(plotPtr->tkwin); return TCL_ERROR; } interp->result = Tk_PathName(plotPtr->tkwin); return TCL_OK;}/* *---------------------------------------------------------------------- * * ConfigurePlot -- * * This procedure is called to process an argv/argc list, plus * the Tk option database, in order to configure (or * reconfigure) a plot widget. * * Results: * The return value is a standard Tcl result. If TCL_ERROR is * returned, then interp->result contains an error message. * * Side effects: * Configuration information, such as colors, border width, * etc. get set for plotPtr; old resources get freed, * if there were any. * *---------------------------------------------------------------------- */static intConfigurePlot(interp, plotPtr, argc, argv, flags) Tcl_Interp *interp; /* Used for error reporting. */ TkPlot *plotPtr; /* Information about widget; may or may * not already have values for some fields. */ int argc; /* Number of valid entries in argv. */ char **argv; /* Arguments. */ int flags; /* Flags to pass to Tk_ConfigureWidget. */{ XGCValues gcValues; GC new; Tk_Window tkwin = plotPtr->tkwin; if (Tk_ConfigureWidget(interp, tkwin, configSpecs, argc, argv, (char *) plotPtr, flags) != TCL_OK) { return TCL_ERROR; } /* * A few options need special processing, such as setting the * background from a 3-D border and creating a GC for copying * bits to the screen. */ Tk_SetBackgroundFromBorder(tkwin, plotPtr->bgBorder); if (plotPtr->highlightWidth < 0) { plotPtr->highlightWidth = 0; } plotPtr->inset = plotPtr->borderWidth + plotPtr->highlightWidth; gcValues.function = GXcopy; gcValues.foreground = Tk_3DBorderColor(plotPtr->bgBorder)->pixel; gcValues.graphics_exposures = False; new = Tk_GetGC(tkwin, GCFunction | GCForeground | GCGraphicsExposures, &gcValues); if (plotPtr->pixmapGC != None) { Tk_FreeGC(plotPtr->display, plotPtr->pixmapGC); } plotPtr->pixmapGC = new; gcValues.foreground = colormap[0]->pixel; new = XCreateGC(Tk_Display(tkwin), RootWindow(Tk_Display(tkwin), 0), GCForeground, &gcValues); if (plotPtr->plotGC != None) { XFreeGC(Tk_Display(plotPtr->tkwin), plotPtr->plotGC); } plotPtr->plotGC = new; /* * Reset the desired dimensions for the window. */ Tk_GeometryRequest(plotPtr->tkwin, plotPtr->width + 2 * plotPtr->inset, plotPtr->height + 2 * plotPtr->inset); return TCL_OK;}/* *---------------------------------------------------------------------- * * PlotCmdDeletedProc -- * * This procedure is invoked when a widget command is deleted. If * the widget isn't already in the process of being destroyed, * this command destroys it. * * Results: * None. * * Side effects: * The widget is destroyed. * *---------------------------------------------------------------------- */static voidPlotCmdDeletedProc(clientData) ClientData clientData; /* Pointer to widget record for widget. */{ TkPlot *plotPtr = (TkPlot *) clientData; Tk_Window tkwin = plotPtr->tkwin; /* * This procedure could be invoked either because the window was * destroyed and the command was then deleted (in which case tkwin * is NULL) or because the command was deleted, and then this procedure * destroys the widget. */ /* NOT SURE IF THIS IS RIGHT - worfolk */ if (tkwin) { plotPtr->tkwin = NULL; Tk_DestroyWindow(tkwin); }}/* *-------------------------------------------------------------- * * PlotWidgetCmd -- * * This procedure is invoked to process the Tcl command * that corresponds to a widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */static intPlotWidgetCmd(clientData, interp, argc, argv) ClientData clientData; /* Information about plot * widget. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ TkPlot *plotPtr = (TkPlot *) clientData;/* size_t length; */ int result = TCL_OK;/* Tk_Item *itemPtr = NULL; *//* Initialization needed only to * prevent compiler warning. */ static char def_plot_color[] = "red"; /* Default or arg plot settings */ static char *plot_color = def_plot_color; static int plot_symbol = POINT; static unsigned int plot_size = MEDIUM; int plot_x; int plot_y; int plot_width; int plot_height; int c; if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " option ?arg arg ...?\"", (char *) NULL); return TCL_ERROR; } Tk_Preserve((ClientData) plotPtr); /* * Process the configure command */ if (strcmp(argv[1], "configure") == 0) { if (argc == 2) { result = Tk_ConfigureInfo(interp, plotPtr->tkwin, configSpecs, (char *) plotPtr, (char *) NULL, 0); } else if (argc == 3) { result = Tk_ConfigureInfo(interp, plotPtr->tkwin, configSpecs, (char *) plotPtr, argv[2], 0); } else { result = ConfigurePlot(interp, plotPtr, argc - 2, argv + 2, TK_CONFIG_ARGV_ONLY); } } /* * Process the plot command */ else if (strcmp(argv[1], "plot") == 0) { if (argc < 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], "plot x y -color [color] -symbol [symbol]\"", (char *) NULL); return TCL_ERROR; } /* * fprintf(stderr,"plot args: "); * for (i=0; i<argc; i++) * fprintf(stderr,"%s ", argv[i]); * fprintf(stderr,"\n"); */ plot_x = atoi(argv[2]); plot_y = atoi(argv[3]); c = 4; while ((c < argc) && (c + 1 < argc)) { if (strcmp(argv[c], "-color") == 0) { plot_color = argv[c + 1]; c++; } else if (strcmp(argv[c], "-symbol") == 0) { if (strcmp(argv[c + 1], "point") == 0) plot_symbol = POINT; else if (strcmp(argv[c + 1], "cross") == 0) plot_symbol = CROSS; else if (strcmp(argv[c + 1], "box") == 0) plot_symbol = BOX; else if (strcmp(argv[c + 1], "triangle") == 0) plot_symbol = TRIANGLE; else if (strcmp(argv[c + 1], "crosshair") == 0) plot_symbol = CROSSHAIR; else if (strcmp(argv[c + 1], "circle") == 0) plot_symbol = CIRCLE; else if (strcmp(argv[c + 1], "disk") == 0) plot_symbol = DISK; else if (strcmp(argv[c + 1], "test") == 0) plot_symbol = TEST_SYMBOL; c++; } else if (strcmp(argv[c], "-size") == 0) { if (strcmp(argv[c + 1], "small") == 0) plot_size = SMALL; else if (strcmp(argv[c + 1], "medium") == 0) plot_size = MEDIUM; else if (strcmp(argv[c + 1], "large") == 0) plot_size = LARGE; else plot_size = atoi(argv[c + 1]); c++; } else { c++; } } Tk_PlotSymbol(plotPtr, plot_x, plot_y, Tk_PlotColorLookup(plot_color), plot_symbol, plot_size); } /* * Process the rubber band box command */ else if (strcmp(argv[1], "rbox") == 0) { plot_x = atoi(argv[2]); plot_y = atoi(argv[3]); plot_width = atoi(argv[4]); plot_height = atoi(argv[5]); Tk_PlotRubberBox(plotPtr, plot_x, plot_y, plot_width, plot_height); } /* * Process the clear command */ else if (strcmp(argv[1], "clear") == 0) { Tk_PlotClear(plotPtr); } /* * Invalid option message */ else { Tcl_AppendResult(interp, "invalid option \"", argv[1], "\": must be clear, configure, or plot", (char *) NULL); goto msg_error; } Tk_Release((ClientData) plotPtr); return result;msg_error: Tk_Release((ClientData) plotPtr); return TCL_ERROR;}/* *-------------------------------------------------------------- * * PlotEventProc -- * * This procedure is invoked by the Tk dispatcher for various * events on plotes. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get * cleaned up. When it gets exposed, it is redisplayed. * *-------------------------------------------------------------- */static voidPlotEventProc(clientData, eventPtr) ClientData clientData; /* Information about window. */ XEvent *eventPtr; /* Information about event. */{ TkPlot *plotPtr = (TkPlot *) clientData; if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) { goto redraw; } else if (eventPtr->type == DestroyNotify) { Tcl_DeleteCommand(plotPtr->interp, Tk_PathName(plotPtr->tkwin)); plotPtr->tkwin = NULL; if (plotPtr->flags & REDRAW_PENDING) { Tk_CancelIdleCall(PlotDisplay, (ClientData) plotPtr); plotPtr->flags &= ~REDRAW_PENDING; } /* Tk_EventuallyFree((ClientData) plotPtr, PlotDestroy); */ /* hack to remove compiler warnings; should be upgraded */#if ( (TK_MAJOR_VERSION > 4) || ( (TK_MAJOR_VERSION == 4) && (TK_MINOR_VERSION > 0)) ) Tcl_EventuallyFree((ClientData) plotPtr, (Tcl_FreeProc *) PlotDestroy);#else Tk_EventuallyFree((ClientData) plotPtr, PlotDestroy);#endif } return;redraw: if (plotPtr->tkwin && !(plotPtr->flags & REDRAW_PENDING)) { Tk_DoWhenIdle(PlotDisplay, (ClientData) plotPtr); plotPtr->flags |= REDRAW_PENDING; }}/* *-------------------------------------------------------------- * * PlotBindProc -- * * This procedure is invoked by the Tk dispatcher to handle * events associated with bindings on items. * * Results: * None. * * Side effects: * Depends on the command invoked as part of the binding * (if there was any). * *-------------------------------------------------------------- */static voidPlotBindProc(clientData, eventPtr) ClientData clientData; /* Pointer to plot structure. */ XEvent *eventPtr; /* Pointer to X event that just * happened. */{/* XPoint bbox[2]; switch( eventPtr->type ) { case ButtonPress: bbox[0].x = eventPtr->xbutton.x; bbox[0].y = eventPtr->xbutton.y; fprintf( stderr, "\nPlotBindProc: ButtonPress [%d,%d]", bbox[0].x, bbox[0].y ); break; case ButtonRelease: bbox[0].x = eventPtr->xbutton.x; bbox[0].y = eventPtr->xbutton.y; fprintf( stderr, "\nPlotBindProc: ButtonRelease [%d,%d]", bbox[0].x, bbox[0].y ); break; case MotionNotify: bbox[0].x = eventPtr->xbutton.x;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -