home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / amiga / gui / x / xfig.lha / src / x11 / w_modepanel.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-26  |  13.4 KB  |  406 lines

  1. /*
  2.  * FIG : Facility for Interactive Generation of figures
  3.  * Copyright (c) 1991 by Paul King
  4.  *
  5.  * "Permission to use, copy, modify, distribute, and sell this software and its
  6.  * documentation for any purpose is hereby granted without fee, provided that
  7.  * the above copyright notice appear in all copies and that both the copyright
  8.  * notice and this permission notice appear in supporting documentation. 
  9.  * No representations are made about the suitability of this software for 
  10.  * any purpose.  It is provided "as is" without express or implied warranty."
  11.  */
  12.  
  13. #include "fig.h"
  14. #include "figx.h"
  15. #include "resources.h"
  16. #include "mode.h"
  17. #include "object.h"
  18. #include "paintop.h"
  19. #include "w_drawprim.h"
  20. #include "w_icons.h"
  21. #include "w_indpanel.h"
  22. #include "w_util.h"
  23. #include "w_mousefun.h"
  24. #include "w_setup.h"
  25.  
  26. extern          finish_text_input();
  27. extern          erase_objecthighlight();
  28.  
  29. extern          circlebyradius_drawing_selected();
  30. extern          circlebydiameter_drawing_selected();
  31. extern          ellipsebyradius_drawing_selected();
  32. extern          ellipsebydiameter_drawing_selected();
  33. extern          box_drawing_selected();
  34. extern          arcbox_drawing_selected();
  35. extern          line_drawing_selected();
  36. extern          regpoly_drawing_selected();
  37. extern          epsobj_drawing_selected();
  38. extern          text_drawing_selected();
  39. extern          arc_drawing_selected();
  40. extern          spline_drawing_selected();
  41. extern          intspline_drawing_selected();
  42. extern          align_selected();
  43. extern          compound_selected();
  44. extern          break_selected();
  45. extern          scale_selected();
  46. extern          point_adding_selected();
  47. extern          delete_point_selected();
  48. extern          move_selected();
  49. extern          move_point_selected();
  50. extern          delete_selected();
  51. extern          copy_selected();
  52. extern          rotate_cw_selected();
  53. extern          rotate_ccw_selected();
  54. extern          flip_ud_selected();
  55. extern          flip_lr_selected();
  56. extern          convert_selected();
  57. extern          arrow_head_selected();
  58. extern          edit_item_selected();
  59. extern          update_selected();
  60.  
  61. /**************        local variables and routines   **************/
  62.  
  63. #define MAX_MODEMSG_LEN 80
  64. typedef struct mode_switch_struct {
  65.     PIXRECT         icon;
  66.     int             mode;
  67.     int             (*setmode_func) ();
  68.     int             objmask;
  69.     int             indmask;
  70.     char            modemsg[MAX_MODEMSG_LEN];
  71.     TOOL            widget;
  72.     Pixmap          normalPM, reversePM;
  73. }               mode_sw_info;
  74.  
  75. #define        setmode_action(z)    (z->setmode_func)(z)
  76.  
  77. DeclareStaticArgs(13);
  78. /* pointer to current mode switch */
  79. static mode_sw_info *current = NULL;
  80.  
  81. /* button selection event handler */
  82. static void     sel_mode_but();
  83. static void     turn_on();
  84.  
  85. static mode_sw_info mode_switches[] = {
  86.     {&cirrad_ic, F_CIRCLE_BY_RAD, circlebyradius_drawing_selected, M_NONE,
  87.     I_BOX, "CIRCLE drawing: specify RADIUS",},
  88.     {&cirdia_ic, F_CIRCLE_BY_DIA, circlebydiameter_drawing_selected, M_NONE,
  89.     I_BOX, "CIRCLE drawing: specify DIAMETER",},
  90.     {&ellrad_ic, F_ELLIPSE_BY_RAD, ellipsebyradius_drawing_selected, M_NONE,
  91.     I_ELLIPSE, "ELLIPSE drawing: specify RADII",},
  92.     {&elldia_ic, F_ELLIPSE_BY_DIA, ellipsebydiameter_drawing_selected, M_NONE,
  93.     I_ELLIPSE, "ELLIPSE drawing: specify DIAMETERS",},
  94.     {&c_spl_ic, F_CLOSED_SPLINE, spline_drawing_selected, M_NONE,
  95.     I_CLOSED, "CLOSED SPLINE drawing: specify control points",},
  96.     {&spl_ic, F_SPLINE, spline_drawing_selected, M_NONE,
  97.     I_OPEN, "SPLINE drawing: specify control points",},
  98.     {&c_intspl_ic, F_CLOSED_INTSPLINE, intspline_drawing_selected, M_NONE,
  99.     I_CLOSED, "CLOSED INTERPOLATED SPLINE drawing",},
  100.     {&intspl_ic, F_INTSPLINE, intspline_drawing_selected, M_NONE,
  101.     I_OPEN, "INTERPOLATED SPLINE drawing",},
  102.     {&polygon_ic, F_POLYGON, line_drawing_selected, M_NONE,
  103.     I_CLOSED, "POLYGON drawing",},
  104.     {&line_ic, F_POLYLINE, line_drawing_selected, M_NONE,
  105.     I_OPEN, "POLYLINE drawing",},
  106.     {&box_ic, F_BOX, box_drawing_selected, M_NONE,
  107.     I_BOX, "Rectangular BOX drawing",},
  108.     {&arc_box_ic, F_ARC_BOX, arcbox_drawing_selected, M_NONE,
  109.     I_ARCBOX, "Rectangular BOX drawing with ROUNDED CORNERS",},
  110.     {®poly_ic, F_REGPOLY, regpoly_drawing_selected, M_NONE,
  111.     I_REGPOLY, "Regular Polygon",},
  112.     {&arc_ic, F_CIRCULAR_ARC, arc_drawing_selected, M_NONE,
  113.     I_ARC, "ARC drawing: specify three points on the arc",},
  114.     {&epsobj_ic, F_EPSOBJ, epsobj_drawing_selected, M_NONE,
  115.     I_EPSOBJ, "Encapsulated Postscript Object",},
  116.     {&text_ic, F_TEXT, text_drawing_selected, M_TEXT_NORMAL,
  117.     I_TEXT, "TEXT input (from keyboard)",},
  118.     {&glue_ic, F_GLUE, compound_selected, M_ALL,
  119.     I_MIN2, "GLUE objects into COMPOUND object",},
  120.     {&break_ic, F_BREAK, break_selected, M_COMPOUND,
  121.     I_MIN1, "BREAK COMPOUND object",},
  122.     {&scale_ic, F_SCALE, scale_selected, M_NO_TEXT,
  123.     I_MIN2, "SCALE objects",},
  124.     {&align_ic, F_ALIGN, align_selected, M_COMPOUND,
  125.     I_ALIGN, "ALIGN objects within a COMPOUND or to CANVAS",},
  126.     {&movept_ic, F_MOVE_POINT, move_point_selected, M_NO_TEXT,
  127.     I_ADDMOVPT, "MOVE POINTs",},
  128.     {&move_ic, F_MOVE, move_selected, M_ALL,
  129.     I_MIN3, "MOVE objects",},
  130.     {&addpt_ic, F_ADD_POINT, point_adding_selected, M_VARPTS_OBJECT,
  131.     I_ADDMOVPT, "ADD POINTs (to lines, polygons and splines)",},
  132.     {©_ic, F_COPY, copy_selected, M_ALL,
  133.     I_MIN3, "COPY objects",},
  134.     {&deletept_ic, F_DELETE_POINT, delete_point_selected, M_VARPTS_OBJECT,
  135.     I_MIN1, "DELETE POINTs (from lines, polygons and splines)",},
  136.     {&delete_ic, F_DELETE, delete_selected, M_ALL,
  137.     I_MIN1, "DELETE objects",},
  138.     {&update_ic, F_UPDATE, update_selected, M_ALL,
  139.     I_OBJECT, "UPDATE object <-> current settings",},
  140.     {&change_ic, F_EDIT, edit_item_selected, M_ALL,
  141.     I_MIN1, "CHANGE OBJECT via EDIT pane",},
  142.     {&flip_x_ic, F_FLIP, flip_ud_selected, M_NO_TEXT,
  143.     I_MIN1, "FLIP objects up or down",},
  144.     {&flip_y_ic, F_FLIP, flip_lr_selected, M_NO_TEXT,
  145.     I_MIN1, "FLIP objects left or right",},
  146.     {&rotCW_ic, F_ROTATE, rotate_cw_selected, M_ALL,
  147.     I_ROTATE, "ROTATE objects clockwise",},
  148.     {&rotCCW_ic, F_ROTATE, rotate_ccw_selected, M_ALL,
  149.     I_ROTATE, "ROTATE objects counter-clockwise",},
  150.     {&convert_ic, F_CONVERT, convert_selected,
  151.     (M_POLYLINE_LINE | M_POLYLINE_POLYGON | M_SPLINE_INTERP), I_MIN1,
  152.     "CONVERT lines (polygons) into splines (closed-splines) or vice versa",},
  153.     {&autoarrow_ic, F_AUTOARROW, arrow_head_selected, M_OPEN_OBJECT,
  154.     I_MIN1 | I_LINEWIDTH, "ADD/DELETE ARROWs",},
  155. };
  156.  
  157. #define        NUM_MODE_SW    (sizeof(mode_switches) / sizeof(mode_sw_info))
  158.  
  159. static Arg      button_args[] =
  160. {
  161.      /* 0 */ {XtNlabel, (XtArgVal) "    "},
  162.      /* 1 */ {XtNwidth, (XtArgVal) 0},
  163.      /* 2 */ {XtNheight, (XtArgVal) 0},
  164.      /* 3 */ {XtNresizable, (XtArgVal) False},
  165.      /* 4 */ {XtNborderWidth, (XtArgVal) 0},
  166.      /* 5 */ {XtNresize, (XtArgVal) False},    /* keeps buttons from being
  167.                          * resized when there are not
  168.                          * a multiple of three of
  169.                          * them */
  170.      /* 6 */ {XtNbackgroundPixmap, (XtArgVal) NULL},
  171. };
  172.  
  173. static XtActionsRec mode_actions[] =
  174. {
  175.     {"EnterModeSw", (XtActionProc) draw_mousefun_mode},
  176.     {"LeaveModeSw", (XtActionProc) clear_mousefun},
  177.     {"PressMiddle", (XtActionProc) notused_middle},
  178.     {"ReleaseMiddle", (XtActionProc) clear_middle},
  179.     {"PressRight", (XtActionProc) notused_right},
  180.     {"ReleaseRight", (XtActionProc) clear_right},
  181. };
  182.  
  183. static String   mode_translations =
  184. "<EnterWindow>:EnterModeSw()highlight()\n\
  185.     <Btn1Down>:\n\
  186.     <Btn1Up>:\n\
  187.     <Btn2Down>:PressMiddle()\n\
  188.     <Btn2Up>:ReleaseMiddle()\n\
  189.     <Btn3Down>:PressRight()\n\
  190.     <Btn3Up>:ReleaseRight()\n\
  191.     <LeaveWindow>:LeaveModeSw()unhighlight()\n";
  192.  
  193. int
  194. init_mode_panel(tool)
  195.     TOOL            tool;
  196. {
  197.     register int    i;
  198.     register mode_sw_info *sw;
  199.  
  200.     FirstArg(XtNwidth, MODEPANEL_WD);
  201.     NextArg(XtNhSpace, INTERNAL_BW);
  202.     NextArg(XtNvSpace, INTERNAL_BW);
  203.     NextArg(XtNtop, XtChainTop);
  204.     NextArg(XtNbottom, XtChainTop);
  205.     NextArg(XtNfromVert, msg_form);
  206.     NextArg(XtNvertDistance, -INTERNAL_BW);
  207.     NextArg(XtNleft, XtChainLeft);
  208.     NextArg(XtNright, XtChainLeft);
  209.     NextArg(XtNresizable, False);
  210.     NextArg(XtNborderWidth, 0);
  211.     NextArg(XtNmappedWhenManaged, False);
  212.  
  213.     mode_panel = XtCreateWidget("mode_panel", boxWidgetClass, tool,
  214.                 Args, ArgCount);
  215.  
  216.     XtAppAddActions(tool_app, mode_actions, XtNumber(mode_actions));
  217.  
  218.     for (i = 0; i < NUM_MODE_SW; ++i) {
  219.     sw = &mode_switches[i];
  220.     if (sw->mode == FIRST_DRAW_MODE) {
  221.         FirstArg(XtNwidth, MODE_SW_WD * SW_PER_ROW +
  222.              INTERNAL_BW * (SW_PER_ROW - 1));
  223.         NextArg(XtNborderWidth, 0);
  224.         NextArg(XtNresize, False);
  225.         NextArg(XtNheight, (MODEPANEL_SPACE + 1) / 2);
  226.         NextArg(XtNlabel, "Drawing\n modes");
  227.         d_label = XtCreateManagedWidget("label", labelWidgetClass,
  228.                         mode_panel, Args, ArgCount);
  229.     } else if (sw->mode == FIRST_EDIT_MODE) {
  230.         /* assume Args still set up from d_label */
  231.         ArgCount -= 2;
  232.         NextArg(XtNheight, (MODEPANEL_SPACE) / 2);
  233.         NextArg(XtNlabel, "Editing\n modes");
  234.         e_label = XtCreateManagedWidget("label", labelWidgetClass,
  235.                         mode_panel, Args, ArgCount);
  236.     }
  237.     button_args[1].value = sw->icon->width;
  238.     button_args[2].value = sw->icon->height;
  239.     sw->widget = XtCreateManagedWidget("button", commandWidgetClass,
  240.                 mode_panel, button_args, XtNumber(button_args));
  241.  
  242.     /* left button changes mode */
  243.     XtAddEventHandler(sw->widget, ButtonPressMask, (Boolean) 0,
  244.               sel_mode_but, (XtPointer) sw);
  245.     XtOverrideTranslations(sw->widget,
  246.                    XtParseTranslationTable(mode_translations));
  247.     }
  248.     return;
  249. }
  250.  
  251. /*
  252.  * after panel widget is realized (in main) put some bitmaps etc. in it
  253.  */
  254.  
  255. setup_mode_panel()
  256. {
  257.     register int    i;
  258.     register mode_sw_info *msw;
  259.     register Display *d = tool_d;
  260.     register Screen *s = tool_s;
  261.  
  262.     blank_gc = XCreateGC(tool_d, XtWindow(mode_panel), (unsigned long) 0, NULL);
  263.     button_gc = XCreateGC(tool_d, XtWindow(mode_panel), (unsigned long) 0, NULL);
  264.     FirstArg(XtNforeground, &but_fg);
  265.     NextArg(XtNbackground, &but_bg);
  266.     GetValues(mode_switches[0].widget);
  267.  
  268.     XSetBackground(tool_d, blank_gc, but_bg);
  269.     XSetForeground(tool_d, blank_gc, but_bg);
  270.  
  271.     FirstArg(XtNfont, button_font);
  272.     SetValues(d_label);
  273.     SetValues(e_label);
  274.  
  275.     if (appres.INVERSE) {
  276.     FirstArg(XtNbackground, WhitePixelOfScreen(tool_s));
  277.     } else {
  278.     FirstArg(XtNbackground, BlackPixelOfScreen(tool_s));
  279.     }
  280.     SetValues(mode_panel);
  281.  
  282.     for (i = 0; i < NUM_MODE_SW; ++i) {
  283.     msw = &mode_switches[i];
  284.     /* create normal bitmaps */
  285.     msw->normalPM = XCreatePixmapFromBitmapData(d, XtWindow(msw->widget),
  286.                (char *) msw->icon->data, msw->icon->width, msw->icon->height,
  287.                    but_fg, but_bg, DefaultDepthOfScreen(s));
  288.  
  289.     FirstArg(XtNbackgroundPixmap, msw->normalPM);
  290.     SetValues(msw->widget);
  291.  
  292.     /* create reverse bitmaps */
  293.     msw->reversePM = XCreatePixmapFromBitmapData(d, XtWindow(msw->widget),
  294.                (char *) msw->icon->data, msw->icon->width, msw->icon->height,
  295.                    but_bg, but_fg, DefaultDepthOfScreen(s));
  296.     /* install the accelerators in the buttons */
  297.     XtInstallAllAccelerators(msw->widget, tool);
  298.     }
  299.     /* install the accelerators for the surrounding parts */
  300.     XtInstallAllAccelerators(mode_panel, tool);
  301.     XtInstallAllAccelerators(d_label, tool);
  302.     XtInstallAllAccelerators(e_label, tool);
  303.  
  304.     XDefineCursor(d, XtWindow(mode_panel), arrow_cursor);
  305.     FirstArg(XtNmappedWhenManaged, True);
  306.     SetValues(mode_panel);
  307. }
  308.  
  309. /* come here when a button is pressed in the mode panel */
  310.  
  311. static void
  312. sel_mode_but(widget, closure, event, continue_to_dispatch)
  313.     Widget          widget;
  314.     XtPointer        closure;
  315.     XEvent*        event;
  316.     Boolean*        continue_to_dispatch;
  317. {
  318.     XButtonEvent    xbutton;
  319.     mode_sw_info    *msw = (mode_sw_info *) closure;
  320.     int             new_objmask;
  321.  
  322.     xbutton = event->xbutton;
  323.     if (action_on) {
  324.     if (cur_mode == F_TEXT)
  325.         finish_text_input();/* finish up any text input */
  326.     else {
  327.         put_msg("Please finish (or cancel) the current operation before changing modes");
  328.         return;
  329.     }
  330.     } else if (highlighting)
  331.     erase_objecthighlight();
  332.     if (xbutton.button == Button1) {    /* left button */
  333.     turn_off_current();
  334.     turn_on(msw);
  335.     /* turn off the update boxes if not in update mode */
  336.     if (msw->mode != F_UPDATE)
  337.         unmanage_update_buts();
  338.     update_indpanel(msw->indmask);
  339.     put_msg(msw->modemsg);
  340.     if ((cur_mode == F_GLUE || cur_mode == F_BREAK) &&
  341.         msw->mode != F_GLUE &&
  342.         msw->mode != F_BREAK)
  343.         /*
  344.          * reset tagged items when changing modes, perhaps this is not
  345.          * really necessary
  346.          */
  347.         set_tags(&objects, 0);
  348.     cur_mode = msw->mode;
  349.     anypointposn = !(msw->indmask & I_POINTPOSN);
  350.     new_objmask = msw->objmask;
  351.     if (cur_mode == F_ROTATE && cur_rotnangle != 90)
  352.         new_objmask = M_ROTATE_ANGLE;
  353.     update_markers(new_objmask);
  354.     current = msw;
  355.     setmode_action(msw);
  356.     }
  357. }
  358.  
  359. void
  360. force_positioning()
  361. {
  362.     update_indpanel(current->indmask | I_POINTPOSN);
  363.     anypointposn = 0;
  364. }
  365.  
  366. void
  367. force_nopositioning()
  368. {
  369.     update_indpanel(current->indmask & ~I_POINTPOSN);
  370.     anypointposn = 1;
  371. }
  372.  
  373. void
  374. force_anglegeom()
  375. {
  376.     update_indpanel(current->indmask | I_ANGLEGEOM);
  377. }
  378.  
  379. void
  380. force_noanglegeom()
  381. {
  382.     update_indpanel(current->indmask & ~I_ANGLEGEOM);
  383. }
  384.  
  385. static void
  386. turn_on(msw)
  387.     mode_sw_info   *msw;
  388. {
  389.     FirstArg(XtNbackgroundPixmap, msw->reversePM);
  390.     SetValues(msw->widget);
  391. }
  392.  
  393. turn_on_current()
  394. {
  395.     if (current)
  396.     turn_on(current);
  397. }
  398.  
  399. turn_off_current()
  400. {
  401.     if (current) {
  402.     FirstArg(XtNbackgroundPixmap, current->normalPM);
  403.     SetValues(current->widget);
  404.     }
  405. }
  406.