home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / XAP / XFM / XFM-1.3 / XFM-1 / xfm-1.3 / xfm / FmUtils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-14  |  19.2 KB  |  560 lines

  1. /*-----------------------------------------------------------------------------
  2.   Module FmUtils.c
  3.  
  4.   (c) Simon Marlow 1990-1993
  5.   (c) Albert Graef 1994
  6.  
  7.   General utility functions for creating menus, buttons, questions,
  8.   and functions for desensetising and 'ticking' menu entries.
  9. -----------------------------------------------------------------------------*/
  10.  
  11. #include <X11/Intrinsic.h>
  12. #include <X11/StringDefs.h>
  13. #include <X11/Shell.h>
  14. #include <X11/Xaw/MenuButton.h>
  15. #include <X11/Xaw/SimpleMenu.h>
  16. #include <X11/Xaw/SmeLine.h>
  17. #include <X11/Xaw/SmeBSB.h>
  18. #include <X11/Xaw/Command.h>
  19. #include <X11/Xaw/Form.h>
  20. #include <X11/Xaw/Label.h>
  21. #include <X11/Xaw/Box.h>
  22. #include <X11/Xaw/AsciiText.h>
  23.  
  24. #include "Am.h"
  25. #include "Fm.h"
  26.  
  27. #define PADDING 20
  28. #define TEXT_WIDTH 350
  29.  
  30. /*-----------------------------------------------------------------------------
  31.   STATIC DATA
  32. -----------------------------------------------------------------------------*/
  33.  
  34. /*-----------------------------------------------------------------------------
  35.   Widget Argument Lists
  36. -----------------------------------------------------------------------------*/
  37.  
  38. static Arg shell_args[] = {
  39.   { XtNtitle, (XtArgVal) NULL }
  40. };
  41.  
  42. static Arg form_args[] = {
  43.   { XtNdefaultDistance, PADDING }
  44. };
  45.  
  46. static Arg bitmap_args[]  = {
  47.   { XtNfromHoriz, (XtArgVal) NULL },
  48.   { XtNfromVert, (XtArgVal) NULL },
  49.   { XtNbitmap, (XtArgVal) NULL },
  50.   { XtNtop, (XtArgVal) XtChainTop },
  51.   { XtNbottom, (XtArgVal) XtChainTop },
  52.   { XtNleft, (XtArgVal) XtChainLeft },
  53.   { XtNright, (XtArgVal) XtChainLeft }
  54. };
  55.  
  56. static Arg label_args[] = {
  57.   { XtNfromHoriz, (XtArgVal) NULL },
  58.   { XtNfromVert, (XtArgVal) NULL },
  59.   { XtNlabel, (XtArgVal) NULL },
  60.   { XtNwidth, (XtArgVal) 0 },
  61.   { XtNfont, (XtArgVal) NULL },
  62.   { XtNjustify, XtJustifyRight },
  63.   { XtNinternalWidth, (XtArgVal) 0 },
  64.   { XtNinternalHeight, (XtArgVal) 0 },
  65.   { XtNtop, XtChainTop },
  66.   { XtNbottom, XtChainTop },
  67.   { XtNleft, XtChainLeft },
  68.   { XtNright, XtChainLeft }
  69. };
  70.  
  71. static Arg text_args[] = {
  72.   { XtNfromHoriz, (XtArgVal) NULL },
  73.   { XtNfromVert, (XtArgVal) NULL },
  74.   { XtNstring, (XtArgVal) NULL },
  75.   { XtNlength, (XtArgVal) NULL },
  76.   { XtNwidth, (XtArgVal) TEXT_WIDTH },
  77.   { XtNfont, (XtArgVal) NULL },
  78.   { XtNtop, XtChainTop },
  79.   { XtNbottom, XtChainTop },
  80.   { XtNleft, XtChainLeft },
  81.   { XtNright, XtChainRight },
  82.   { XtNeditType, XawtextEdit },
  83.   { XtNtype, XawAsciiString },
  84.   { XtNuseStringInPlace, (XtArgVal) True },
  85. };
  86.  
  87. static Arg button_box_args[] = {
  88.   { XtNfromHoriz, (XtArgVal) NULL },
  89.   { XtNfromVert, (XtArgVal) NULL },
  90.   { XtNtop, XtChainTop },
  91.   { XtNbottom, XtChainTop },
  92.   { XtNleft, XtChainLeft },
  93.   { XtNright, XtChainLeft }
  94. };
  95.  
  96. static Arg button_args[] = {
  97.   { XtNlabel, (XtArgVal) NULL },
  98.   { XtNfont, (XtArgVal) NULL }
  99. };
  100.  
  101. static Arg menu_button_args[] = {
  102.   { XtNlabel, (XtArgVal) NULL },
  103.   { XtNfont, (XtArgVal) NULL }
  104. };
  105.  
  106. static Arg menu_item_args[] = {
  107.   { XtNlabel, (XtArgVal) NULL },
  108.   { XtNfont, (XtArgVal) NULL },
  109.   { XtNleftMargin , (XtArgVal) 0 }
  110. };
  111.  
  112. /*-----------------------------------------------------------------------------
  113.   PUBLIC FUNCTIONS
  114. -----------------------------------------------------------------------------*/
  115.  
  116. void initUtils()
  117. {
  118.   button_args[1].value = (XtArgVal) resources.button_font;
  119.   menu_button_args[1].value = (XtArgVal) resources.button_font;
  120.   menu_item_args[1].value = (XtArgVal) resources.menu_font;
  121.   label_args[4].value = (XtArgVal) resources.label_font;
  122.   text_args[5].value = (XtArgVal) resources.cell_font;
  123. };
  124.  
  125. /*****************************************************************************/
  126. /* Function: createFloatingMenu                                              */
  127. /* Arguments: menu_name   :  The menu widget name                            */
  128. /*            items       :  Items to put in menu                            */
  129. /*            n_items     :  Number of items                                 */
  130. /*            left_margin :  left_margin in pixels (in case ticks are needed */
  131. /*            parent      :  The parent widget to use                        */
  132. /*            client_data :  Client data to be returned by any callback      */
  133. /*            menu_widget :  returns the menu widget                         */
  134. /*                                                                           */
  135. /* Create a popup menu with the specified attributes and place in it the     */
  136. /* specifed items; return the list of item widgets                           */
  137. /*****************************************************************************/
  138.  
  139. Widget *createFloatingMenu(String menu_name,
  140.                MenuItemRec *items, Cardinal n_items, 
  141.                Dimension left_margin, Widget parent, 
  142.                XtPointer client_data,
  143.                Widget *menu_widget)
  144. {
  145.   int i;
  146.   Widget *item_widgets;
  147.   
  148.   item_widgets = (Widget *) XtMalloc(n_items * sizeof(Widget));
  149.  
  150.   *menu_widget = XtCreatePopupShell(menu_name, simpleMenuWidgetClass,
  151.                     parent, NULL, 0 );
  152.     
  153.   menu_item_args[2].value = (XtArgVal) left_margin;
  154.  
  155.   for (i = 0; i < n_items; i++) {
  156.     if (items[i].callback == NULL)
  157.       XtCreateManagedWidget(items[i].item_name, smeLineObjectClass,
  158.                 *menu_widget, NULL, 0 );
  159.     else {
  160.       menu_item_args[0].value = (XtArgVal) items[i].item_label;
  161.       item_widgets[i] = XtCreateManagedWidget(items[i].item_name,
  162.                           smeBSBObjectClass, *menu_widget,
  163.                           menu_item_args, 
  164.                           XtNumber(menu_item_args));
  165.       XtAddCallback(item_widgets[i], XtNcallback,
  166.             (XtCallbackProc) items[i].callback, client_data );
  167.     }
  168.   }
  169.  
  170.   return item_widgets;
  171. }
  172.  
  173. /*****************************************************************************/
  174. /* Function: createMenu                                                      */
  175. /* Arguments: menu_name   :  The menu widget name                            */
  176. /*            menu_label  :  The label for the menu button                   */
  177. /*            items       :  Items to put in menu                            */
  178. /*            n_items     :  Number of items                                 */
  179. /*            left_margin :  left_margin in pixels (in case ticks are needed */
  180. /*            parent      :  The parent widget to use                        */
  181. /*            client_data :  Client data to be returned by any callback      */
  182. /*                                                                           */
  183. /* Create a menu with the specified attributes and place in it the           */
  184. /* specifed items                                                            */
  185. /*****************************************************************************/
  186.  
  187. Widget *createMenu(String menu_name, String menu_label, MenuItemList items,
  188.            Cardinal n_items, Dimension left_margin,
  189.            Widget parent, XtPointer client_data)
  190. {
  191.   int i;
  192.   Widget menu_widget, button_widget, *item_widgets;
  193.   
  194.   item_widgets = (Widget *) XtMalloc(n_items * sizeof(Widget));
  195.  
  196.   menu_button_args[0].value = (XtArgVal) menu_label;
  197.   button_widget = XtCreateManagedWidget(menu_name, menuButtonWidgetClass,
  198.     parent, menu_button_args, XtNumber(menu_button_args));
  199.   menu_widget = XtCreatePopupShell( "menu", simpleMenuWidgetClass,
  200.       button_widget, NULL, 0 );
  201.     
  202.   menu_item_args[2].value = (XtArgVal) left_margin;
  203.  
  204.   for (i = 0; i < n_items; i++) {
  205.     if (items[i].callback == NULL)
  206.       XtCreateManagedWidget(items[i].item_name, smeLineObjectClass,
  207.                 menu_widget, NULL, 0 );
  208.     else {
  209.       menu_item_args[0].value = (XtArgVal) items[i].item_label;
  210.       item_widgets[i] = XtCreateManagedWidget(items[i].item_name,
  211.                           smeBSBObjectClass, menu_widget,
  212.                           menu_item_args, 
  213.                           XtNumber(menu_item_args));
  214.       XtAddCallback(item_widgets[i], XtNcallback, 
  215.             (XtCallbackProc) items[i].callback, client_data );
  216.     }
  217.   }
  218.  
  219.   return item_widgets;
  220. }
  221.  
  222. /*****************************************************************************/
  223. /* Function: createButtons                                                   */
  224. /* Arguments: buttons     :  The list of buttons to create                   */
  225. /*            n_buttons   :  Number of buttons                               */
  226. /*            parent      : The parent widget to use                         */
  227. /*            client data :  Client data returned by all buttons             */
  228. /*                                                                           */
  229. /* Create a set of buttons (usually in a box) with the attributes specified  */
  230. /*****************************************************************************/
  231.  
  232.  
  233. Widget *createButtons(ButtonList buttons, Cardinal n_buttons, Widget parent,
  234.            XtPointer client_data)
  235. {
  236.   int i;
  237.   Widget *button_widgets;
  238.   
  239.   button_widgets = (Widget *) XtMalloc(n_buttons * sizeof(Widget));
  240.  
  241.   for (i = 0; i < n_buttons; i++) {
  242.     button_args[0].value = (XtArgVal) buttons[i].button_label;
  243.     button_widgets[i] = XtCreateManagedWidget(buttons[i].button_name,
  244.       commandWidgetClass, parent, button_args, XtNumber(button_args));
  245.     XtAddCallback(button_widgets[i], XtNcallback, 
  246.           (XtCallbackProc) buttons[i].callback, client_data );
  247.   }
  248.  
  249.   return button_widgets;
  250. }
  251.  
  252. /*****************************************************************************/
  253. /* Function: createPopupQuestions                                            */
  254. /* Arguments: name        :  The widget name for the shell                   */
  255. /*            title       :  The title of the popup window                   */
  256. /*            bitmap      :  A bitmap to display to the left of the box      */
  257. /*            questions   :  A list of questions to use                      */
  258. /*            n_questions :  Number of questions                             */
  259. /*            buttons     :  A set of buttons to put at the bottom           */
  260. /*            n_buttons   :  Number of buttons                               */
  261. /*                                                                           */
  262. /* Create a popup questionaire with a bitmap to the left (or none), several  */
  263. /* questions (each consisting of a label and a text area) to the right of    */
  264. /* the bitmap, and a set of buttons underneath all this.                     */
  265. /*****************************************************************************/
  266.  
  267. Widget createPopupQuestions(String name, String title, Pixmap bitmap,
  268.                 QuestionList questions, Cardinal n_questions,
  269.                 ButtonList buttons, Cardinal n_buttons)
  270. {
  271.   int i, l;
  272.   Widget form_widget, box_widget, bitmap_widget = NULL, shell,
  273.     vert = NULL, horiz = NULL;
  274.  
  275.   /* create popup shell */
  276.   shell_args[0].value = (XtArgVal) title;
  277.   shell = XtCreatePopupShell(name, transientShellWidgetClass, aw.shell,
  278.                  shell_args, XtNumber(shell_args) );
  279.  
  280.   /* create form */
  281.   form_widget = XtCreateManagedWidget("popup form", formWidgetClass, shell, 
  282.                       form_args, XtNumber(form_args) );
  283.  
  284.   /* create bitmap */
  285.   if (bitmap != None) {
  286.     bitmap_args[2].value = (XtArgVal) bitmap;
  287.     bitmap_widget = XtCreateManagedWidget("bitmap", labelWidgetClass,
  288.       form_widget, bitmap_args, XtNumber(bitmap_args));
  289.   }
  290.  
  291.   /* Find width of label */
  292.   label_args[3].value = (XtArgVal) 0;
  293.   for (i=0; i<n_questions; i++) {
  294.     l = XTextWidth(resources.label_font, questions[i].label, 
  295.            strlen(questions[i].label));
  296.     if (l > label_args[3].value)
  297.       label_args[3].value = l;
  298.   }
  299.  
  300.   for (i = 0; i<n_questions; i++) {
  301.     label_args[0].value = (XtArgVal) bitmap_widget;
  302.     label_args[1].value = (XtArgVal) vert;
  303.     label_args[2].value = (XtArgVal) questions[i].label;
  304.     horiz = XtCreateManagedWidget("label", labelWidgetClass, form_widget,
  305.                      label_args, XtNumber(label_args));
  306.     if (n_questions == 1) {
  307.       text_args[0].value = (XtArgVal) bitmap_widget;
  308.       text_args[1].value = (XtArgVal) horiz;
  309.     }
  310.     else {
  311.       text_args[0].value = (XtArgVal) horiz;
  312.       text_args[1].value = (XtArgVal) vert;
  313.     }      
  314.     text_args[2].value = (XtArgVal) questions[i].value;
  315.     text_args[3].value = (XtArgVal) questions[i].length;
  316.     vert = questions[i].widget = XtCreateManagedWidget("text", 
  317.        asciiTextWidgetClass, form_widget, text_args, XtNumber(text_args));
  318.   }
  319.  
  320.   if (buttons != NULL) {
  321.     button_box_args[0].value = (XtArgVal) NULL;
  322.     button_box_args[1].value = (XtArgVal) vert;
  323.     box_widget = XtCreateManagedWidget("button box", boxWidgetClass, 
  324.             form_widget, button_box_args, XtNumber(button_box_args));
  325.     createButtons(buttons, n_buttons, box_widget, NULL);
  326.   }
  327.  
  328.   XtRealizeWidget(shell);
  329.  
  330.   return shell;
  331. }
  332.  
  333. /*****************************************************************************/
  334. /* Function: fillIn                                                          */
  335. /* Arguments: w : The widget to fill in                                      */
  336. /*                                                                           */
  337. /* sensitize a menu entry                                                    */
  338. /*****************************************************************************/
  339.  
  340. void fillIn(Widget w)
  341. {
  342.   XtVaSetValues(w, XtNsensitive, (XtArgVal) True, NULL);
  343. }
  344.  
  345. /*****************************************************************************/
  346. /* Function: grayOut                                                         */
  347. /* Arguments: w : the widget to gray out                                     */
  348. /*                                                                           */
  349. /* desensitises a menu entry                                                 */
  350. /*****************************************************************************/
  351.  
  352. void grayOut(Widget w)
  353. {
  354.   XtVaSetValues(w, XtNsensitive, (XtArgVal) False, NULL);
  355. }
  356.  
  357. /*****************************************************************************/
  358. /* Function: tick                                                            */
  359. /* Arguments: w : the widget to tick                                         */
  360. /*                                                                           */
  361. /* place a tick to the left of the specifed menu entry                       */
  362. /*****************************************************************************/
  363.  
  364. void tick(Widget w)
  365. {
  366.   XtVaSetValues(w, XtNleftBitmap, (XtArgVal) bm[TICK_BM], NULL);
  367. }
  368.  
  369. /*****************************************************************************/
  370. /* Function: notick                                                          */
  371. /* Arguments: w : the widget                                                 */
  372. /*                                                                           */
  373. /* remove a tick from a menu entry                                           */
  374. /*****************************************************************************/
  375.  
  376. void noTick(Widget w)
  377. {
  378.   XtVaSetValues(w, XtNleftBitmap, (XtArgVal) bm[NOTICK_BM], NULL);
  379. }
  380.  
  381. /*****************************************************************************/
  382. /* Function: popupByCursor                                                   */
  383. /* Arguments: shell       :  the shell to popup                              */
  384. /*            grab_kind   :  parameter passed to XtPopup                     */
  385. /*                                                                           */
  386. /* Try to popup a shell by the cursor, make sure it fits on the screen       */
  387. /*****************************************************************************/
  388.  
  389. void popupByCursor(Widget shell, XtGrabKind grab_kind)
  390. {
  391.   char *geom;
  392.   Display *dpy;
  393.   Screen *scr;
  394.   Window root, child;
  395.   int x, y, x_win, y_win, scr_width, scr_height;
  396.   Dimension width, height;
  397.   unsigned int mask;
  398.  
  399.   XtVaGetValues(shell, XtNgeometry, &geom, NULL);
  400.  
  401.   if (!geom || !(strchr(geom, '+') || strchr(geom, '-'))) {
  402.     dpy = XtDisplay(aw.shell);
  403.     scr = XtScreen(aw.shell);
  404.     scr_width = WidthOfScreen(scr);
  405.     scr_height = HeightOfScreen(scr);
  406.   
  407.     XQueryPointer(dpy, DefaultRootWindow(dpy), &root, &child, &x, &y, 
  408.           &x_win, &y_win, &mask);
  409.  
  410.     XtVaGetValues(shell, XtNwidth, &width, XtNheight, &height, NULL);
  411.  
  412.     x -= width/2;
  413.     y -= height/2;
  414.  
  415.     if (x + width > scr_width)
  416.       x = scr_width - width;
  417.     else if (x < 0)
  418.       x = 0;
  419.  
  420.     if (y + height > scr_height)
  421.       y = scr_height - height;
  422.     else if (y < 0)
  423.       y = 0;
  424.  
  425.     XtVaSetValues(shell, XtNx, (XtArgVal) x, XtNy, (XtArgVal) y, NULL);
  426.   }
  427.  
  428.   XtPopup(shell, grab_kind);
  429. }
  430.  
  431. /*---------------------------------------------------------------------------*/
  432.  
  433. void zzz(void)
  434. {
  435.   FileWindowRec *fw;
  436.   Display *dpy = XtDisplay(aw.shell);
  437.  
  438.   for (fw = file_windows; fw; fw = fw->next)
  439.     XDefineCursor(dpy, XtWindow(fw->viewport), curs[WATCH_CUR]);
  440.  
  441.   if (resources.appmgr)
  442.     XDefineCursor(dpy, XtWindow(aw.shell), curs[WATCH_CUR]);
  443.  
  444.   XFlush(dpy);
  445. }
  446.  
  447. /*---------------------------------------------------------------------------*/
  448.  
  449. void wakeUp(void)
  450. {
  451.   FileWindowRec *fw;
  452.   Display *dpy = XtDisplay(aw.shell);
  453.  
  454.   for (fw = file_windows; fw; fw = fw->next)
  455.     XUndefineCursor(dpy, XtWindow(fw->viewport));
  456.  
  457.   if (resources.appmgr)
  458.     XUndefineCursor(dpy, XtWindow(aw.shell));
  459. }
  460.  
  461. /*---------------------------------------------------------------------------*/
  462.  
  463. #define MAXVARSTRINGLEN MAXPATHLEN
  464.  
  465. static enum { DontKnow, Ok, Cancel } dialog_flag;
  466. static Widget dialog;
  467.  
  468. static void dialogOkCb(Widget w, XtPointer client_data, XtPointer call_data)
  469. {
  470.   XtPopdown(dialog);
  471.   dialog_flag = Ok;
  472. }
  473.  
  474. /*---------------------------------------------------------------------------*/
  475.  
  476. static void dialogCancelCb(Widget w, XtPointer client_data, 
  477.                XtPointer call_data)
  478. {
  479.   XtPopdown(dialog);
  480.   dialog_flag = Cancel;
  481. }
  482.  
  483. /*---------------------------------------------------------------------------*/
  484.  
  485. static ButtonRec dialog_buttons[] = {
  486.   { "ok", "Ok", (FmCallbackProc *) dialogOkCb },
  487.   { "cancel", "Cancel", (FmCallbackProc *) dialogCancelCb }
  488. };
  489.  
  490. char *varPopup(Pixmap icon_bm, char *action)
  491. {
  492.   static char *act = NULL;
  493.   char *act1 = alloca(strlen(action)+1), *s, *t;
  494.   char **acts = NULL, **vars = NULL;
  495.   int n_acts = 0, n_vars = 0;
  496.  
  497.   if (act) XTFREE(act);
  498.   act = NULL;
  499.   strcpy(act1, action);
  500.  
  501.   for (s = split(act1, '%'); s; s = split(NULL, '%')) {
  502.     acts = (char **)XTREALLOC(acts, (n_acts+1)*sizeof(char *));
  503.     acts[n_acts++] = s;
  504.     if (t = split(NULL, '%')) {
  505.       vars = (char **)XTREALLOC(vars, (n_vars+1)*sizeof(char *));
  506.       vars[n_vars++] = t;
  507.     } else
  508.       break;
  509.   }
  510.  
  511.   if (n_vars) {
  512.     char **vals;
  513.     QuestionRec *dialog_questions;
  514.     int i, l;
  515.     XEvent e;
  516.  
  517.     vals = (char **)XtMalloc(n_vars*sizeof(char *));
  518.     dialog_questions = (QuestionRec *)XtMalloc(n_vars*sizeof(QuestionRec));
  519.     for (i = 0; i < n_vars; i++) {
  520.       vals[i] = (char *)XtMalloc(MAXVARSTRINGLEN);
  521.       dialog_questions[i].label = vars[i];
  522.       dialog_questions[i].value = vals[i];
  523.       dialog_questions[i].length = MAXVARSTRINGLEN;
  524.       dialog_questions[i].widget = NULL;
  525.     }
  526.  
  527.     dialog = createPopupQuestions("dialog", "Parameter Dialog", icon_bm,
  528.                   dialog_questions, n_vars, dialog_buttons,
  529.                   XtNumber(dialog_buttons));
  530.     popupByCursor(dialog, XtGrabExclusive);
  531.  
  532.     dialog_flag = DontKnow;
  533.  
  534.     do {
  535.       XtAppNextEvent(app_context, &e);
  536.       XtDispatchEvent(&e);
  537.     } while (dialog_flag == DontKnow);
  538.  
  539.     if (dialog_flag == Ok)
  540.       for (l = i = 0; i < n_acts; i++) {
  541.     int l1 = strlen(acts[i]), l2 = i<n_vars?strlen(vals[i]):0;
  542.     act = (char *)XTREALLOC(act, l+l1+l2+1);
  543.     strcpy(act+l, acts[i]);
  544.     if (l2) strcpy(act+l+l1, vals[i]);
  545.     l += l1+l2;
  546.       }
  547.  
  548.     XTFREE(dialog_questions);
  549.     for (i = 0; i < n_vars; i++)
  550.       XTFREE(vals[i]);
  551.     XTFREE(acts); XTFREE(vars); XTFREE(vals);
  552.     XtDestroyWidget(dialog);
  553.     return act;
  554.   } else {
  555.     if (n_acts) XTFREE(acts);
  556.     return action;
  557.   }
  558. }
  559.  
  560.