Merge the usermenu branch. This reworks how the menus and hotkeys
[geda-pcb/leaky.git] / src / hid / lesstif / dialogs.c
blob82bee31b6e4834f015c30fa9d3360e5743fbefb5
1 /* $Id$ */
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
7 #include <stdio.h>
8 #include <stdarg.h>
9 #include <stdlib.h>
10 #include <string.h>
12 #include "xincludes.h"
14 #include "compat.h"
15 #include "global.h"
16 #include "data.h"
17 #include "crosshair.h"
18 #include "misc.h"
20 #include "hid.h"
21 #include "../hidint.h"
22 #include "lesstif.h"
24 #ifdef HAVE_LIBDMALLOC
25 #include <dmalloc.h>
26 #endif
28 RCSID ("$Id$");
30 #define CRASH fprintf(stderr, "HID error: pcb called unimplemented GUI function %s\n", __FUNCTION__), abort()
32 static Arg args[30];
33 static int n;
34 #define stdarg(t,v) XtSetArg(args[n], t, v); n++
36 static int ok;
38 #define COMPONENT_SIDE_NAME "(top)"
39 #define SOLDER_SIDE_NAME "(bottom)"
41 /* ------------------------------------------------------------ */
43 static void
44 dialog_callback (Widget w, void *v, void *cbs)
46 ok = (int) (size_t) v;
49 static int
50 wait_for_dialog (Widget w)
52 ok = -1;
53 XtManageChild (w);
54 while (ok == -1 && XtIsManaged (w))
56 XEvent e;
57 XtAppNextEvent (app_context, &e);
58 XtDispatchEvent (&e);
60 XtUnmanageChild (w);
61 return ok;
64 /* ------------------------------------------------------------ */
66 static Widget fsb = 0;
67 static XmString xms_pcb, xms_net, xms_vend, xms_all, xms_load, xms_loadv,
68 xms_save;
70 static void
71 setup_fsb_dialog ()
73 if (fsb)
74 return;
76 xms_pcb = XmStringCreateLocalized ("*.pcb");
77 xms_net = XmStringCreateLocalized ("*.net");
78 xms_vend = XmStringCreateLocalized ("*.vend");
79 xms_all = XmStringCreateLocalized ("*");
80 xms_load = XmStringCreateLocalized ("Load From");
81 xms_loadv = XmStringCreateLocalized ("Load Vendor");
82 xms_save = XmStringCreateLocalized ("Save As");
84 n = 0;
85 fsb = XmCreateFileSelectionDialog (mainwind, "file", args, n);
87 XtAddCallback (fsb, XmNokCallback, (XtCallbackProc) dialog_callback,
88 (XtPointer) 1);
89 XtAddCallback (fsb, XmNcancelCallback, (XtCallbackProc) dialog_callback,
90 (XtPointer) 0);
93 static const char load_syntax[] =
94 "Load()\n"
95 "Load(Layout|LayoutToBuffer|ElementToBuffer|Netlist|Revert)";
97 static const char load_help[] =
98 "Load layout data from a user-selected file.";
100 /* %start-doc actions Load
102 This action is a GUI front-end to the core's @code{LoadFrom} action
103 (@pxref{LoadFrom Action}). If you happen to pass a filename, like
104 @code{LoadFrom}, then @code{LoadFrom} is called directly. Else, the
105 user is prompted for a filename to load, and then @code{LoadFrom} is
106 called with that filename.
108 %end-doc */
110 static int
111 Load (int argc, char **argv, int x, int y)
113 char *function;
114 char *name;
115 XmString xmname, pattern;
117 if (argc > 1)
118 return hid_actionv ("LoadFrom", argc, argv);
120 function = argc ? argv[0] : "Layout";
122 setup_fsb_dialog ();
124 if (strcasecmp (function, "Netlist") == 0)
125 pattern = xms_net;
126 else
127 pattern = xms_pcb;
129 n = 0;
130 stdarg (XmNtitle, "Load From");
131 XtSetValues (XtParent (fsb), args, n);
133 n = 0;
134 stdarg (XmNpattern, pattern);
135 stdarg (XmNmustMatch, True);
136 stdarg (XmNselectionLabelString, xms_load);
137 XtSetValues (fsb, args, n);
139 if (!wait_for_dialog (fsb))
140 return 1;
142 n = 0;
143 stdarg (XmNdirSpec, &xmname);
144 XtGetValues (fsb, args, n);
146 XmStringGetLtoR (xmname, XmFONTLIST_DEFAULT_TAG, &name);
148 hid_actionl ("LoadFrom", function, name, NULL);
150 XtFree (name);
152 return 0;
155 static const char loadvendor_syntax[] =
156 "LoadVendor()";
158 static const char loadvendor_help[] =
159 "Loads a user-selected vendor resource file.";
161 /* %start-doc actions LoadVendor
163 The user is prompted for a file to load, and then
164 @code{LoadVendorFrom} is called (@pxref{LoadVendorFrom Action}) to
165 load that vendor file.
167 %end-doc */
169 static int
170 LoadVendor (int argc, char **argv, int x, int y)
172 char *name;
173 XmString xmname, pattern;
175 if (argc > 0)
176 return hid_actionv ("LoadVendorFrom", argc, argv);
178 setup_fsb_dialog ();
180 pattern = xms_vend;
182 n = 0;
183 stdarg (XmNtitle, "Load Vendor");
184 XtSetValues (XtParent (fsb), args, n);
186 n = 0;
187 stdarg (XmNpattern, pattern);
188 stdarg (XmNmustMatch, True);
189 stdarg (XmNselectionLabelString, xms_loadv);
190 XtSetValues (fsb, args, n);
192 if (!wait_for_dialog (fsb))
193 return 1;
195 n = 0;
196 stdarg (XmNdirSpec, &xmname);
197 XtGetValues (fsb, args, n);
199 XmStringGetLtoR (xmname, XmFONTLIST_DEFAULT_TAG, &name);
201 hid_actionl ("LoadVendorFrom", name, NULL);
203 XtFree (name);
205 return 0;
208 static const char save_syntax[] =
209 "Save()\n"
210 "Save(Layout|LayoutAs)\n"
211 "Save(AllConnections|AllUnusedPins|ElementConnections)";
213 static const char save_help[] =
214 "Save layout data to a user-selected file.";
216 /* %start-doc actions Save
218 This action is a GUI front-end to the core's @code{SaveTo} action
219 (@pxref{SaveTo Action}). If you happen to pass a filename, like
220 @code{SaveTo}, then @code{SaveTo} is called directly. Else, the
221 user is prompted for a filename to save, and then @code{SaveTo} is
222 called with that filename.
224 %end-doc */
226 static int
227 Save (int argc, char **argv, int x, int y)
229 char *function;
230 char *name;
231 XmString xmname, pattern;
233 if (argc > 1)
234 hid_actionv ("SaveTo", argc, argv);
236 function = argc ? argv[0] : "Layout";
238 if (strcasecmp (function, "Layout") == 0)
239 if (PCB->Filename)
240 return hid_actionl ("SaveTo", "Layout", PCB->Filename, NULL);
242 setup_fsb_dialog ();
244 pattern = xms_pcb;
246 XtManageChild (fsb);
248 n = 0;
249 stdarg (XmNtitle, "Save As");
250 XtSetValues (XtParent (fsb), args, n);
252 n = 0;
253 stdarg (XmNpattern, pattern);
254 stdarg (XmNmustMatch, False);
255 stdarg (XmNselectionLabelString, xms_save);
256 XtSetValues (fsb, args, n);
258 if (!wait_for_dialog (fsb))
259 return 1;
261 n = 0;
262 stdarg (XmNdirSpec, &xmname);
263 XtGetValues (fsb, args, n);
265 XmStringGetLtoR (xmname, XmFONTLIST_DEFAULT_TAG, &name);
267 if (strcasecmp (function, "PasteBuffer") == 0)
268 hid_actionl ("PasteBuffer", "Save", name, NULL);
269 else
272 * if we got this far and the function is Layout, then
273 * we really needed it to be a LayoutAs. Otherwise
274 * ActionSaveTo() will ignore the new file name we
275 * just obtained.
277 if (strcasecmp (function, "Layout") == 0)
278 hid_actionl ("SaveTo", "LayoutAs", name, NULL);
279 else
280 hid_actionl ("SaveTo", function, name, NULL);
282 XtFree (name);
284 return 0;
287 /* ------------------------------------------------------------ */
289 static Widget log_form, log_text;
290 static char *msg_buffer = 0;
291 static int msg_buffer_size = 0;
292 static int log_size = 0;
293 static int pending_newline = 0;
295 static void
296 log_clear (Widget w, void *up, void *cbp)
298 XmTextSetString (log_text, "");
299 log_size = 0;
300 pending_newline = 0;
303 static void
304 log_dismiss (Widget w, void *up, void *cbp)
306 XtUnmanageChild (log_form);
309 void
310 lesstif_logv (const char *fmt, va_list ap)
312 int i;
313 char *bp;
314 if (!mainwind)
316 vprintf (fmt, ap);
317 return;
319 if (!log_form)
321 Widget clear_button, dismiss_button;
323 n = 0;
324 stdarg (XmNautoUnmanage, False);
325 stdarg (XmNwidth, 600);
326 stdarg (XmNheight, 200);
327 stdarg (XmNtitle, "PCB Log");
328 log_form = XmCreateFormDialog (mainwind, "log", args, n);
330 n = 0;
331 stdarg (XmNrightAttachment, XmATTACH_FORM);
332 stdarg (XmNbottomAttachment, XmATTACH_FORM);
333 clear_button = XmCreatePushButton (log_form, "clear", args, n);
334 XtManageChild (clear_button);
335 XtAddCallback (clear_button, XmNactivateCallback,
336 (XtCallbackProc) log_clear, 0);
338 n = 0;
339 stdarg (XmNrightAttachment, XmATTACH_WIDGET);
340 stdarg (XmNrightWidget, clear_button);
341 stdarg (XmNbottomAttachment, XmATTACH_FORM);
342 dismiss_button = XmCreatePushButton (log_form, "dismiss", args, n);
343 XtManageChild (dismiss_button);
344 XtAddCallback (dismiss_button, XmNactivateCallback,
345 (XtCallbackProc) log_dismiss, 0);
347 n = 0;
348 stdarg (XmNeditable, False);
349 stdarg (XmNeditMode, XmMULTI_LINE_EDIT);
350 stdarg (XmNcursorPositionVisible, True);
351 stdarg (XmNtopAttachment, XmATTACH_FORM);
352 stdarg (XmNleftAttachment, XmATTACH_FORM);
353 stdarg (XmNrightAttachment, XmATTACH_FORM);
354 stdarg (XmNbottomAttachment, XmATTACH_WIDGET);
355 stdarg (XmNbottomWidget, clear_button);
356 log_text = XmCreateScrolledText (log_form, "text", args, n);
357 XtManageChild (log_text);
359 msg_buffer = (char *) malloc (1002);
360 msg_buffer_size = 1002;
361 XtManageChild (log_form);
363 bp = msg_buffer;
364 if (pending_newline)
366 *bp++ = '\n';
367 pending_newline = 0;
369 #ifdef HAVE_VSNPRINTF
370 i = vsnprintf (bp, msg_buffer_size, fmt, ap);
371 if (i >= msg_buffer_size)
373 msg_buffer_size = i + 100;
374 msg_buffer = (char *) realloc (msg_buffer, msg_buffer_size + 2);
375 vsnprintf (bp, msg_buffer_size, fmt, ap);
377 #else
378 vsprintf (bp, fmt, ap);
379 #endif
380 bp = msg_buffer + strlen (msg_buffer) - 1;
381 while (bp >= msg_buffer && bp[0] == '\n')
383 pending_newline++;
384 *bp-- = 0;
386 XmTextInsert (log_text, log_size, msg_buffer);
387 log_size += strlen (msg_buffer);
388 XmTextSetCursorPosition (log_text, log_size);
391 void
392 lesstif_log (const char *fmt, ...)
394 va_list ap;
395 va_start (ap, fmt);
396 lesstif_logv (fmt, ap);
397 va_end (ap);
400 /* ------------------------------------------------------------ */
402 static Widget confirm_dialog = 0;
403 static Widget confirm_cancel, confirm_ok, confirm_label;
406 lesstif_confirm_dialog (char *msg, ...)
408 char *cancelmsg, *okmsg;
409 va_list ap;
410 XmString xs;
412 if (mainwind == 0)
413 return 1;
415 if (confirm_dialog == 0)
417 n = 0;
418 stdarg (XmNdefaultButtonType, XmDIALOG_OK_BUTTON);
419 stdarg (XmNtitle, "Confirm");
420 confirm_dialog = XmCreateQuestionDialog (mainwind, "confirm", args, n);
421 XtAddCallback (confirm_dialog, XmNcancelCallback,
422 (XtCallbackProc) dialog_callback, (XtPointer) 0);
423 XtAddCallback (confirm_dialog, XmNokCallback,
424 (XtCallbackProc) dialog_callback, (XtPointer) 1);
426 confirm_cancel =
427 XmMessageBoxGetChild (confirm_dialog, XmDIALOG_CANCEL_BUTTON);
428 confirm_ok = XmMessageBoxGetChild (confirm_dialog, XmDIALOG_OK_BUTTON);
429 confirm_label =
430 XmMessageBoxGetChild (confirm_dialog, XmDIALOG_MESSAGE_LABEL);
431 XtUnmanageChild (XmMessageBoxGetChild
432 (confirm_dialog, XmDIALOG_HELP_BUTTON));
435 va_start (ap, msg);
436 cancelmsg = va_arg (ap, char *);
437 okmsg = va_arg (ap, char *);
438 va_end (ap);
440 if (!cancelmsg)
442 cancelmsg = "Cancel";
443 okmsg = "Ok";
446 n = 0;
447 xs = XmStringCreateLocalized (cancelmsg);
449 if (okmsg)
451 stdarg (XmNcancelLabelString, xs);
452 xs = XmStringCreateLocalized (okmsg);
453 XtManageChild (confirm_cancel);
455 else
456 XtUnmanageChild (confirm_cancel);
458 stdarg (XmNokLabelString, xs);
460 xs = XmStringCreateLocalized (msg);
461 stdarg (XmNmessageString, xs);
462 XtSetValues (confirm_dialog, args, n);
464 wait_for_dialog (confirm_dialog);
466 n = 0;
467 stdarg (XmNdefaultPosition, False);
468 XtSetValues (confirm_dialog, args, n);
470 return ok;
473 static int
474 ConfirmAction (int argc, char **argv, int x, int y)
476 int rv = lesstif_confirm_dialog (argc > 0 ? argv[0] : 0,
477 argc > 1 ? argv[1] : 0,
478 argc > 2 ? argv[2] : 0,
480 return rv;
483 /* ------------------------------------------------------------ */
485 static Widget report = 0, report_form;
487 void
488 lesstif_report_dialog (char *title, char *msg)
490 if (!report)
492 if (mainwind == 0)
493 return;
495 n = 0;
496 stdarg (XmNautoUnmanage, False);
497 stdarg (XmNwidth, 600);
498 stdarg (XmNheight, 200);
499 stdarg (XmNtitle, title);
500 report_form = XmCreateFormDialog (mainwind, "report", args, n);
502 n = 0;
503 stdarg (XmNeditable, False);
504 stdarg (XmNeditMode, XmMULTI_LINE_EDIT);
505 stdarg (XmNcursorPositionVisible, False);
506 stdarg (XmNtopAttachment, XmATTACH_FORM);
507 stdarg (XmNleftAttachment, XmATTACH_FORM);
508 stdarg (XmNrightAttachment, XmATTACH_FORM);
509 stdarg (XmNbottomAttachment, XmATTACH_FORM);
510 report = XmCreateScrolledText (report_form, "text", args, n);
511 XtManageChild (report);
513 n = 0;
514 stdarg (XmNtitle, title);
515 XtSetValues (report_form, args, n);
516 XmTextSetString (report, msg);
518 XtManageChild (report_form);
521 /* ------------------------------------------------------------ */
523 static Widget prompt_dialog = 0;
524 static Widget prompt_label, prompt_text;
526 char *
527 lesstif_prompt_for (char *msg, char *default_string)
529 char *rv;
530 XmString xs;
531 if (prompt_dialog == 0)
533 n = 0;
534 stdarg (XmNautoUnmanage, False);
535 stdarg (XmNtitle, "PCB Prompt");
536 prompt_dialog = XmCreateFormDialog (mainwind, "prompt", args, n);
538 n = 0;
539 stdarg (XmNtopAttachment, XmATTACH_FORM);
540 stdarg (XmNleftAttachment, XmATTACH_FORM);
541 stdarg (XmNrightAttachment, XmATTACH_FORM);
542 stdarg (XmNalignment, XmALIGNMENT_BEGINNING);
543 prompt_label = XmCreateLabel (prompt_dialog, "label", args, n);
544 XtManageChild (prompt_label);
546 n = 0;
547 stdarg (XmNtopAttachment, XmATTACH_WIDGET);
548 stdarg (XmNtopWidget, prompt_label);
549 stdarg (XmNbottomAttachment, XmATTACH_WIDGET);
550 stdarg (XmNleftAttachment, XmATTACH_FORM);
551 stdarg (XmNrightAttachment, XmATTACH_FORM);
552 stdarg (XmNeditable, True);
553 prompt_text = XmCreateText (prompt_dialog, "text", args, n);
554 XtManageChild (prompt_text);
555 XtAddCallback (prompt_text, XmNactivateCallback,
556 (XtCallbackProc) dialog_callback, (XtPointer) 1);
558 if (!default_string)
559 default_string = "";
560 if (!msg)
561 msg = "Enter text:";
562 n = 0;
563 xs = XmStringCreateLocalized (msg);
564 stdarg (XmNlabelString, xs);
565 XtSetValues (prompt_label, args, n);
566 XmTextSetString (prompt_text, default_string);
567 XmTextSetCursorPosition (prompt_text, strlen (default_string));
568 wait_for_dialog (prompt_dialog);
569 rv = XmTextGetString (prompt_text);
570 return rv;
573 static const char promptfor_syntax[] =
574 "PromptFor([message[,default]])";
576 static const char promptfor_help[] =
577 "Prompt for a response.";
579 /* %start-doc actions PromptFor
581 This is mostly for testing the lesstif HID interface. The parameters
582 are passed to the @code{prompt_for()} HID function, causing the user
583 to be prompted for a response. The respose is simply printed to the
584 user's stdout.
586 %end-doc */
588 static int
589 PromptFor (int argc, char **argv, int x, int y)
591 char *rv = lesstif_prompt_for (argc > 0 ? argv[0] : 0,
592 argc > 1 ? argv[1] : 0);
593 printf ("rv = `%s'\n", rv);
594 return 0;
597 /* ------------------------------------------------------------ */
599 static Widget
600 create_form_ok_dialog (char *name, int ok)
602 Widget dialog, topform;
603 n = 0;
604 dialog = XmCreateQuestionDialog (mainwind, name, args, n);
606 XtUnmanageChild (XmMessageBoxGetChild (dialog, XmDIALOG_SYMBOL_LABEL));
607 XtUnmanageChild (XmMessageBoxGetChild (dialog, XmDIALOG_MESSAGE_LABEL));
608 XtUnmanageChild (XmMessageBoxGetChild (dialog, XmDIALOG_HELP_BUTTON));
609 XtAddCallback (dialog, XmNcancelCallback, (XtCallbackProc) dialog_callback,
610 (XtPointer) 0);
611 if (ok)
612 XtAddCallback (dialog, XmNokCallback, (XtCallbackProc) dialog_callback,
613 (XtPointer) 1);
614 else
615 XtUnmanageChild (XmMessageBoxGetChild (dialog, XmDIALOG_OK_BUTTON));
617 n = 0;
618 topform = XmCreateForm (dialog, "attributes", args, n);
619 XtManageChild (topform);
620 return topform;
624 lesstif_attribute_dialog (HID_Attribute * attrs,
625 int n_attrs, HID_Attr_Val * results)
627 Widget dialog, topform, lform, form;
628 Widget *wl;
629 int i, rv;
630 static XmString empty = 0;
632 if (!empty)
633 empty = XmStringCreateLocalized (" ");
635 for (i = 0; i < n_attrs; i++)
637 results[i] = attrs[i].default_val;
638 if (results[i].str_value)
639 results[i].str_value = strdup (results[i].str_value);
642 wl = (Widget *) malloc (n_attrs * sizeof (Widget));
644 topform = create_form_ok_dialog ("attributes", 1);
645 dialog = XtParent (topform);
647 n = 0;
648 stdarg (XmNfractionBase, n_attrs);
649 XtSetValues (topform, args, n);
651 n = 0;
652 stdarg (XmNtopAttachment, XmATTACH_FORM);
653 stdarg (XmNbottomAttachment, XmATTACH_FORM);
654 stdarg (XmNleftAttachment, XmATTACH_FORM);
655 stdarg (XmNfractionBase, n_attrs);
656 lform = XmCreateForm (topform, "attributes", args, n);
657 XtManageChild (lform);
659 n = 0;
660 stdarg (XmNtopAttachment, XmATTACH_FORM);
661 stdarg (XmNbottomAttachment, XmATTACH_FORM);
662 stdarg (XmNleftAttachment, XmATTACH_WIDGET);
663 stdarg (XmNleftWidget, lform);
664 stdarg (XmNrightAttachment, XmATTACH_FORM);
665 stdarg (XmNfractionBase, n_attrs);
666 form = XmCreateForm (topform, "attributes", args, n);
667 XtManageChild (form);
669 for (i = 0; i < n_attrs; i++)
671 Widget w;
673 n = 0;
674 stdarg (XmNleftAttachment, XmATTACH_FORM);
675 stdarg (XmNrightAttachment, XmATTACH_FORM);
676 stdarg (XmNtopAttachment, XmATTACH_POSITION);
677 stdarg (XmNtopPosition, i);
678 stdarg (XmNbottomAttachment, XmATTACH_POSITION);
679 stdarg (XmNbottomPosition, i + 1);
680 stdarg (XmNalignment, XmALIGNMENT_END);
681 w = XmCreateLabel (lform, attrs[i].name, args, n);
682 XtManageChild (w);
685 for (i = 0; i < n_attrs; i++)
687 static char buf[30];
688 n = 0;
689 stdarg (XmNleftAttachment, XmATTACH_FORM);
690 stdarg (XmNrightAttachment, XmATTACH_FORM);
691 stdarg (XmNtopAttachment, XmATTACH_POSITION);
692 stdarg (XmNtopPosition, i);
693 stdarg (XmNbottomAttachment, XmATTACH_POSITION);
694 stdarg (XmNbottomPosition, i + 1);
695 stdarg (XmNalignment, XmALIGNMENT_END);
697 switch (attrs[i].type)
699 case HID_Label:
700 stdarg (XmNlabelString, empty);
701 wl[i] = XmCreateLabel (form, attrs[i].name, args, n);
702 break;
703 case HID_Boolean:
704 stdarg (XmNlabelString, empty);
705 stdarg (XmNset, results[i].int_value);
706 wl[i] = XmCreateToggleButton (form, attrs[i].name, args, n);
707 break;
708 case HID_String:
709 stdarg (XmNcolumns, 40);
710 stdarg (XmNresizeWidth, True);
711 stdarg (XmNvalue, results[i].str_value);
712 wl[i] = XmCreateTextField (form, attrs[i].name, args, n);
713 break;
714 case HID_Integer:
715 stdarg (XmNcolumns, 13);
716 stdarg (XmNresizeWidth, True);
717 sprintf (buf, "%d", results[i].int_value);
718 stdarg (XmNvalue, buf);
719 wl[i] = XmCreateTextField (form, attrs[i].name, args, n);
720 break;
721 case HID_Real:
722 stdarg (XmNcolumns, 16);
723 stdarg (XmNresizeWidth, True);
724 sprintf (buf, "%g", results[i].real_value);
725 stdarg (XmNvalue, buf);
726 wl[i] = XmCreateTextField (form, attrs[i].name, args, n);
727 break;
728 case HID_Enum:
730 static XmString empty = 0;
731 Widget submenu, default_button=0;
732 int sn = n;
734 if (empty == 0)
735 empty = XmStringCreateLocalized ("");
737 submenu = XmCreatePulldownMenu (form, attrs[i].name, args+sn, n-sn);
739 n = sn;
740 stdarg (XmNlabelString, empty);
741 stdarg (XmNsubMenuId, submenu);
742 wl[i] = XmCreateOptionMenu (form, attrs[i].name, args, n);
744 for (sn=0; attrs[i].enumerations[sn]; sn++)
746 Widget btn;
747 XmString label;
748 n = 0;
749 label = XmStringCreateLocalized ((char *)attrs[i].enumerations[sn]);
750 stdarg (XmNuserData, & attrs[i].enumerations[sn]);
751 stdarg (XmNlabelString, label);
752 btn = XmCreatePushButton (submenu, "menubutton", args, n);
753 XtManageChild (btn);
754 XmStringFree (label);
755 if (sn == attrs[i].default_val.int_value)
756 default_button = btn;
758 if (default_button)
760 n = 0;
761 stdarg (XmNmenuHistory, default_button);
762 XtSetValues (wl[i], args, n);
765 break;
766 default:
767 wl[i] = XmCreateLabel (form, "UNIMPLEMENTED", args, n);
768 break;
771 XtManageChild (wl[i]);
774 rv = wait_for_dialog (dialog);
776 for (i = 0; i < n_attrs; i++)
778 char *cp;
779 switch (attrs[i].type)
781 case HID_Boolean:
782 results[i].int_value = XmToggleButtonGetState (wl[i]);
783 break;
784 case HID_String:
785 results[i].str_value = XmTextGetString (wl[i]);
786 break;
787 case HID_Integer:
788 cp = XmTextGetString (wl[i]);
789 sscanf (cp, "%d", &results[i].int_value);
790 break;
791 case HID_Real:
792 cp = XmTextGetString (wl[i]);
793 sscanf (cp, "%lg", &results[i].real_value);
794 break;
795 case HID_Enum:
797 const char **uptr;
798 Widget btn;
800 n = 0;
801 stdarg (XmNmenuHistory, &btn);
802 XtGetValues (wl[i], args, n);
803 n = 0;
804 stdarg (XmNuserData, &uptr);
805 XtGetValues (btn, args, n);
806 results[i].int_value = uptr - attrs[i].enumerations;
808 break;
809 default:
810 break;
814 free (wl);
815 XtDestroyWidget (dialog);
817 return rv ? 0 : 1;
820 /* ------------------------------------------------------------ */
822 static const char dowindows_syntax[] =
823 "DoWindows(1|2|3|4)\n"
824 "DoWindows(Layout|Library|Log|Netlist)";
826 static const char dowindows_help[] =
827 "Open various GUI windows.";
829 /* %start-doc actions DoWindows
831 @table @code
833 @item 1
834 @itemx Layout
835 Open the layout window. Since the layout window is always shown
836 anyway, this has no effect.
838 @item 2
839 @itemx Library
840 Open the library window.
842 @item 3
843 @itemx Log
844 Open the log window.
846 @item 4
847 @itemx Netlist
848 Open the netlist window.
850 @end table
852 %end-doc */
854 static int
855 DoWindows (int argc, char **argv, int x, int y)
857 char *a = argc == 1 ? argv[0] : "";
858 if (strcmp (a, "1") == 0 || strcasecmp (a, "Layout") == 0)
861 else if (strcmp (a, "2") == 0 || strcasecmp (a, "Library") == 0)
863 lesstif_show_library ();
865 else if (strcmp (a, "3") == 0 || strcasecmp (a, "Log") == 0)
867 if (log_form == 0)
868 lesstif_log ("");
869 XtManageChild (log_form);
871 else if (strcmp (a, "4") == 0 || strcasecmp (a, "Netlist") == 0)
873 lesstif_show_netlist ();
875 else
877 lesstif_log ("Usage: DoWindows(1|2|3|4|Layout|Library|Log|Netlist)");
878 return 1;
880 return 0;
883 /* ------------------------------------------------------------ */
884 static const char about_syntax[] =
885 "About()";
887 static const char about_help[] =
888 "Tell the user about this version of PCB.";
890 /* %start-doc actions About
892 This just pops up a dialog telling the user which version of
893 @code{pcb} they're running.
895 %end-doc */
898 static int
899 About (int argc, char **argv, int x, int y)
901 static Widget about = 0;
902 if (!about)
904 Cardinal n = 0;
905 XmString xs = XmStringCreateLocalized (GetInfoString ());
906 stdarg (XmNmessageString, xs);
907 stdarg (XmNtitle, "About PCB");
908 about = XmCreateInformationDialog (mainwind, "about", args, n);
909 XtUnmanageChild (XmMessageBoxGetChild (about, XmDIALOG_CANCEL_BUTTON));
910 XtUnmanageChild (XmMessageBoxGetChild (about, XmDIALOG_HELP_BUTTON));
912 wait_for_dialog (about);
913 return 0;
916 /* ------------------------------------------------------------ */
918 static const char print_syntax[] =
919 "Print()";
921 static const char print_help[] =
922 "Print the layout.";
924 /* %start-doc actions Print
926 This will find the default printing HID, prompt the user for its
927 options, and print the layout.
929 %end-doc */
931 static int
932 Print (int argc, char **argv, int x, int y)
934 HID_Attribute *opts;
935 HID *printer;
936 HID_Attr_Val *vals;
937 int n;
939 printer = hid_find_printer ();
940 if (!printer)
942 lesstif_confirm_dialog ("No printer?", "Oh well", 0);
943 return 1;
945 opts = printer->get_export_options (&n);
946 vals = (HID_Attr_Val *) calloc (n, sizeof (HID_Attr_Val));
947 if (lesstif_attribute_dialog (opts, n, vals))
949 free (vals);
950 return 1;
952 printer->do_export (vals);
953 free (vals);
954 return 0;
957 static HID_Attribute
958 printer_calibrate_attrs[] = {
959 {"Enter Values here:", "",
960 HID_Label, 0, 0, {0, 0, 0}, 0, 0},
961 {"x-calibration", "X scale for calibrating your printer",
962 HID_Real, 0.5, 2, {0, 0, 1.00}, 0, 0},
963 {"y-calibration", "Y scale for calibrating your printer",
964 HID_Real, 0.5, 2, {0, 0, 1.00}, 0, 0}
966 static HID_Attr_Val printer_calibrate_values[3];
968 static const char printcalibrate_syntax[] =
969 "PrintCalibrate()";
971 static const char printcalibrate_help[] =
972 "Calibrate the printer.";
974 /* %start-doc actions PrintCalibrate
976 This will print a calibration page, which you would measure and type
977 the measurements in, so that future printouts will be more precise.
979 %end-doc */
981 static int
982 PrintCalibrate (int argc, char **argv, int x, int y)
984 HID *printer = hid_find_printer ();
985 printer->calibrate (0.0, 0.0);
986 if (gui->attribute_dialog (printer_calibrate_attrs, 3,
987 printer_calibrate_values))
988 return 1;
989 printer->calibrate (printer_calibrate_values[1].real_value,
990 printer_calibrate_values[2].real_value);
991 return 0;
994 static const char export_syntax[] =
995 "Export()";
997 static const char export_help[] =
998 "Export the layout.";
1000 /* %start-doc actions Export
1002 Prompts the user for an exporter to use. Then, prompts the user for
1003 that exporter's options, and exports the layout.
1005 %end-doc */
1007 static int
1008 Export (int argc, char **argv, int x, int y)
1010 static Widget selector = 0;
1011 HID_Attribute *opts;
1012 HID *printer, **hids;
1013 HID_Attr_Val *vals;
1014 int n, i;
1015 Widget prev = 0;
1016 Widget w;
1018 hids = hid_enumerate ();
1020 if (!selector)
1022 n = 0;
1023 stdarg (XmNtitle, "Export HIDs");
1024 selector = create_form_ok_dialog ("export", 0);
1025 for (i = 0; hids[i]; i++)
1027 if (hids[i]->exporter)
1029 n = 0;
1030 if (prev)
1032 stdarg (XmNtopAttachment, XmATTACH_WIDGET);
1033 stdarg (XmNtopWidget, prev);
1035 else
1037 stdarg (XmNtopAttachment, XmATTACH_FORM);
1039 stdarg (XmNrightAttachment, XmATTACH_FORM);
1040 stdarg (XmNleftAttachment, XmATTACH_FORM);
1042 XmCreatePushButton (selector, (char *) hids[i]->name, args,
1044 XtManageChild (w);
1045 XtAddCallback (w, XmNactivateCallback,
1046 (XtCallbackProc) dialog_callback,
1047 (XtPointer) ((size_t) i + 1));
1048 prev = w;
1051 selector = XtParent (selector);
1054 i = wait_for_dialog (selector);
1056 if (i <= 0)
1057 return 1;
1058 printer = hids[i - 1];
1060 exporter = printer;
1062 opts = printer->get_export_options (&n);
1063 vals = (HID_Attr_Val *) calloc (n, sizeof (HID_Attr_Val));
1064 if (lesstif_attribute_dialog (opts, n, vals))
1066 free (vals);
1067 return 1;
1069 printer->do_export (vals);
1070 free (vals);
1071 exporter = NULL;
1072 return 0;
1075 /* ------------------------------------------------------------ */
1077 static Widget sizes_dialog = 0;
1078 static Widget sz_pcb_w, sz_pcb_h, sz_bloat, sz_shrink, sz_drc_wid, sz_drc_slk,
1079 sz_drc_drill, sz_drc_ring;
1080 static Widget sz_text;
1081 static Widget sz_set, sz_reset, sz_units;
1083 static int
1084 sz_str2val (Widget w, int pcbu)
1086 double d;
1087 char *buf;
1088 buf = XmTextGetString (w);
1089 if (!pcbu)
1090 return atoi (buf);
1091 sscanf (buf, "%lf", &d);
1092 if (Settings.grid_units_mm)
1093 return MM_TO_PCB (d);
1094 else
1095 return MIL_TO_PCB (d);
1098 static void
1099 sz_val2str (Widget w, int u, int pcbu)
1101 double d;
1102 static char buf[40];
1103 if (pcbu)
1105 if (Settings.grid_units_mm)
1106 d = PCB_TO_MM (u);
1107 else
1108 d = PCB_TO_MIL (u);
1109 sprintf (buf, "%.2f", d + 0.002);
1111 else
1112 sprintf (buf, "%d %%", u);
1113 XmTextSetString (w, buf);
1116 static void
1117 sizes_set ()
1119 PCB->MaxWidth = sz_str2val (sz_pcb_w, 1);
1120 PCB->MaxHeight = sz_str2val (sz_pcb_h, 1);
1121 PCB->Bloat = sz_str2val (sz_bloat, 1);
1122 PCB->Shrink = sz_str2val (sz_shrink, 1);
1123 PCB->minWid = sz_str2val (sz_drc_wid, 1);
1124 PCB->minSlk = sz_str2val (sz_drc_slk, 1);
1125 PCB->minDrill = sz_str2val (sz_drc_drill, 1);
1126 PCB->minRing = sz_str2val (sz_drc_ring, 1);
1127 Settings.TextScale = sz_str2val (sz_text, 0);
1129 Settings.Bloat = PCB->Bloat;
1130 Settings.Shrink = PCB->Shrink;
1131 Settings.minWid = PCB->minWid;
1132 Settings.minSlk = PCB->minSlk;
1133 Settings.minDrill = PCB->minDrill;
1134 Settings.minRing = PCB->minRing;
1136 SetCrosshairRange (0, 0, PCB->MaxWidth, PCB->MaxHeight);
1137 lesstif_pan_fixup ();
1140 void
1141 lesstif_sizes_reset ()
1143 char *ls;
1144 if (!sizes_dialog)
1145 return;
1146 sz_val2str (sz_pcb_w, PCB->MaxWidth, 1);
1147 sz_val2str (sz_pcb_h, PCB->MaxHeight, 1);
1148 sz_val2str (sz_bloat, PCB->Bloat, 1);
1149 sz_val2str (sz_shrink, PCB->Shrink, 1);
1150 sz_val2str (sz_drc_wid, PCB->minWid, 1);
1151 sz_val2str (sz_drc_slk, PCB->minSlk, 1);
1152 sz_val2str (sz_drc_drill, PCB->minDrill, 1);
1153 sz_val2str (sz_drc_ring, PCB->minRing, 1);
1154 sz_val2str (sz_text, Settings.TextScale, 0);
1156 if (Settings.grid_units_mm)
1157 ls = "Units are MMs";
1158 else
1159 ls = "Units are Mils";
1160 n = 0;
1161 stdarg (XmNlabelString, XmStringCreateLocalized (ls));
1162 XtSetValues (sz_units, args, n);
1165 static Widget
1166 size_field (Widget parent, char *label, int posn)
1168 Widget w, l;
1169 n = 0;
1170 stdarg (XmNrightAttachment, XmATTACH_FORM);
1171 stdarg (XmNtopAttachment, XmATTACH_POSITION);
1172 stdarg (XmNtopPosition, posn);
1173 stdarg (XmNbottomAttachment, XmATTACH_POSITION);
1174 stdarg (XmNbottomPosition, posn + 1);
1175 stdarg (XmNcolumns, 10);
1176 w = XmCreateTextField (parent, "field", args, n);
1177 XtManageChild (w);
1179 n = 0;
1180 stdarg (XmNleftAttachment, XmATTACH_FORM);
1181 stdarg (XmNrightAttachment, XmATTACH_WIDGET);
1182 stdarg (XmNrightWidget, w);
1183 stdarg (XmNtopAttachment, XmATTACH_POSITION);
1184 stdarg (XmNtopPosition, posn);
1185 stdarg (XmNbottomAttachment, XmATTACH_POSITION);
1186 stdarg (XmNbottomPosition, posn + 1);
1187 stdarg (XmNlabelString, XmStringCreateLocalized (label));
1188 stdarg (XmNalignment, XmALIGNMENT_END);
1189 l = XmCreateLabel (parent, "label", args, n);
1190 XtManageChild (l);
1192 return w;
1195 static const char adjustsizes_syntax[] =
1196 "AdjustSizes()";
1198 static const char adjustsizes_help[] =
1199 "Let the user change the board size, DRC parameters, etc";
1201 /* %start-doc actions AdjustSizes
1203 Displays a dialog box that lets the user change the board
1204 size, DRC parameters, and text scale.
1206 The units are determined by the default display units.
1208 %end-doc */
1210 static int
1211 AdjustSizes (int argc, char **argv, int x, int y)
1213 if (!sizes_dialog)
1215 Widget inf, sep;
1217 n = 0;
1218 stdarg (XmNmarginWidth, 3);
1219 stdarg (XmNmarginHeight, 3);
1220 stdarg (XmNhorizontalSpacing, 3);
1221 stdarg (XmNverticalSpacing, 3);
1222 stdarg (XmNautoUnmanage, False);
1223 stdarg (XmNtitle, "Board Sizes");
1224 sizes_dialog = XmCreateFormDialog (mainwind, "sizes", args, n);
1226 n = 0;
1227 stdarg (XmNrightAttachment, XmATTACH_FORM);
1228 stdarg (XmNbottomAttachment, XmATTACH_FORM);
1229 sz_reset = XmCreatePushButton (sizes_dialog, "Reset", args, n);
1230 XtManageChild (sz_reset);
1231 XtAddCallback (sz_reset, XmNactivateCallback,
1232 (XtCallbackProc) lesstif_sizes_reset, 0);
1234 n = 0;
1235 stdarg (XmNrightAttachment, XmATTACH_WIDGET);
1236 stdarg (XmNrightWidget, sz_reset);
1237 stdarg (XmNbottomAttachment, XmATTACH_FORM);
1238 sz_set = XmCreatePushButton (sizes_dialog, "Set", args, n);
1239 XtManageChild (sz_set);
1240 XtAddCallback (sz_set, XmNactivateCallback, (XtCallbackProc) sizes_set,
1243 n = 0;
1244 stdarg (XmNrightAttachment, XmATTACH_FORM);
1245 stdarg (XmNleftAttachment, XmATTACH_FORM);
1246 stdarg (XmNbottomAttachment, XmATTACH_WIDGET);
1247 stdarg (XmNbottomWidget, sz_reset);
1248 sep = XmCreateSeparator (sizes_dialog, "sep", args, n);
1249 XtManageChild (sep);
1251 n = 0;
1252 stdarg (XmNrightAttachment, XmATTACH_FORM);
1253 stdarg (XmNleftAttachment, XmATTACH_FORM);
1254 stdarg (XmNbottomAttachment, XmATTACH_WIDGET);
1255 stdarg (XmNbottomWidget, sep);
1256 sz_units = XmCreateLabel (sizes_dialog, "units", args, n);
1257 XtManageChild (sz_units);
1259 n = 0;
1260 stdarg (XmNrightAttachment, XmATTACH_FORM);
1261 stdarg (XmNleftAttachment, XmATTACH_FORM);
1262 stdarg (XmNtopAttachment, XmATTACH_FORM);
1263 stdarg (XmNbottomAttachment, XmATTACH_WIDGET);
1264 stdarg (XmNbottomWidget, sz_units);
1265 stdarg (XmNfractionBase, 9);
1266 inf = XmCreateForm (sizes_dialog, "sizes", args, n);
1267 XtManageChild (inf);
1269 sz_pcb_w = size_field (inf, "PCB Width", 0);
1270 sz_pcb_h = size_field (inf, "PCB Height", 1);
1271 sz_bloat = size_field (inf, "Bloat", 2);
1272 sz_shrink = size_field (inf, "Shrink", 3);
1273 sz_drc_wid = size_field (inf, "DRC Min Wid", 4);
1274 sz_drc_slk = size_field (inf, "DRC Min Silk", 5);
1275 sz_drc_drill = size_field (inf, "DRC Min Drill", 6);
1276 sz_drc_ring = size_field (inf, "DRC Min Annular Ring", 7);
1277 sz_text = size_field (inf, "Text Scale", 8);
1279 lesstif_sizes_reset ();
1280 XtManageChild (sizes_dialog);
1281 return 0;
1284 /* ------------------------------------------------------------ */
1286 static Widget layer_groups_form = 0;
1287 static Widget lg_buttonform = 0;
1289 static int lg_setcol[MAX_LAYER+2];
1290 static int lg_width, lg_height;
1291 static int lg_r[MAX_LAYER+3];
1292 static int lg_c[MAX_LAYER+1];
1293 static int lg_label_width, lg_fa, lg_fd;
1294 static GC lg_gc = 0;
1296 #if 0
1297 static Widget lglabels[MAX_LAYER + 2];
1298 static Widget lgbuttons[MAX_LAYER + 2][MAX_LAYER];
1299 #endif
1301 typedef struct {
1302 XFontStruct *font;
1303 Pixel fg, bg, sel;
1304 } LgResource;
1306 static LgResource lgr;
1308 static XtResource lg_resources[] = {
1309 { "font", "Font", XtRFontStruct, sizeof(XFontStruct*), XtOffset(LgResource*, font), XtRString, "fixed" },
1310 { "foreground", "Foreground", XtRPixel, sizeof(Pixel), XtOffset(LgResource*, fg), XtRString, "black" },
1311 { "selectColor", "Foreground", XtRPixel, sizeof(Pixel), XtOffset(LgResource*, sel), XtRString, "blue" },
1312 { "background", "Background", XtRPixel, sizeof(Pixel), XtOffset(LgResource*, bg), XtRString, "white" }
1315 #if 0
1316 static void
1317 lgbutton_cb (Widget w, int ij, void *cbs)
1319 int layer, group, k;
1321 layer = ij / max_layer;
1322 group = ij % max_layer;
1323 group = MoveLayerToGroup (layer, group);
1324 for (k = 0; k < max_layer; k++)
1326 if (k == group)
1327 XmToggleButtonSetState (lgbuttons[layer][k], 1, 0);
1328 else
1329 XmToggleButtonSetState (lgbuttons[layer][k], 0, 0);
1332 #endif
1334 static void
1335 lgbutton_expose (Widget w, XtPointer u, XmDrawingAreaCallbackStruct *cbs)
1337 int i;
1338 Window win = XtWindow(w);
1340 if (cbs && cbs->event->xexpose.count)
1341 return;
1342 if (lg_gc == 0 && !cbs)
1343 return;
1344 if (lg_gc == 0 && cbs)
1346 lg_gc = XCreateGC (display, win, 0, 0);
1347 XSetFont (display, lg_gc, lgr.font->fid);
1350 XSetForeground (display, lg_gc, lgr.bg);
1351 XFillRectangle (display, win, lg_gc, 0, 0, lg_width, lg_height);
1352 XSetForeground (display, lg_gc, lgr.fg);
1353 for (i=0; i<max_layer; i++)
1354 XDrawLine(display, win, lg_gc, lg_c[i], 0, lg_c[i], lg_height);
1355 for (i=1; i<max_layer+2; i++)
1356 XDrawLine(display, win, lg_gc, lg_label_width, lg_r[i], lg_width, lg_r[i]);
1357 for (i=0; i<max_layer+2; i++)
1359 int dir;
1360 XCharStruct size;
1361 int swidth;
1362 const char *name;
1364 if (i == max_layer)
1365 name = SOLDER_SIDE_NAME;
1366 else if (i == max_layer + 1)
1367 name = COMPONENT_SIDE_NAME;
1368 else
1369 name = PCB->Data->Layer[i].Name;
1370 XTextExtents (lgr.font, name, strlen(name), &dir, &lg_fa, &lg_fd, &size);
1371 swidth = size.rbearing - size.lbearing;
1372 XDrawString(display, win, lg_gc,
1373 (lg_label_width - swidth)/2 - size.lbearing,
1374 (lg_r[i] + lg_r[i+1] + lg_fd + lg_fa)/2 - 1,
1375 name, strlen(name));
1377 XSetForeground (display, lg_gc, lgr.sel);
1378 for (i=0; i<max_layer+2; i++)
1380 int c = lg_setcol[i];
1381 int x1 = lg_c[c] + 2;
1382 int x2 = lg_c[c+1] - 2;
1383 int y1 = lg_r[i] + 2;
1384 int y2 = lg_r[i+1] - 2;
1385 XFillRectangle (display, win, lg_gc, x1, y1, x2-x1+1, y2-y1+1);
1389 static void
1390 lgbutton_input (Widget w, XtPointer u, XmDrawingAreaCallbackStruct *cbs)
1392 int layer, group;
1393 if (cbs->event->type != ButtonPress)
1394 return;
1395 layer = cbs->event->xbutton.y * (max_layer+2) / lg_height;
1396 group = (cbs->event->xbutton.x - lg_label_width) * max_layer / (lg_width - lg_label_width);
1397 group = MoveLayerToGroup (layer, group);
1398 lg_setcol[layer] = group;
1399 lgbutton_expose (w, 0, 0);
1400 gui->invalidate_all ();
1403 static void
1404 lgbutton_resize (Widget w, XtPointer u, XmDrawingAreaCallbackStruct *cbs)
1406 int i;
1407 Dimension width, height;
1408 n = 0;
1409 stdarg(XmNwidth, &width);
1410 stdarg(XmNheight, &height);
1411 XtGetValues(w, args, n);
1412 lg_width = width;
1413 lg_height = height;
1415 for (i=0; i<=max_layer; i++)
1416 lg_c[i] = lg_label_width + (lg_width - lg_label_width) * i / max_layer;
1417 for (i=0; i<=max_layer+2; i++)
1418 lg_r[i] = lg_height * i / (max_layer+2);
1419 lgbutton_expose (w, 0, 0);
1422 void
1423 lesstif_update_layer_groups ()
1425 int sets[MAX_LAYER + 2][MAX_LAYER];
1426 int i, j, n;
1427 LayerGroupType *l = &(PCB->LayerGroups);
1429 if (!layer_groups_form)
1430 return;
1432 memset (sets, 0, sizeof (sets));
1434 for (i = 0; i < max_layer; i++)
1435 for (j = 0; j < l->Number[i]; j++)
1437 sets[l->Entries[i][j]][i] = 1;
1438 lg_setcol[l->Entries[i][j]] = i;
1441 lg_label_width = 0;
1442 for (i=0; i<max_layer+2; i++)
1444 int dir;
1445 XCharStruct size;
1446 int swidth;
1447 const char *name;
1449 if (i == max_layer)
1450 name = SOLDER_SIDE_NAME;
1451 else if (i == max_layer + 1)
1452 name = COMPONENT_SIDE_NAME;
1453 else
1454 name = PCB->Data->Layer[i].Name;
1455 XTextExtents (lgr.font, name, strlen(name), &dir, &lg_fa, &lg_fd, &size);
1456 swidth = size.rbearing - size.lbearing;
1457 if (lg_label_width < swidth)
1458 lg_label_width = swidth;
1460 lg_label_width += 4;
1462 n = 0;
1463 stdarg(XmNwidth, lg_label_width + (lg_fa+lg_fd) * max_layer);
1464 stdarg(XmNheight, (lg_fa+lg_fd) * (max_layer + 2));
1465 XtSetValues(lg_buttonform, args, n);
1466 lgbutton_expose (lg_buttonform, 0, 0);
1468 #if 0
1469 for (i = 0; i < max_layer + 2; i++)
1471 char *name = "unknown";
1472 n = 0;
1473 if (i < max_layer)
1474 name = PCB->Data->Layer[i].Name;
1475 else if (i == max_layer)
1476 name = SOLDER_SIDE_NAME;
1477 else if (i == max_layer + 1)
1478 name = COMPONENT_SIDE_NAME;
1479 stdarg (XmNlabelString, XmStringCreateLocalized (name));
1480 XtSetValues (lglabels[i], args, n);
1481 for (j = 0; j < max_layer; j++)
1483 if (sets[i][j] != XmToggleButtonGetState (lgbuttons[i][j]))
1485 XmToggleButtonSetState (lgbuttons[i][j], sets[i][j], 0);
1489 XtUnmanageChild(lg_buttonform);
1490 for (i = 0; i < MAX_LAYER + 2; i++)
1491 for (j = 0; j < MAX_LAYER; j++)
1493 if (i < max_layer + 2 && j < max_layer)
1495 XtManageChild(lgbuttons[i][j]);
1496 n = 0;
1497 stdarg (XmNleftPosition, j * (max_layer + 2));
1498 stdarg (XmNrightPosition, (j + 1) * (max_layer + 2));
1499 stdarg (XmNtopPosition, i * max_layer);
1500 stdarg (XmNbottomPosition, (i + 1) * max_layer);
1501 XtSetValues(lgbuttons[i][j], args, n);
1503 else
1504 XtUnmanageChild(lgbuttons[i][j]);
1506 n = 0;
1507 stdarg (XmNfractionBase, max_layer + 2);
1508 XtSetValues (layer_groups_form, args, n);
1509 n = 0;
1510 stdarg (XmNfractionBase, max_layer * (max_layer + 2));
1511 XtSetValues (lg_buttonform, args, n);
1512 XtManageChild(lg_buttonform);
1513 #endif
1516 static const char editlayergroups_syntax[] =
1517 "EditLayerGroups()";
1519 static const char editlayergroups_help[] =
1520 "Let the user change the layer groupings";
1522 /* %start-doc actions EditLayerGroups
1524 Displays a dialog that lets the user view and change the layer
1525 groupings. Each layer (row) can be a member of any one layer group
1526 (column). Note the special layers @code{solder} and @code{component}
1527 allow you to specify which groups represent the top and bottom of the
1528 board.
1530 See @ref{ChangeName Action}.
1532 %end-doc */
1534 static int
1535 EditLayerGroups (int argc, char **argv, int x, int y)
1537 if (!layer_groups_form)
1540 n = 0;
1541 stdarg (XmNfractionBase, max_layer + 2);
1542 stdarg (XmNtitle, "Layer Groups");
1543 layer_groups_form = XmCreateFormDialog (mainwind, "layers", args, n);
1545 n = 0;
1546 stdarg (XmNtopAttachment, XmATTACH_FORM);
1547 stdarg (XmNbottomAttachment, XmATTACH_FORM);
1548 stdarg (XmNrightAttachment, XmATTACH_FORM);
1549 stdarg (XmNleftAttachment, XmATTACH_FORM);
1550 lg_buttonform = XmCreateDrawingArea (layer_groups_form, "layers", args, n);
1551 XtManageChild (lg_buttonform);
1553 XtAddCallback (lg_buttonform, XmNexposeCallback,
1554 (XtCallbackProc) lgbutton_expose, 0);
1555 XtAddCallback (lg_buttonform, XmNinputCallback,
1556 (XtCallbackProc) lgbutton_input, 0);
1557 XtAddCallback (lg_buttonform, XmNresizeCallback,
1558 (XtCallbackProc) lgbutton_resize, 0);
1560 XtGetSubresources (layer_groups_form, &lgr,
1561 "layergroups", "LayerGroups",
1562 lg_resources, XtNumber(lg_resources), 0, 0);
1563 #if 0
1564 stdarg (XmNfractionBase, max_layer * (MAX_LAYER + 2));
1565 lg_buttonform = XmCreateForm (layer_groups_form, "lgbutton", args, n);
1567 for (i = 0; i < MAX_LAYER + 2; i++)
1569 n = 0;
1570 stdarg (XmNleftAttachment, XmATTACH_FORM);
1571 stdarg (XmNtopAttachment, XmATTACH_POSITION);
1572 stdarg (XmNtopPosition, i);
1573 stdarg (XmNbottomAttachment, XmATTACH_POSITION);
1574 stdarg (XmNbottomPosition, i + 1);
1575 stdarg (XmNrightAttachment, XmATTACH_WIDGET);
1576 stdarg (XmNrightWidget, lg_buttonform);
1577 lglabels[i] = XmCreateLabel (layer_groups_form, "layer", args, n);
1578 XtManageChild (lglabels[i]);
1580 for (j = 0; j < MAX_LAYER; j++)
1582 n = 0;
1583 stdarg (XmNleftAttachment, XmATTACH_POSITION);
1584 stdarg (XmNleftPosition, j * (MAX_LAYER + 2));
1585 stdarg (XmNrightAttachment, XmATTACH_POSITION);
1586 stdarg (XmNrightPosition, (j + 1) * (MAX_LAYER + 2));
1587 stdarg (XmNtopAttachment, XmATTACH_POSITION);
1588 stdarg (XmNtopPosition, i * MAX_LAYER);
1589 stdarg (XmNbottomAttachment, XmATTACH_POSITION);
1590 stdarg (XmNbottomPosition, (i + 1) * MAX_LAYER);
1591 stdarg (XmNlabelString, XmStringCreateLocalized (" "));
1592 stdarg (XmNspacing, 0);
1593 stdarg (XmNvisibleWhenOff, True);
1594 stdarg (XmNfillOnSelect, True);
1595 stdarg (XmNshadowThickness, 0);
1596 stdarg (XmNmarginWidth, 0);
1597 stdarg (XmNmarginHeight, 0);
1598 stdarg (XmNhighlightThickness, 0);
1599 lgbuttons[i][j] =
1600 XmCreateToggleButton (lg_buttonform, "label", args, n);
1601 XtManageChild (lgbuttons[i][j]);
1603 XtAddCallback (lgbuttons[i][j], XmNvalueChangedCallback,
1604 (XtCallbackProc) lgbutton_cb,
1605 (XtPointer) (i * max_layer + j));
1608 #endif
1610 lesstif_update_layer_groups ();
1611 XtManageChild (layer_groups_form);
1612 return 1;
1615 /* ------------------------------------------------------------ */
1617 HID_Action lesstif_dialog_action_list[] = {
1618 {"Load", 0, Load,
1619 load_help, load_syntax},
1620 {"LoadVendor", 0, LoadVendor,
1621 loadvendor_help, loadvendor_syntax},
1622 {"Save", 0, Save,
1623 save_help, save_syntax},
1624 {"DoWindows", 0, DoWindows,
1625 dowindows_help, dowindows_syntax},
1626 {"PromptFor", 0, PromptFor,
1627 promptfor_help, promptfor_syntax},
1628 {"Confirm", 0, ConfirmAction},
1629 {"About", 0, About,
1630 about_help, about_syntax},
1631 {"Print", 0, Print,
1632 print_help, print_syntax},
1633 {"PrintCalibrate", 0, PrintCalibrate,
1634 printcalibrate_help, printcalibrate_syntax},
1635 {"Export", 0, Export,
1636 export_help, export_syntax},
1637 {"AdjustSizes", 0, AdjustSizes,
1638 adjustsizes_help, adjustsizes_syntax},
1639 {"EditLayerGroups", 0, EditLayerGroups,
1640 editlayergroups_help, editlayergroups_syntax},
1643 REGISTER_ACTIONS (lesstif_dialog_action_list)