1 /*
2 * FIG : Facility for Interactive Generation of figures
3 * This file Copyright (c) 2002 Stephane Mancini
4 *
5 * Any party obtaining a copy of these files is granted, free of charge, a
6 * full and unrestricted irrevocable, world-wide, paid up, royalty-free,
7 * nonexclusive right and license to deal in this software and documentation
8 * files (the "Software"), including without limitation the rights to use,
9 * copy, modify, merge, publish, distribute, sublicense and/or sell copies of
10 * the Software, and to permit persons who receive copies from any such
11 * party to do so, with the only requirement being that the above copyright
12 * and this permission notice remain intact.
13 *
14 */
15
16 #include "fig.h"
17 #include "figx.h"
18 #include "resources.h"
19 #include "object.h"
20 #include "mode.h"
21 #include "paintop.h"
22 #include "d_text.h"
23 #include "e_edit.h"
24 #include "e_update.h"
25 #include "u_draw.h"
26 #include "u_fonts.h"
27 #include "w_drawprim.h"
28 #include "w_file.h"
29 #include "w_fontbits.h"
30 #include "w_indpanel.h"
31 #include "w_color.h"
32 #include "w_listwidget.h"
33 #include "w_mousefun.h"
34 #include "w_msgpanel.h"
35 #include "w_setup.h"
36 #include "w_style.h"
37 #include "w_util.h"
38 #include "w_zoom.h"
39
40 #include "w_modepanel.h"
41
42 /* EXPORTS */
43
44 void popup_manage_style_panel(void);
45 void close_style(Widget w, XButtonEvent *ev);
46 Boolean style_dirty_flag = False;
47
48 /* LOCALS */
49
50 static Style_family current_family_set[MAX_STYLE_FAMILY_SET];
51 int current_family = -1, current_style = -1;
52 Widget style_popup, style_main_form, style_main_label;
53 Widget style_family_form, style_style_form;
54 Widget style_family_label, style_family_list_viewport,
55 style_family_choice_label, style_family_list, style_family_name,
56 style_add_family, style_delete_family;
57 Widget style_style_label, style_style_list_viewport,
58 style_style_choice_label, style_style_list, style_style_name,
59 style_add_style, style_delete_style;
60 Widget style_save_style, style_load_style, style_close_style;
61 char *family_text[MAX_STYLE_FAMILY_SET + 1];
62 char *style_text[MAX_STYLE_FAMILY + 1];
63
64 DeclareStaticArgs (20);
65
66 Element style_reference[] = {
67 "depth", Tint, "", &cur_depth, I_DEPTH,
68 "text_step", Tfloat, NULL, &cur_textstep, I_TEXTSTEP,
69 "font_size", Tint, NULL, &cur_fontsize, I_FONTSIZE,
70 "font", Tint, NULL, &cur_latex_font, I_FONT,
71 "font_ps", Tint, NULL, &cur_ps_font, I_FONT,
72 "font_latex", Tint, NULL, &cur_latex_font, I_FONT,
73 "text_flags", Tint, NULL, &cur_textflags, I_FONT | I_TEXTFLAGS,
74 "text_just", Tint, NULL, &cur_textjust, I_TEXTJUST,
75 "line_width", Tint, NULL, &cur_linewidth, I_LINEWIDTH,
76 "line_style", Tint, NULL, &cur_linestyle, I_LINESTYLE,
77 "join_style", Tint, NULL, &cur_joinstyle, I_JOINSTYLE,
78 "cap_style", Tint, NULL, &cur_capstyle, I_CAPSTYLE,
79 "dash_length", Tfloat, NULL, &cur_dashlength, I_CAPSTYLE,
80 "dot_gap", Tfloat, NULL, &cur_dotgap, I_CAPSTYLE,
81 "pen_color", TColor, NULL, &cur_pencolor, I_PEN_COLOR,
82 "fill_color", TColor, NULL, &cur_fillcolor, I_FILL_COLOR,
83 "box_radius", Tint, NULL, &cur_boxradius, I_BOXRADIUS,
84 "fill_style", Tint, NULL, &cur_fillstyle, I_FILLSTYLE,
85 "arrow_mode", Tint, NULL, &cur_arrowmode, I_ARROWMODE,
86 "arrow_type", Tint, NULL, &cur_arrowtype, I_ARROWTYPE,
87 "arrow_width", Tfloat, NULL, &cur_arrowwidth, I_ARROWSIZE,
88 "arrow_height", Tfloat, NULL, &cur_arrowheight, I_ARROWSIZE,
89 "arrow_thick", Tfloat, NULL, &cur_arrowthick, I_ARROWSIZE,
90 "arrow_mult_width", Tfloat, NULL, &cur_arrow_multwidth, I_ARROWSIZE,
91 "arrow_mult_height", Tfloat, NULL, &cur_arrow_multheight, I_ARROWSIZE,
92 "arrow_mult_thick", Tfloat, NULL, &cur_arrow_multthick, I_ARROWSIZE,
93 "arc_type", Tint, NULL, &cur_arctype, I_ARCTYPE,
94 "ellipse_text_angle", Tfloat, NULL, &cur_elltextangle, I_ELLTEXTANGLE,
95 NULL, 0, NULL, NULL, 0
96 };
97
98
99
100 void
construct_style(Style * style,unsigned long flag)101 construct_style (Style * style, unsigned long flag)
102 {
103 int i = 0, j = 0;
104
105 while (style_reference[i].name != NULL) {
106 if (flag & style_reference[i].flag) {
107 style->element[j].name = style_reference[i].name;
108 style->element[j].type = style_reference[i].type;
109 style->element[j].toset = style_reference[i].toset;
110 style->element[j].flag = style_reference[i].flag;
111 switch (style_reference[i].type) {
112 case Tint:
113 style->element[j].value = malloc (sizeof (int));
114 *((int *) style->element[j].value) =
115 *((int *) style_reference[i].toset);
116 break;
117 case Tfloat:
118 style->element[j].value = malloc (sizeof (float));
119 *((float *) style->element[j].value) =
120 *((float *) style_reference[i].toset);
121 break;
122 case TColor:
123 style->element[j].value = malloc (sizeof (int));
124 *((int *) style->element[j].value) =
125 *((int *) style_reference[i].toset);
126 break;
127 }
128 j++;
129 }
130 i++;
131 }
132 if (j < MAX_STYLE_ELEMENT)
133 style->element[j].name = NULL;
134 }
135
136 unsigned long
set_style(Style * style)137 set_style (Style * style)
138 {
139 int i = 0;
140 unsigned long flag = 0;
141
142 while (style->element[i].name != NULL) {
143 flag = flag | style->element[i].flag;
144 switch (style->element[i].type) {
145 case Tint:
146 *((int *) style->element[i].toset) = *((int *) style->element[i].value);
147 break;
148 case Tfloat:
149 *((float *) style->element[i].toset) =
150 *((float *) style->element[i].value);
151 break;
152 case TColor:
153 *((int *) style->element[i].toset) = *((int *) style->element[i].value);
154 break;
155 }
156 i++;
157 }
158 return flag;
159 }
160
161 static int indent;
162
print_indent(FILE * file)163 void print_indent (FILE * file)
164 {
165 int i;
166
167 for (i = 0; i < indent; i++)
168 fprintf (file, " ");
169 }
170
171 void
print_style(FILE * file,Style * style)172 print_style (FILE * file, Style * style)
173 {
174 int i = 0;
175
176 print_indent (file);
177 fprintf (file, "%s [\n", style[i].name);
178 indent += 2;
179 while (style->element[i].name != NULL) {
180 print_indent (file);
181 fprintf (file, "%s : ", style->element[i].name);
182 switch (style->element[i].type) {
183 case Tint:
184 fprintf (file, "%d\n", *((int *) style->element[i].value));
185 break;
186 case Tfloat:
187 fprintf (file, "%f\n", *((float *) style->element[i].value));
188 break;
189 case TColor:
190 fprintf (file, "%d\n", *((int *) style->element[i].value));
191 break;
192 }
193 i++;
194 }
195 indent -= 2;
196 print_indent (file);
197 fprintf (file, "]\n");
198 }
199
200 void
print_style_family(FILE * file,Style_family * family)201 print_style_family (FILE * file, Style_family * family)
202 {
203 int i = 0;
204
205 print_indent (file);
206 fprintf (file, "%s {\n", family->name);
207 indent += 2;
208 while (family->style[i].name != NULL) {
209 print_style (file, &family->style[i]);
210 i++;
211 }
212 indent -= 2;
213 print_indent (file);
214 fprintf (file, "}\n");
215 }
216
217 void
print_family_set(FILE * file,Style_family * family)218 print_family_set (FILE * file, Style_family * family)
219 {
220 int i = 0;
221
222 indent = 0;
223 while (family[i].name != NULL) {
224 print_style_family (file, &family[i]);
225 i++;
226 }
227 }
228
229 /* return the next non-blank line */
230
231 char *
get_nstyle_line(char * string,int buflen,FILE * file)232 get_nstyle_line (char *string, int buflen, FILE * file)
233 {
234 int i;
235
236 while (1) {
237 if (fgets (string, buflen, file) == NULL)
238 return NULL;
239 if (strlen (string) == 1)
240 continue; /* empty (except for newline) - read next */
241 for (i = strlen (string); i >= 0; i--)
242 if (string[i] != '\t' && string[i] != ' ')
243 return string; /* found at least one non-blank char */
244 }
245 }
246
247 /* remove leading and trailing blanks */
248
249 void
trim(char * string)250 trim (char *string)
251 {
252 int i, j, k, len;
253
254 len = strlen (string);
255 for (i = 0; i < len; i++)
256 if (string[i] != ' ')
257 break;
258 for (j = strlen (string) - 1; j > i; j--)
259 if (string[j] != ' ')
260 break;
261 if (j)
262 string[j + 1] = '\0';
263 /* now move string left if i>0 */
264 if (i)
265 for (k = 0; k <= j; i++, k++)
266 string[k] = string[i];
267 }
268
269 /* parse a single style */
270 int
parse_style(Style * style,FILE * file)271 parse_style (Style * style, FILE * file)
272 {
273 int i = 0, j = 0;
274 char name[256], value[256], string[256];
275 long pos;
276
277 pos = ftell (file);
278 if (get_nstyle_line (string, 256, file) == NULL)
279 return 1;
280 if ((sscanf (string, "%[^[^\n] [", name) != 1) || string[0] == '}') {
281 fseek (file, pos, 0);
282 return 1;
283 }
284 /* remove leading and trailing blanks */
285 trim (name);
286 style->name = strdup (name);
287 if (get_nstyle_line (string, 256, file) == NULL)
288 return 1;
289 while (string[0] != ']' &&
290 i < MAX_STYLE_ELEMENT && sscanf (string, "%s : %s", name, value) == 2) {
291 while (style_reference[j].name != NULL && strcmp (style_reference[j].name, name))
292 j++;
293 if (style_reference[j].name != NULL) {
294 style->element[i].name = style_reference[j].name;
295 style->element[i].type = style_reference[j].type;
296 style->element[i].toset = style_reference[j].toset;
297 style->element[i].flag = style_reference[j].flag;
298 switch (style->element[i].type) {
299 case Tint:
300 style->element[i].value = malloc (sizeof (int));
301 *((int *) style->element[i].value) = atoi (value);
302 break;
303
304 case Tfloat:
305 style->element[i].value = malloc (sizeof (float));
306 *((float *) style->element[i].value) = atof (value);
307 break;
308
309 case TColor:
310 style->element[i].value = malloc (sizeof (int));
311 *((int *) style->element[i].value) = atoi (value);
312 break;
313 }
314 i++;
315 }
316 if (get_nstyle_line (string, 256, file) == NULL)
317 return 1;
318 }
319 style->element[i].name = NULL;
320 return 0;
321 }
322
323 int
parse_family_style(Style_family * family,FILE * file)324 parse_family_style (Style_family * family, FILE * file)
325 {
326 int i = 0, r;
327 char name[256], string[256];
328
329 if (get_nstyle_line (string, 256, file) == NULL)
330 return EOF;
331
332 r = sscanf (string, "%[^{^\n] {", name);
333 /* remove leading and trailing blanks */
334 trim (name);
335 family->name = strdup (name);
336 while (i < MAX_STYLE_FAMILY && !parse_style (&family->style[i], file)) {
337 i++;
338 }
339 if (get_nstyle_line (string, 256, file) == NULL)
340 return 1;
341 if (string[0] != '}') {
342 i = 0;
343 return 1;
344 }
345 if (i < MAX_STYLE_FAMILY)
346 family->style[i].name = NULL;
347 return 0;
348 }
349
350 void
parse_family_set(Style_family * family,FILE * file)351 parse_family_set (Style_family * family, FILE * file)
352 {
353 int i = 0, ok;
354
355 while ((ok = parse_family_style (&family[i], file)) == 0)
356 i++;
357 if (ok == 1)
358 i = 0;
359 if (i < MAX_STYLE_FAMILY_SET)
360 family[i].name = NULL;
361 }
362
363 void
load_family_set(Style_family * family)364 load_family_set (Style_family * family)
365 {
366 FILE *file;
367 char name[PATH_MAX];
368
369 strcpy (name, xfigrc_name);
370 strcat (name, "style");
371 if ((file = fopen (name, "r")) != NULL) {
372 parse_family_set (family, file);
373 fclose (file);
374 }
375 else {
376 family[0].name = NULL;
377 }
378 /* clear dirty flag */
379 style_dirty_flag = False;
380 }
381
382 void
save_family_set(Style_family * family)383 save_family_set (Style_family * family)
384 {
385 FILE *file;
386 char name[PATH_MAX];
387
388 strcpy (name, xfigrc_name);
389 strcat (name, "style");
390 file = fopen (name, "w");
391 print_family_set (file, family);
392 fclose (file);
393 /* clear dirty flag */
394 style_dirty_flag = False;
395 }
396
397 /* the name should not contain blanks */
398 int
add_family_to_family_set(Style_family * family,char * name)399 add_family_to_family_set (Style_family * family, char *name)
400 {
401 int i, ok;
402
403 /* search if the family already exists */
404 i = 0;
405 while (i < MAX_STYLE_FAMILY_SET &&
406 family[i].name != NULL && (ok = (strcmp (family[i].name, name) != 0)))
407 i++;
408
409 if ((i < MAX_STYLE_FAMILY_SET) && (family[i].name == NULL)) {
410 family[i].name = strdup (name);
411 family[i].style[0].name = NULL;
412 if (i + 1 < MAX_STYLE_FAMILY_SET)
413 family[i + 1].name = NULL;
414 /* set dirty flag */
415 style_dirty_flag = True;
416 }
417 return i;
418 }
419
420 Boolean
add_style_to_family(Style_family * family,int * iii,int * jjj,char * family_name,char * style_name,unsigned long flag)421 add_style_to_family (Style_family * family,
422 int *iii, int *jjj,
423 char *family_name, char *style_name, unsigned long flag)
424 {
425 int i, j, ok;
426 Boolean status;
427
428 i = add_family_to_family_set (family, family_name);
429 j = 0;
430 while (j < MAX_STYLE_FAMILY &&
431 family[i].style[j].name != NULL &&
432 (ok = (strcmp (family[i].style[j].name, style_name) != 0)))
433 j++;
434
435 if (j < MAX_STYLE_FAMILY) {
436 if (family[i].style[j].name == NULL) {
437 family[i].style[j].name = strdup (style_name);
438 family[i].style[j].element[0].name = NULL;
439 if (j + 1 < MAX_STYLE_FAMILY)
440 family[i].style[j + 1].name = NULL;
441 /* set dirty flag */
442 style_dirty_flag = True;
443 }
444 construct_style (&family[i].style[j], flag);
445 *iii = i;
446 *jjj = j;
447 status = True;
448 } else {
449 *iii = -1;
450 *jjj = -1;
451 status = False;
452 }
453 return status;
454 }
455
delete_family_from_family_set(Style_family * family,char * name)456 void delete_family_from_family_set (Style_family * family, char *name)
457 {
458 int i, ii, j, k, ok;
459
460 /* search if the family exists */
461 i = 0;
462 while (i < MAX_STYLE_FAMILY_SET &&
463 family[i].name != NULL && (ok = (strcmp (family[i].name, name) != 0)))
464 i++;
465 /* it exists */
466 if (!ok) {
467 free (family[i].name);
468 j = 0;
469 while (j < MAX_STYLE_FAMILY && family[i].style[j].name != NULL) {
470 free (family[i].style[j].name);
471 k = 0;
472 while (family[i].style[j].element[k].name != NULL) {
473 free (family[i].style[j].element[k].value);
474 k++;
475 }
476 j++;
477 }
478 for (ii = i + 1; ii < MAX_STYLE_FAMILY_SET && family[ii].name != NULL; ii++) {
479 family[ii - 1].name = family[ii].name;
480 j = 0;
481 while (j < MAX_STYLE_FAMILY && family[ii].style[j].name != NULL) {
482 family[ii - 1].style[j].name = family[ii].style[j].name;
483 k = 0;
484 while (family[ii].style[j].element[k].name != NULL) {
485 family[ii - 1].style[j].element[k] = family[ii].style[j].element[k];
486 k++;
487 }
488 family[ii - 1].style[j].element[k].name = NULL;
489 j++;
490 }
491 family[ii - 1].style[j].name = NULL;
492 }
493 family[ii - 1].name = NULL;
494 /* set dirty flag */
495 style_dirty_flag = True;
496 }
497 }
498
delete_style_from_family(Style_family * family,char * family_name,char * style_name)499 void delete_style_from_family (Style_family * family, char *family_name, char *style_name)
500 {
501 int i, j, jj, k, ok;
502
503 /* search the family */
504 i = 0;
505 while (i < MAX_STYLE_FAMILY_SET &&
506 family[i].name != NULL && (ok = (strcmp (family[i].name, family_name) != 0)))
507 i++;
508 /* it exists */
509 if (!ok) {
510 /* search the style */
511 j = 0;
512 while (j < MAX_STYLE_FAMILY &&
513 family[i].style[j].name != NULL &&
514 (ok = (strcmp (family[i].style[j].name, style_name) != 0)))
515 j++;
516 if (!ok) {
517 free (family[i].style[j].name);
518 k = 0;
519 while (family[i].style[j].element[k].name != NULL) {
520 free (family[i].style[j].element[k].value);
521 k++;
522 }
523 for (jj = j + 1;
524 jj < MAX_STYLE_FAMILY && family[i].style[jj].name != NULL; jj++) {
525 family[i].style[jj - 1].name = family[i].style[jj].name;
526 k = 0;
527 while (family[i].style[jj].element[k].name != NULL) {
528 family[i].style[jj - 1].element[k] = family[i].style[jj].element[k];
529 k++;
530 }
531 family[i].style[jj].element[k].name = NULL;
532 }
533 family[i].style[jj - 1].name = NULL;
534 /* set dirty flag */
535 style_dirty_flag = True;
536 }
537 }
538 }
539
540 static void
build_family_text(Style_family * family)541 build_family_text (Style_family * family)
542 {
543 int i = 0;
544
545 while (i < MAX_STYLE_FAMILY_SET && family[i].name != NULL) {
546 family_text[i] = family[i].name;
547 i++;
548 }
549 family_text[i] = NULL;
550 }
551
552 static void
build_style_text(Style_family * family,int f)553 build_style_text (Style_family * family, int f)
554 {
555 int i = 0;
556
557 if (f >= 0) {
558 while (i < MAX_STYLE_FAMILY && family[f].style[i].name != NULL) {
559 style_text[i] = family[f].style[i].name;
560 i++;
561 }
562 style_text[i] = NULL;
563 }
564 else
565 style_text[0] = NULL;
566 }
567
568 static void
style_update(void)569 style_update (void)
570 {
571 build_family_text (current_family_set);
572 build_style_text (current_family_set, current_family);
573 XawListChange (style_family_list, family_text, 0, 0, True);
574 XawListChange (style_style_list, style_text, 0, 0, True);
575 if (current_family >= 0)
576 panel_set_value (style_family_name, family_text[current_family]);
577 else
578 panel_set_value (style_family_name, "");
579
580 if (current_style >= 0)
581 panel_set_value (style_style_name, style_text[current_style]);
582 else
583 panel_set_value (style_style_name, "");
584 }
585
586 static void
family_select(Widget w,XtPointer closure,XtPointer call_data)587 family_select (Widget w, XtPointer closure, XtPointer call_data)
588 {
589
590 XawListReturnStruct *ret_struct = (XawListReturnStruct *) call_data;
591
592 if (ret_struct == 0)
593 return;
594 current_family = ret_struct->list_index;
595 current_style = -1;
596 style_update ();
597 }
598
599 static void
style_select(Widget w,XtPointer closure,XtPointer call_data)600 style_select (Widget w, XtPointer closure, XtPointer call_data)
601 {
602 XawListReturnStruct *ret_struct = (XawListReturnStruct *) call_data;
603
604 if (ret_struct == 0)
605 return;
606 current_style = ret_struct->list_index;
607 style_update ();
608 cur_updatemask = set_style (¤t_family_set[current_family].style[current_style]);
609
610 tog_selective_update (cur_updatemask);
611 update_current_settings ();
612 }
613
614 void
add_family(Widget w,XButtonEvent * ev)615 add_family (Widget w, XButtonEvent *ev)
616 {
617 char *fval;
618
619 FirstArg (XtNstring, &fval);
620 GetValues (style_family_name);
621 if (strlen (fval)) {
622 current_family = add_family_to_family_set (current_family_set, fval);
623 current_style = -1;
624 style_update ();
625 }
626 }
627
628 void
delete_family(Widget w,XButtonEvent * ev)629 delete_family (Widget w, XButtonEvent *ev)
630 {
631 char *fval;
632
633 FirstArg (XtNstring, &fval);
634 GetValues (style_family_name);
635 if (strlen (fval)) {
636 delete_family_from_family_set (current_family_set, fval);
637 current_family = -1;
638 current_style = -1;
639 style_update ();
640 }
641 }
642
643 void
add_style(Widget w,XButtonEvent * ev)644 add_style (Widget w, XButtonEvent *ev)
645 {
646 char *fval, *sval, ftemp[256], stemp[256];
647
648 FirstArg (XtNstring, &fval);
649 GetValues (style_family_name);
650 strcpy (ftemp, fval);
651 FirstArg (XtNstring, &sval);
652 GetValues (style_style_name);
653 strcpy (stemp, sval);
654 if (strlen (ftemp) && strlen (stemp)) {
655 if (!add_style_to_family (current_family_set,
656 ¤t_family, ¤t_style,
657 ftemp, stemp, cur_updatemask))
658 file_msg("Sorry, no more room available in this family : use a new one");
659 style_update ();
660 }
661 }
662
663
664
665 void
delete_style(Widget w,XButtonEvent * ev)666 delete_style (Widget w, XButtonEvent *ev)
667 {
668 char *fval, *sval;
669
670 FirstArg (XtNstring, &fval);
671 GetValues (style_family_name);
672 FirstArg (XtNstring, &sval);
673 GetValues (style_style_name);
674 if (strlen (fval) && strlen (sval)) {
675 delete_style_from_family (current_family_set, fval, sval);
676 current_style = -1;
677 style_update ();
678 }
679 }
680
681 void
save_style(Widget w,XButtonEvent * ev)682 save_style (Widget w, XButtonEvent *ev)
683 {
684 save_family_set (current_family_set);
685 }
686
687 void
load_style(Widget w,XButtonEvent * ev)688 load_style (Widget w, XButtonEvent *ev)
689 {
690 load_family_set (current_family_set);
691 current_family = current_style = -1;
692 style_update ();
693 }
694
695 int
confirm_close_style(void)696 confirm_close_style (void)
697 {
698 int status;
699
700 if (style_dirty_flag) {
701 status = popup_query(QUERY_YESNOCAN, "Do you wish to save the changes you made to the styles?");
702 if (status == RESULT_YES)
703 save_style((Widget) 0, (XButtonEvent *) 0);
704 return status;
705 }
706 return RESULT_YES;
707 }
708
709 void
close_style(Widget w,XButtonEvent * ev)710 close_style (Widget w, XButtonEvent *ev)
711 {
712 if (confirm_close_style() == RESULT_CANCEL)
713 return;
714 XtPopdown (style_popup);
715 }
716
717 static String style_family_list_translations = "<Btn1Down>,<Btn1Up>: Set()Notify()\n\
718 <Btn1Up>(2): family_select()\n\
719 <Key>Escape: CloseStyle()\n\
720 <Key>Return: family_select()\n";
721
722 static String style_family_name_translations = "<Key>Escape: CloseStyle()\n\
723 <Key>Return: add_family()\n";
724
725 static String style_style_list_translations = "<Btn1Down>,<Btn1Up>: Set()Notify()\n\
726 <Btn1Up>(2): style_select()\n\
727 <Key>Escape: CloseStyle()\n\
728 <Key>Return: style_select()\n";
729
730 static String style_style_name_translations = "<Key>Escape: CloseStyle()\n\
731 <Key>Return: add_style()\n";
732
733 static String style_translations = "<Message>WM_PROTOCOLS: CloseStyle()\n\
734 <Key>Escape: CloseStyle()\n";
735
736 static XtActionsRec style_actions[] = {
737 "ShowNamedStyles", (XtActionProc) popup_manage_style_panel,
738 "add_family", (XtActionProc) add_family,
739 "delete_family", (XtActionProc) delete_family,
740 "add_style", (XtActionProc) add_style,
741 "delete_style", (XtActionProc) delete_style,
742 "family_select", (XtActionProc) family_select,
743 "style_select", (XtActionProc) style_select,
744 "CloseStyle", (XtActionProc) close_style
745 };
746
747 /**********************************/
748 /* create the style manager panel */
749 /**********************************/
750
751 void
init_manage_style_panel(void)752 init_manage_style_panel (void)
753 {
754 load_family_set (current_family_set);
755 FirstArg (XtNtitle, "Xfig: Manage Styles");
756 NextArg (XtNcolormap, tool_cm);
757
758 style_popup = XtCreatePopupShell ("style_manage_panel",
759 transientShellWidgetClass, tool, Args, ArgCount);
760
761 XtOverrideTranslations (style_popup, XtParseTranslationTable (style_translations));
762 FirstArg (XtNborderWidth, 0);
763
764 style_main_form = XtCreateManagedWidget ("style_main_form",
765 formWidgetClass, style_popup,
766 Args, ArgCount);
767 XtOverrideTranslations (style_main_form,
768 XtParseTranslationTable (style_translations));
769
770 /* label for title - "Manage Styles" */
771 FirstArg (XtNlabel, "Manage Styles");
772 NextArg (XtNborderWidth, 0);
773 style_main_label =
774 XtCreateManagedWidget ("style_main_label", labelWidgetClass,
775 style_main_form, Args, ArgCount);
776
777 /* frame for Family stuff */
778
779 FirstArg (XtNborderWidth, 1);
780 NextArg (XtNfromVert, style_main_label);
781 style_family_form = XtCreateManagedWidget ("style_family_form",
782 formWidgetClass,
783 style_main_form, Args, ArgCount);
784 /* Put family stuff */
785 FirstArg (XtNlabel, "Family");
786 NextArg (XtNborderWidth, 0);
787 style_family_label =
788 XtCreateManagedWidget ("style_family_label", labelWidgetClass,
789 style_family_form, Args, ArgCount);
790
791 FirstArg (XtNallowVert, True);
792 NextArg (XtNfromHoriz, style_family_label);
793 NextArg (XtNborderWidth, INTERNAL_BW);
794 NextArg (XtNwidth, 180);
795 NextArg (XtNheight, 100);
796 NextArg (XtNtop, XtChainBottom);
797 NextArg (XtNbottom, XtChainBottom);
798 NextArg (XtNleft, XtChainLeft);
799 NextArg (XtNright, XtChainRight);
800 style_family_list_viewport =
801 XtCreateManagedWidget ("style_family_list_viewport",
802 viewportWidgetClass, style_family_form, Args, ArgCount);
803 FirstArg (XtNlist, family_text);
804 NextArg (XtNforceColumns, True);
805 NextArg (XtNdefaultColumns, 1);
806 NextArg (XtNallowVert, True);
807 style_family_list =
808 XtCreateManagedWidget ("family_list", figListWidgetClass,
809 style_family_list_viewport, Args, ArgCount);
810
811 XawListChange (style_family_list, family_text, 0, 0, True);
812 XtAddCallback (style_family_list, XtNcallback, family_select, (XtPointer) NULL);
813 XtAugmentTranslations (style_family_list,
814 XtParseTranslationTable (style_family_list_translations));
815
816 FirstArg (XtNlabel, "Choice");
817 NextArg (XtNfromVert, style_family_list_viewport);
818 NextArg (XtNborderWidth, 0);
819 style_family_choice_label =
820 XtCreateManagedWidget ("family_choice_label", labelWidgetClass,
821 style_family_form, Args, ArgCount);
822 FirstArg (XtNeditType, XawtextEdit);
823 NextArg (XtNfromVert, style_family_list_viewport);
824 NextArg (XtNfromHoriz, style_family_choice_label);
825 NextArg (XtNwidth, 180);
826 NextArg (XtNheight, 30);
827 NextArg (XtNstring, "\0");
828 NextArg (XtNscrollHorizontal, XawtextScrollWhenNeeded);
829 style_family_name = XtCreateManagedWidget ("style_family_name",
830 asciiTextWidgetClass,
831 style_family_form, Args, ArgCount);
832 XtOverrideTranslations (style_family_name,
833 XtParseTranslationTable (style_family_name_translations));
834
835 FirstArg (XtNlabel, "Add");
836 NextArg (XtNfromVert, style_family_name);
837 style_add_family =
838 XtCreateManagedWidget ("style_add_family", commandWidgetClass,
839 style_family_form, Args, ArgCount);
840 XtAddCallback (style_add_family, XtNcallback, (XtCallbackProc) add_family,
841 (XtPointer) NULL);
842
843 FirstArg (XtNlabel, "Delete");
844 NextArg (XtNfromVert, style_family_name);
845 NextArg (XtNfromHoriz, style_add_family);
846 style_delete_family = XtCreateManagedWidget ("style_delete_family",
847 commandWidgetClass,
848 style_family_form, Args, ArgCount);
849 XtAddCallback (style_delete_family, XtNcallback,
850 (XtCallbackProc) delete_family, (XtPointer) NULL);
851
852
853 /* frame for Style stuff inside family frame */
854
855 FirstArg (XtNborderWidth, 1);
856 NextArg (XtNfromVert, style_add_family);
857 style_style_form = XtCreateManagedWidget ("style_style_form",
858 formWidgetClass,
859 style_family_form, Args, ArgCount);
860 FirstArg (XtNlabel, "Style ");
861 NextArg (XtNborderWidth, 0);
862 style_style_label =
863 XtCreateManagedWidget ("style_style_label", labelWidgetClass,
864 style_style_form, Args, ArgCount);
865 FirstArg (XtNallowVert, True);
866 NextArg (XtNfromHoriz, style_style_label);
867 NextArg (XtNborderWidth, INTERNAL_BW);
868 NextArg (XtNwidth, 180);
869 NextArg (XtNheight, 100);
870 NextArg (XtNtop, XtChainBottom);
871 NextArg (XtNbottom, XtChainBottom);
872 NextArg (XtNleft, XtChainLeft);
873 NextArg (XtNright, XtChainRight);
874 style_style_list_viewport =
875 XtCreateManagedWidget ("style_family_list_viewport",
876 viewportWidgetClass, style_style_form, Args, ArgCount);
877
878
879 FirstArg (XtNlist, style_text);
880 NextArg (XtNforceColumns, True);
881 NextArg (XtNdefaultColumns, 1);
882 style_style_list =
883 XtCreateManagedWidget ("style_list", figListWidgetClass,
884 style_style_list_viewport, Args, ArgCount);
885
886 XawListChange (style_style_list, style_text, 0, 0, True);
887 XtAddCallback (style_style_list, XtNcallback, style_select, (XtPointer) NULL);
888 XtAugmentTranslations (style_style_list,
889 XtParseTranslationTable (style_style_list_translations));
890
891
892 FirstArg (XtNlabel, "Choice");
893 NextArg (XtNfromVert, style_style_list_viewport);
894 NextArg (XtNborderWidth, 0);
895 style_style_choice_label =
896 XtCreateManagedWidget ("style_choice_label", labelWidgetClass,
897 style_style_form, Args, ArgCount);
898 FirstArg (XtNeditType, XawtextEdit);
899 NextArg (XtNfromVert, style_style_list_viewport);
900 NextArg (XtNfromHoriz, style_style_choice_label);
901 NextArg (XtNwidth, 180);
902 NextArg (XtNheight, 30);
903 NextArg (XtNstring, "\0");
904 NextArg (XtNscrollHorizontal, XawtextScrollWhenNeeded);
905 style_style_name = XtCreateManagedWidget ("style_style_name",
906 asciiTextWidgetClass,
907 style_style_form, Args, ArgCount);
908 XtOverrideTranslations (style_style_name,
909 XtParseTranslationTable (style_style_name_translations));
910
911 FirstArg (XtNlabel, "Add");
912 NextArg (XtNfromVert, style_style_name);
913 style_add_style =
914 XtCreateManagedWidget ("style_add_family", commandWidgetClass,
915 style_style_form, Args, ArgCount);
916 XtAddCallback (style_add_style, XtNcallback, (XtCallbackProc) add_style,
917 (XtPointer) NULL);
918
919 FirstArg (XtNlabel, "Delete");
920 NextArg (XtNfromVert, style_style_name);
921 NextArg (XtNfromHoriz, style_add_style);
922 style_delete_style = XtCreateManagedWidget ("style_delete_family",
923 commandWidgetClass,
924 style_style_form, Args, ArgCount);
925 XtAddCallback (style_delete_style, XtNcallback,
926 (XtCallbackProc) delete_style, (XtPointer) NULL);
927
928 /* overall save/load/close buttons */
929
930 FirstArg (XtNlabel, "Save settings");
931 NextArg (XtNfromVert, style_family_form);
932 style_save_style = XtCreateManagedWidget ("style_save",
933 commandWidgetClass,
934 style_main_form, Args, ArgCount);
935 XtAddCallback (style_save_style, XtNcallback, (XtCallbackProc) save_style,
936 (XtPointer) NULL);
937
938 FirstArg (XtNlabel, "Reload settings");
939 NextArg (XtNfromVert, style_family_form);
940 NextArg (XtNfromHoriz, style_save_style);
941 style_load_style = XtCreateManagedWidget ("style_load",
942 commandWidgetClass,
943 style_main_form, Args, ArgCount);
944 XtAddCallback (style_load_style, XtNcallback, (XtCallbackProc) load_style,
945 (XtPointer) NULL);
946
947 FirstArg (XtNlabel, "Close");
948 NextArg (XtNfromHoriz, style_load_style);
949 NextArg (XtNfromVert, style_family_form);
950 style_close_style = XtCreateManagedWidget ("style_close",
951 commandWidgetClass,
952 style_main_form, Args, ArgCount);
953 XtAddCallback (style_close_style, XtNcallback,
954 (XtCallbackProc) close_style, (XtPointer) NULL);
955
956 style_update ();
957 }
958
959 void
add_style_actions(void)960 add_style_actions(void)
961 {
962 XtAppAddActions (tool_app, style_actions, XtNumber (style_actions));
963 }
964
965 /* now that the main tool has been created we can position (although it
966 is not popped up yet) the style panel */
967
968 void
setup_manage_style_panel(void)969 setup_manage_style_panel (void)
970 {
971 Position x_val, y_val;
972 Dimension width, height;
973
974 FirstArg (XtNwidth, &width);
975 NextArg (XtNheight, &height);
976 GetValues (tool);
977 /* position the popup 1/6 in from left and 1/4 down from top */
978 XtTranslateCoords (tool, (Position) (width / 6), (Position) (height / 4),
979 &x_val, &y_val);
980
981 FirstArg (XtNx, x_val);
982 NextArg (XtNy, y_val);
983 SetValues (style_popup);
984 }
985
986 void
popup_manage_style_panel(void)987 popup_manage_style_panel (void)
988 {
989 /* first make sure we're in update mode */
990 change_mode (&update_ic);
991 /* use GrabNone so user can choose styles while drawing */
992 XtPopup (style_popup, XtGrabNone);
993 (void) XSetWMProtocols (tool_d, XtWindow (style_popup), &wm_delete_window, 1);
994 }
995