Logo Search packages:      
Sourcecode: acm version File versions  Download package

gedit.c

/*
 *  Copyright (c) 1994, Riley Rainey,  riley@netcon.com
 *
 *  Permission to use, copy, modify and distribute (without charge) this
 *  software, documentation, images, etc. is granted, provided that this 
 *  comment and the author's name is retained.
 *
 *  This software is provided by the author as is, and without any expressed
 *  or implied warranties, including, but not limited to, the implied
 *  warranties of merchantability and fitness for a particular purpose.  In no
 *  event shall the author be liable for any direct, indirect, incidental, or
 *  consequential damages arising in any way out of the use of this software.
 */

#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>

#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <Xm/Xm.h>
#include <Xm/MainW.h>
#include <Xm/PushB.h>
#include <Xm/ToggleB.h>
#include <Xm/TextF.h>
#include <Xm/RowColumn.h>
#include <Xm/Form.h>
#include <Xm/MessageB.h>
#include <Xm/Frame.h>
#include <Xm/CascadeB.h>
#include <Xm/BulletinB.h>
#include <Xm/DrawingA.h>
#include <Xm/Separator.h>
#include <Xm/SelectioB.h>
#include <Xm/FileSB.h>
#include <Xm/LabelG.h>
#include <X11/cursorfont.h>

#define DEFINE_STORAGE
#include "gedit.h"
#include "XrMisc.h"

#include "curs_poly"
#include "curs_poly_mask"
#include "curs_marker"
#include "curs_marker_mask"


static unsigned char    grid_dash_list[2] = { 1, 4 };

static XmStringCharSet  charset = (XmStringCharSet) XmSTRING_DEFAULT_CHARSET;

/*
 *  fallback resources
 */

static String     fallback[] = {
      "*.Background:                GhostWhite",
      "*buttons*highlightColor:     GhostWhite",

      "*.fontList:                  -*-helvetica-medium-r-*-*-*-140-*",
      "*.rulerFont:                 -*-courier-bold-r-*-*-*-140-*",
      "*XmTextField.fontList:       -*-courier-medium-r-*-*-*-140-*",
      "*XmPushButton.shadowThickness:     3",
      "*XmDrawingArea.traversalOn:  false",
      "*.menu_bar*Background:       #4af",
      "*.menu_bar.spacing:          10",
      "*.top_frame.shadowType:      XmSHADOW_ETCHED_OUT",
      "*.bottom_frame.shadowType:   XmSHADOW_ETCHED_OUT",
      "*.twindow.background:        #d8d8d8",
      "*.twindow.foreground:        black",
      "*.bwindow.background:        #e1caac",
      "*.bwindow.foreground:        black",
      "*.main.form.height:          950",
      "*.main.form.width:           950",

      "*set_views.labelString: Set Views ...",
      "*mirror_xz.labelString: Mirror left/right",
      "*mirror_xz.acceleratorText:  Alt-L",
      "*mirror_xz.accelerator:      Meta<Key>l:",
      "*mirror_xz.mnemonic:         l",
      "*mirror_xy.labelString: Mirror top/bottom",
      "*mirror_xy.acceleratorText:  Alt-T",
      "*mirror_xy.accelerator:      Meta<Key>t:",
      "*mirror_xy.mnemonic:         t",
      "*mirror_yz.labelString: Mirror front/back",
      "*mirror_yz.acceleratorText:  Alt-F",
      "*mirror_yz.accelerator:      Meta<Key>f:",
      "*mirror_yz.mnemonic:         f",
      "*rescale.labelString: Rescale Object ...",
      "*rescale.mnemonic:           R",

      "*info.labelString: Aircraft Information ...",
      "*gear.labelString: Landing Gear ...",
      "*stability.labelString: Stability Derivatives ...",
      "*powerplant.labelString: Powerplant ...",

      "*rescale_dialog.dialogTitle: Rescale Object",

      "*open_d.dialogTitle:         Open a File",
      "*open_d.okLabelString:       Open",
      "*open_d.selectionLabelString:      Open which file?",
      "*open_d.autoUnmanage:        true",
      "*open_d*pattern:       *.gdf",

      "*save_as_d.dialogTitle:      Save Work",
      "*save_as_d.selectionLabelString:   File name:",
      "*save_as_d.okLabelString:    Save",
      "*save_as_d.*.fontList:       -*-helvetica-medium-r-*-*-*-120-*",

      "*gedit_format.labelString:   Gedit format",
      "*gedit_format.set:           true",
      "*v_format.labelString:       V format",
      "*rayshade_format.labelString:      ACM Inventory format",

      "*show_grid.visibleWhenOff:   true",
      "*show_ruler.visibleWhenOff:  true",

      "*coodinates*columns:         8",
      "*coodinates*sensitive:       false",

      "*new.labelString:            New",
      "*open.labelString:           Open ...",
      "*save.labelString:           Save",
      "*save_as.labelString:        Save As ...",
      "*exit.labelString:           Exit",

      "*new.acceleratorText:        Alt-N",
      "*new.accelerator:            Meta<Key>n:",
      "*new.mnemonic:               N",
      "*open.acceleratorText:       Alt-O",
      "*open.accelerator:           Meta<Key>o:",
      "*open.mnemonic:        O",
      "*save.acceleratorText:       Alt-S",
      "*save.accelerator:           Meta<Key>s:",
      "*save.mnemonic:        S",
      "*save_as.mnemonic:           A",
      "*exit.acceleratorText:       Alt-E",
      "*exit.accelerator:           Meta<Key>e:",
      "*exit.mnemonic:        E",

      "*cut.labelString:            Cut",
      "*cut.acceleratorText:        Shift-Del",
      "*cut.accelerator:            Shift<Key>Delete:",
      "*cut.mnemonic:               t",
      "*copy.labelString:           Copy",
      "*copy.acceleratorText:       Ctrl-Ins",
      "*copy.accelerator:           Ctrl<Key>Insert:",
      "*copy.mnemonic:        C",
      "*paste.labelString:          Paste",
      "*paste.acceleratorText:      Shift-Ins",
      "*paste.accelerator:          Shift<Key>Insert:",
      "*paste.mnemonic:       P",
      "*clear.labelString:          Clear",
      "*clear.mnemonic:       e",
      "*rotx.labelString:           Rotate 90 about X-Axis",
      
      "*info_dialog*XmLabelGadget.topOffset:          7",
      "*info_dialog*XmLabelGadget.rightOffset:  10",
      "*info_dialog*XmLabelGadget.leftOffset:         10",  
      "*info_dialog*XmTextField.rightOffset:          10",
      "*gear_dialog*XmLabelGadget.topOffset:          7",
      "*gear_dialog*XmLabelGadget.rightOffset:  10",
      "*gear_dialog*XmLabelGadget.leftOffset:         10",
      "*gear_dialog*XmTextField.rightOffset:          10",
      "*powerplant_dialog*XmLabelGadget.topOffset:    7",
      "*powerplant_dialog*XmLabelGadget.rightOffset:  10",
      "*powerplant_dialog*XmLabelGadget.leftOffset:   10",
      "*powerplant_dialog*XmTextField.rightOffset:    10",
      "*stability_dialog*XmLabelGadget.topOffset:     7",
      "*stability_dialog*XmLabelGadget.rightOffset:   10",
      "*stability_dialog*XmLabelGadget.leftOffset:    10",
      "*stability_dialog*XmTextField.rightOffset:     10",

      "*stability_dialog*Calculate.sensitive:   false",
      "*info_dialog*Calculate.sensitive:  false",
      "*info_dialog*Calculate.sensitive:  false",

      NULL
      };

static XrmOptionDescRec options[] = {
      {"-controllerClass", "*controllerClass", XrmoptionSepArg, "is"},
      };

static XtResource resources[] = {
      {
            XtNselectionColor,
            XtCSelectionColor,
            XtRPixel,
            sizeof(Pixel),
            XtOffset(AppDataPtr, select_pixel),
            XtRString,
            (caddr_t) "firebrick"
      },
      {
            XtNgridColor,
            XtCGridColor,
            XtRPixel,
            sizeof(Pixel),
            XtOffset(AppDataPtr, grid_pixel),
            XtRString,
            (caddr_t) "black"
      },
      {
            XtNlineThickness,
            XtCLineThickness,
            XtRInt,
            sizeof(int),
            XtOffset(AppDataPtr, line_thickness),
            XtRImmediate,
            (caddr_t) 0
      },
      {
            XtNselectionThickness,
            XtCSelectionThickness,
            XtRInt,
            sizeof(int),
            XtOffset(AppDataPtr, selection_thickness),
            XtRImmediate,
            (caddr_t) 2
      },
      {
            XtNboxSize,
            XtCBoxSize,
            XtRInt,
            sizeof(int),
            XtOffset(AppDataPtr, box_size),
            XtRImmediate,
            (caddr_t) 5
      },
      {
            XtNpickSensitivity,
            XtCPickSensitivity,
            XtRInt,
            sizeof(int),
            XtOffset(AppDataPtr, pick_sensitivity),
            XtRImmediate,
            (caddr_t) 64
      },
      {
            XtNbuttonSize,
            XtCButtonSize,
            XtRInt,
            sizeof(int),
            XtOffset(AppDataPtr, button_size),
            XtRImmediate,
            (caddr_t) 32
      },
      {
            XtNcursorForeground,
            XtCCursorForeground,
            XtRPixel,
            sizeof(Pixel),
            XtOffset(AppDataPtr, cursor_foreground),
            XtRString,
            (caddr_t) "black"
      },
      {
            XtNcursorBackground,
            XtCCursorBackground,
            XtRPixel,
            sizeof(Pixel),
            XtOffset(AppDataPtr, cursor_background),
            XtRString,
            (caddr_t) "white"
      },
      {
            XtNshowGrid,
            XtCShowGrid,
            XmRBoolean,
            sizeof(Boolean),
            XtOffset(AppDataPtr, show_grid),
            XtRString,
            (caddr_t) "true"
      },
      {
            XtNshowRuler,
            XtCShowRuler,
            XmRBoolean,
            sizeof(Boolean),
            XtOffset(AppDataPtr, show_ruler),
            XtRString,
            (caddr_t) "false"
      },
      {
            XtNrulerFont,
            XtCFont,
            XtRFontStruct,
            sizeof(XFontStruct *),
            XtOffset(AppDataPtr, ruler_font),
            XtRString,
            (caddr_t) "fixed"
      }

      };

typedef struct {
      Boolean     defined_in_this_version;
      Widget      widget;
      char  *name;
      char  *pixmap_file;
      } button_list_t;

button_list_t button_list[] = {
      { True,           NULL, "point",          "cursor_%d.xbm" },
      { False,    NULL, "hand",           "hand_%d.xbm" },
      { True,           NULL, "polygon",  "polygon_%d.xbm" },
      { True,           NULL, "circle",         "circle_%d.xbm" },
      { True,           NULL, "origin",         "origin_%d.xbm" },
      { True,           NULL, "zoom_out", "zoom_out_%d.xbm" },
      { True,           NULL, "zoom_in",  "zoom_in_%d.xbm" }
      };


#define MAX_ARGS  16
#define APP_CLASS "Gedit"

void  QuitCB(), HelpCB(), ButtonCB(), WindowCB();
void  MenuCB(), FileCB(), ViewCB();
void  InitializeCursors(), SetCursor();
extern      void InitializeTranslations(), DrawWidget(), ClearSelection();
extern      void DetermineObjectExtent();
extern      void CreateMarkerList();
Widget      CreateHelp (), CreateViewsDialog(), CreateRescaleDialog();
Widget  CreateInfoDialog(), CreateGearDialog();
Widget  CreateDerivDialog(), CreatePowerplantDialog();

Widget      help_box;
Widget      view_box = (Widget) NULL;

static      view_info_t t_info, b_info;

main (argc, argv)
int   argc;
char  *argv[];
{

      Widget            toplevel;
      Widget            main_window;
      Widget            menu_bar;
      Widget            menu_pane;
      Widget            button;
      Widget            cascade;
      Widget            top_frame, bottom_frame, main_form, row_col;
      Widget            row_col1, form, index_form;
      int         n, i;
      Arg         args[16];
      char        name[128];
      XmString    label_string;
      XtAppContext      context;
      static int  tw = 1, bw = 2;
      Display           *display;
      Pixmap            pixmap;
      Pixel       fg, bg;
      XGCValues   gcv;
      XmString    string;

      toplevel = XtAppInitialize (&context, APP_CLASS, options,
            XtNumber(options), &argc, argv, fallback, NULL, 0);

      XtGetApplicationResources (toplevel, &app_data, resources,
            XtNumber(resources), NULL, 0);

      n = 0; 
      main_window = XmCreateMainWindow (toplevel, "main", args, n);
      XtManageChild (main_window);

      n = 0;
      menu_bar = XmCreateMenuBar (main_window, "menu_bar", args, n); 
      XtManageChild (menu_bar);

/*
 *  The File menu
 */

      n = 0;
      menu_pane = XmCreatePulldownMenu (menu_bar, "file_menu", args, n);

      n = 0;
      button = XmCreatePushButton (menu_pane, "new", args, n);
      XtManageChild (button);
      XtAddCallback (button, XmNactivateCallback, MenuCB,
            (XtPointer) MENU_NEW);

      n = 0;
      button = XmCreatePushButton (menu_pane, "open", args, n);
      XtManageChild (button);
      XtAddCallback (button, XmNactivateCallback, MenuCB,
            (XtPointer) MENU_OPEN); 
      XmStringFree (string);

      n = 0;
      button = XmCreatePushButton (menu_pane, "save", args, n);
      XtManageChild (button);
      XtAddCallback (button, XmNactivateCallback, MenuCB,
            (XtPointer) MENU_SAVE);
      /* XmStringFree (string); */

      n = 0;
      button = XmCreatePushButton (menu_pane, "save_as", args, n);
      XtManageChild (button);
      XtAddCallback (button, XmNactivateCallback, MenuCB,
            (XtPointer) MENU_SAVE_AS);

      n = 0;
      button = XmCreatePushButton (menu_pane, "exit", args, n);
      XtManageChild (button);
      XtAddCallback (button, XmNactivateCallback, QuitCB, NULL);

      n = 0;
      XtSetArg (args[n], XmNsubMenuId, menu_pane);  n++;
      XtSetArg (args[n], XmNmnemonic, 'F');  n++;
      cascade = XmCreateCascadeButton (menu_bar, "File", args, n);
      XtManageChild (cascade);

/*
 *  The Edit menu
 */

      n = 0;
      menu_pane = XmCreatePulldownMenu (menu_bar, "edit_menu", args, n);

      n = 0;
      button = XmCreatePushButton (menu_pane, "cut", args, n);
      XtManageChild (button);
      XtAddCallback (button, XmNactivateCallback, MenuCB,
            (XtPointer) MENU_CUT);

      n = 0;
      button = XmCreatePushButton (menu_pane, "copy", args, n);
      XtManageChild (button);
      XtAddCallback (button, XmNactivateCallback, MenuCB,
            (XtPointer) MENU_COPY);

      n = 0;
      button = XmCreatePushButton (menu_pane, "paste", args, n);
      XtManageChild (button);
      XtAddCallback (button, XmNactivateCallback, MenuCB,
            (XtPointer) MENU_PASTE);

      n = 0;
      button = XmCreateSeparator (menu_pane, "separator1", args, n);
      XtManageChild (button);

      n = 0;
      button = XmCreatePushButton (menu_pane, "clear", args, n);
      XtManageChild (button);
      XtAddCallback (button, XmNactivateCallback, MenuCB,
            (XtPointer) MENU_CLEAR);

      n = 0;
      button = XmCreateSeparator (menu_pane, "separator2", args, n);
      XtManageChild (button);

      n = 0;
      button = XmCreatePushButton (menu_pane, "rotx", args, n);
      XtManageChild (button);
      XtAddCallback (button, XmNactivateCallback, MenuCB,
            (XtPointer) MENU_ROTATE_X);

      n = 0;
      button = XmCreatePushButton (menu_pane, "mirror_xz", args, n);
      XtManageChild (button);
      XtAddCallback (button, XmNactivateCallback, MenuCB,
            (XtPointer) MENU_MIRROR_XZ);

      n = 0;
      button = XmCreatePushButton (menu_pane, "mirror_xy", args, n);
      XtManageChild (button);
      XtAddCallback (button, XmNactivateCallback, MenuCB,
            (XtPointer) MENU_MIRROR_XY);

      n = 0;
      button = XmCreatePushButton (menu_pane, "mirror_yz", args, n);
      XtManageChild (button);
      XtAddCallback (button, XmNactivateCallback, MenuCB,
            (XtPointer) MENU_MIRROR_YZ);

      n = 0;
      button = XmCreateSeparator (menu_pane, "separator", args, n);
      XtManageChild (button);

      n = 0;
      button = XmCreatePushButton (menu_pane, "rescale", args, n);
      XtManageChild (button);
      XtAddCallback (button, XmNactivateCallback, MenuCB,
            (XtPointer) MENU_RESCALE);

      n = 0;
      XtSetArg (args[n], XmNsubMenuId, menu_pane);  n++;
      XtSetArg (args[n], XmNmnemonic, 'E');  n++;
      cascade = XmCreateCascadeButton (menu_bar, "Edit", args, n);
      XtManageChild (cascade);

/*
 *  The Layout menu
 */

      n = 0;
      menu_pane = XmCreatePulldownMenu (menu_bar, "layout_menu", args, n);

      n = 0;
      string = XmStringCreateSimple ("Show Grid");
      XtSetArg (args[n], XmNlabelString, string);  n++;
      XtSetArg (args[n], XmNset, app_data.show_grid);  n++;
      XtSetArg (args[n], XmNindicatorType, XmN_OF_MANY);  n++;
      XtSetArg (args[n], XmNradioBehavior, False);  n++;
      button = XmCreateToggleButton (menu_pane, "show_grid", args, n);
      XmStringFree (string);
      XtManageChild (button); 
      XtAddCallback (button, XmNvalueChangedCallback, MenuCB,
            (XtPointer) MENU_GRID);

      n = 0;
      string = XmStringCreateSimple ("Show Ruler");
      XtSetArg (args[n], XmNlabelString, string);  n++;
      XtSetArg (args[n], XmNset, app_data.show_ruler);  n++;
      XtSetArg (args[n], XmNindicatorType, XmN_OF_MANY);  n++;
      XtSetArg (args[n], XmNradioBehavior, False);  n++;
      button = XmCreateToggleButton (menu_pane, "show_ruler", args, n);
      XmStringFree (string);
      XtManageChild (button); 
      XtAddCallback (button, XmNvalueChangedCallback, MenuCB,
            (XtPointer) MENU_RULER);

      n = 0;
      button = XmCreateSeparator (menu_pane, "separator", args, n);
      XtManageChild (button); 

      n = 0;
      button = XmCreatePushButton (menu_pane, "set_views", args, n);
      XtManageChild (button);
      XtAddCallback (button, XmNactivateCallback, MenuCB,
            (XtPointer) MENU_SET_VIEWS);

      n = 0;
      XtSetArg (args[n], XmNsubMenuId, menu_pane);  n++;
      XtSetArg (args[n], XmNmnemonic, 'L');  n++;
      cascade = XmCreateCascadeButton (menu_bar, "Layout", args, n);
      XtManageChild (cascade);

      CreateMarkerList (menu_bar);

      n = 0;
      XtSetArg (args[n], XmNmnemonic, 'H');  n++;
      cascade = XmCreateCascadeButton (menu_bar, "Help", args, n);
      XtManageChild (cascade);
      XtAddCallback (cascade, XmNactivateCallback, HelpCB, NULL);

      n = 0;
      XtSetArg (args[n], XmNmenuHelpWidget, cascade);  n++;
      XtSetValues (menu_bar, args, n);

/*
 *  The Aircraft Performance menu
 */

      n = 0;
      menu_pane = XmCreatePulldownMenu (menu_bar, "perf_menu", args, n);

      n = 0;
      button = XmCreatePushButton (menu_pane, "info", args, n);
      XtManageChild (button);
      XtAddCallback (button, XmNactivateCallback, MenuCB,
            (XtPointer) MENU_INFO);
      
      n = 0;
      button = XmCreatePushButton (menu_pane, "gear", args, n);
      XtManageChild (button);
      XtAddCallback (button, XmNactivateCallback, MenuCB,
            (XtPointer) MENU_GEAR);

      n = 0;
      button = XmCreatePushButton (menu_pane, "stability", args, n);
      XtManageChild (button);
      XtAddCallback (button, XmNactivateCallback, MenuCB,
            (XtPointer) MENU_DERIV);

      n = 0;
      button = XmCreatePushButton (menu_pane, "powerplant", args, n);
      XtManageChild (button);
      XtAddCallback (button, XmNactivateCallback, MenuCB,
            (XtPointer) MENU_PWR);

      n = 0;
      XtSetArg (args[n], XmNsubMenuId, menu_pane);  n++;
      XtSetArg (args[n], XmNmnemonic, 'P');  n++;
      cascade = XmCreateCascadeButton (menu_bar, "Performance", args, n);
      XtManageChild (cascade);

/*
 *  The main window hierarchy
 */

      main_form = XtVaCreateWidget ("form", xmFormWidgetClass,
            main_window,
            NULL);

      XtVaSetValues (main_window,
            XmNworkWindow,    main_form,
            NULL);

      index_form = XtVaCreateWidget ("index", xmFormWidgetClass,
            main_form,
            XmNleftAttachment,      XmATTACH_FORM,
            XmNtopAttachment, XmATTACH_FORM,
            XmNbottomAttachment,    XmATTACH_FORM,
            NULL);

      row_col = XtVaCreateWidget ("buttons", xmRowColumnWidgetClass,
            index_form,
            XmNleftAttachment,      XmATTACH_FORM,
            XmNtopAttachment, XmATTACH_FORM,
            NULL);

      XtVaGetValues (row_col,
            XmNforeground,    &fg,
            XmNbackground,    &bg,
            NULL);

      for (i=0; i < XtNumber(button_list); ++i) {

          if (button_list[i].defined_in_this_version) {
          
            sprintf (name, button_list[i].pixmap_file,
                  app_data.button_size);

            pixmap = XmGetPixmap (XtScreen (row_col), name, fg, bg);

            button_list[i].widget = XtVaCreateManagedWidget (
                  button_list[i].name, xmPushButtonWidgetClass, row_col,
                  XmNlabelType,           XmPIXMAP,
                  XmNlabelPixmap,         pixmap,
                  XmNwidth,         64,
                  XmNheight,        64,
                  XmNshadowType,          XmSHADOW_ETCHED_OUT,
                  NULL);

            XtAddCallback (button_list[i].widget,
                  XmNactivateCallback, ButtonCB, (XtPointer) i);
          }

      }

      XtManageChild (row_col);

      row_col1 = XtVaCreateWidget ("coordinates", xmRowColumnWidgetClass,
            index_form,
            XmNleftAttachment,      XmATTACH_FORM,
            XmNrightAttachment,     XmATTACH_FORM,
            XmNtopAttachment, XmATTACH_WIDGET,
            XmNtopWidget,           row_col,
            XmNbottomAttachment,    XmATTACH_FORM,
            NULL);

      x_field = XtVaCreateManagedWidget("x",
            xmTextFieldWidgetClass, row_col1,
            XmNcolumns,    12,
            NULL);

      y_field = XtVaCreateManagedWidget("y",
            xmTextFieldWidgetClass, row_col1,
            XmNcolumns,    12,
            NULL);

      z_field = XtVaCreateManagedWidget("z",
            xmTextFieldWidgetClass, row_col1,
            XmNcolumns,    12,
            NULL);

      XtManageChild (row_col1);
      XtManageChild (index_form);

      top_frame = XtVaCreateManagedWidget ("top_frame", xmFrameWidgetClass,
            main_form,
            XmNtopAttachment, XmATTACH_FORM,
            XmNleftAttachment,      XmATTACH_WIDGET,
            XmNleftWidget,          index_form,
            XmNrightAttachment,     XmATTACH_FORM,
            XmNbottomAttachment,    XmATTACH_POSITION,
            XmNbottomPosition,      50,
            NULL);

      twindow = XmCreateDrawingArea (top_frame, "twindow", args, n);

      XtAddCallback (twindow, XmNexposeCallback, WindowCB, (caddr_t) &tw);
      XtAddCallback (twindow, XmNinputCallback, WindowCB, (caddr_t) &tw);
      XtAddCallback (twindow, XmNresizeCallback, WindowCB, (caddr_t) &tw);

      XtManageChild (twindow);

      bottom_frame = XtVaCreateManagedWidget ("bottom_frame",
            xmFrameWidgetClass, main_form,
            XmNtopAttachment, XmATTACH_WIDGET,
            XmNtopWidget,           top_frame,
            XmNleftAttachment,      XmATTACH_WIDGET,
            XmNleftWidget,          index_form,
            XmNrightAttachment,     XmATTACH_FORM,
            XmNbottomAttachment,    XmATTACH_FORM,
            NULL);

      n = 0;
      bwindow = XmCreateDrawingArea (bottom_frame, "bwindow", args, n);

      XtAddCallback (bwindow, XmNexposeCallback, WindowCB, (caddr_t) &bw);
      XtAddCallback (bwindow, XmNinputCallback, WindowCB, (caddr_t) &bw);
      XtAddCallback (bwindow, XmNresizeCallback, WindowCB, (caddr_t) &bw);

      XtManageChild (bwindow);
      XtManageChild (main_form);

      InitializeTranslations (context, twindow, bwindow);

/*
 *  File dialogs
 */

      n = 0;
      open_dialog = XmCreateFileSelectionDialog (toplevel, "open_d", args, n);
      XtAddCallback (open_dialog, XmNokCallback, FileCB, (XtPointer) MENU_OPEN);

      n = 0;
      save_as_dialog = XmCreatePromptDialog (toplevel, "save_as_d", args, n);
      XtAddCallback (save_as_dialog, XmNokCallback, FileCB, (XtPointer) MENU_SAVE_AS);

      n = 0;
      row_col = XmCreateRadioBox (save_as_dialog, "file_formats", args, n);
      XtManageChild (row_col);

      save_formats[0] = XtVaCreateManagedWidget ("gedit_format",
            xmToggleButtonWidgetClass, row_col,
            NULL);

      save_formats[1] = XtVaCreateManagedWidget ("v_format",
            xmToggleButtonWidgetClass, row_col,
            NULL);

      save_formats[2] = XtVaCreateManagedWidget ("rayshade_format",
            xmToggleButtonWidgetClass, row_col,
            NULL);

      set_views_dialog = CreateViewsDialog (toplevel);

      rescale_dialog = CreateRescaleDialog (toplevel);

      info_dialog = CreateInfoDialog(toplevel);
      
      gear_dialog = CreateGearDialog(toplevel);

      deriv_dialog = CreateDerivDialog(toplevel);

      powerplant_dialog = CreatePowerplantDialog(toplevel);

/*
 *  We logically cross-connect each of the two drawing areas with a data
 *  structure that is hung off each widget's userData field.
 */

      display = XtDisplay (twindow);
      t_info.flags = 0;
      t_info.other_view = &b_info;
      t_info.layout = VL_NXZ;
      t_info.other_widget = bwindow;
      t_info.other_window = XtWindow (bwindow);
      gcv.graphics_exposures = False;
      gcv.line_style = LineOnOffDash;
      gcv.font = app_data.ruler_font->fid;
      t_info.gc = XCreateGC (display,
            RootWindow(display, DefaultScreen(display)),
            GCGraphicsExposures | GCFont, &gcv);
      t_info.erase_gc = XCreateGC (display,
            RootWindow(display, DefaultScreen(display)),
            GCGraphicsExposures, &gcv);
      t_info.grid_gc = XCreateGC (display,
            RootWindow(display, DefaultScreen(display)),
            GCGraphicsExposures | GCLineStyle, &gcv);
      XSetDashes (display, t_info.grid_gc, 0, grid_dash_list, 2);

      XtVaSetValues (twindow,
            XmNuserData,      &t_info,
            NULL);

      display = XtDisplay (twindow);
      b_info.flags = 0;
      b_info.other_view = &t_info;
      b_info.layout = VL_NXNY;
      b_info.other_widget = twindow;
      b_info.other_window = XtWindow (twindow);
      b_info.gc = XCreateGC (display,
            RootWindow(display, DefaultScreen(display)),
            GCGraphicsExposures | GCFont, &gcv);
      b_info.erase_gc = XCreateGC (display,
            RootWindow(display, DefaultScreen(display)),
            GCGraphicsExposures, &gcv);
      b_info.grid_gc = XCreateGC (display,
            RootWindow(display, DefaultScreen(display)),
            GCGraphicsExposures | GCLineStyle, &gcv);
      XSetDashes (display, b_info.grid_gc, 0, grid_dash_list, 2);

      XtVaSetValues (bwindow,
            XmNuserData,      &b_info,
            NULL);

      help_box = CreateHelp (toplevel);

      edit_state = STATE_POINT;
      cur_polygon = (polygon_t *) NULL;
      polygon_max = 256;
      polygon_list = (polygon_t *) malloc (polygon_max * sizeof (polygon_t));
      sel_polygon = unsel_polygon = clipboard_polygon = -1;
      drag_mode = False;

      for (i=0; i<polygon_max; ++i) {
            polygon_list[i].id = i;
            polygon_list[i].num_points = 0;
            polygon_list[i].next = -1;
      }

      polygon_count = 0;
      tmp_point_max = 128;
      tmp_point = (point_t *) malloc (tmp_point_max * sizeof (point_t));

      pixel_scale = 0.125;
      app_data.box_offset = - app_data.box_size / 2;

      filename_valid = False;
      strcpy (filename, "Untitled");

      desired_view = VIEW_LEFT_TOP;

      XtRealizeWidget (toplevel);

      InitializeCursors ();
      SetCursor (CURSOR_POINT);

      XtAppMainLoop (context);
}

Widget
CreateHelp (parent) 
Widget            parent;
{

      Widget            button;
      Widget            message_box;
      Arg         args[MAX_ARGS];
      register int      n;

      static char message[BUFSIZ];
      XmString    title_string = NULL;
      XmString    message_string = NULL;
      XmString    button_string = NULL;

      sprintf (message, "\
Gedit:  A Three Dimensional Object Editor\n\
\n\
Copyright (c) 1991  Riley Rainey\n\
\n\n\
\0");

      message_string = XmStringCreateLtoR (message, charset);
      button_string = XmStringCreateLtoR ("Continue", charset);
      title_string = XmStringCreateLtoR ("graphics editor help", charset);

      n = 0;
      XtSetArg (args[n], XmNdialogTitle, title_string);  n++;
      XtSetArg (args[n], XmNokLabelString, button_string);  n++;
      XtSetArg (args[n], XmNmessageString, message_string);  n++;
      message_box = XmCreateMessageDialog (parent, "help_box", args, n);

      button = XmMessageBoxGetChild (message_box, XmDIALOG_CANCEL_BUTTON);
      XtUnmanageChild (button);
      button = XmMessageBoxGetChild (message_box, XmDIALOG_HELP_BUTTON);
      XtUnmanageChild (button);

      if (title_string)
            XtFree (title_string);
      if (message_string)
            XtFree (message_string);
      if (button_string)
            XtFree (button_string);

      return (message_box);
}

Widget
CreateViewsDialog (parent)
Widget parent;
{

      XmString string;
      extern Widget CreateExtendedFormDialog();
      Arg args[10];
      static ActionAreaButton action_items[] = {
            { "Ok",     MenuCB,     (XtPointer) MENU_SET_VIEWS_COMPLETE},
            { "Cancel", MenuCB,     (XtPointer) MENU_SET_VIEWS_CANCEL},
            { "Help",   NULL, NULL  },
      };
      Widget      dialog, string_w, form, box;

      dialog = CreateExtendedFormDialog("dialog", parent, &form, action_items,
            XtNumber (action_items), 0); 

      string = XmStringCreateSimple("Select the desired views:");
      string_w = XtVaCreateManagedWidget("label", xmLabelGadgetClass, form,
            XmNlabelString,    string,
            XmNleftAttachment, XmATTACH_FORM,
            XmNtopAttachment,  XmATTACH_FORM,
            NULL);
      XmStringFree(string);

      box = XmVaCreateSimpleRadioBox (form, "box", 0, ViewCB,
            XmVaRADIOBUTTON,
            XmStringCreateSimple("Left side / Top"), NULL, NULL, NULL,
            XmVaRADIOBUTTON,
            XmStringCreateSimple("Front / Top"), NULL, NULL, NULL,
            XmNleftAttachment,      XmATTACH_FORM,
            XmNrightAttachment,     XmATTACH_FORM,
            XmNtopAttachment, XmATTACH_WIDGET,
            XmNtopWidget,           string_w,
            NULL);

      XtManageChild (box);
      XtManageChild (form);
      return dialog;

}

Widget
CreateRescaleDialog (parent)
Widget parent;
{

      XmString string;
      extern Widget CreateExtendedFormDialog();
      Arg args[10];
      VPoint extent;
      static ActionAreaButton action_items[] = {
            { "Apply",     MenuCB,  (XtPointer) MENU_RESCALE_APPLY},
            { "Cancel", MenuCB,     (XtPointer) MENU_RESCALE_CANCEL},
            { "Help",   NULL, NULL  },
      };
      Widget      dialog, string_w, prompt, form;

      dialog = CreateExtendedFormDialog("rescale_dialog", parent, &form,
            action_items, XtNumber (action_items), 0); 

      string = XmStringCreateSimple("Current object dimensions:");
      string_w = XtVaCreateManagedWidget("label", xmLabelGadgetClass, form,
            XmNlabelString,    string,
            XmNleftAttachment, XmATTACH_FORM,
            XmNtopAttachment,  XmATTACH_FORM,
            NULL);
      XmStringFree(string);

      extent_x = XtVaCreateManagedWidget("label_x", xmLabelGadgetClass, form,
            XmNleftAttachment, XmATTACH_FORM,
            XmNtopAttachment,  XmATTACH_WIDGET,
            XmNtopWidget,        string_w,
            NULL);

      extent_y = XtVaCreateManagedWidget("label_y", xmLabelGadgetClass, form,
            XmNleftAttachment, XmATTACH_FORM,
            XmNtopAttachment,  XmATTACH_WIDGET,
            XmNtopWidget,        extent_x,
            NULL);

      extent_z = XtVaCreateManagedWidget("label_z", xmLabelGadgetClass, form,
            XmNleftAttachment, XmATTACH_FORM,
            XmNtopAttachment,  XmATTACH_WIDGET,
            XmNtopWidget,        extent_y,
            NULL);

      string = XmStringCreateSimple("Enter the object scaling factor:");
      prompt = XtVaCreateManagedWidget("label_z", xmLabelGadgetClass, form,
            XmNlabelString,    string,
            XmNleftAttachment, XmATTACH_FORM,
            XmNtopAttachment,  XmATTACH_WIDGET,
            XmNtopWidget,        extent_z,
            NULL);
      XmStringFree(string);

      rescale_field = XtVaCreateManagedWidget("rescale_field",
            xmTextFieldWidgetClass, form,
            XmNleftAttachment, XmATTACH_FORM,
            XmNtopAttachment,  XmATTACH_WIDGET,
            XmNtopWidget,        prompt,
            XmNcolumns,    32,
            NULL);

      XtManageChild (form);
      return dialog;

}

void
ViewCB (w, client_data, call_data)
Widget      w;
caddr_t     client_data;
caddr_t call_data;
{
      register XmToggleButtonCallbackStruct     *cbs =
            (XmToggleButtonCallbackStruct *) call_data;
      register int id = (int) client_data;

      if (cbs->set == False)
            return;

      if (id == 0)
            desired_view = VIEW_LEFT_TOP;
      else
            desired_view = VIEW_FRONT_TOP;

}

void
QuitCB (w, client_data, call_data)
Widget      w;
caddr_t     client_data;
caddr_t call_data;
{

      exit (0);
}

void
HelpCB (w, client_data, call_data)
Widget      w;
caddr_t     client_data;
caddr_t call_data;
{

      XtManageChild (help_box);
}

void
ButtonCB (w, client_data, call_data)
Widget      w;
caddr_t     client_data;
caddr_t call_data;
{

      switch ((int) client_data) {

      case 0:
            edit_state = STATE_POINT;
            SetCursor (CURSOR_POINT);
            break;

      case 1:
            break;

      case 2:
            edit_state = STATE_POLYGON;
            SetCursor (CURSOR_POLY);
            break;

      case 3:
            edit_state = STATE_CIRCLE;
            SetCursor (CURSOR_CIRCLE);
            break;

      case 4:
            edit_state = STATE_MOVE_ORIGIN;
            SetCursor (CURSOR_ORIGIN);
            break;

      case 5:
            RescaleView(twindow, 1 / 1.2);
            XmProcessTraversal (button_list[0].widget, XmTRAVERSE_CURRENT);
            edit_state = STATE_POINT;
            SetCursor (CURSOR_POINT);
            break;

      case 6:
            RescaleView(twindow, 1.2);
            XmProcessTraversal (button_list[0].widget, XmTRAVERSE_CURRENT);
            edit_state = STATE_POINT;
            SetCursor (CURSOR_POINT);
            break;

      default:
            printf ("button %d\n", (int) client_data);

      }
}

void
MenuCB (w, client_data, call_data)
Widget      w;
caddr_t     client_data;
caddr_t call_data;
{

      register int      menu_id = (int) client_data;
      extern void Mirror();
      Boolean           value;
      VPoint            extent;
      XmString    string;
      char        s[64], *factor_s;
      double            factor;

      if (menu_id >= MENU_MARKER && menu_id < MENU_MARKER+32) {
            current_marker = menu_id - MENU_MARKER;
            if (marker_list[current_marker].defined)
                  DisplayPoint(&marker_list[current_marker].location);
            SetCursor (CURSOR_MARKER);
            edit_state = STATE_MARKER;
            return;
      }

      switch (menu_id) {

      case MENU_MIRROR_XZ:
      case MENU_MIRROR_XY:
      case MENU_MIRROR_YZ:
            Mirror (menu_id);
            break;

      case MENU_CLEAR:
            ClearSelection();
            break;

      case MENU_COPY:
            CopySelection();
            break;

      case MENU_PASTE:
            PasteSelection();
            break;

      case MENU_ROTATE_X:
            RotateXSelection();
            break;

      case MENU_SAVE:
            if (filename_valid)
                  WriteGeditFile (filename);
            else
                  XtManageChild (save_as_dialog);
            break;

      case MENU_GRID:
            XtVaGetValues (w,
                  XmNset,     &value,
                  NULL);

            if (value != app_data.show_grid) {
                  app_data.show_grid = value;
                  DrawWidget (twindow, False);
                  DrawWidget (bwindow, False);
            }
            else {
                  app_data.show_grid = value;
            }
            break;

      case MENU_RULER:
            XtVaGetValues (w,
                  XmNset,     &value,
                  NULL);

            if (value != app_data.show_ruler) {
                  app_data.show_ruler = value;
                  DrawWidget (twindow, False);
                  DrawWidget (bwindow, False);
            }
            else {
                  app_data.show_ruler = value;
            }
            break;

      case MENU_OPEN:
            XtManageChild (open_dialog);
            break;

      case MENU_SAVE_AS:
            XtManageChild (save_as_dialog);
            break;

      case MENU_SET_VIEWS:
            XtManageChild (set_views_dialog);
            break;

      case MENU_SET_VIEWS_COMPLETE:
            switch (desired_view) {

            case VIEW_LEFT_TOP:
                  t_info.layout = VL_NXZ;
                  b_info.layout = VL_NXNY;
                  break;

            case VIEW_FRONT_TOP:
                  t_info.layout = VL_NYZ;
                  b_info.layout = VL_NYX;
                  break;
            }

            RescaleView (twindow, 1.0);
            XtUnmanageChild (set_views_dialog);
            break;

      case MENU_SET_VIEWS_CANCEL:
            XtUnmanageChild (set_views_dialog);
            break;

      case MENU_RESCALE:
            DetermineObjectExtent (&extent);

            sprintf (s, "   %s :   %f", "X", extent.x);
            string = XmStringCreateSimple(s);
            XtVaSetValues (extent_x,
                  XmNlabelString, string,
                  NULL);
            XmStringFree (string);

            sprintf (s, "   %s :   %f", "Y", extent.y);
            string = XmStringCreateSimple(s);
            XtVaSetValues (extent_y,
                  XmNlabelString, string,
                  NULL);
            XmStringFree (string);

            sprintf (s, "   %s :   %f", "Z", extent.z);
            string = XmStringCreateSimple(s);
            XtVaSetValues (extent_z,
                  XmNlabelString, string,
                  NULL);
            XmStringFree (string);

            XtManageChild (rescale_dialog);
            break;

      case MENU_RESCALE_APPLY:
            factor_s = XmTextFieldGetString (rescale_field);
            factor = atof(factor_s);
            if (factor != 0.0)
                  RescaleObject (factor);
            break;

      case MENU_RESCALE_CANCEL:
            XtUnmanageChild (rescale_dialog);
            break;
            
      case MENU_GEAR:
            XtManageChild (gear_dialog);
            break;

      case MENU_GEAR_CANCEL:
            GetCraftInfo (&c);
            XtUnmanageChild (gear_dialog);
            break;

      case MENU_GEAR_CALCULATE:
            GearCalculate (&c);
            GetCraftInfo (&c);
            break;

      case MENU_INFO:
            XtManageChild (info_dialog);
            break;

      case MENU_INFO_CANCEL:
            GetCraftInfo (&c);
            XtUnmanageChild (info_dialog);
            break;

      case MENU_INFO_CALCULATE:
            GetCraftInfo (&c);
            break;

      case MENU_DERIV:
            XtManageChild (deriv_dialog);
            break;

      case MENU_DERIV_CANCEL:
            GetCraftInfo (&c);
            XtUnmanageChild (deriv_dialog);
            break;

      case MENU_DERIV_CALCULATE:
            GetCraftInfo (&c);
            break;

      case MENU_PWR:
            XtManageChild (powerplant_dialog);
            break;

      case MENU_PWR_CANCEL:
            GetCraftInfo (&c);
            XtUnmanageChild (powerplant_dialog);
            break;

      case MENU_PWR_CALCULATE:
            GetCraftInfo (&c);
            break;
      }

}

void
FileCB (w, client_data, call_data)
Widget      w;
caddr_t     client_data;
caddr_t call_data;
{
      register int      menu_id = (int) client_data, i;
      register XmSelectionBoxCallbackStruct     *p =
            (XmSelectionBoxCallbackStruct *) call_data;
      char  *value;
      Boolean     state;
      extern int  ReadGeditFile(), WriteGeditFile();

      XmStringGetLtoR (p->value, charset, &value);

      switch (menu_id) {

      case MENU_OPEN:
            ReadGeditFile (value);
            break;

      case MENU_SAVE_AS:
            for (i=0; i < 3; ++i) {

                  XtVaGetValues (save_formats[i],
                        XmNset,           &state,
                        NULL);

                  if (state) {
                        switch (i) {

                        case 0:
                              WriteGeditFile (value);
                              break;
                        case 1:
                              WriteVFile (value);
                              break;
                        }

                        break;
                  }
            }
            break;
      }

      strcpy (filename, value);
      filename_valid = True;

      XtFree (value);
}

void
AllocPixmap (w, width, height)
Widget      w;
Dimension   width, height;
{

      Pixel       bg;
      view_info_t *p;
      Display           *d;
      int         depth;

      d = XtDisplay (w);

      XtVaGetValues (w,
            XmNbackground,    &bg,
            XmNuserData,      &p,
            XmNdepth,   &depth,
            NULL);

      if (p->flags & VI_PIXMAP_ALLOCATED)
            XFreePixmap (d, p->pixmap);

      p->pixmap = XCreatePixmap (d, RootWindow (d, DefaultScreen(d)),
            width, height, depth);

      XSetForeground (d, p->erase_gc, bg);
      XSetLineAttributes (d, p->erase_gc, app_data.selection_thickness,
            LineSolid, CapButt, JoinMiter);

      XFillRectangle (d, p->pixmap, p->erase_gc, 0, 0, width, height);

      p->width = width;
      p->height = height;
      p->flags |= VI_PIXMAP_ALLOCATED;
}


void
WindowCB (w, client_data, call_data)
Widget      w;
caddr_t     client_data;
caddr_t call_data;
{

      register XmDrawingAreaCallbackStruct      *q;
      view_info_t *p;

      q = (XmDrawingAreaCallbackStruct *) call_data;

      XtVaGetValues (w,
            XmNuserData,      &p,
            NULL);

      switch (q->reason) {

      case XmCR_EXPOSE:
            if ((p->flags & VI_PIXMAP_ALLOCATED) == 0) {
                  XtVaGetValues (w,
                        XmNwidth,   &p->width,
                        XmNheight,  &p->height,
                        NULL);
                  AllocPixmap (w, p->width, p->height);
            }
            XCopyArea (XtDisplay(w), p->pixmap, XtWindow(w),
                  p->gc, 0, 0, p->width, p->height, 0, 0);
            break;

      case XmCR_RESIZE:
            XtVaGetValues (w,
                  XmNwidth,   &p->width,
                  XmNheight,  &p->height,
                  NULL);
            AllocPixmap (w, p->width, p->height);
            p->origin_x = (p->width + 1) / 2;
            p->origin_y = (p->height + 1) / 2;
            DrawWidget (w, False);
            break;

      }

}

void
InitializeCursors()
{

      unsigned long     fg = 1, bg = 0;
      XColor            colors[2];
      Drawable    d;
      Display           *dpy;
      Pixmap            source, mask;
      Colormap    cmap;

      dpy = XtDisplay (twindow);
      d = RootWindow(dpy, DefaultScreen(dpy));

      XtVaGetValues (twindow,
            XmNcolormap,      &cmap,
            NULL);

      cursors[CURSOR_POINT] = XCreateFontCursor (dpy, XC_left_ptr);

      source = XCreatePixmapFromBitmapData (dpy, d, curs_poly_bits,
            curs_poly_width, curs_poly_height,
            fg, bg, 1);
      mask = XCreatePixmapFromBitmapData (dpy, d, curs_poly_mask_bits,
            curs_poly_width, curs_poly_height,
            fg, bg, 1);

      colors[0].pixel = app_data.cursor_foreground;
      colors[1].pixel = app_data.cursor_background;
      XQueryColors (dpy, cmap, colors, 2);

      cursors[CURSOR_POLY] = XCreatePixmapCursor (dpy, source,
            mask, &colors[0], &colors[1],
            curs_poly_x_hot, curs_poly_y_hot);
      XFreePixmap (dpy, source);
      XFreePixmap (dpy, mask);

      source = XCreatePixmapFromBitmapData (dpy, d, curs_marker_bits,
            curs_marker_width, curs_marker_height,
            fg, bg, 1);
      mask = XCreatePixmapFromBitmapData (dpy, d, curs_marker_mask_bits,
            curs_marker_width, curs_marker_height,
            fg, bg, 1);

      cursors[CURSOR_MARKER] = XCreatePixmapCursor (dpy, source,
            mask, &colors[0], &colors[1],
            curs_marker_x_hot, curs_marker_y_hot);
      XFreePixmap (dpy, source);
      XFreePixmap (dpy, mask);

      cursors[CURSOR_ORIGIN] = XCreateFontCursor (dpy, XC_crosshair);

}

void SetCursor (id)
int   id;
{

      Cursor cursor;

      switch (id) {

      case CURSOR_POINT:
            cursor = cursors[CURSOR_POINT];
            break;

      case CURSOR_POLY_PLANE:
            cursor = cursors[CURSOR_POLY];
            break;

      case CURSOR_CIRCLE:
      case CURSOR_POLY:
            cursor = cursors[CURSOR_POLY];
            break;

      case CURSOR_ORIGIN:
            cursor = cursors[CURSOR_ORIGIN];
            break;

      case CURSOR_MARKER:
            cursor = cursors[CURSOR_MARKER];
            break;
      }

      XDefineCursor (XtDisplay(twindow), XtWindow(twindow), cursor);
      XDefineCursor (XtDisplay(bwindow), XtWindow(bwindow), cursor);
}

Generated by  Doxygen 1.6.0   Back to index