/* * Grace - GRaphing, Advanced Computation and Exploration of data * * Home page: http://plasma-gate.weizmann.ac.il/Grace/ * * Copyright (c) 1991-1995 Paul J Turner, Portland, OR * Copyright (c) 1996-2003 Grace Development Team * * Maintained by Evgeny Stambulchik * * * All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * * Main Motif interface * */ #include #include #include #include #include #include #include #include #include #include #if defined(HAVE_XPM_H) # include #else # if defined (HAVE_X11_XPM_H) # include # endif #endif #include "globals.h" #include "bitmaps.h" #include "utils.h" #include "files.h" #include "device.h" #include "x11drv.h" #include "graphs.h" #include "graphutils.h" #include "plotone.h" #include "events.h" #include "protos.h" #include "motifinc.h" /* used globally */ XtAppContext app_con; Widget app_shell; static Widget canvas; static Widget drawing_window; /* container for drawing area */ Widget loclab; /* locator label */ Widget statlab; /* status line at the bottom */ Widget stack_depth_item; /* stack depth item on the main panel */ Widget curw_item; /* current world stack item on the main panel */ Display *disp = NULL; Window xwin; extern Window root; extern GC gc; extern int screennumber; extern int depth; extern Colormap cmap; extern unsigned long xvlibcolors[]; /* used locally */ static Widget main_frame; static Widget menu_bar; static Widget frleft, frtop, frbot; /* dialogs along canvas edge */ static Widget form; /* form for mainwindow */ static void MenuCB(void *data); static Widget CreateMainMenuBar(Widget parent); static int toolbar_visible = 1; static int statusbar_visible = 1; static int locbar_visible = 1; static Widget windowbarw[3]; static void graph_scroll_proc(void *data); static void graph_zoom_proc(void *data); static void world_stack_proc(void *data); static void load_example(void *data); #define WSTACK_PUSH 0 #define WSTACK_POP 1 #define WSTACK_CYCLE 2 #define WSTACK_PUSH_ZOOM 3 /* * action routines, to be used with translations */ /* This is for buggy Motif-2.1 that crashes with Ctrl+ */ static void do_nothing_action(Widget w, XEvent *e, String *par, Cardinal *npar) { } static XtActionsRec dummy_actions[] = { {"do_nothing", do_nothing_action} }; static XtActionsRec canvas_actions[] = { { "autoscale", (XtActionProc) autoscale_action }, { "autoscale_on_near", (XtActionProc) autoscale_on_near_action }, { "draw_line", (XtActionProc) draw_line_action }, { "draw_box", (XtActionProc) draw_box_action }, { "draw_ellipse", (XtActionProc) draw_ellipse_action }, { "write_string", (XtActionProc) write_string_action }, { "delete_object", (XtActionProc) delete_object_action }, { "place_legend", (XtActionProc) place_legend_action }, { "place_timestamp", (XtActionProc) place_timestamp_action }, { "move_object", (XtActionProc) move_object_action }, { "refresh_hotlink", (XtActionProc) refresh_hotlink_action }, { "set_viewport", (XtActionProc) set_viewport_action }, { "enable_zoom", (XtActionProc) enable_zoom_action } }; static XtActionsRec list_select_actions[] = { {"list_selectall_action", list_selectall_action}, {"list_unselectall_action", list_unselectall_action}, {"list_invertselection_action", list_invertselection_action} }; static XtActionsRec cstext_actions[] = { {"cstext_edit_action", cstext_edit_action} }; static char canvas_table[] = "#override\n\ Ctrl Alt l: draw_line()\n\ Ctrl Alt b: draw_box()\n\ Ctrl Alt e: draw_ellipse()\n\ Ctrl Alt t: write_string()\n\ Ctrl a: autoscale()\n\ Ctrl d: delete_object()\n\ Ctrl l: place_legend()\n\ Ctrl m: move_object()\n\ Ctrl t: place_timestamp()\n\ Ctrl u: refresh_hotlink()\n\ Ctrl v: set_viewport()\n\ Ctrl z: enable_zoom()"; /* * establish resource stuff */ typedef struct { Boolean invert; Boolean allow_dc; Boolean auto_redraw; Boolean toolbar; Boolean statusbar; Boolean locatorbar; } ApplicationData, *ApplicationDataPtr; static XtResource resources[] = { {"invertDraw", "InvertDraw", XtRBoolean, sizeof(Boolean), XtOffset(ApplicationDataPtr, invert), XtRImmediate, (XtPointer) TRUE}, {"allowDoubleClick", "AllowDoubleClick", XtRBoolean, sizeof(Boolean), XtOffset(ApplicationDataPtr, allow_dc), XtRImmediate, (XtPointer) TRUE}, {"allowRedraw", "AllowRedraw", XtRBoolean, sizeof(Boolean), XtOffset(ApplicationDataPtr, auto_redraw), XtRImmediate, (XtPointer) TRUE}, {"toolBar", "ToolBar", XtRBoolean, sizeof(Boolean), XtOffset(ApplicationDataPtr, toolbar), XtRImmediate, (XtPointer) TRUE}, {"statusBar", "StatusBar", XtRBoolean, sizeof(Boolean), XtOffset(ApplicationDataPtr, statusbar), XtRImmediate, (XtPointer) TRUE}, {"locatorBar", "LocatorBar", XtRBoolean, sizeof(Boolean), XtOffset(ApplicationDataPtr, locatorbar), XtRImmediate, (XtPointer) TRUE} }; String fallbackResourcesCommon[] = { "XMgrace.consoleDialog*text.columns: 72", "XMgrace.consoleDialog*text.rows: 5", "XMgrace*background: #e5e5e5", "XMgrace*foreground: #000000", "XMgrace*XbaeMatrix.oddRowBackground: #cccccc", "XMgrace*XbaeMatrix.evenRowBackground: #cfe7e7", "XMgrace*XbaeMatrix.textBackground: #cfe7e7", "XMgrace*XbaeMatrix.allowColumnResize: False", "XMgrace*XbaeMatrix.allowRowResize: False", "XMgrace*XbaeMatrix.showArrows: True", "XMgrace*fontTable.evenRowBackground: #e5e5e5", "XMgrace*XmPushButton.background: #b0c4de", "XMgrace*XmMenuShell*XmPushButton.background: #e5e5e5", "XMgrace*XmText*background: #cfe7e7", "XMgrace*XmToggleButton.selectColor: #ff0000", "XMgrace*XmToggleButton.fillOnSelect: true", "XMgrace*XmSeparator.margin: 0", #ifdef WITH_XMHTML "XMgrace*XmHTML.background: #ffffff", "XMgrace*XmHTML.foreground: #000000", "XMgrace*XmHTML.width: 600", "XMgrace*XmHTML.height: 500", #endif "XMgrace*mainWin.shadowThickness: 0", "XMgrace*mainWin.menuBar.shadowThickness: 1", "XMgrace*menuBar*tearOffModel: XmTEAR_OFF_ENABLED", "XMgrace*dragInitiatorProtocolStyle: XmDRAG_NONE", "XMgrace*dragReceiverProtocolStyle: XmDRAG_NONE", "XMgrace*fileMenu.newButton.acceleratorText: Ctrl+N", "XMgrace*fileMenu.newButton.accelerator: Ctrln", "XMgrace*fileMenu.openButton.acceleratorText: Ctrl+O", "XMgrace*fileMenu.openButton.accelerator: Ctrlo", "XMgrace*fileMenu.saveButton.acceleratorText: Ctrl+S", "XMgrace*fileMenu.saveButton.accelerator: Ctrls", "XMgrace*fileMenu.exitButton.acceleratorText: Ctrl+Q", "XMgrace*fileMenu.exitButton.accelerator: Ctrlq", "XMgrace*fileMenu.printButton.acceleratorText: Ctrl+P", "XMgrace*fileMenu.printButton.accelerator: Ctrlp", "XMgrace*helpMenu.onContextButton.acceleratorText: Shift+F1", "XMgrace*helpMenu.onContextButton.accelerator: ShiftF1", "XMgrace*readHistoryFSB*pattern: *.com", "XMgrace*openProjectFSB*pattern: *.agr", "XMgrace*saveProjectFSB*pattern: *.agr", "XMgrace*readSetsFSB*pattern: *.dat", "XMgrace*writeSetsFSB*pattern: *.dat", "XMgrace*readParametersFSB*pattern: *.par", "XMgrace*writeParametersFSB*pattern: *.par", "XMgrace*selectNetcdfFileFSB*pattern: *.nc", "XMgrace*selectHotLinkFileFSB*pattern: *.dat", "XMgrace*openFitParameterFileFSB*pattern: *.fit", "XMgrace*saveFitParameterFileFSB*pattern: *.fit", NULL }; String fallbackResourcesHighRes[] = { "XMgrace*mainWin.width: 680", "XMgrace*mainWin.height: 700", "XMgrace*fontList:-*-helvetica-medium-r-normal-*-12-*-*-*-*-*-*-*", "XMgrace.consoleDialog*text.fontList:-*-courier-medium-r-normal-*-12-*-*-*-*-*-*-*", "XMgrace*HContainer.marginHeight: 3", "XMgrace*VContainer.marginHeight: 3", NULL }; String fallbackResourcesLowRes[] = { "XMgrace*mainWin.width: 530", "XMgrace*mainWin.height: 545", "XMgrace*fontList:-*-helvetica-medium-r-normal-*-8-*-*-*-*-*-*-*", "XMgrace.consoleDialog*text.fontList:-*-courier-medium-r-normal-*-8-*-*-*-*-*-*-*", "XMgrace*HContainer.marginHeight: 1", "XMgrace*VContainer.marginHeight: 1", NULL }; /* * main menubar */ /* #define MENU_HELP 200 */ #define MENU_EXIT 201 #define MENU_NEW 203 #define MENU_OPEN 204 #define MENU_SAVE 205 #define MENU_SAVEAS 206 #define MENU_REVERT 207 #define MENU_PRINT 208 #ifdef HAVE__XMVERSIONSTRING extern const char _XmVersionString[]; #endif static int is_motif_compatible(void) { char buf[128]; int bd_lesstif; #ifdef HAVE__XMVERSIONSTRING char *s; int rt_lesstif; #endif /* First, check for compatible version */ if (xmUseVersion < XmVersion) { sprintf(buf, "Run-time Motif library is older than the build, %d < %d", xmUseVersion, XmVersion); errmsg(buf); return FALSE; } bd_lesstif = (strstr(bi_gui(), "Motif") == NULL); #ifdef HAVE__XMVERSIONSTRING /* Then, check whether we are in the Motif/LessTif binary compatibility mode */ /* strcpy is dangerous since the sizeof(_XmVersionString) may be different at run time! 13 chars should be safe, though, and enough to distinguish between Motif and LessTif :) */ strncpy(buf, _XmVersionString, 13); buf[13] = '\0'; rt_lesstif = (strstr(buf, "Motif") == NULL); if (bd_lesstif != rt_lesstif) { sprintf(buf, "The software was built with %s, but is running with %s!", bd_lesstif ? "LessTif":"Motif", rt_lesstif ? "LessTif":"Motif"); errmsg(buf); errmsg("We don't support binary Motif/LessTif compatibility."); errmsg("Use a semistatic binary or compile Grace yourself!"); return FALSE; } /* Finally, if LessTif is used, check for a reasonably new release */ if (rt_lesstif) { s = strstr(_XmVersionString, "Version"); if (s == NULL || (strcmp(s, "Version 0.92.0") < 0)) { errmsg("An old version of LessTif, please upgrade to 0.92.0 at least"); } } #endif #if XbaeVersion >= 40800 /* Now we should compare whether Xbae was built against the runtime version of M*tif/LessTif. */ strncpy(buf, XbaeGetXmVersionTxt(), 13); buf[13] = '\0'; rt_lesstif = (strstr(buf, "Motif") == NULL); if (bd_lesstif != rt_lesstif) { sprintf(buf, "libXbae was built with %s, but is running with %s!", bd_lesstif ? "LessTif":"Motif", rt_lesstif ? "LessTif":"Motif"); errmsg(buf); errmsg("Use a semistatic binary or compile Grace/libXbae yourself!"); return FALSE; } /* Now we check for consistency of the used M*tif version */ if (XbaeGetXmVersionNum() != XmVersion) { sprintf(buf, "libXbae was built with Motif/LessTif %i, but is running with %i!", XbaeGetXmVersionNum(), XmVersion); errmsg(buf); errmsg("Use a semistatic binary or compile Grace/libXbae yourself!"); return FALSE; } #endif /* XbaeVersion > 40800 */ return TRUE; } int initialize_gui(int *argc, char **argv) { Screen *screen; ApplicationData rd; String *allResources, *resolResources; int lowres = FALSE; unsigned int i, n_common, n_resol; char *display_name = NULL; /* Locale settings for GUI */ XtSetLanguageProc(NULL, NULL, NULL); XtToolkitInitialize(); app_con = XtCreateApplicationContext(); /* Check if we're running in the low-resolution X */ for (i = 1; i < *argc - 1; i++) { /* See if display name was specified in the args */ char *pattern = "-display"; if (strlen(argv[i]) > 1 && strstr(pattern, argv[i]) == pattern) { display_name = argv[i + 1]; } } disp = XOpenDisplay(display_name); if (disp == NULL) { errmsg("Can't open display"); return RETURN_FAILURE; } screen = DefaultScreenOfDisplay(disp); if (HeightOfScreen(screen) < 740) { lowres = TRUE; } n_common = sizeof(fallbackResourcesCommon)/sizeof(String) - 1; if (lowres) { n_resol = sizeof(fallbackResourcesLowRes)/sizeof(String) - 1; resolResources = fallbackResourcesLowRes; } else { n_resol = sizeof(fallbackResourcesHighRes)/sizeof(String) - 1; resolResources = fallbackResourcesHighRes; } allResources = xmalloc((n_common + n_resol + 1)*sizeof(String)); for (i = 0; i < n_common; i++) { allResources[i] = fallbackResourcesCommon[i]; } for (i = 0; i < n_resol; i++) { allResources[n_common + i] = resolResources[i]; } allResources[n_common + n_resol] = NULL; XtAppSetFallbackResources(app_con, allResources); XtDisplayInitialize(app_con, disp, "xmgrace", "XMgrace", NULL, 0, argc, argv); XtAppAddActions(app_con, dummy_actions, XtNumber(dummy_actions)); XtAppAddActions(app_con, canvas_actions, XtNumber(canvas_actions)); XtAppAddActions(app_con, list_select_actions, XtNumber(list_select_actions)); XtAppAddActions(app_con, cstext_actions, XtNumber(cstext_actions)); app_shell = XtAppCreateShell(NULL, "XMgrace", applicationShellWidgetClass, disp, NULL, 0); if (is_motif_compatible() != TRUE) { return RETURN_FAILURE; } XtGetApplicationResources(app_shell, &rd, resources, XtNumber(resources), NULL, 0); invert = rd.invert; allow_dc = rd.allow_dc; auto_redraw = rd.auto_redraw; toolbar_visible = rd.toolbar; statusbar_visible = rd.statusbar; locbar_visible = rd.locatorbar; return RETURN_SUCCESS; } static void do_drawgraph(void *data) { drawgraph(); } static void MenuCB(void *data) { char *s; switch ((int) data) { case MENU_EXIT: bailout(); break; case MENU_NEW: new_project(NULL); xdrawgraph(); break; case MENU_OPEN: create_openproject_popup(); break; case MENU_SAVE: if (strcmp (get_docname(), NONAME) != 0) { set_wait_cursor(); save_project(get_docname()); unset_wait_cursor(); } else { create_saveproject_popup(); } break; case MENU_SAVEAS: create_saveproject_popup(); break; case MENU_REVERT: set_wait_cursor(); s = copy_string(NULL, get_docname()); if (strcmp (s, NONAME) != 0) { load_project(s); } else { new_project(NULL); } xfree(s); xdrawgraph(); unset_wait_cursor(); break; case MENU_PRINT: set_wait_cursor(); do_hardcopy(); unset_wait_cursor(); break; default: break; } } /* * service the autoscale buttons on the main panel */ static void autoscale_proc(void *data) { int cg = get_cg(); if (autoscale_graph(cg, (int) data) == RETURN_SUCCESS) { update_ticks(cg); xdrawgraph(); } else { errmsg("Can't autoscale (no active sets?)"); } } void autoon_proc(void *data) { set_action(0); set_action(AUTO_NEAREST); } /* * service the autoticks button on the main panel */ void autoticks_proc(void *data) { autotick_axis(get_cg(), ALL_AXES); update_ticks(get_cg()); xdrawgraph(); } /* * set the message in the left footer */ void set_left_footer(char *s) { if (s == NULL) { char hbuf[64]; char buf[GR_MAXPATHLEN + 100]; gethostname(hbuf, 63); sprintf(buf, "%s, %s, %s", hbuf, display_name(), get_docname()); SetLabel(statlab, buf); } else { SetLabel(statlab, s); } XmUpdateDisplay(statlab); } /* * for world stack */ void set_stack_message(void) { char buf[16]; if (stack_depth_item) { sprintf(buf, " SD:%1d ", graph_world_stack_size(get_cg())); SetLabel(stack_depth_item, buf); sprintf(buf, " CW:%1d ", get_world_stack_current(get_cg())); SetLabel(curw_item, buf); } } /* * clear the locator reference point */ void do_clear_point(void *data) { GLocator locator; get_graph_locator(get_cg(), &locator); locator.pointset = FALSE; set_graph_locator(get_cg(), &locator); xdrawgraph(); } /* * set visibility of the toolbars */ static void set_view_items(void) { if (statusbar_visible) { SetToggleButtonState(windowbarw[1], TRUE); ManageChild(frbot); XtVaSetValues(drawing_window, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, frbot, NULL); if (toolbar_visible) { XtVaSetValues(frleft, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, frbot, NULL); } } else { SetToggleButtonState(windowbarw[1], FALSE); XtVaSetValues(drawing_window, XmNbottomAttachment, XmATTACH_FORM, NULL); UnmanageChild(frbot); if (toolbar_visible) { XtVaSetValues(frleft, XmNbottomAttachment, XmATTACH_FORM, NULL); } } if (toolbar_visible) { SetToggleButtonState(windowbarw[2], TRUE); ManageChild(frleft); if (statusbar_visible) { XtVaSetValues(frleft, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, frbot, NULL); } if (locbar_visible) { XtVaSetValues(frleft, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, frtop, NULL); } XtVaSetValues(drawing_window, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, frleft, NULL); } else { SetToggleButtonState(windowbarw[2], FALSE); UnmanageChild(frleft); XtVaSetValues(drawing_window, XmNleftAttachment, XmATTACH_FORM, NULL); } if (locbar_visible) { SetToggleButtonState(windowbarw[0], TRUE); ManageChild(frtop); XtVaSetValues(drawing_window, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, frtop, NULL); if (toolbar_visible) { XtVaSetValues(frleft, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, frtop, NULL); } } else { SetToggleButtonState(windowbarw[0], FALSE); UnmanageChild(frtop); XtVaSetValues(drawing_window, XmNtopAttachment, XmATTACH_FORM, NULL); if (toolbar_visible) { XtVaSetValues(frleft, XmNtopAttachment, XmATTACH_FORM, NULL); } } } /* * service routines for the View pulldown */ void set_statusbar(int onoff, void *data) { if (onoff) { statusbar_visible = 1; } else { statusbar_visible = 0; } set_view_items(); } void set_toolbar(int onoff, void *data) { if (onoff) { toolbar_visible = 1; } else { toolbar_visible = 0; } set_view_items(); } void set_locbar(int onoff, void *data) { if (onoff) { locbar_visible = 1; } else { locbar_visible = 0; } set_view_items(); } void set_barebones(int onoff) { if (onoff){ locbar_visible = 0; toolbar_visible = 0; statusbar_visible = 0; } } /* * create the main menubar */ static Widget CreateMainMenuBar(Widget parent) { Widget menubar; Widget menupane, submenupane, sub2menupane; static char buf[128]; menubar = CreateMenuBar(parent); /* * File menu */ menupane = CreateMenu(menubar, "File", 'F', FALSE); CreateMenuButton(menupane, "New", 'N', MenuCB, (void *) MENU_NEW); CreateMenuButton(menupane, "Open...", 'O', MenuCB, (void *) MENU_OPEN); CreateMenuButton(menupane, "Save", 'S', MenuCB, (void *) MENU_SAVE); CreateMenuButton(menupane, "Save as...", 'a', MenuCB, (void *) MENU_SAVEAS); CreateMenuButton(menupane, "Revert to saved", 'v', MenuCB, (void *) MENU_REVERT); CreateMenuSeparator(menupane); CreateMenuButton(menupane, "Print setup...", 't', create_printer_setup, &hdevice); CreateMenuButton(menupane, "Print", 'P', MenuCB, (void *) MENU_PRINT); CreateMenuSeparator(menupane); CreateMenuButton(menupane, "Exit", 'x', MenuCB, (void *) MENU_EXIT); /* * Edit menu */ menupane = CreateMenu(menubar, "Edit", 'E', FALSE); CreateMenuButton(menupane, "Data sets...", 'D', create_datasetprop_popup, NULL); CreateMenuButton(menupane, "Set operations...", 'o', create_setop_popup, NULL); CreateMenuSeparator(menupane); CreateMenuButton(menupane, "Arrange graphs...", 'r', create_arrange_frame, NULL); CreateMenuButton(menupane, "Overlay graphs...", 'O', create_overlay_frame, NULL); CreateMenuButton(menupane, "Autoscale graphs...", 'A', create_autos_frame, NULL); CreateMenuSeparator(menupane); submenupane = CreateMenu(menupane, "Regions", 'i', FALSE); CreateMenuButton(submenupane, "Status...", 'S', define_status_popup, NULL); CreateMenuButton(submenupane, "Define...", 'D', create_define_frame, NULL); CreateMenuButton(submenupane, "Clear...", 'C', create_clear_frame, NULL); CreateMenuSeparator(submenupane); CreateMenuButton(submenupane, "Report on...", 'R', create_reporton_frame, NULL); CreateMenuButton(menupane, "Hot links...", 'l', create_hotlinks_popup, NULL); CreateMenuSeparator(menupane); CreateMenuButton(menupane, "Set locator fixed point", 'f', set_actioncb, (void *) SEL_POINT); CreateMenuButton(menupane, "Clear locator fixed point", 'C', do_clear_point, NULL); CreateMenuButton(menupane, "Locator props...", 'p', create_locator_frame, NULL); CreateMenuSeparator(menupane); CreateMenuButton(menupane, "Preferences...", 'r', create_props_frame, NULL); /* * Data menu */ menupane = CreateMenu(menubar, "Data", 'D', FALSE); CreateMenuButton(menupane, "Data set operations...", 'o', create_datasetop_popup, NULL); submenupane = CreateMenu(menupane, "Transformations", 'T', FALSE); CreateMenuButton(submenupane, "Evaluate expression...", 'E', create_eval_frame, NULL); CreateMenuSeparator(submenupane); CreateMenuButton(submenupane, "Histograms...", 'H', create_histo_frame, NULL); CreateMenuButton(submenupane, "Fourier transforms...", 'u', create_fourier_frame, NULL); CreateMenuSeparator(submenupane); CreateMenuButton(submenupane, "Running averages...", 'a', create_run_frame, NULL); CreateMenuButton(submenupane, "Differences...", 'D', create_diff_frame, NULL); CreateMenuButton(submenupane, "Seasonal differences...", 'o', create_seasonal_frame, NULL); CreateMenuButton(submenupane, "Integration...", 'I', create_int_frame, NULL); CreateMenuSeparator(submenupane); CreateMenuButton(submenupane, "Interpolation/splines...", 't', create_interp_frame, NULL); CreateMenuButton(submenupane, "Regression...", 'R', create_reg_frame, NULL); CreateMenuButton(submenupane, "Non-linear curve fitting...", 'N', create_nonl_frame, NULL); CreateMenuSeparator(submenupane); CreateMenuButton(submenupane, "Correlation/covariance...", 'C', create_xcor_frame, NULL); CreateMenuButton(submenupane, "Digital filter...", 'f', create_digf_frame, NULL); CreateMenuButton(submenupane, "Linear convolution...", 'v', create_lconv_frame, NULL); CreateMenuSeparator(submenupane); CreateMenuButton(submenupane, "Geometric transforms...", 'G', create_geom_frame, NULL); CreateMenuSeparator(submenupane); CreateMenuButton(submenupane, "Sample points...", 'm', create_samp_frame, NULL); CreateMenuButton(submenupane, "Prune data...", 'P', create_prune_frame, NULL); CreateMenuButton(menupane, "Feature extraction...", 'x', create_featext_frame, NULL); CreateMenuSeparator(menupane); submenupane = CreateMenu(menupane, "Import", 'I', FALSE); CreateMenuButton(submenupane, "ASCII...", 'A', create_file_popup, NULL); #ifdef HAVE_NETCDF CreateMenuButton(submenupane, "NetCDF...", 'N', create_netcdfs_popup, NULL); #endif submenupane = CreateMenu(menupane, "Export", 'E', FALSE); CreateMenuButton(submenupane, "ASCII...", 'A', create_write_popup, NULL); /* Plot menu */ menupane = CreateMenu(menubar, "Plot", 'P', FALSE); CreateMenuButton(menupane, "Plot appearance...", 'p', create_plot_frame_cb, NULL); CreateMenuButton(menupane, "Graph appearance...", 'G', create_graphapp_frame_cb, (void *) -1); CreateMenuButton(menupane, "Set appearance...", 'S', define_symbols_popup, (void *) -1); CreateMenuButton(menupane, "Axis properties...", 'x', create_axes_dialog_cb, NULL); CreateMenuSeparator(menupane); CreateMenuButton(menupane, "Load parameters...", 'L', create_rparams_popup, NULL); CreateMenuButton(menupane, "Save parameters...", 'S', create_wparam_frame, NULL); /* View menu */ menupane = CreateMenu(menubar, "View", 'V', FALSE); windowbarw[0] = CreateMenuToggle(menupane, "Show locator bar", 'L', set_locbar, NULL); windowbarw[1] = CreateMenuToggle(menupane, "Show status bar", 'S', set_statusbar, NULL); windowbarw[2] = CreateMenuToggle(menupane, "Show tool bar", 'T', set_toolbar, NULL); CreateMenuSeparator(menupane); CreateMenuButton(menupane, "Page setup...", 'P', create_printer_setup, &tdevice); CreateMenuSeparator(menupane); CreateMenuButton(menupane, "Redraw", 'R', do_drawgraph, NULL); CreateMenuSeparator(menupane); CreateMenuButton(menupane, "Update all", 'U', update_all_cb, NULL); /* Window menu */ menupane = CreateMenu(menubar, "Window", 'W', FALSE); CreateMenuButton(menupane, "Commands", 'C', open_command, NULL); CreateMenuButton(menupane, "Point explorer", 'P', create_points_frame, NULL); CreateMenuButton(menupane, "Drawing objects", 'o', define_objects_popup, NULL); CreateMenuButton(menupane, "Font tool", 'F', create_fonttool_cb, NULL); /* * CreateMenuButton(menupane, "Area/perimeter...", 'A', create_area_frame, NULL); */ CreateMenuButton(menupane, "Console", 'l', create_monitor_frame_cb, NULL); /* help menu */ menupane = CreateMenu(menubar, "Help", 'H', TRUE); CreateMenuButton(menupane, "User's Guide", 'G', HelpCB, "doc/UsersGuide.html"); CreateMenuButton(menupane, "Tutorial", 'T', HelpCB, "doc/Tutorial.html"); CreateMenuButton(menupane, "FAQ", 'Q', HelpCB, "doc/FAQ.html"); CreateMenuButton(menupane, "Changes", 'C', HelpCB, "doc/CHANGES.html"); CreateMenuSeparator(menupane); submenupane = CreateMenu(menupane, "Examples", 'E', FALSE); sub2menupane = CreateMenu(submenupane, "General intro", 'i', FALSE); CreateMenuButton(sub2menupane, "Explain", '\0', load_example, "explain.agr"); CreateMenuButton(sub2menupane, "Properties", '\0', load_example, "props.agr"); CreateMenuButton(sub2menupane, "Axes", '\0',load_example, "axes.agr"); CreateMenuButton(sub2menupane, "Fonts", '\0', load_example, "tfonts.agr"); CreateMenuButton(sub2menupane, "Arrows", '\0', load_example, "arrows.agr"); CreateMenuButton(sub2menupane, "Symbols and lines", '\0', load_example, "symslines.agr"); CreateMenuButton(sub2menupane, "Fills", '\0', load_example, "fills.agr"); CreateMenuButton(sub2menupane, "World stack", '\0', load_example, "tstack.agr"); CreateMenuButton(sub2menupane, "Inset graphs", '\0', load_example, "tinset.agr"); CreateMenuButton(sub2menupane, "Many graphs", '\0', load_example, "manygraphs.agr"); sub2menupane = CreateMenu(submenupane, "XY graphs", 'g', FALSE); CreateMenuButton(sub2menupane, "Log scale", '\0', load_example, "tlog.agr"); CreateMenuButton(sub2menupane, "Log2 scale", '\0', load_example, "log2.agr"); CreateMenuButton(sub2menupane, "Log2/log scale", '\0', load_example, "log2log.agr"); CreateMenuButton(sub2menupane, "Logit scale", '\0', load_example, "logit.agr"); CreateMenuButton(sub2menupane, "Reciprocal scale", '\0', load_example, "reciprocal.agr"); CreateMenuButton(sub2menupane, "Error bars", '\0', load_example, "terr.agr"); CreateMenuButton(sub2menupane, "Date/time axis formats", '\0', load_example, "times.agr"); CreateMenuButton(sub2menupane, "Australia map", '\0', load_example, "au.agr"); CreateMenuButton(sub2menupane, "A CO2 analysis", '\0', load_example, "co2.agr"); CreateMenuButton(sub2menupane, "Motif statistics", '\0', load_example, "motif.agr"); CreateMenuButton(sub2menupane, "Spectrum", '\0', load_example, "spectrum.agr"); sub2menupane = CreateMenu(submenupane, "XY charts", 'c', FALSE); CreateMenuButton(sub2menupane, "Bar chart", '\0', load_example, "bar.agr"); CreateMenuButton(sub2menupane, "Stacked bar", '\0', load_example, "stackedb.agr"); CreateMenuButton(sub2menupane, "Bar chart with error bars", '\0', load_example, "chartebar.agr"); CreateMenuButton(sub2menupane, "Different charts", '\0', load_example, "charts.agr"); sub2menupane = CreateMenu(submenupane, "Polar graphs", 'P', FALSE); CreateMenuButton(sub2menupane, "Polar graph", '\0', load_example, "polar.agr"); sub2menupane = CreateMenu(submenupane, "Pie charts", 'i', FALSE); CreateMenuButton(sub2menupane, "Pie chart", '\0', load_example, "pie.agr"); sub2menupane = CreateMenu(submenupane, "Special set presentations", 'S', FALSE); CreateMenuButton(sub2menupane, "HILO", '\0', load_example, "hilo.agr"); CreateMenuButton(sub2menupane, "XY Radius", '\0', load_example, "txyr.agr"); CreateMenuButton(sub2menupane, "XYZ", '\0', load_example, "xyz.agr"); CreateMenuButton(sub2menupane, "Box plot", '\0', load_example, "boxplot.agr"); CreateMenuButton(sub2menupane, "Vector map", '\0', load_example, "vmap.agr"); CreateMenuButton(sub2menupane, "XY Size", '\0', load_example, "xysize.agr"); CreateMenuButton(sub2menupane, "XY Color", '\0', load_example, "xycolor.agr"); sub2menupane = CreateMenu(submenupane, "Type setting", 'T', FALSE); CreateMenuButton(sub2menupane, "Simple", '\0', load_example, "test2.agr"); CreateMenuButton(sub2menupane, "Text transforms", '\0', load_example, "txttrans.agr"); CreateMenuButton(sub2menupane, "Advanced", '\0', load_example, "typeset.agr"); sub2menupane = CreateMenu(submenupane, "Calculus", 'u', FALSE); CreateMenuButton(sub2menupane, "Non-linear fit", '\0', load_example, "logistic.agr"); CreateMenuSeparator(menupane); sprintf(buf, "http://plasma-gate.weizmann.ac.il/Grace/comments.phtml?version_id=%ld", bi_version_id()); CreateMenuButton(menupane, "Comments", 'm', HelpCB, buf); CreateMenuSeparator(menupane); CreateMenuButton(menupane, "License terms", 'L', HelpCB, "doc/GPL.html"); CreateMenuButton(menupane, "About...", 'A', create_about_grtool, NULL); return (menubar); } /* * build the GUI */ void startup_gui(void) { Widget bt, rc3, rcleft; Pixmap icon, shape; /* * Allow users to change tear off menus with X resources */ XmRepTypeInstallTearOffModelConverter(); RegisterEditRes(app_shell); /* * We handle important WM events ourselves */ handle_close(app_shell); xlibinit(); XtVaSetValues(app_shell, XmNcolormap, cmap, NULL); /* * build the UI here */ main_frame = XtVaCreateManagedWidget("mainWin", xmMainWindowWidgetClass, app_shell, NULL); menu_bar = CreateMainMenuBar(main_frame); ManageChild(menu_bar); form = XmCreateForm(main_frame, "form", NULL, 0); frleft = CreateFrame(form, NULL); rcleft = XtVaCreateManagedWidget("toolBar", xmRowColumnWidgetClass, frleft, XmNorientation, XmVERTICAL, XmNpacking, XmPACK_TIGHT, XmNspacing, 0, XmNentryBorder, 0, XmNmarginWidth, 0, XmNmarginHeight, 0, NULL); frtop = CreateFrame(form, NULL); loclab = CreateLabel(frtop, ""); frbot = CreateFrame(form, NULL); statlab = CreateLabel(frbot, ""); if (get_pagelayout() == PAGE_FIXED) { drawing_window = XtVaCreateManagedWidget("drawing_window", xmScrolledWindowWidgetClass, form, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP, XmNscrollingPolicy, XmAUTOMATIC, XmNvisualPolicy, XmVARIABLE, NULL); canvas = XtVaCreateManagedWidget("canvas", xmDrawingAreaWidgetClass, drawing_window, XmNresizePolicy, XmRESIZE_ANY, XmNbackground, xvlibcolors[0], NULL); } else { canvas = XtVaCreateManagedWidget("canvas", xmDrawingAreaWidgetClass, form, XmNresizePolicy, XmRESIZE_ANY, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP, XmNbackground, xvlibcolors[0], NULL); drawing_window = canvas; } XtAddCallback(canvas, XmNexposeCallback, (XtCallbackProc) expose_resize, NULL); XtAddCallback(canvas, XmNresizeCallback, (XtCallbackProc) expose_resize, NULL); XtAddEventHandler(canvas, EnterWindowMask | LeaveWindowMask | ButtonPressMask | PointerMotionMask | KeyPressMask | ColormapChangeMask, False, (XtEventHandler) my_proc, NULL); XtOverrideTranslations(canvas, XtParseTranslationTable(canvas_table)); AddHelpCB(canvas, "doc/UsersGuide.html#canvas"); XtVaSetValues(frtop, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL); XtVaSetValues(frbot, XmNbottomAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, NULL); XtVaSetValues(frleft, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, frtop, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, frbot, XmNleftAttachment, XmATTACH_FORM, NULL); XtVaSetValues(drawing_window, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, frtop, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, frbot, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, frleft, XmNrightAttachment, XmATTACH_FORM, NULL); ManageChild(form); if (get_pagelayout() == PAGE_FIXED) { unsigned int w, h; sync_canvas_size(&w, &h, FALSE); } XmMainWindowSetAreas(main_frame, menu_bar, NULL, NULL, NULL, form); bt = CreateButton(rcleft, "Draw"); AddButtonCB(bt, do_drawgraph, NULL); /* zoom and autoscale */ rc3 = XtVaCreateManagedWidget("rc", xmRowColumnWidgetClass, rcleft, XmNorientation, XmHORIZONTAL, XmNpacking, XmPACK_COLUMN, XmNnumColumns, 4, XmNspacing, 0, XmNentryBorder, 0, NULL); bt = CreateBitmapButton(rc3, 16, 16, zoom_bits); AddButtonCB(bt, set_actioncb, (void *) ZOOM_1ST); bt = CreateBitmapButton(rc3, 16, 16, auto_bits); AddButtonCB(bt, autoscale_proc, (void *) AUTOSCALE_XY); /* expand/shrink */ bt = CreateBitmapButton(rc3, 16, 16, expand_bits); AddButtonCB(bt, graph_zoom_proc, (void *) GZOOM_EXPAND); bt = CreateBitmapButton(rc3, 16, 16, shrink_bits); AddButtonCB(bt, graph_zoom_proc, (void *) GZOOM_SHRINK); /* * scrolling buttons */ bt = CreateBitmapButton(rc3, 16, 16, left_bits); AddButtonCB(bt, graph_scroll_proc, (void *) GSCROLL_LEFT); bt = CreateBitmapButton(rc3, 16, 16, right_bits); AddButtonCB(bt, graph_scroll_proc, (void *) GSCROLL_RIGHT); bt = CreateBitmapButton(rc3, 16, 16, down_bits); AddButtonCB(bt, graph_scroll_proc, (void *) GSCROLL_DOWN); bt = CreateBitmapButton(rc3, 16, 16, up_bits); AddButtonCB(bt, graph_scroll_proc, (void *) GSCROLL_UP); CreateSeparator(rcleft); bt = CreateButton(rcleft, "AutoT"); AddButtonCB(bt, autoticks_proc, NULL); bt = CreateButton(rcleft, "AutoO"); AddButtonCB(bt, autoon_proc, NULL); rc3 = XtVaCreateManagedWidget("rc", xmRowColumnWidgetClass, rcleft, XmNorientation, XmHORIZONTAL, XmNpacking, XmPACK_COLUMN, XmNnumColumns, 4, XmNspacing, 0, XmNentryBorder, 0, NULL); bt = CreateButton(rc3, "ZX"); AddButtonCB(bt, set_actioncb, (void *) ZOOMX_1ST); bt = CreateButton(rc3, "ZY"); AddButtonCB(bt, set_actioncb, (void *) ZOOMY_1ST); bt = CreateButton(rc3, "AX"); AddButtonCB(bt, autoscale_proc, (void *) AUTOSCALE_X); bt = CreateButton(rc3, "AY"); AddButtonCB(bt, autoscale_proc, (void *) AUTOSCALE_Y); bt = CreateButton(rc3, "PZ"); AddButtonCB(bt, world_stack_proc, (void *) WSTACK_PUSH_ZOOM); bt = CreateButton(rc3, "Pu"); AddButtonCB(bt, world_stack_proc, (void *) WSTACK_PUSH); bt = CreateButton(rc3, "Po"); AddButtonCB(bt, world_stack_proc, (void *) WSTACK_POP); bt = CreateButton(rc3, "Cy"); AddButtonCB(bt, world_stack_proc, (void *) WSTACK_CYCLE); stack_depth_item = CreateLabel(rcleft, ""); curw_item = CreateLabel(rcleft, ""); bt = CreateButton(rcleft, "Exit"); AddButtonCB(bt, MenuCB, (void *) MENU_EXIT); /* * initialize cursors */ init_cursors(); /* * initialize some option menus */ init_option_menus(); /* * initialize the tool bars */ set_view_items(); SetLabel(loclab, "G0:[X, Y] = "); set_stack_message(); set_left_footer(NULL); /* * set icon */ #if defined(HAVE_XPM) XpmCreatePixmapFromData(disp, root, grace_icon_xpm, &icon, &shape, NULL); #else icon = XCreateBitmapFromData(disp, root, (char *) grace_icon_bits, grace_icon_width, grace_icon_height); shape = XCreateBitmapFromData(disp, root, (char *) grace_mask_bits, grace_icon_width, grace_icon_height); #endif XtVaSetValues(app_shell, XtNiconPixmap, icon, XtNiconMask, shape, NULL); XtRealizeWidget(app_shell); xwin = XtWindow(canvas); inwin = 1; /* * set the title */ update_app_title(); XtAppMainLoop(app_con); } void sync_canvas_size(unsigned int *w, unsigned int *h, int inv) { Page_geometry pg = get_page_geometry(); if (inv) { GetDimensions(canvas, w, h); set_page_dimensions(*w*72.0/pg.dpi, *h*72.0/pg.dpi, TRUE); } else { *w = pg.width; *h = pg.height; SetDimensions(canvas, *w, *h); } } static int page_layout = PAGE_FIXED; int get_pagelayout(void) { return page_layout; } void set_pagelayout(int layout) { if (page_layout == layout) { return; } if (inwin) { errmsg("Can not change layout after initialization of GUI"); return; } else { page_layout = layout; } } static void graph_scroll_proc(void *data) { graph_scroll((int) data); xdrawgraph(); } static void graph_zoom_proc(void *data) { graph_zoom((int) data); xdrawgraph(); } static void world_stack_proc(void *data) { switch ((int) data) { case WSTACK_PUSH_ZOOM: push_and_zoom(); break; case WSTACK_PUSH: push_world(); break; case WSTACK_POP: pop_world(); break; case WSTACK_CYCLE: cycle_world_stack(); break; default: return; } update_all(); xdrawgraph(); } static void load_example(void *data) { char *s, buf[128]; set_wait_cursor(); s = (char *) data; sprintf(buf, "examples/%s", s); load_project_file(buf, FALSE); xdrawgraph(); unset_wait_cursor(); }