1 /*
2 * FIG : Facility for Interactive Generation of figures
3 * Copyright (c) 1985-1988 by Supoj Sutanthavibul
4 * Parts Copyright (c) 1989-2015 by Brian V. Smith
5 * Parts Copyright (c) 1991 by Paul King
6 * Parts Copyright (c) 2016-2018 by Thomas Loimer
7 *
8 * Any party obtaining a copy of these files is granted, free of charge, a
9 * full and unrestricted irrevocable, world-wide, paid up, royalty-free,
10 * nonexclusive right and license to deal in this software and documentation
11 * files (the "Software"), including without limitation the rights to use,
12 * copy, modify, merge, publish, distribute, sublicense and/or sell copies of
13 * the Software, and to permit persons who receive copies from any such
14 * party to do so, with the only requirement being that the above copyright
15 * and this permission notice remain intact.
16 *
17 */
18
19 #include "fig.h"
20 #include "figx.h"
21 #include "resources.h"
22 #include "object.h"
23 #include "mode.h"
24 #include "paintop.h"
25 #include "d_text.h"
26 #include "e_edit.h"
27 #include "u_create.h"
28 #include "u_draw.h"
29 #include "u_fonts.h"
30 #include "w_drawprim.h"
31 #include "w_file.h"
32 #include "w_fontbits.h"
33 #include "w_indpanel.h"
34 #include "w_color.h"
35 #include "w_mousefun.h"
36 #include "w_msgpanel.h"
37 #include "w_setup.h"
38 #include "w_style.h"
39 #include "w_util.h"
40 #include "w_zoom.h"
41
42 #include "f_util.h"
43 #include "u_bound.h"
44 #include "u_free.h"
45 #include "u_list.h"
46 #include "u_markers.h"
47 #include "u_redraw.h"
48 #include "w_canvas.h"
49 #include "w_grid.h"
50 #include "w_rulers.h"
51
52 #define MAX_SCROLL_WD 50
53
54 /* EXPORTS */
55
56 Boolean update_buts_managed;
57 Widget choice_popup;
58 void show_depth(ind_sw_info *sw), show_zoom(ind_sw_info *sw);
59 void show_fillstyle(ind_sw_info *sw);
60 void fontpane_popup(int *psfont_adr, int *latexfont_adr, int *psflag_adr, void (*showfont_fn) (/* ??? */), Widget show_widget);
61 void make_pulldown_menu_images(choice_info *entries, Cardinal nent, Pixmap *images, char **texts, Widget parent, XtCallbackProc callback);
62 void tog_selective_update(long unsigned int mask);
63 unsigned long cur_indmask; /* mask showing which indicator buttons are mapped */
64 void inc_zoom_centered(ind_sw_info *sw);
65 void dec_zoom_centered(ind_sw_info *sw);
66 void fit_zoom(ind_sw_info *sw);
67 ind_sw_info ind_switches[];
68 ind_sw_info *fill_style_sw;
69 ind_sw_info *pen_color_button, *fill_color_button, *depth_button;
70 unsigned long cur_indmask = 0; /* start showing only zoom and grid buttons */
71
72 /* LOCAL */
73
74 #define MAX_FLAGS 3 /* number of text flags (cur_flagshown) */
75 #define MAX_ARROWPARMS 3 /* number of arrow size parms (cur_arrowshown) */
76 #define MAX_DIMLINEPARMS 15 /* number of dimension line parms (cur_dimline) */
77
78 static int cur_anglegeom = L_UNCONSTRAINED;
79 static int cur_flagshown = 0;
80 static int cur_arrowsizeshown = 0;
81 static int cur_dimlineshown = 0;
82 static Pixel arrow_size_bg, arrow_size_fg;
83 static Boolean save_use_abs;
84
85 #ifndef XAW3D1_5E
86 /* popup message over button when mouse enters it */
87 static void ind_balloon_trigger(Widget widget, XtPointer closure, XEvent *event, Boolean *continue_to_dispatch);
88 static void ind_unballoon(Widget widget, XtPointer closure, XEvent *event, Boolean *continue_to_dispatch);
89 #endif /* XAW3D1_5E */
90
91 /***** value panel set translations *****/
92 static String set_translations =
93 "<Key>Return: ClearMousefunKbd()SetValue()\n\
94 Meta<Key>Q: QuitNval()\n\
95 <Key>Escape: QuitNval()\n\
96 Ctrl<Key>J: no-op(RingBell)\n\
97 Ctrl<Key>M: no-op(RingBell)\n\
98 Ctrl<Key>X: EmptyTextKey()\n\
99 Ctrl<Key>U: multiply(4)\n\
100 <Key>F18: PastePanelKey()\n";
101
102 /***** value panel translations, prototypes and actions *****/
103 static String nval_translations =
104 "<Key>Escape: QuitNval()\n\
105 <Message>WM_PROTOCOLS: QuitNval()\n";
106
107 static void nval_panel_set(Widget w, XButtonEvent *ev);
108 static void nval_panel_cancel(Widget w, XButtonEvent *ev);
109 static XtActionsRec nval_actions[] =
110 {
111 {"SetValue", (XtActionProc) nval_panel_set},
112 {"QuitNval", (XtActionProc) nval_panel_cancel},
113 };
114
115 /***** dimension line panel translations *****/
116 static void dimline_panel_cancel(Widget w, XButtonEvent *ev);
117 static void dimline_panel_ok(Widget w, XButtonEvent *ev);
118 static String dimline_translations =
119 "<Key>Escape: QuitDimline()\n\
120 <Message>WM_PROTOCOLS: QuitDimline()";
121 static XtActionsRec dimline_actions[] =
122 {
123 {"QuitDimline", (XtActionProc) dimline_panel_cancel},
124 };
125
126 /***** choice panel cancel actions and translations *****/
127 static String choice_translations =
128 "<Key>Escape: QuitChoice()\n\
129 <Message>WM_PROTOCOLS: QuitChoice()";
130 static void choice_panel_cancel(Widget w, XButtonEvent *ev);
131 static XtActionsRec choice_actions[] =
132 {
133 {"QuitChoice", (XtActionProc) choice_panel_cancel},
134 };
135
136 DeclareStaticArgs(20);
137
138 /* declarations for value buttons */
139
140 /* this flag is used to get around a bug in XFree86 3.3.1 where when an update
141 is done from an object to the indicator panel, the images don't update properly.
142 This will make the update button be unmapped then remapped to force the image
143 to be updated. From Heiko Schroeder (hschroe@ebs.wilhelmshaven-online.de) */
144 Boolean update_buts_managed = False;
145
146 /* and these can be static */
147
148 /* declarations for choice buttons */
149 static void darken_fill(ind_sw_info *sw), lighten_fill(ind_sw_info *sw);
150 static void inc_choice(ind_sw_info *sw), dec_choice(ind_sw_info *sw);
151 static void show_valign(ind_sw_info *sw), show_halign(ind_sw_info *sw), show_textjust(ind_sw_info *sw);
152 static void show_arrowmode(ind_sw_info *sw), show_arrowtype(ind_sw_info *sw);
153 static void show_arrowsize(ind_sw_info *sw), inc_arrowsize(ind_sw_info *sw), dec_arrowsize(ind_sw_info *sw);
154 static void show_linestyle(ind_sw_info *sw), show_joinstyle(ind_sw_info *sw), show_capstyle(ind_sw_info *sw);
155 static void show_anglegeom(ind_sw_info *sw), show_arctype(ind_sw_info *sw);
156 static void show_pointposn(ind_sw_info *sw), show_gridmode(ind_sw_info *sw), show_linkmode(ind_sw_info *sw);
157 static void show_linewidth(ind_sw_info *sw), inc_linewidth(ind_sw_info *sw), dec_linewidth(ind_sw_info *sw);
158 static void show_boxradius(ind_sw_info *sw), inc_boxradius(ind_sw_info *sw), dec_boxradius(ind_sw_info *sw);
159 static void show_font(ind_sw_info *sw), inc_font(ind_sw_info *sw), dec_font(ind_sw_info *sw);
160 static void show_flags(ind_sw_info *sw), inc_flags(ind_sw_info *sw), dec_flags(ind_sw_info *sw);
161 static void show_fontsize(ind_sw_info *sw), inc_fontsize(ind_sw_info *sw), dec_fontsize(ind_sw_info *sw);
162 static void show_textstep(ind_sw_info *sw), inc_textstep(ind_sw_info *sw), dec_textstep(ind_sw_info *sw);
163 static void show_rotnangle(ind_sw_info *sw), show_rotnangle_0(ind_sw_info *sw, int panel), inc_rotnangle(ind_sw_info *sw), dec_rotnangle(ind_sw_info *sw);
164 static void show_elltextangle(ind_sw_info *sw), inc_elltextangle(ind_sw_info *sw), dec_elltextangle(ind_sw_info *sw);
165 static void show_numsides(ind_sw_info *sw), inc_numsides(ind_sw_info *sw), dec_numsides(ind_sw_info *sw);
166 static void show_numcopies(ind_sw_info *sw), inc_numcopies(ind_sw_info *sw), dec_numcopies(ind_sw_info *sw);
167 static void show_numxcopies(ind_sw_info *sw), inc_numxcopies(ind_sw_info *sw), dec_numxcopies(ind_sw_info *sw);
168 static void show_numycopies(ind_sw_info *sw), inc_numycopies(ind_sw_info *sw), dec_numycopies(ind_sw_info *sw);
169 static void inc_depth(ind_sw_info *sw), dec_depth(ind_sw_info *sw);
170 static void show_tangnormlen(ind_sw_info *sw), inc_tangnormlen(ind_sw_info *sw), dec_tangnormlen(ind_sw_info *sw);
171 static void show_dimline(ind_sw_info *sw), inc_dimline(ind_sw_info *sw), dec_dimline(ind_sw_info *sw);
172 static void dimline_style_select(Widget w, XtPointer new_style, XtPointer call_data);
173 static void popup_fonts(ind_sw_info *sw);
174 static void note_state(Widget w, XtPointer closure, XtPointer call_data);
175 static void set_all_update(Widget w, XtPointer data, XEvent *event, Boolean *cont);
176 static void clr_all_update(Widget w, XtPointer data, XEvent *event, Boolean *cont);
177 static void tog_all_update(Widget w, XtPointer data, XEvent *event, Boolean *cont);
178
179 static void zoom_to_fit(Widget w, XtPointer closure, XtPointer call_data);
180
181 static char indbuf[30];
182 static float old_display_zoomscale = -1.0;
183 static float old_rotnangle = -1.0;
184 static float old_elltextangle = -1.0;
185
186 Dimension UPD_CTRL_WD;
187
188 Widget set_upd, upd_tog,
189 clr_upd, tog_upd, upd_ctrl_lab, upd_ctrl_btns;
190 Widget abstoggle, multtoggle;
191
192 /* indicator switch definitions */
193
194 static choice_info anglegeom_choices[] = {
195 {L_UNCONSTRAINED, &unconstrained_ic,},
196 {L_LATEXLINE, &latexline_ic,},
197 {L_LATEXARROW, &latexarrow_ic,},
198 {L_MOUNTHATTAN, &mounthattan_ic,},
199 {L_MANHATTAN, &manhattan_ic,},
200 {L_MOUNTAIN, &mountain_ic,},
201 };
202 #define NUM_ANGLEGEOM_CHOICES (sizeof(anglegeom_choices)/sizeof(choice_info))
203
204 static choice_info valign_choices[] = {
205 {ALIGN_NONE, &none_ic,},
206 {ALIGN_TOP, &valignt_ic,},
207 {ALIGN_CENTER, &valignc_ic,},
208 {ALIGN_BOTTOM, &valignb_ic,},
209 {ALIGN_DISTRIB_C, &valigndc_ic,},
210 {ALIGN_DISTRIB_E, &valignde_ic,},
211 {ALIGN_ABUT, &valigna_ic,},
212 };
213 #define NUM_VALIGN_CHOICES (sizeof(valign_choices)/sizeof(choice_info))
214
215 static choice_info halign_choices[] = {
216 {ALIGN_NONE, &none_ic,},
217 {ALIGN_LEFT, &halignl_ic,},
218 {ALIGN_CENTER, &halignc_ic,},
219 {ALIGN_RIGHT, &halignr_ic,},
220 {ALIGN_DISTRIB_C, &haligndc_ic,},
221 {ALIGN_DISTRIB_E, &halignde_ic,},
222 {ALIGN_ABUT, &haligna_ic,},
223 };
224 #define NUM_HALIGN_CHOICES (sizeof(halign_choices)/sizeof(choice_info))
225
226 static choice_info gridmode_choices[] = {
227 {GRID_0, &none_ic,},
228 {GRID_1, &grid1_ic,},
229 {GRID_2, &grid2_ic,},
230 {GRID_3, &grid3_ic,},
231 {GRID_4, &grid4_ic,},
232 {GRID_ISO_1, &grid_iso1_ic,}, // isometric grid
233 {GRID_ISO_2, &grid_iso2_ic,},
234 {GRID_ISO_3, &grid_iso3_ic,},
235 {GRID_ISO_4, &grid_iso4_ic,},
236 };
237 #define NUM_GRIDMODE_CHOICES (sizeof(gridmode_choices)/sizeof(choice_info))
238
239 static choice_info pointposn_choices[] = {
240 {P_ANY, &any_ic,},
241 {P_MAGNET, &fine_grid_ic,},
242 {P_GRID1, &grid1_ic,},
243 {P_GRID2, &grid2_ic,},
244 {P_GRID3, &grid3_ic,},
245 {P_GRID4, &grid4_ic,},
246 };
247 #define NUM_POINTPOSN_CHOICES (sizeof(pointposn_choices)/sizeof(choice_info))
248
249 static choice_info arrowmode_choices[] = {
250 {L_NOARROWS, &noarrows_ic,},
251 {L_FARROWS, &farrows_ic,},
252 {L_FBARROWS, &fbarrows_ic,},
253 {L_BARROWS, &barrows_ic,},
254 };
255 #define NUM_ARROWMODE_CHOICES (sizeof(arrowmode_choices)/sizeof(choice_info))
256
257 /* the following are used for the dimension-line arrowhead selection */
258 /* e_edit.c also uses these */
259
260 choice_info dim_arrowtype_choices[] = {
261 {-1, &arrow0_ic,},
262 {0, &arrow0_ic,},
263 {1, &arrow1o_ic,},
264 {2, &arrow1f_ic,},
265 {3, &arrow2o_ic,},
266 {4, &arrow2f_ic,},
267 {5, &arrow3o_ic,},
268 {6, &arrow3f_ic,},
269 #ifdef ARROWS4TO14
270 {7, &arrow4o_ic,},
271 {8, &arrow4f_ic,},
272 {9, &arrow5o_ic,},
273 {10, &arrow5f_ic,},
274 {11, &arrow6o_ic,},
275 {12, &arrow6f_ic,},
276 {13, &arrow7o_ic,},
277 {14, &arrow7f_ic,},
278 {15, &arrow8o_ic,},
279 {16, &arrow8f_ic,},
280 {17, &arrow9a_ic,},
281 {18, &arrow9b_ic,},
282 {19, &arrow10o_ic,},
283 {20, &arrow10f_ic,},
284 {21, &arrow11o_ic,},
285 {22, &arrow11f_ic,},
286 {23, &arrow12o_ic,},
287 {24, &arrow12f_ic,},
288 {25, &arrow13a_ic,},
289 {26, &arrow13b_ic,},
290 {27, &arrow14a_ic,},
291 {28, &arrow14b_ic,},
292 #endif /* ARROWS4TO14 */
293 };
294 #define NUM_DIM_ARROWTYPE_CHOICES (sizeof(dim_arrowtype_choices)/sizeof(choice_info))
295
296 /* these are used only for the arrow type button on the ind panel */
297
298 choice_info arrowtype_choices[] = {
299 {0, &arrow0_ic,},
300 {1, &arrow1o_ic,},
301 {2, &arrow1f_ic,},
302 {3, &arrow2o_ic,},
303 {4, &arrow2f_ic,},
304 {5, &arrow3o_ic,},
305 {6, &arrow3f_ic,},
306 #ifdef ARROWS4TO14
307 {7, &arrow4o_ic,},
308 {8, &arrow4f_ic,},
309 {9, &arrow5o_ic,},
310 {10, &arrow5f_ic,},
311 {11, &arrow6o_ic,},
312 {12, &arrow6f_ic,},
313 {13, &arrow7o_ic,},
314 {14, &arrow7f_ic,},
315 {15, &arrow8o_ic,},
316 {16, &arrow8f_ic,},
317 {17, &arrow9a_ic,},
318 {18, &arrow9b_ic,},
319 {19, &arrow10o_ic,},
320 {20, &arrow10f_ic,},
321 {21, &arrow11o_ic,},
322 {22, &arrow11f_ic,},
323 {23, &arrow12o_ic,},
324 {24, &arrow12f_ic,},
325 {25, &arrow13a_ic,},
326 {26, &arrow13b_ic,},
327 {27, &arrow14a_ic,},
328 {28, &arrow14b_ic,},
329 #endif /* ARROWS4TO14 */
330 };
331 #define NUM_ARROWTYPE_CHOICES (sizeof(arrowtype_choices)/sizeof(choice_info))
332
333 static choice_info textjust_choices[] = {
334 {T_LEFT_JUSTIFIED, &textL_ic,},
335 {T_CENTER_JUSTIFIED, &textC_ic,},
336 {T_RIGHT_JUSTIFIED, &textR_ic,},
337 };
338 #define NUM_TEXTJUST_CHOICES (sizeof(textjust_choices)/sizeof(choice_info))
339
340 static choice_info arctype_choices[] = {
341 {T_OPEN_ARC, &open_arc_ic,},
342 {T_PIE_WEDGE_ARC, &pie_wedge_arc_ic,},
343 };
344 #define NUM_ARCTYPE_CHOICES (sizeof(arctype_choices)/sizeof(choice_info))
345
346 choice_info linestyle_choices[] = {
347 {SOLID_LINE, &solidline_ic,},
348 {DASH_LINE, &dashline_ic,},
349 {DOTTED_LINE, &dottedline_ic,},
350 {DASH_DOT_LINE, &dashdotline_ic,},
351 {DASH_2_DOTS_LINE, &dash2dotsline_ic,},
352 {DASH_3_DOTS_LINE, &dash3dotsline_ic,},
353 };
354
355 choice_info joinstyle_choices[] = {
356 {JOIN_MITER, &joinmiter_ic,},
357 {JOIN_ROUND, &joinround_ic,},
358 {JOIN_BEVEL, &joinbevel_ic,},
359 };
360
361 choice_info capstyle_choices[] = {
362 {CAP_BUTT, &capbutt_ic,},
363 {CAP_ROUND, &capround_ic,},
364 {CAP_PROJECT, &capproject_ic,},
365 };
366
367 static choice_info linkmode_choices[] = {
368 {SMART_OFF, &smartoff_ic,},
369 {SMART_MOVE, &smartmove_ic,},
370 {SMART_SLIDE, &smartslide_ic,},
371 };
372 #define NUM_LINKMODE_CHOICES (sizeof(linkmode_choices)/sizeof(choice_info))
373
374 choice_info fillstyle_choices[NUMFILLPATS + 1];
375
376 choice_info color_choices[NUM_STD_COLS + 1];
377 ind_sw_info *zoom_sw;
378 ind_sw_info *fill_style_sw;
379
380 #define inc_action(z) (z->inc_func)(z)
381 #define dec_action(z) (z->dec_func)(z)
382 #define show_action(z) (z->show_func)(z)
383
384 ind_sw_info ind_switches[] = {
385 {I_FVAL, 0, "Zoom", "", NARROW_IND_SW_WD, /* always show zoom button */
386 NULL, &display_zoomscale, inc_zoom_centered, dec_zoom_centered,
387 show_zoom, 0 /* MIN_ZOOM */, MAX_ZOOM, 1.0},
388 {I_CHOICE, 0, "Grid", "Mode", DEF_IND_SW_WD, /* and grid button */ // isometric grid
389 &cur_gridmode, NULL, inc_choice, dec_choice, show_gridmode, 0, 0, 0.0,
390 gridmode_choices, NUM_GRIDMODE_CHOICES, (NUM_GRIDMODE_CHOICES+1)/2},
391 {I_CHOICE, I_POINTPOSN, "Point", "Posn", DEF_IND_SW_WD,
392 &cur_pointposn, NULL, inc_choice, dec_choice, show_pointposn, 0, 0, 0.0,
393 pointposn_choices, NUM_POINTPOSN_CHOICES, NUM_POINTPOSN_CHOICES},
394 {I_IVAL, I_DEPTH, "Depth", "", NARROW_IND_SW_WD,
395 &cur_depth, NULL, inc_depth, dec_depth, show_depth, MIN_DEPTH, MAX_DEPTH, 1.0},
396 {I_FVAL, I_ROTNANGLE, "Rotn", "Angle", WIDE_IND_SW_WD,
397 NULL, &cur_rotnangle, inc_rotnangle, dec_rotnangle, show_rotnangle, -360.0, 360.0, 1.0},
398 {I_IVAL, I_NUMSIDES, "Num", "Sides", NARROW_IND_SW_WD,
399 &cur_numsides, NULL, inc_numsides, dec_numsides, show_numsides,
400 MIN_POLY_SIDES, MAX_POLY_SIDES, 1.0},
401 {I_IVAL, I_NUMCOPIES, "Num", "Copies", NARROW_IND_SW_WD,
402 &cur_numcopies, NULL, inc_numcopies, dec_numcopies, show_numcopies, 1, 99, 1.0},
403 {I_IVAL, I_NUMXCOPIES, "Num X", "Copies", NARROW_IND_SW_WD,
404 &cur_numxcopies, NULL, inc_numxcopies, dec_numxcopies, show_numxcopies, 1, 99, 1.0},
405 {I_IVAL, I_NUMYCOPIES, "Num Y", "Copies", NARROW_IND_SW_WD,
406 &cur_numycopies, NULL, inc_numycopies, dec_numycopies, show_numycopies, 1, 99, 1.0},
407 {I_CHOICE, I_VALIGN, "Vert", "Align", DEF_IND_SW_WD,
408 &cur_valign, NULL, inc_choice, dec_choice, show_valign, 0, 0, 0.0,
409 valign_choices, NUM_VALIGN_CHOICES, NUM_VALIGN_CHOICES},
410 {I_CHOICE, I_HALIGN, "Horiz", "Align", DEF_IND_SW_WD,
411 &cur_halign, NULL, inc_choice, dec_choice, show_halign, 0, 0, 0.0,
412 halign_choices, NUM_HALIGN_CHOICES, NUM_HALIGN_CHOICES},
413 {I_CHOICE, I_ANGLEGEOM, "Angle", "Geom", DEF_IND_SW_WD,
414 &cur_anglegeom, NULL, inc_choice, dec_choice, show_anglegeom, 0, 0, 0.0,
415 anglegeom_choices, NUM_ANGLEGEOM_CHOICES, NUM_ANGLEGEOM_CHOICES},
416 {I_CHOICE, I_PEN_COLOR, "PenColor", "", XWIDE_IND_SW_WD,
417 (int *) &cur_pencolor, NULL, next_pencolor, prev_pencolor, show_pencolor, 0, 0, 0.0,
418 color_choices, NUM_STD_COLS + 1, 7},
419 {I_CHOICE, I_FILL_COLOR, "FillColor", "", XWIDE_IND_SW_WD,
420 (int *) &cur_fillcolor, NULL, next_fillcolor, prev_fillcolor, show_fillcolor,0, 0, 0.0,
421 color_choices, NUM_STD_COLS + 1, 7},
422 {I_CHOICE, I_FILLSTYLE, "Fill", "Style", DEF_IND_SW_WD,
423 &cur_fillstyle, NULL, darken_fill, lighten_fill, show_fillstyle,0, 0, 0.0,
424 fillstyle_choices, NUMFILLPATS + 1, 11},
425 {I_CHOICE, I_ARCTYPE, "Arc", "Type", DEF_IND_SW_WD,
426 &cur_arctype, NULL, inc_choice, dec_choice, show_arctype, 0, 0, 0.0,
427 arctype_choices, NUM_ARCTYPE_CHOICES, NUM_ARCTYPE_CHOICES},
428 {I_CHOICE, I_LINKMODE, "Smart", "Links", DEF_IND_SW_WD,
429 &cur_linkmode, NULL, inc_choice, dec_choice, show_linkmode, 0, 0, 0.0,
430 linkmode_choices, NUM_LINKMODE_CHOICES, NUM_LINKMODE_CHOICES},
431 {I_IVAL, I_LINEWIDTH, "Line", "Width", DEF_IND_SW_WD,
432 &cur_linewidth, NULL, inc_linewidth, dec_linewidth, show_linewidth,
433 0, MAX_LINE_WIDTH, 1.0},
434 {I_CHOICE, I_LINESTYLE, "Line", "Style", DEF_IND_SW_WD,
435 &cur_linestyle, NULL, inc_choice, dec_choice, show_linestyle, 0, 0, 0.0,
436 linestyle_choices, NUM_LINESTYLE_TYPES, NUM_LINESTYLE_TYPES},
437 {I_FVAL, I_TANGNORMLEN, "Tangent/Norm", "Length", WIDE_IND_SW_WD,
438 NULL, &cur_tangnormlen, inc_tangnormlen, dec_tangnormlen, show_tangnormlen, MIN_TANGNORMLEN, MAX_TANGNORMLEN, 0.2},
439 {I_CHOICE, I_JOINSTYLE, "Join", "Style", DEF_IND_SW_WD,
440 &cur_joinstyle, NULL, inc_choice, dec_choice, show_joinstyle, 0, 0, 0.0,
441 joinstyle_choices, NUM_JOINSTYLE_TYPES, NUM_JOINSTYLE_TYPES},
442 {I_CHOICE, I_CAPSTYLE, "Cap", "Style", DEF_IND_SW_WD,
443 &cur_capstyle, NULL, inc_choice, dec_choice, show_capstyle, 0, 0, 0.0,
444 capstyle_choices, NUM_CAPSTYLE_TYPES, NUM_CAPSTYLE_TYPES},
445 {I_CHOICE, I_ARROWMODE, "Arrow", "Mode", DEF_IND_SW_WD,
446 &cur_arrowmode, NULL, inc_choice, dec_choice, show_arrowmode, 0, 0, 0.0,
447 arrowmode_choices, NUM_ARROWMODE_CHOICES, NUM_ARROWMODE_CHOICES},
448 {I_CHOICE, I_ARROWTYPE, "Arrow", "Type", DEF_IND_SW_WD,
449 &cur_arrowtype, NULL, inc_choice, dec_choice, show_arrowtype, 0, 0, 0.0,
450 arrowtype_choices, NUM_ARROWTYPE_CHOICES, 9},
451 {I_CHOICE, I_ARROWSIZE, "Arrow Size", "", WIDE_IND_SW_WD,
452 NULL, NULL, inc_arrowsize, dec_arrowsize, show_arrowsize, 0, 0, 0.0},
453 {I_IVAL, I_BOXRADIUS, "Box", "Curve", DEF_IND_SW_WD,
454 &cur_boxradius, NULL, inc_boxradius, dec_boxradius, show_boxradius,
455 MIN_BOX_RADIUS, MAX_BOX_RADIUS, 1.0},
456 {I_DIMLINE, I_DIMLINE, "Dimension line", "", XWIDE_IND_SW_WD,
457 NULL, NULL, inc_dimline, dec_dimline, show_dimline, 0, 0, 0.0},
458 {I_CHOICE, I_TEXTJUST, "Text", "Just", DEF_IND_SW_WD,
459 &cur_textjust, NULL, inc_choice, dec_choice, show_textjust, 0, 0, 0.0,
460 textjust_choices, NUM_TEXTJUST_CHOICES, NUM_TEXTJUST_CHOICES},
461 {I_FVAL, I_ELLTEXTANGLE, "Text/Ellipse", "Angle", XWIDE_IND_SW_WD,
462 NULL, &cur_elltextangle, inc_elltextangle, dec_elltextangle, show_elltextangle,
463 -360, 360, 1.0},
464 {I_IVAL, I_TEXTFLAGS, "Text Flags", "", WIDE_IND_SW_WD,
465 &cur_textflags, NULL, inc_flags, dec_flags, show_flags, 0, 0, 0.0},
466 {I_IVAL, I_FONTSIZE, "Text", "Size", NARROW_IND_SW_WD,
467 &cur_fontsize, NULL, inc_fontsize, dec_fontsize, show_fontsize,
468 MIN_FONT_SIZE, MAX_FONT_SIZE, 1.0},
469 {I_FVAL, I_TEXTSTEP, "Text", "Step", NARROW_IND_SW_WD,
470 NULL, &cur_textstep, inc_textstep, dec_textstep, show_textstep, 0, 1000, 0.1},
471 {I_IVAL, I_FONT, "Text", "Font", FONT_IND_SW_WD,
472 &cur_ps_font, NULL, inc_font, dec_font, show_font, 0, 0, 0.0},
473 };
474
475 #define NUM_IND_SW (sizeof(ind_switches) / sizeof(ind_sw_info))
476
477
478 /* button selection event handler */
479 static void sel_ind_but(Widget widget, XtPointer closure, XEvent *event, Boolean *continue_to_dispatch);
480
481 /* arguments for the update indicator boxes in the indicator buttons */
482
483 static Arg upd_args[] =
484 {
485 /* 0 */ {XtNwidth, (XtArgVal) 8},
486 /* 1 */ {XtNheight, (XtArgVal) 8},
487 /* 2 */ {XtNborderWidth, (XtArgVal) 1},
488 /* 3 */ {XtNtop, (XtArgVal) XtChainTop},
489 /* 4 */ {XtNright, (XtArgVal) XtChainRight},
490 /* 5 */ {XtNstate, (XtArgVal) True},
491 /* 6 */ {XtNvertDistance, (XtArgVal) 0},
492 /* 7 */ {XtNhorizDistance, (XtArgVal) 0},
493 /* 8 */ {XtNlabel, (XtArgVal) " "},
494 };
495
496 static XtActionsRec ind_actions[] =
497 {
498 {"EnterIndSw", (XtActionProc) draw_mousefun_ind},
499 {"LeaveIndSw", (XtActionProc) clear_mousefun},
500 {"ZoomIn", (XtActionProc) wheel_inc_zoom},
501 {"ZoomOut", (XtActionProc) wheel_dec_zoom},
502 {"ZoomFit", (XtActionProc) fit_zoom},
503 };
504
505 static String ind_translations =
506 "<EnterWindow>:EnterIndSw()highlight()\n\
507 <LeaveWindow>:LeaveIndSw()unhighlight()\n";
508
509 /* bitmaps for set/clear and toggle buttons (10x10) */
510 static unsigned char set_bits[] = {
511 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
512 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
513 static unsigned char clr_bits[] = {
514 0xff, 0x03, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
515 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xff, 0x03};
516 static unsigned char tog_bits[] = {
517 0xff, 0x03, 0x01, 0x02, 0x03, 0x02, 0x07, 0x02, 0x0f, 0x02, 0x1f, 0x02,
518 0x3f, 0x02, 0x7f, 0x02, 0xff, 0x02, 0xff, 0x03};
519
520 /* create a ind_sw_info struct for the update widget
521 so we can use the balloon routines or the Tip widget */
522
523 static ind_sw_info upd_sw_info, upd_set_sw_info, upd_clr_sw_info, upd_tog_sw_info;
524
525
526
527 void
init_ind_panel(Widget tool)528 init_ind_panel(Widget tool)
529 {
530 ind_sw_info *sw;
531 Widget tw; /* temporary widget to get scrollbar widget */
532 int i;
533
534 /* Make a widget which contains the label and toggle/set/clear form.
535 This will be managed and unmanaged as needed. It's parent is the
536 main form (tool) and the ind_panel will be chained to it when it
537 is managed */
538
539 FirstArg(XtNdefaultDistance, 0);
540 NextArg(XtNborderWidth, INTERNAL_BW);
541 NextArg(XtNorientation, XtorientVertical);
542 NextArg(XtNhSpace, 0);
543 NextArg(XtNvSpace, 1);
544 NextArg(XtNresizable, False);
545 NextArg(XtNfromVert, canvas_sw);
546 NextArg(XtNtop, XtChainBottom); /* don't resize when form changes */
547 NextArg(XtNbottom, XtChainBottom);
548 NextArg(XtNleft, XtChainLeft);
549 NextArg(XtNright, XtChainLeft);
550
551 upd_ctrl = XtCreateWidget("upd_ctrl_form", boxWidgetClass,
552 tool, Args, ArgCount);
553 /* popup when mouse passes over button */
554 strcpy(upd_sw_info.line1,"Selects which settings are updated");
555 upd_sw_info.line2[0] = '\0';
556 upd_sw_info.sw_width = 70; /* rough guess */
557 #ifndef XAW3D1_5E
558 XtAddEventHandler(upd_ctrl, EnterWindowMask, False,
559 ind_balloon_trigger, (XtPointer) &upd_sw_info);
560 XtAddEventHandler(upd_ctrl, LeaveWindowMask, False,
561 ind_unballoon, (XtPointer) &upd_sw_info);
562 #endif /* XAW3D1_5E */
563
564 FirstArg(XtNborderWidth, 0);
565 NextArg(XtNjustify, XtJustifyCenter);
566 NextArg(XtNfont, button_font);
567 NextArg(XtNlabel, " Update \n Control ");
568 NextArg(XtNinternalHeight, 0);
569 upd_ctrl_lab = XtCreateManagedWidget("upd_ctrl_label", labelWidgetClass,
570 upd_ctrl, Args, ArgCount);
571 #ifndef XAW3D1_5E
572 XtAddEventHandler(upd_ctrl_lab, EnterWindowMask, False,
573 ind_balloon_trigger, (XtPointer) &upd_sw_info);
574 XtAddEventHandler(upd_ctrl_lab, LeaveWindowMask, False,
575 ind_unballoon, (XtPointer) &upd_sw_info);
576 #endif /* XAW3D1_5E */
577
578 FirstArg(XtNdefaultDistance, 0);
579 NextArg(XtNborderWidth, 0);
580 NextArg(XtNorientation, XtorientHorizontal);
581 NextArg(XtNhSpace, 3);
582 NextArg(XtNvSpace, 0);
583 upd_ctrl_btns = XtCreateManagedWidget("upd_ctrl_btns", boxWidgetClass,
584 upd_ctrl, Args, ArgCount);
585
586 FirstArg(XtNheight, UPD_BITS);
587 NextArg(XtNwidth, UPD_BITS);
588 NextArg(XtNinternalWidth, UPD_INT);
589 NextArg(XtNinternalHeight, UPD_INT);
590 NextArg(XtNborderWidth, UPD_BORD);
591 set_upd = XtCreateManagedWidget("set_upd", commandWidgetClass,
592 upd_ctrl_btns, Args, ArgCount);
593 XtAddEventHandler(set_upd, ButtonReleaseMask, False,
594 set_all_update, (XtPointer) 0);
595
596 strcpy(upd_set_sw_info.line1,"Sets all update flags");
597 upd_set_sw_info.line2[0] = '\0';
598 upd_set_sw_info.sw_width = UPD_BITS+6;
599 #ifndef XAW3D1_5E
600 XtAddEventHandler(set_upd, EnterWindowMask, False,
601 ind_balloon_trigger, (XtPointer) &upd_set_sw_info);
602 XtAddEventHandler(set_upd, LeaveWindowMask, False,
603 ind_unballoon, (XtPointer) &upd_set_sw_info);
604 #endif /* XAW3D1_5E */
605
606 clr_upd = XtCreateManagedWidget("clr_upd", commandWidgetClass,
607 upd_ctrl_btns, Args, ArgCount);
608 XtAddEventHandler(clr_upd, ButtonReleaseMask, False,
609 clr_all_update, (XtPointer) 0);
610
611 strcpy(upd_clr_sw_info.line1,"Clears all update flags");
612 upd_clr_sw_info.line2[0] = '\0';
613 upd_clr_sw_info.sw_width = UPD_BITS+6;
614 #ifndef XAW3D1_5E
615 XtAddEventHandler(clr_upd, EnterWindowMask, False,
616 ind_balloon_trigger, (XtPointer) &upd_clr_sw_info);
617 XtAddEventHandler(clr_upd, LeaveWindowMask, False,
618 ind_unballoon, (XtPointer) &upd_clr_sw_info);
619 #endif /* XAW3D1_5E */
620
621 tog_upd = XtCreateManagedWidget("tog_upd", commandWidgetClass,
622 upd_ctrl_btns, Args, ArgCount);
623 XtAddEventHandler(tog_upd, ButtonReleaseMask, False,
624 tog_all_update, (XtPointer) 0);
625
626 strcpy(upd_tog_sw_info.line1,"Toggles all update flags");
627 upd_tog_sw_info.line2[0] = '\0';
628 upd_tog_sw_info.sw_width = UPD_BITS+6;
629 #ifndef XAW3D1_5E
630 XtAddEventHandler(tog_upd, EnterWindowMask, False,
631 ind_balloon_trigger, (XtPointer) &upd_tog_sw_info);
632 XtAddEventHandler(tog_upd, LeaveWindowMask, False,
633 ind_unballoon, (XtPointer) &upd_tog_sw_info);
634 #endif /* XAW3D1_5E */
635
636 /* start with all components affected by update */
637 cur_updatemask = I_UPDATEMASK;
638
639 /**********************************/
640 /* Now the indicator panel itself */
641 /**********************************/
642
643 /* make a scrollable viewport in case all the buttons don't fit */
644 /* resize this later when we know how high the scrollbar is */
645 /* When the update control is managed, make the fromHoriz that widget */
646
647 FirstArg(XtNallowHoriz, True);
648 NextArg(XtNwidth, INDPANEL_WD);
649 /* does he want to always see ALL of the indicator buttons? */
650 if (appres.showallbuttons) { /* yes, but set cur_indmask to all later */
651 i = 2*DEF_IND_SW_HT+5*INTERNAL_BW; /* two rows high when showing all buttons */
652 } else {
653 i = DEF_IND_SW_HT + 2*INTERNAL_BW;
654 }
655 /* account for the scrollbar thickness */
656 i += MAX_SCROLL_WD;
657 /* and force it to be created so we can see how thick it is */
658 NextArg(XtNforceBars, True);
659
660 NextArg(XtNheight, i);
661 NextArg(XtNborderWidth, 0);
662 NextArg(XtNuseBottom, True);
663 NextArg(XtNfromVert, canvas_sw);
664 NextArg(XtNtop, XtChainBottom); /* don't resize height when main form changes */
665 NextArg(XtNbottom, XtChainBottom);
666 NextArg(XtNleft, XtChainLeft); /* but do resize width when main form widens */
667 NextArg(XtNright, XtChainRight);
668
669 ind_panel = XtCreateManagedWidget("ind_panel", viewportWidgetClass, tool,
670 Args, ArgCount);
671
672 FirstArg(XtNheight, i);
673 NextArg(XtNhSpace, 0);
674 NextArg(XtNvSpace, 0);
675 NextArg(XtNresizable, True);
676 NextArg(XtNborderWidth, 0);
677 if (appres.showallbuttons) {
678 NextArg(XtNorientation, XtorientVertical); /* use two rows */
679 } else {
680 NextArg(XtNorientation, XtorientHorizontal); /* expand horizontally */
681 }
682
683 ind_box = XtCreateManagedWidget("ind_box", boxWidgetClass, ind_panel,
684 Args, ArgCount);
685
686
687 for (i = 0; i < NUM_IND_SW; ++i) {
688 sw = &ind_switches[i];
689 sw->panel = (Widget) NULL; /* not created yet */
690
691 FirstArg(XtNwidth, sw->sw_width);
692 NextArg(XtNheight, DEF_IND_SW_HT);
693 NextArg(XtNdefaultDistance, 0);
694 NextArg(XtNborderWidth, INTERNAL_BW);
695 sw->formw = XtCreateWidget("button_form", formWidgetClass,
696 ind_box, Args, ArgCount);
697
698 /* make an update button in the upper-right corner of the main button */
699 if (sw->func & I_UPDATEMASK) {
700 upd_args[7].value = sw->sw_width
701 - upd_args[0].value
702 - 2*upd_args[2].value;
703 sw->updbut = XtCreateWidget("update", toggleWidgetClass,
704 sw->formw, upd_args, XtNumber(upd_args));
705 sw->update = True;
706 XtAddCallback(sw->updbut, XtNcallback, note_state, (XtPointer) sw);
707 }
708
709 /* now create the command button */
710 FirstArg(XtNlabel, " ");
711 NextArg(XtNwidth, sw->sw_width);
712 NextArg(XtNheight, DEF_IND_SW_HT);
713 NextArg(XtNresizable, False);
714 NextArg(XtNborderWidth, 0);
715 NextArg(XtNresize, False);
716 NextArg(XtNresizable, False);
717 NextArg(XtNbackgroundPixmap, NULL);
718 sw->button = XtCreateManagedWidget("button", commandWidgetClass,
719 sw->formw, Args, ArgCount);
720 /* map this button if it is needed */
721 if (sw->func & cur_indmask)
722 XtManageChild(sw->formw);
723
724 /* allow left & right buttons */
725 /* (callbacks pass same data for ANY button) */
726 XtAddEventHandler(sw->button, ButtonReleaseMask, False,
727 sel_ind_but, (XtPointer) sw);
728 #ifndef XAW3D1_5E
729 /* popup when mouse passes over button */
730 XtAddEventHandler(sw->button, EnterWindowMask, False,
731 ind_balloon_trigger, (XtPointer) sw);
732 XtAddEventHandler(sw->button, LeaveWindowMask, False,
733 ind_unballoon, (XtPointer) sw);
734 #endif /* XAW3D1_5E */
735 XtOverrideTranslations(sw->button,
736 XtParseTranslationTable(ind_translations));
737 }
738
739 /* now get the real height of the scrollbar and resize the ind_panel if necessary */
740 tw = XtNameToWidget(ind_panel, "horizontal");
741 if (tw != NULL) {
742 Dimension td1; /* temporary variable to get scrollbar thickness */
743 Dimension td2; /* temporary variable to get indpanel height */
744 Dimension bdw; /* temporary variable to get scrollbar border width */
745
746 FirstArg(XtNthumb, None); /* make solid scrollbar instead of tiled */
747 SetValues(tw);
748
749 FirstArg(XtNthickness, &td1);
750 NextArg(XtNborderWidth, &bdw);
751 GetValues(tw);
752 FirstArg(XtNheight, &td2);
753 GetValues(ind_panel);
754 /* make it no shorter than the control panel height */
755 td2 = max2(td2 - MAX_SCROLL_WD + td1 + 4 + bdw, UPD_CTRL_HT);
756 XtUnmanageChild(ind_panel);
757 FirstArg(XtNheight, td2);
758 SetValues(ind_box);
759 SetValues(ind_panel);
760 /* now turn off the scrollbar until we need it */
761 FirstArg(XtNforceBars, False);
762 SetValues(ind_panel);
763 XtManageChild(ind_panel);
764 }
765
766 if (appres.showallbuttons) {
767 cur_indmask = I_ALL; /* now turn all indicator buttons */
768 appres.showallbuttons = False;
769 update_indpanel(cur_indmask);
770 appres.showallbuttons = True;
771 }
772 update_indpanel(cur_indmask);
773 /* set up action and translation for mousefun kbd icon */
774 init_kbd_actions();
775 }
776
777 void
add_ind_actions(void)778 add_ind_actions(void)
779 {
780 XtAppAddActions(tool_app, ind_actions, XtNumber(ind_actions));
781 }
782
783 static void
note_state(Widget w,XtPointer closure,XtPointer call_data)784 note_state(Widget w, XtPointer closure, XtPointer call_data)
785 {
786 ind_sw_info *sw = (ind_sw_info *) closure;
787
788 /* toggle update status of this indicator */
789 /* for some reason, the state is the opposite of reality */
790 sw->update = !sw->update;
791 if (sw->update)
792 cur_updatemask |= sw->func; /* turn on update status */
793 else
794 cur_updatemask &= ~sw->func; /* turn off update status */
795 }
796
797 /* toggle the update buttons in all the widgets */
798 static void
tog_all_update(Widget w,XtPointer data,XEvent * event,Boolean * cont)799 tog_all_update(Widget w, XtPointer data, XEvent *event, Boolean *cont)
800 {
801 int i;
802
803 cur_updatemask = ~cur_updatemask; /* tuggle all */
804 for (i = 0; i < NUM_IND_SW; ++i) {
805 if (ind_switches[i].updbut == NULL)
806 continue;
807 ind_switches[i].update = !ind_switches[i].update;
808 FirstArg(XtNstate, ind_switches[i].update);
809 SetValues(ind_switches[i].updbut);
810 }
811 put_msg("Update command status TOGGLED for all buttons");
812 }
813
814 /* turn on the update buttons in all the widgets */
815 static void
set_all_update(Widget w,XtPointer data,XEvent * event,Boolean * cont)816 set_all_update(Widget w, XtPointer data, XEvent *event, Boolean *cont)
817 {
818 int i;
819
820 cur_updatemask = I_UPDATEMASK; /* turn all on */
821 for (i = 0; i < NUM_IND_SW; ++i) {
822 if (ind_switches[i].updbut == NULL)
823 continue;
824 ind_switches[i].update = True;
825 FirstArg(XtNstate, True);
826 SetValues(ind_switches[i].updbut);
827 }
828 put_msg("Update commands are now ENABLED for all buttons");
829 }
830
831 /* turn off the update buttons in all the widgets */
832 static void
clr_all_update(Widget w,XtPointer data,XEvent * event,Boolean * cont)833 clr_all_update(Widget w, XtPointer data, XEvent *event, Boolean *cont)
834 {
835 int i;
836
837 for (i = 0; i < NUM_IND_SW; ++i) {
838 cur_updatemask = 0; /* turn all off */
839 if (ind_switches[i].updbut == NULL)
840 continue;
841 ind_switches[i].update = False;
842 FirstArg(XtNstate, False);
843 SetValues(ind_switches[i].updbut);
844 }
845 put_msg("Update commands will be IGNORED for all buttons");
846 }
847
manage_update_buts(void)848 void manage_update_buts(void)
849 {
850 int i;
851 for (i = 0; i < NUM_IND_SW; ++i)
852 if (ind_switches[i].func & I_UPDATEMASK)
853 XtManageChild(ind_switches[i].updbut);
854 update_buts_managed = True;
855 }
856
unmanage_update_buts(void)857 void unmanage_update_buts(void)
858 {
859 int i;
860 for (i = 0; i < NUM_IND_SW; ++i)
861 if (ind_switches[i].func & I_UPDATEMASK)
862 XtUnmanageChild(ind_switches[i].updbut);
863 update_buts_managed = False;
864 }
865
setup_ind_panel(void)866 void setup_ind_panel(void)
867 {
868 int i;
869 ind_sw_info *isw;
870 Pixmap p;
871 Pixel fg,bg;
872
873 /* get the foreground and background from the indicator widget */
874 /* and create a gc with those values */
875 ind_button_gc = XCreateGC(tool_d, XtWindow(ind_panel), (unsigned long) 0, NULL);
876 FirstArg(XtNforeground, &ind_but_fg);
877 NextArg(XtNbackground, &ind_but_bg);
878 GetValues(ind_switches[0].button);
879 XSetBackground(tool_d, ind_button_gc, ind_but_bg);
880 XSetForeground(tool_d, ind_button_gc, ind_but_fg);
881 XSetFont(tool_d, ind_button_gc, button_font->fid);
882
883 /* also create gc with fore=background for blanking areas */
884 ind_blank_gc = XCreateGC(tool_d, XtWindow(ind_panel), (unsigned long) 0, NULL);
885 XSetBackground(tool_d, ind_blank_gc, ind_but_bg);
886 XSetForeground(tool_d, ind_blank_gc, ind_but_bg);
887
888 /* create a gc for the fill and border color 'palettes' */
889 fill_color_gc = XCreateGC(tool_d, XtWindow(ind_panel), (unsigned long) 0, NULL);
890 pen_color_gc = XCreateGC(tool_d, XtWindow(ind_panel), (unsigned long) 0, NULL);
891
892 /* initialize the fill style gc and pixmaps */
893 init_fill_pm();
894 init_fill_gc();
895
896 for (i = 0; i < NUM_IND_SW; ++i) {
897 isw = &ind_switches[i];
898 /* keep track of a few switches */
899 if (ind_switches[i].func == I_FILLSTYLE)
900 fill_style_sw = isw;
901 else if (strcmp(ind_switches[i].line1,"Zoom")==0)
902 zoom_sw = isw;
903 else if (ind_switches[i].func == I_PEN_COLOR)
904 pen_color_button = isw; /* to update its pixmap in the indicator panel */
905 else if (ind_switches[i].func == I_FILL_COLOR)
906 fill_color_button = isw; /* to update its pixmap in the indicator panel */
907 else if (ind_switches[i].func == I_DEPTH)
908 depth_button = isw; /* to update depth when user right-clicks on depth checkbox */
909
910 p = XCreatePixmap(tool_d, XtWindow(isw->button), isw->sw_width,
911 DEF_IND_SW_HT, tool_dpth);
912 XFillRectangle(tool_d, p, ind_blank_gc, 0, 0,
913 isw->sw_width, DEF_IND_SW_HT);
914 XDrawImageString(tool_d, p, ind_button_gc, 3, 12, isw->line1, strlen(isw->line1));
915 XDrawImageString(tool_d, p, ind_button_gc, 3, 25, isw->line2, strlen(isw->line2));
916
917 isw->pixmap = p;
918 FirstArg(XtNbackgroundPixmap, p);
919 SetValues(isw->button);
920 /* generate pixmaps if this is a choice panel */
921 if (ind_switches[i].type == I_CHOICE)
922 generate_choice_pixmaps(isw);
923 }
924
925 /* setup the pixmap in the color button */
926 show_pencolor();
927 show_fillcolor();
928
929 /* now put cute little images in update buttons (full box (set), empty box (clear)
930 and half full (toggle) */
931 FirstArg(XtNforeground, &fg);
932 NextArg(XtNbackground, &bg);
933 for (i = 0; i < NUM_IND_SW; ++i) /* find one of the update buttons */
934 if (ind_switches[i].func & I_UPDATEMASK) { /* and get its fg and bg colors */
935 GetValues(ind_switches[i].updbut);
936 break;
937 }
938
939 p = XCreatePixmapFromBitmapData(tool_d, XtWindow(ind_panel),
940 (char *) set_bits, UPD_BITS, UPD_BITS, fg, bg, tool_dpth);
941 FirstArg(XtNbitmap, p);
942 SetValues(set_upd);
943 p = XCreatePixmapFromBitmapData(tool_d, XtWindow(ind_panel),
944 (char *) clr_bits, UPD_BITS, UPD_BITS, fg, bg, tool_dpth);
945 FirstArg(XtNbitmap, p);
946 SetValues(clr_upd);
947 p = XCreatePixmapFromBitmapData(tool_d, XtWindow(ind_panel),
948 (char *) tog_bits, UPD_BITS, UPD_BITS, fg, bg, tool_dpth);
949 FirstArg(XtNbitmap, p);
950 SetValues(tog_upd);
951
952 XDefineCursor(tool_d, XtWindow(ind_panel), arrow_cursor);
953 update_current_settings();
954
955 FirstArg(XtNmappedWhenManaged, True);
956 SetValues(ind_panel);
957
958 /* get the width of the update control panel */
959 FirstArg(XtNwidth, &UPD_CTRL_WD);
960 GetValues(upd_ctrl);
961
962 }
963
964 #ifndef XAW3D1_5E
965 /* come here when the mouse passes over a button in the indicator panel */
966
967 static Widget ind_balloon_popup = (Widget) 0;
968 static Widget balloon_label;
969 static XtIntervalId balloon_id = (XtIntervalId) 0;
970 static Widget balloon_w;
971 static XtPointer clos;
972
973 static void ind_balloon(void);
974
975 static void
ind_balloon_trigger(Widget widget,XtPointer closure,XEvent * event,Boolean * continue_to_dispatch)976 ind_balloon_trigger(Widget widget, XtPointer closure, XEvent *event, Boolean *continue_to_dispatch)
977 {
978 if (!appres.showballoons)
979 return;
980 balloon_w = widget;
981 clos = closure;
982 /* if an old balloon is still up, destroy it */
983 if ((balloon_id != 0) || (ind_balloon_popup != (Widget) 0)) {
984 ind_unballoon((Widget) 0, (XtPointer) 0, (XEvent*) 0, (Boolean*) 0);
985 }
986 balloon_id = XtAppAddTimeOut(tool_app, appres.balloon_delay,
987 (XtTimerCallbackProc) ind_balloon, (XtPointer) NULL);
988 }
989
990 static void
ind_balloon(void)991 ind_balloon(void)
992 {
993 Position x, y, appx, appy;
994 ind_sw_info *isw = (ind_sw_info *) clos;
995 char msg[60];
996 Widget box;
997
998 XtTranslateCoords(balloon_w, isw->sw_width+5, 0, &x, &y);
999 XtTranslateCoords(tool, TOOL_WD, 0, &appx, &appy);
1000 /* if part of the button is hidden in the scroll area, put the balloon
1001 at the right edge of xfig's main window */
1002 if (x > appx)
1003 x = appx+2;
1004
1005 /* set the position */
1006 FirstArg(XtNx, x);
1007 NextArg(XtNy, y);
1008 ind_balloon_popup = XtCreatePopupShell("ind_balloon_popup",overrideShellWidgetClass,
1009 tool, Args, ArgCount);
1010 FirstArg(XtNborderWidth, 0);
1011 NextArg(XtNhSpace, 0);
1012 NextArg(XtNvSpace, 0);
1013 box = XtCreateManagedWidget("box", boxWidgetClass, ind_balloon_popup,
1014 Args, ArgCount);
1015 FirstArg(XtNborderWidth, 0);
1016 sprintf(msg,"%s %s",isw->line1,isw->line2);
1017 NextArg(XtNlabel, msg);
1018 balloon_label = XtCreateManagedWidget("label", labelWidgetClass,
1019 box, Args, ArgCount);
1020
1021 XtPopup(ind_balloon_popup,XtGrabNone);
1022 XtRemoveTimeOut(balloon_id);
1023 balloon_id = (XtIntervalId) 0;
1024 }
1025
1026 /* come here when the mouse leaves a button in the indicator panel */
1027
1028 static void
ind_unballoon(Widget widget,XtPointer closure,XEvent * event,Boolean * continue_to_dispatch)1029 ind_unballoon(Widget widget, XtPointer closure, XEvent *event, Boolean *continue_to_dispatch)
1030 {
1031 if (balloon_id)
1032 XtRemoveTimeOut(balloon_id);
1033 balloon_id = (XtIntervalId) 0;
1034 if (ind_balloon_popup != (Widget) 0) {
1035 XtDestroyWidget(ind_balloon_popup);
1036 ind_balloon_popup = (Widget) 0;
1037 }
1038 }
1039 #endif /* XAW3D1_5E */
1040
generate_choice_pixmaps(ind_sw_info * isw)1041 void generate_choice_pixmaps(ind_sw_info *isw)
1042 {
1043 int i;
1044 choice_info *tmp_choice;
1045
1046 tmp_choice = isw->choices;
1047 for (i = 0; i < isw->numchoices; tmp_choice++, i++) {
1048 if (tmp_choice->icon != 0)
1049 tmp_choice->pixmap = XCreatePixmapFromBitmapData(tool_d,
1050 XtWindow(ind_panel),
1051 tmp_choice->icon->bits,
1052 tmp_choice->icon->width,
1053 tmp_choice->icon->height,
1054 ind_but_fg, ind_but_bg, tool_dpth);
1055 }
1056 }
1057
update_indpanel(long unsigned int mask)1058 void update_indpanel(long unsigned int mask)
1059 {
1060 #ifdef XAW3D1_5E
1061 char msg[60];
1062 #endif /* XAW3D1_5E */
1063 register int i;
1064 register ind_sw_info *isw;
1065
1066 /*
1067 * We must test for the widgets, as this is called by
1068 * w_cmdpanel.c:refresh_view_menu().
1069 */
1070
1071 #ifdef XAW3D1_5E
1072 if (upd_ctrl)
1073 if (appres.showballoons)
1074 XawTipEnable(upd_ctrl, upd_sw_info.line1);
1075 else
1076 XawTipDisable(upd_ctrl);
1077 if (upd_ctrl_lab)
1078 if (appres.showballoons)
1079 XawTipEnable(upd_ctrl_lab, upd_sw_info.line1);
1080 else
1081 XawTipDisable(upd_ctrl_lab);
1082 if (set_upd)
1083 if (appres.showballoons)
1084 XawTipEnable(set_upd, upd_set_sw_info.line1);
1085 else
1086 XawTipDisable(set_upd);
1087 if (clr_upd)
1088 if (appres.showballoons)
1089 XawTipEnable(clr_upd, upd_clr_sw_info.line1);
1090 else
1091 XawTipDisable(clr_upd);
1092 if (tog_upd)
1093 if (appres.showballoons)
1094 XawTipEnable(tog_upd, upd_tog_sw_info.line1);
1095 else
1096 XawTipDisable(tog_upd);
1097 for (isw = ind_switches, i = 0; i < NUM_IND_SW; isw++, i++) {
1098 if (!isw->button)
1099 continue;
1100 if (appres.showballoons) {
1101 sprintf(msg, "%s", isw->line1);
1102 if (strlen(isw->line2))
1103 sprintf(msg + strlen(msg), " %s", isw->line2);
1104 XawTipEnable(isw->button, msg);
1105 } else
1106 XawTipDisable(isw->button);
1107 }
1108 #endif /* XAW3D1_5E */
1109
1110 /* only update current mask if user wants to see relevant ind buttons */
1111 if (appres.showallbuttons)
1112 return;
1113
1114 if (!ind_box)
1115 return;
1116
1117 cur_indmask = mask;
1118 XtUnmanageChild(ind_box);
1119 for (isw = ind_switches, i = 0; i < NUM_IND_SW; isw++, i++) {
1120 /* show buttons with func=0 (zoom and grid) */
1121 if ((isw->func == 0) || (isw->func & cur_indmask)) {
1122 XtManageChild(isw->formw);
1123 } else {
1124 XtUnmanageChild(isw->formw);
1125 }
1126 }
1127 { /* fix scrollbar */
1128 Dimension w,h;
1129 FirstArg(XtNwidth, &w);
1130 NextArg(XtNheight, &h);
1131 GetValues(ind_box);
1132 XtMakeResizeRequest(ind_box, w, h+1, NULL,NULL);
1133 }
1134
1135 XtManageChild(ind_box);
1136 }
1137
1138 /* come here when a button is pressed in the indicator panel */
1139
1140 static void
sel_ind_but(Widget widget,XtPointer closure,XEvent * event,Boolean * continue_to_dispatch)1141 sel_ind_but(Widget widget, XtPointer closure, XEvent *event, Boolean *continue_to_dispatch)
1142 {
1143 XButtonEvent xbutton;
1144 ind_sw_info *isw = (ind_sw_info *) closure;
1145
1146 #ifndef XAW3D1_5E
1147 /* since this command popups a window, destroy the balloon popup now. */
1148 ind_unballoon((Widget) 0, (XtPointer) 0, (XEvent*) 0, (Boolean*) 0);
1149 app_flush();
1150 #endif /* XAW3D1_5E */
1151
1152 xbutton = event->xbutton;
1153 /* see if wheel mouse */
1154 switch (xbutton.button) {
1155 case Button4: xbutton.button = Button2;
1156 break;
1157 case Button5: xbutton.button = Button3;
1158 break;
1159 }
1160 if ((xbutton.button == Button2) ||
1161 (xbutton.button == Button3 && xbutton.state & Mod1Mask)) { /* middle button */
1162 dec_action(isw);
1163 } else if (xbutton.button == Button3) { /* right button */
1164 inc_action(isw);
1165 } else { /* left button */
1166 if (isw->func == I_FONT)
1167 popup_fonts(isw);
1168 else if (isw->func == I_TEXTFLAGS)
1169 popup_flags_panel(isw);
1170 else if (isw->func == I_ARROWSIZE)
1171 popup_arrowsize_panel(isw);
1172 else if (isw->type == I_IVAL || isw->type == I_FVAL)
1173 popup_nval_panel(isw);
1174 else if (isw->type == I_CHOICE)
1175 popup_choice_panel(isw);
1176 else if (isw->type == I_DIMLINE)
1177 popup_dimline_panel(isw);
1178 }
1179 }
1180
1181 static void
update_string_pixmap(ind_sw_info * isw,char * buf,int xpos,int ypos)1182 update_string_pixmap(ind_sw_info *isw, char *buf, int xpos, int ypos)
1183 {
1184 XDrawImageString(tool_d, isw->pixmap, ind_button_gc,
1185 xpos, ypos, buf, strlen(buf));
1186 if (isw->updbut && update_buts_managed)
1187 XtUnmanageChild(isw->updbut);
1188 /*
1189 * Fool the toolkit by changing the background pixmap to 0 then giving it
1190 * the modified one again. Otherwise, it sees that the pixmap ID is not
1191 * changed and doesn't actually draw it into the widget window
1192 */
1193 FirstArg(XtNbackgroundPixmap, 0);
1194 SetValues(isw->button);
1195 /* put the pixmap in the widget background */
1196 FirstArg(XtNbackgroundPixmap, isw->pixmap);
1197 SetValues(isw->button);
1198 if (isw->updbut && update_buts_managed)
1199 XtManageChild(isw->updbut);
1200 }
1201
1202 static void
update_choice_pixmap(ind_sw_info * isw,int mode)1203 update_choice_pixmap(ind_sw_info *isw, int mode)
1204 {
1205 choice_info *tmp_choice;
1206
1207 if (isw->updbut && update_buts_managed)
1208 XtUnmanageChild(isw->updbut);
1209 /* put the pixmap in the widget background */
1210 tmp_choice = isw->choices + mode;
1211 XCopyArea(tool_d, tmp_choice->pixmap, isw->pixmap, ind_button_gc,
1212 0, 0, tmp_choice->icon->width, tmp_choice->icon->height, 32, 0);
1213 /*
1214 * Fool the toolkit by changing the background pixmap to 0 then giving it
1215 * the modified one again. Otherwise, it sees that the pixmap ID is not
1216 * changed and doesn't actually draw it into the widget window
1217 */
1218 FirstArg(XtNbackgroundPixmap, 0);
1219 SetValues(isw->button);
1220 /* put the pixmap in the widget background */
1221 FirstArg(XtNbackgroundPixmap, isw->pixmap);
1222 SetValues(isw->button);
1223 if (isw->updbut && update_buts_managed)
1224 XtManageChild(isw->updbut);
1225 }
1226
1227 Widget choice_popup;
1228 static ind_sw_info *choice_i;
1229 static Widget nval_popup, form, cancel, set;
1230 static Widget beside, below, newvalue, label;
1231 static Widget dash_length, dot_gap;
1232 static ind_sw_info *nval_i;
1233
1234 /* handle arrow sizes settings */
1235
1236 static Widget arrow_thick_w, arrow_width_w, arrow_height_w;
1237 static Widget arrow_mult_thick_w, arrow_mult_width_w, arrow_mult_height_w;
1238 static Widget a_t_spin, m_t_spin, a_w_spin, m_w_spin, a_h_spin, m_h_spin;
1239
1240 static void
arrowsize_panel_dismiss(void)1241 arrowsize_panel_dismiss(void)
1242 {
1243 XtDestroyWidget(nval_popup);
1244 XtSetSensitive(nval_i->button, True);
1245 }
1246
1247 static void
arrowsize_panel_cancel(Widget w,XButtonEvent * ev)1248 arrowsize_panel_cancel(Widget w, XButtonEvent *ev)
1249 {
1250 use_abs_arrowvals = save_use_abs;
1251 arrowsize_panel_dismiss();
1252 }
1253
1254 static void
arrowsize_panel_set(Widget w,XButtonEvent * ev)1255 arrowsize_panel_set(Widget w, XButtonEvent *ev)
1256 {
1257 cur_arrowwidth = (float) atof(panel_get_value(arrow_width_w));
1258 if (cur_arrowwidth == 0.0)
1259 cur_arrowwidth = 1.0;
1260 cur_arrowthick = (float) atof(panel_get_value(arrow_thick_w));
1261 if (cur_arrowthick == 0.0)
1262 cur_arrowthick = 1.0;
1263 cur_arrowheight = (float) atof(panel_get_value(arrow_height_w));
1264 if (cur_arrowheight == 0.0)
1265 cur_arrowheight = 1.0;
1266 cur_arrow_multwidth = (float) atof(panel_get_value(arrow_mult_width_w));
1267 if (cur_arrow_multwidth == 0.0)
1268 cur_arrow_multwidth = 1.0;
1269 cur_arrow_multthick = (float) atof(panel_get_value(arrow_mult_thick_w));
1270 if (cur_arrow_multthick == 0.0)
1271 cur_arrow_multthick = 1.0;
1272 cur_arrow_multheight = (float) atof(panel_get_value(arrow_mult_height_w));
1273 if (cur_arrow_multheight == 0.0)
1274 cur_arrow_multheight = 1.0;
1275 arrowsize_panel_dismiss();
1276 show_action(nval_i);
1277 }
1278
1279 static void
set_arrow_size_state(Widget w,XtPointer closure,XtPointer call_data)1280 set_arrow_size_state(Widget w, XtPointer closure, XtPointer call_data)
1281 {
1282 Boolean state;
1283 intptr_t which;
1284 Pixel bg1, bg2, fg1, fg2;
1285
1286 /* check state of the toggle and set/remove checkmark */
1287 FirstArg(XtNstate, &state);
1288 GetValues(w);
1289
1290 if (state ) {
1291 FirstArg(XtNbitmap, check_pm);
1292 } else {
1293 FirstArg(XtNbitmap, null_check_pm);
1294 }
1295 SetValues(w);
1296
1297 /* set the sensitivity of the toggle button to the opposite of its state
1298 so that the user must press the other one now */
1299 XtSetSensitive(w, !state);
1300 /* and make the *other* button the opposite state */
1301 if (w==abstoggle)
1302 XtSetSensitive(multtoggle, state);
1303 else
1304 XtSetSensitive(abstoggle, state);
1305
1306 /* which button */
1307 FirstArg(XtNradioData, &which);
1308 GetValues(w);
1309 if (which == 1) /* "multiple button", invert state */
1310 state = !state;
1311
1312 /* set global state */
1313 use_abs_arrowvals = state;
1314
1315 /* make spinners sensitive or insensitive */
1316 XtSetSensitive(a_t_spin, state);
1317 XtSetSensitive(a_w_spin, state);
1318 XtSetSensitive(a_h_spin, state);
1319
1320 state = !state;
1321 XtSetSensitive(m_t_spin, state);
1322 XtSetSensitive(m_w_spin, state);
1323 XtSetSensitive(m_h_spin, state);
1324
1325 /* now make the insensitive ones gray and the sensitive ones their original bg */
1326 bg1 = state? dark_gray_color: arrow_size_bg;
1327 bg2 = state? arrow_size_bg: dark_gray_color;
1328 fg1 = state? lt_gray_color: arrow_size_fg;
1329 fg2 = state? arrow_size_fg: lt_gray_color;
1330
1331 FirstArg(XtNbackground, bg1);
1332 NextArg(XtNforeground, fg1);
1333 SetValues(arrow_thick_w);
1334 SetValues(arrow_width_w);
1335 SetValues(arrow_height_w);
1336
1337 FirstArg(XtNbackground, bg2);
1338 NextArg(XtNforeground, fg2);
1339 SetValues(arrow_mult_thick_w);
1340 SetValues(arrow_mult_width_w);
1341 SetValues(arrow_mult_height_w);
1342 }
1343
1344 /* panel to handle the three arrow sizes (thickness, width and height) */
1345
popup_arrowsize_panel(ind_sw_info * isw)1346 void popup_arrowsize_panel(ind_sw_info *isw)
1347 {
1348 Position x_val, y_val;
1349 Dimension width, height;
1350 char buf[50];
1351 static Boolean actions_added=False;
1352 Widget abslabel;
1353
1354 /* save state of abs/mult in case user cancels */
1355 save_use_abs = use_abs_arrowvals;
1356
1357 nval_i = isw;
1358 XtSetSensitive(nval_i->button, False);
1359
1360 FirstArg(XtNwidth, &width);
1361 NextArg(XtNheight, &height);
1362 GetValues(tool);
1363 /* position the popup 1/3 in from left and 2/3 down from top */
1364 XtTranslateCoords(tool, (Position) (width / 3), (Position) (2 * height / 3),
1365 &x_val, &y_val);
1366
1367 FirstArg(XtNx, x_val);
1368 NextArg(XtNy, y_val);
1369 NextArg(XtNtitle, "Xfig: Arrow Size Panel");
1370 NextArg(XtNcolormap, tool_cm);
1371
1372 nval_popup = XtCreatePopupShell("set_nval_panel",
1373 transientShellWidgetClass, tool,
1374 Args, ArgCount);
1375 /* put in the widget so we don't have to create it next time */
1376 isw->panel = nval_popup;
1377
1378 XtOverrideTranslations(nval_popup,
1379 XtParseTranslationTable(nval_translations));
1380 if (!actions_added) {
1381 XtAppAddActions(tool_app, nval_actions, XtNumber(nval_actions));
1382 actions_added = True;
1383 }
1384 form = XtCreateManagedWidget("arrowsize_form", formWidgetClass, nval_popup, NULL, 0);
1385
1386 /* label for title - "Arrow Size" */
1387 FirstArg(XtNborderWidth, 0);
1388 NextArg(XtNresizable, True);
1389 NextArg(XtNlabel, "Arrow Size");
1390 NextArg(XtNtop, XtChainTop);
1391 NextArg(XtNbottom, XtChainTop);
1392 NextArg(XtNleft, XtChainLeft);
1393 NextArg(XtNright, XtChainLeft);
1394 label = XtCreateManagedWidget("arrow_size_panel", labelWidgetClass, form, Args, ArgCount);
1395
1396 /* toggle for using absolute values */
1397 FirstArg(XtNwidth, 20);
1398 NextArg(XtNheight, 20);
1399 NextArg(XtNfromVert, label);
1400 NextArg(XtNinternalWidth, 1);
1401 NextArg(XtNinternalHeight, 1);
1402 NextArg(XtNfont, bold_font);
1403 NextArg(XtNlabel, " ");
1404 NextArg(XtNbitmap, (use_abs_arrowvals?check_pm:null_check_pm));
1405 NextArg(XtNsensitive, (use_abs_arrowvals?False:True)); /* make opposite button sens */
1406 NextArg(XtNstate, use_abs_arrowvals); /* initial state */
1407 NextArg(XtNradioData, 0); /* when this is pressed the value is 0 */
1408 NextArg(XtNtop, XtChainTop);
1409 NextArg(XtNbottom, XtChainTop);
1410 NextArg(XtNleft, XtChainLeft);
1411 NextArg(XtNright, XtChainLeft);
1412 abstoggle = XtCreateManagedWidget("abstoggle", toggleWidgetClass, form, Args, ArgCount);
1413 XtAddCallback(abstoggle, XtNcallback, set_arrow_size_state, (XtPointer) NULL);
1414
1415 /* label - "Absolute Values" */
1416
1417 FirstArg(XtNborderWidth, 0);
1418 NextArg(XtNfromVert, label);
1419 NextArg(XtNfromHoriz, abstoggle);
1420 NextArg(XtNresizable, True);
1421 NextArg(XtNleft, XtChainLeft);
1422 NextArg(XtNright, XtChainLeft);
1423 NextArg(XtNlabel, "Absolute \nValues");
1424 NextArg(XtNtop, XtChainTop);
1425 NextArg(XtNbottom, XtChainTop);
1426 NextArg(XtNleft, XtChainLeft);
1427 NextArg(XtNright, XtChainLeft);
1428 abslabel = XtCreateManagedWidget("abslabel", labelWidgetClass, form, Args, ArgCount);
1429
1430 /* label - "Multiple of Line Width" */
1431
1432 FirstArg(XtNborderWidth, 0);
1433 NextArg(XtNfromVert, label);
1434 NextArg(XtNfromHoriz, abslabel);
1435 NextArg(XtNhorizDistance, 6);
1436 NextArg(XtNresizable, True);
1437 NextArg(XtNlabel, "Multiple of\nLine Width");
1438 NextArg(XtNtop, XtChainTop);
1439 NextArg(XtNbottom, XtChainTop);
1440 NextArg(XtNleft, XtChainLeft);
1441 NextArg(XtNright, XtChainLeft);
1442 beside = XtCreateManagedWidget("multlabel", labelWidgetClass, form,
1443 Args, ArgCount);
1444
1445 /* toggle for using multiple of line width */
1446 FirstArg(XtNwidth, 20);
1447 NextArg(XtNheight, 20);
1448 NextArg(XtNfromVert, label);
1449 NextArg(XtNfromHoriz, beside);
1450 NextArg(XtNinternalWidth, 1);
1451 NextArg(XtNinternalHeight, 1);
1452 NextArg(XtNfont, bold_font);
1453 NextArg(XtNlabel, " ");
1454 NextArg(XtNbitmap, (use_abs_arrowvals?null_check_pm:check_pm));
1455 NextArg(XtNsensitive, (use_abs_arrowvals?True:False)); /* make opposite button sens */
1456 NextArg(XtNstate, !use_abs_arrowvals); /* initial state */
1457 NextArg(XtNradioData, 1); /* when this is pressed the value is 1 */
1458 NextArg(XtNradioGroup, abstoggle); /* this is the other radio button in the group */
1459 NextArg(XtNtop, XtChainTop);
1460 NextArg(XtNbottom, XtChainTop);
1461 NextArg(XtNleft, XtChainLeft);
1462 NextArg(XtNright, XtChainLeft);
1463 multtoggle = XtCreateManagedWidget("multtoggle", toggleWidgetClass, form,
1464 Args, ArgCount);
1465 XtAddCallback(multtoggle, XtNcallback, set_arrow_size_state, (XtPointer) NULL);
1466
1467 /* make arrow thickness label and entries */
1468
1469 /* make a spinner entry widget for abs values */
1470 sprintf(buf,"%.1f",cur_arrowthick);
1471 a_t_spin = beside = MakeFloatSpinnerEntry(form, &arrow_thick_w, "arrow_thickness",
1472 abslabel, (Widget) NULL, (XtCallbackProc) 0, buf, 0.1, 10000.0, 1.0, 50);
1473
1474 FirstArg(XtNfromHoriz, beside);
1475 NextArg(XtNfromVert, abslabel);
1476 NextArg(XtNborderWidth, 0);
1477 NextArg(XtNtop, XtChainTop);
1478 NextArg(XtNbottom, XtChainTop);
1479 NextArg(XtNleft, XtChainLeft);
1480 NextArg(XtNright, XtChainLeft);
1481 beside = XtCreateManagedWidget("Thickness ", labelWidgetClass, form, Args, ArgCount);
1482
1483 /* make a spinner for Thickness = Multiple of line width */
1484 sprintf(buf,"%.1f",cur_arrow_multthick);
1485 m_t_spin = below = MakeFloatSpinnerEntry(form, &arrow_mult_thick_w, "arrow_mult_thickness",
1486 abslabel, beside, (XtCallbackProc) 0, buf, 0.1, 10000.0, 1.0, 50);
1487
1488 /* save the "normal" background so we can switch between that and gray (insensitive) */
1489 FirstArg(XtNbackground, &arrow_size_bg);
1490 NextArg(XtNforeground, &arrow_size_fg);
1491 GetValues(arrow_mult_thick_w);
1492
1493 /* make arrow width label and entries */
1494
1495 /* make a spinner entry widget for abs values */
1496 sprintf(buf,"%.1f",cur_arrowwidth);
1497 a_w_spin = beside = MakeFloatSpinnerEntry(form, &arrow_width_w, "arrow_width",
1498 below, (Widget) NULL, (XtCallbackProc) 0, buf, 0.1, 10000.0, 1.0, 50);
1499
1500 FirstArg(XtNfromHoriz, beside);
1501 NextArg(XtNfromVert, below);
1502 NextArg(XtNborderWidth, 0);
1503 NextArg(XtNtop, XtChainTop);
1504 NextArg(XtNbottom, XtChainTop);
1505 NextArg(XtNleft, XtChainLeft);
1506 NextArg(XtNright, XtChainLeft);
1507 beside = XtCreateManagedWidget(" Width ", labelWidgetClass, form, Args, ArgCount);
1508
1509 /* make a spinner for Width = Multiple of line width */
1510 sprintf(buf,"%.1f",cur_arrow_multwidth);
1511 m_w_spin = below = MakeFloatSpinnerEntry(form, &arrow_mult_width_w, "arrow_mult_width",
1512 below, beside, (XtCallbackProc) 0, buf, 0.1, 10000.0, 1.0, 50);
1513
1514 /* make arrow length label and entries */
1515
1516 /* make a spinner entry widget for abs values */
1517 sprintf(buf,"%.1f",cur_arrowheight);
1518 a_h_spin = beside = MakeFloatSpinnerEntry(form, &arrow_height_w, "arrow_height",
1519 below, (Widget) NULL, (XtCallbackProc) 0, buf, 0.1, 10000.0, 1.0, 50);
1520
1521 FirstArg(XtNfromHoriz, beside);
1522 NextArg(XtNfromVert, below);
1523 NextArg(XtNborderWidth, 0);
1524 NextArg(XtNtop, XtChainTop);
1525 NextArg(XtNbottom, XtChainTop);
1526 NextArg(XtNleft, XtChainLeft);
1527 NextArg(XtNright, XtChainLeft);
1528 beside = XtCreateManagedWidget(" Length ", labelWidgetClass, form, Args, ArgCount);
1529
1530 /* make a spinner for Height = Multiple of line width */
1531 sprintf(buf,"%.1f",cur_arrow_multheight);
1532 m_h_spin = below = MakeFloatSpinnerEntry(form, &arrow_mult_height_w, "arrow_mult_height",
1533 below, beside, (XtCallbackProc) 0, buf, 0.1, 10000.0, 1.0, 50);
1534
1535 /* make spinners sensitive or insensitive */
1536 XtSetSensitive(a_t_spin, use_abs_arrowvals);
1537 XtSetSensitive(a_w_spin, use_abs_arrowvals);
1538 XtSetSensitive(a_h_spin, use_abs_arrowvals);
1539
1540 XtSetSensitive(m_t_spin, !use_abs_arrowvals);
1541 XtSetSensitive(m_w_spin, !use_abs_arrowvals);
1542 XtSetSensitive(m_h_spin, !use_abs_arrowvals);
1543
1544 /* set the state of the widgets */
1545 set_arrow_size_state(abstoggle, NULL, NULL);
1546 set_arrow_size_state(multtoggle, NULL, NULL);
1547
1548 /***************************************/
1549 /* finally, the Set and Cancel buttons */
1550 /***************************************/
1551
1552 FirstArg(XtNlabel, "Cancel");
1553 NextArg(XtNfromVert, below);
1554 NextArg(XtNborderWidth, INTERNAL_BW);
1555 NextArg(XtNtop, XtChainTop);
1556 NextArg(XtNbottom, XtChainTop);
1557 NextArg(XtNleft, XtChainLeft);
1558 NextArg(XtNright, XtChainLeft);
1559 cancel = XtCreateManagedWidget("cancel", commandWidgetClass,
1560 form, Args, ArgCount);
1561 XtAddEventHandler(cancel, ButtonReleaseMask, False,
1562 (XtEventHandler) arrowsize_panel_cancel, (XtPointer) NULL);
1563
1564 FirstArg(XtNlabel, " Set ");
1565 NextArg(XtNfromVert, below);
1566 NextArg(XtNfromHoriz, cancel);
1567 NextArg(XtNborderWidth, INTERNAL_BW);
1568 NextArg(XtNtop, XtChainTop);
1569 NextArg(XtNbottom, XtChainTop);
1570 NextArg(XtNleft, XtChainLeft);
1571 NextArg(XtNright, XtChainLeft);
1572 set = XtCreateManagedWidget("set", commandWidgetClass,
1573 form, Args, ArgCount);
1574 XtAddEventHandler(set, ButtonReleaseMask, False,
1575 (XtEventHandler) arrowsize_panel_set, (XtPointer) NULL);
1576
1577 XtPopup(nval_popup, XtGrabExclusive);
1578 /* if the file message window is up add it to the grab */
1579 file_msg_add_grab();
1580 (void) XSetWMProtocols(tool_d, XtWindow(nval_popup), &wm_delete_window, 1);
1581 /* insure that the most recent colormap is installed */
1582 set_cmap(XtWindow(nval_popup));
1583
1584 XtInstallAccelerators(form, cancel);
1585 }
1586
1587 /* Update current dash length or dot gap including */
1588 /* the corresponding string value in the indicator panel. */
1589
1590 /* handle choice settings */
1591
1592 void
choice_panel_dismiss(void)1593 choice_panel_dismiss(void)
1594 {
1595 XtPopdown(choice_popup);
1596 XtSetSensitive(choice_i->button, True);
1597 }
1598
1599 static void
choice_panel_cancel(Widget w,XButtonEvent * ev)1600 choice_panel_cancel(Widget w, XButtonEvent *ev)
1601 {
1602 choice_panel_dismiss();
1603 }
1604
1605 static void
choice_panel_set(Widget w,choice_info * sel_choice,XButtonEvent * ev)1606 choice_panel_set(Widget w, choice_info *sel_choice, XButtonEvent *ev)
1607 {
1608 (*choice_i->i_varadr) = sel_choice->value;
1609 show_action(choice_i);
1610
1611 /* auxiliary info */
1612 switch (choice_i->func) {
1613 case I_LINESTYLE:
1614 /* dash length */
1615 cur_dashlength = (float) atof(panel_get_value(dash_length));
1616 if (cur_dashlength <= 0.0)
1617 cur_dashlength = DEF_DASHLENGTH;
1618
1619 /* dot gap */
1620 cur_dotgap = (float) atof(panel_get_value(dot_gap));
1621 if (cur_dotgap <= 0.0)
1622 cur_dotgap = DEF_DOTGAP;
1623
1624 if(cur_linestyle==DASH_LINE || cur_linestyle==DASH_DOT_LINE ||
1625 cur_linestyle==DASH_2_DOTS_LINE ||
1626 cur_linestyle==DASH_3_DOTS_LINE)
1627 cur_styleval=cur_dashlength;
1628 else if(cur_linestyle==DOTTED_LINE)
1629 cur_styleval=cur_dotgap;
1630
1631 break;
1632 }
1633
1634 choice_panel_dismiss();
1635 }
1636
popup_choice_panel(ind_sw_info * isw)1637 void popup_choice_panel(ind_sw_info *isw)
1638 {
1639 Position x_val, y_val;
1640 Dimension width, height;
1641 char buf[50];
1642 choice_info *tmp_choice;
1643 Pixmap p;
1644 int i, count;
1645 static Boolean actions_added=False;
1646 Widget obeside;
1647
1648 choice_i = isw;
1649 XtSetSensitive(choice_i->button, False);
1650
1651 /* if already created, just pop it up */
1652 if (isw->panel) {
1653 choice_popup = isw->panel;
1654 if (isw->func == I_PEN_COLOR || isw->func == I_FILL_COLOR) {
1655 /* activate the one the user pressed (pen or fill) */
1656 pen_fill_activate(isw->func);
1657 /* and store current pen and fill colors in the panels */
1658 restore_mixed_colors();
1659 /* finally, count the number of user colors */
1660 count_user_colors();
1661 /* and color the color cell borders */
1662 color_borders();
1663 /* make the "delete unused colors" button sensitive if there are user colors */
1664 if (num_usr_cols != 0)
1665 XtSetSensitive(delunusedColors, True);
1666 else
1667 XtSetSensitive(delunusedColors, False);
1668 } else if (isw->func == I_LINESTYLE) {
1669 /* update current dash length/dot gap indicators */
1670 sprintf(buf, "%.1f", cur_dashlength);
1671 FirstArg(XtNstring, buf);
1672 SetValues(dash_length);
1673 sprintf(buf, "%.1f", cur_dotgap);
1674 FirstArg(XtNstring, buf);
1675 SetValues(dot_gap);
1676 }
1677 if (appres.DEBUG)
1678 XtPopup(choice_popup, XtGrabNone); /* makes debugging easier */
1679 else
1680 XtPopup(choice_popup, XtGrabExclusive);
1681 /* if the file message window is up add it to the grab */
1682 file_msg_add_grab();
1683 /* insure that the most recent colormap is installed */
1684 set_cmap(XtWindow(isw->panel));
1685 return;
1686 }
1687
1688 FirstArg(XtNwidth, &width);
1689 NextArg(XtNheight, &height);
1690 GetValues(tool);
1691 if (isw->func == I_PEN_COLOR || isw->func == I_FILL_COLOR) {
1692 /* initially position the popup 1/3 in from left and 1/5 down from top */
1693 XtTranslateCoords(tool, (Position) (width / 3), (Position) (height / 5),
1694 &x_val, &y_val);
1695 } else {
1696 /* initially position the popup 1/3 in from left and 2/3 down from top */
1697 XtTranslateCoords(tool, (Position) (width / 3), (Position) (2 * height / 3),
1698 &x_val, &y_val);
1699 }
1700
1701 FirstArg(XtNx, x_val);
1702 NextArg(XtNy, y_val);
1703 NextArg(XtNresize, False);
1704 NextArg(XtNresizable, False);
1705 /* make a title for the panel */
1706 sprintf(buf,"Xfig: %s %s Panel",isw->line1,isw->line2);
1707 NextArg(XtNtitle, buf);
1708 NextArg(XtNcolormap, tool_cm);
1709
1710 choice_popup = XtCreatePopupShell("set_choice_panel",
1711 transientShellWidgetClass, tool,
1712 Args, ArgCount);
1713
1714 /* put in the widget so we don't have to create it next time */
1715 isw->panel = choice_popup;
1716
1717 XtOverrideTranslations(choice_popup,
1718 XtParseTranslationTable(choice_translations));
1719 if (!actions_added) {
1720 XtAppAddActions(tool_app, choice_actions, XtNumber(choice_actions));
1721 actions_added = True;
1722 }
1723
1724 form = XtCreateManagedWidget("choice_form", formWidgetClass, choice_popup, NULL, 0);
1725
1726 /* label first */
1727 FirstArg(XtNborderWidth, 0);
1728 NextArg(XtNtop, XtChainTop);
1729 NextArg(XtNbottom, XtChainTop);
1730 NextArg(XtNleft, XtChainLeft);
1731 NextArg(XtNright, XtChainLeft);
1732 /* color panel? */
1733 if (isw->func == I_PEN_COLOR || isw->func == I_FILL_COLOR) {
1734 /* yes */
1735 sprintf(buf, "Colors");
1736 } else {
1737 /* no, other */
1738 sprintf(buf, "%s %s", isw->line1, isw->line2);
1739 }
1740 label = XtCreateManagedWidget(buf, labelWidgetClass, form, Args, ArgCount);
1741
1742 /* create the cancel button here, but only manage it if this is the color panel
1743 (we'll put it at the bottom for the others) */
1744
1745 FirstArg(XtNlabel, "Cancel");
1746 NextArg(XtNfromVert, label); /* this will be changed for the non-color panels */
1747 NextArg(XtNresize, False);
1748 NextArg(XtNresizable, False);
1749 NextArg(XtNborderWidth, INTERNAL_BW);
1750 NextArg(XtNtop, XtChainTop);
1751 NextArg(XtNbottom, XtChainTop);
1752 NextArg(XtNleft, XtChainLeft);
1753 NextArg(XtNright, XtChainLeft);
1754 cancel = XtCreateWidget("cancel", commandWidgetClass, form, Args, ArgCount);
1755 XtAddEventHandler(cancel, ButtonReleaseMask, False,
1756 (XtEventHandler) choice_panel_cancel, (XtPointer) NULL);
1757
1758 /* manage it now only if this is the color panel */
1759 if (isw->func == I_PEN_COLOR || isw->func == I_FILL_COLOR)
1760 XtManageChild(cancel);
1761
1762 /* colors have the additional "extended color" panel */
1763 if (isw->func == I_PEN_COLOR || isw->func == I_FILL_COLOR) {
1764 create_color_panel(form,label,cancel,isw);
1765 /* if this is a color popup button copy the panel id to the other one too */
1766 /* (e.g. if this is the pen color pop, copy id to fill color panel */
1767 if (isw->func == I_FILL_COLOR)
1768 pen_color_button->panel = isw->panel;
1769 else if (isw->func == I_PEN_COLOR)
1770 fill_color_button->panel = isw->panel;
1771 return;
1772 }
1773
1774 tmp_choice = isw->choices;
1775
1776 for (i = 0; i < isw->numchoices; tmp_choice++, i++) {
1777 if (isw->func == I_FILLSTYLE) {
1778 if (cur_fillcolor == BLACK || cur_fillcolor == WHITE ||
1779 cur_fillcolor == DEFAULT) {
1780 if (i > NUMSHADEPATS && i <= NUMSHADEPATS+NUMTINTPATS)
1781 continue; /* skip the tints for black and white */
1782 }
1783 p = fillstyle_choices[i].pixmap;
1784 tmp_choice->value = i-1; /* fill value = i-1 */
1785 } else {
1786 p = tmp_choice->pixmap;
1787 }
1788
1789 /* check for new row of buttons */
1790 if (i==0 || count >= isw->sw_per_row) {
1791 if (i == 0)
1792 below = label;
1793 else
1794 below = beside;
1795 beside = (Widget) NULL;
1796 count = 0;
1797 }
1798 /* create a title for the pattern section */
1799 if (isw->func == I_FILLSTYLE && i == NUMSHADEPATS+NUMTINTPATS+1) {
1800 FirstArg(XtNlabel, "Patterns");
1801 NextArg(XtNfromVert, obeside);
1802 NextArg(XtNborderWidth, 0);
1803 NextArg(XtNtop, XtChainTop);
1804 NextArg(XtNbottom, XtChainTop);
1805 NextArg(XtNleft, XtChainLeft);
1806 NextArg(XtNright, XtChainLeft);
1807 below = XtCreateManagedWidget("pattern_label", labelWidgetClass,
1808 form, Args, ArgCount);
1809 beside = (Widget) 0;
1810 count = 0;
1811 }
1812 FirstArg(XtNfromVert, below);
1813 NextArg(XtNfromHoriz, beside);
1814 NextArg(XtNbackgroundPixmap, p);
1815 NextArg(XtNwidth, tmp_choice->icon->width);
1816 NextArg(XtNheight, tmp_choice->icon->height);
1817 NextArg(XtNresize, False);
1818 NextArg(XtNresizable, False);
1819 NextArg(XtNborderWidth, INTERNAL_BW);
1820 NextArg(XtNtop, XtChainTop);
1821 NextArg(XtNbottom, XtChainTop);
1822 NextArg(XtNleft, XtChainLeft);
1823 NextArg(XtNright, XtChainLeft);
1824 beside = XtCreateManagedWidget((String)" ", commandWidgetClass,
1825 form, Args, ArgCount);
1826 obeside = beside;
1827 XtAddEventHandler(beside, ButtonReleaseMask, False,
1828 (XtEventHandler) choice_panel_set, (XtPointer) tmp_choice);
1829 count++;
1830 }
1831 below = beside;
1832
1833 /* auxiliary info */
1834 switch (isw->func) {
1835 case I_LINESTYLE:
1836 /* dash length */
1837 FirstArg(XtNfromVert, beside);
1838 NextArg(XtNborderWidth, 0);
1839 NextArg(XtNlabel, "Default dash length");
1840 NextArg(XtNtop, XtChainTop);
1841 NextArg(XtNbottom, XtChainTop);
1842 NextArg(XtNleft, XtChainLeft);
1843 NextArg(XtNright, XtChainLeft);
1844 label = XtCreateManagedWidget("default_dash_length",
1845 labelWidgetClass, form, Args, ArgCount);
1846
1847 sprintf(buf, "%.1f", cur_dashlength);
1848 below = MakeFloatSpinnerEntry(form, &dash_length, "dash_length", beside, label,
1849 (XtCallbackProc) 0, buf, 0.0, 10000.0, 1.0, 50);
1850
1851 /* enable mousefun kbd icon */
1852 XtAugmentTranslations(dash_length,
1853 XtParseTranslationTable(kbd_translations));
1854
1855 /* dot gap */
1856 FirstArg(XtNfromVert, below);
1857 NextArg(XtNborderWidth, 0);
1858 NextArg(XtNlabel, " Default dot gap");
1859 NextArg(XtNtop, XtChainTop);
1860 NextArg(XtNbottom, XtChainTop);
1861 NextArg(XtNleft, XtChainLeft);
1862 NextArg(XtNright, XtChainLeft);
1863 label = XtCreateManagedWidget("default_dot_gap",
1864 labelWidgetClass, form, Args, ArgCount);
1865
1866 sprintf(buf, "%.1f", cur_dotgap);
1867 below = MakeFloatSpinnerEntry(form, &dot_gap, "dot_gap", below, label,
1868 (XtCallbackProc) 0, buf, 0.0, 10000.0, 1.0, 50);
1869
1870 /* enable mousefun kbd icon */
1871 XtAugmentTranslations(dot_gap,
1872 XtParseTranslationTable(kbd_translations));
1873 break;
1874 }
1875
1876 /* now position the cancel button below the last button created and manage it */
1877 FirstArg(XtNfromVert, below);
1878 SetValues(cancel);
1879 XtManageChild(cancel);
1880
1881 if (appres.DEBUG)
1882 XtPopup(choice_popup, XtGrabNone); /* makes debugging easier */
1883 else
1884 XtPopup(choice_popup, XtGrabExclusive);
1885 /* if the file message window is up add it to the grab */
1886 file_msg_add_grab();
1887 (void) XSetWMProtocols(tool_d, XtWindow(choice_popup), &wm_delete_window, 1);
1888 /* insure that the most recent colormap is installed */
1889 set_cmap(XtWindow(choice_popup));
1890
1891 XtInstallAccelerators(form, cancel);
1892 }
1893
1894 /* handle text flag settings */
1895
1896 static intptr_t hidden_text_flag, special_text_flag, rigid_text_flag;
1897 static Widget hidden_text_panel, rigid_text_panel, special_text_panel;
1898
1899 static void
flags_panel_dismiss(void)1900 flags_panel_dismiss(void)
1901 {
1902 XtDestroyWidget(nval_popup);
1903 XtSetSensitive(nval_i->button, True);
1904 }
1905
1906 static void
flags_panel_cancel(Widget w,XButtonEvent * ev)1907 flags_panel_cancel(Widget w, XButtonEvent *ev)
1908 {
1909 flags_panel_dismiss();
1910 }
1911
1912 static void
flags_panel_set(Widget w,XButtonEvent * ev)1913 flags_panel_set(Widget w, XButtonEvent *ev)
1914 {
1915 if (hidden_text_flag)
1916 cur_textflags |= HIDDEN_TEXT;
1917 else
1918 cur_textflags &= ~HIDDEN_TEXT;
1919 if (special_text_flag)
1920 cur_textflags |= SPECIAL_TEXT;
1921 else
1922 cur_textflags &= ~SPECIAL_TEXT;
1923 if (rigid_text_flag)
1924 cur_textflags |= RIGID_TEXT;
1925 else
1926 cur_textflags &= ~RIGID_TEXT;
1927 flags_panel_dismiss();
1928 show_action(nval_i);
1929 }
1930
1931 static void
hidden_text_select(Widget w,XtPointer new_hidden_text,XtPointer call_data)1932 hidden_text_select(Widget w, XtPointer new_hidden_text, XtPointer call_data)
1933 {
1934 FirstArg(XtNlabel, XtName(w));
1935 SetValues(hidden_text_panel);
1936 hidden_text_flag = (intptr_t) new_hidden_text;
1937 if (hidden_text_flag)
1938 put_msg("Text will be displayed as hidden");
1939 else
1940 put_msg("Text will be displayed normally");
1941 }
1942
1943 static void
rigid_text_select(Widget w,XtPointer new_rigid_text,XtPointer call_data)1944 rigid_text_select(Widget w, XtPointer new_rigid_text, XtPointer call_data)
1945 {
1946 FirstArg(XtNlabel, XtName(w));
1947 SetValues(rigid_text_panel);
1948 rigid_text_flag = (intptr_t) new_rigid_text;
1949 if (rigid_text_flag)
1950 put_msg("Text in compound group will not scale with compound");
1951 else
1952 put_msg("Text in compound group will scale with compound");
1953 }
1954
1955 static void
special_text_select(Widget w,XtPointer new_special_text,XtPointer call_data)1956 special_text_select(Widget w, XtPointer new_special_text, XtPointer call_data)
1957 {
1958 FirstArg(XtNlabel, XtName(w));
1959 SetValues(special_text_panel);
1960 special_text_flag = (intptr_t) new_special_text;
1961 if (special_text_flag)
1962 put_msg("Text may contain characters with special meaning for TeX/LaTeX");
1963 else
1964 put_msg("Characters special to TeX will be quoted during print/export");
1965 }
1966
popup_flags_panel(ind_sw_info * isw)1967 void popup_flags_panel(ind_sw_info *isw)
1968 {
1969 Position x_val, y_val;
1970 Dimension width, height;
1971 char buf[50];
1972 static Boolean actions_added=False;
1973 static char *hidden_text_items[] = {
1974 "Normal", "Hidden"};
1975 static char *rigid_text_items[] = {
1976 "Normal", "Rigid "};
1977 static char *special_text_items[] = {
1978 "Normal", "TeX "};
1979
1980 nval_i = isw;
1981 XtSetSensitive(nval_i->button, False);
1982
1983 rigid_text_flag = (intptr_t) ((cur_textflags & RIGID_TEXT) ? 1 : 0);
1984 special_text_flag = (intptr_t) ((cur_textflags & SPECIAL_TEXT) ? 1 : 0);
1985 hidden_text_flag = (intptr_t) ((cur_textflags & HIDDEN_TEXT) ? 1 : 0);
1986
1987 FirstArg(XtNwidth, &width);
1988 NextArg(XtNheight, &height);
1989 GetValues(tool);
1990 /* position the popup 1/3 in from left and 2/3 down from top */
1991 XtTranslateCoords(tool, (Position) (width / 3), (Position) (2 * height / 3),
1992 &x_val, &y_val);
1993
1994 FirstArg(XtNx, x_val);
1995 NextArg(XtNy, y_val);
1996 NextArg(XtNtitle, "Xfig: Text Flags Panel");
1997 NextArg(XtNcolormap, tool_cm);
1998
1999 nval_popup = XtCreatePopupShell("set_nval_panel",
2000 transientShellWidgetClass, tool,
2001 Args, ArgCount);
2002 /* put in the widget so we don't have to create it next time */
2003 isw->panel = nval_popup;
2004
2005 XtOverrideTranslations(nval_popup,
2006 XtParseTranslationTable(nval_translations));
2007 if (!actions_added) {
2008 XtAppAddActions(tool_app, nval_actions, XtNumber(nval_actions));
2009 actions_added = True;
2010 }
2011 form = XtCreateManagedWidget("flags_form", formWidgetClass, nval_popup, NULL, 0);
2012
2013 FirstArg(XtNborderWidth, 0);
2014 sprintf(buf, "%s %s", isw->line1, isw->line2);
2015 NextArg(XtNtop, XtChainTop);
2016 NextArg(XtNbottom, XtChainTop);
2017 NextArg(XtNleft, XtChainLeft);
2018 NextArg(XtNright, XtChainLeft);
2019 label = XtCreateManagedWidget(buf, labelWidgetClass, form, Args, ArgCount);
2020
2021 /* make hidden text menu */
2022
2023 FirstArg(XtNfromVert, label);
2024 NextArg(XtNborderWidth, 0);
2025 NextArg(XtNtop, XtChainTop);
2026 NextArg(XtNbottom, XtChainTop);
2027 NextArg(XtNleft, XtChainLeft);
2028 NextArg(XtNright, XtChainLeft);
2029 beside = XtCreateManagedWidget("Hidden Flag", labelWidgetClass,
2030 form, Args, ArgCount);
2031
2032 FirstArg(XtNfromVert, label);
2033 NextArg(XtNfromHoriz, beside);
2034 NextArg(XtNleftBitmap, menu_arrow); /* use menu arrow for pull-down */
2035 NextArg(XtNtop, XtChainTop);
2036 NextArg(XtNbottom, XtChainTop);
2037 NextArg(XtNleft, XtChainLeft);
2038 NextArg(XtNright, XtChainLeft);
2039 hidden_text_panel = XtCreateManagedWidget(
2040 hidden_text_items[hidden_text_flag], menuButtonWidgetClass,
2041 form, Args, ArgCount);
2042 below = hidden_text_panel;
2043 make_pulldown_menu(hidden_text_items,
2044 XtNumber(hidden_text_items), -1, "",
2045 hidden_text_panel, hidden_text_select);
2046
2047 /* make rigid text menu */
2048
2049 FirstArg(XtNfromVert, below);
2050 NextArg(XtNborderWidth, 0);
2051 NextArg(XtNtop, XtChainTop);
2052 NextArg(XtNbottom, XtChainTop);
2053 NextArg(XtNleft, XtChainLeft);
2054 NextArg(XtNright, XtChainLeft);
2055 beside = XtCreateManagedWidget(" Rigid Flag", labelWidgetClass,
2056 form, Args, ArgCount);
2057
2058 FirstArg(XtNfromVert, below);
2059 NextArg(XtNfromHoriz, beside);
2060 NextArg(XtNleftBitmap, menu_arrow); /* use menu arrow for pull-down */
2061 NextArg(XtNtop, XtChainTop);
2062 NextArg(XtNbottom, XtChainTop);
2063 NextArg(XtNleft, XtChainLeft);
2064 NextArg(XtNright, XtChainLeft);
2065 rigid_text_panel = XtCreateManagedWidget(
2066 rigid_text_items[rigid_text_flag], menuButtonWidgetClass,
2067 form, Args, ArgCount);
2068 below = rigid_text_panel;
2069 make_pulldown_menu(rigid_text_items,
2070 XtNumber(rigid_text_items), -1, "",
2071 rigid_text_panel, rigid_text_select);
2072
2073 /* make special text menu */
2074
2075 FirstArg(XtNfromVert, below);
2076 NextArg(XtNborderWidth, 0);
2077 NextArg(XtNtop, XtChainTop);
2078 NextArg(XtNbottom, XtChainTop);
2079 NextArg(XtNleft, XtChainLeft);
2080 NextArg(XtNright, XtChainLeft);
2081 beside = XtCreateManagedWidget(" TeX Flag", labelWidgetClass,
2082 form, Args, ArgCount);
2083
2084 FirstArg(XtNfromVert, below);
2085 NextArg(XtNfromHoriz, beside);
2086 NextArg(XtNleftBitmap, menu_arrow); /* use menu arrow for pull-down */
2087 NextArg(XtNtop, XtChainTop);
2088 NextArg(XtNbottom, XtChainTop);
2089 NextArg(XtNleft, XtChainLeft);
2090 NextArg(XtNright, XtChainLeft);
2091 special_text_panel = XtCreateManagedWidget(
2092 special_text_items[special_text_flag],
2093 menuButtonWidgetClass, form, Args, ArgCount);
2094 below = special_text_panel;
2095 make_pulldown_menu(special_text_items,
2096 XtNumber(special_text_items), -1, "",
2097 special_text_panel, special_text_select);
2098
2099 FirstArg(XtNlabel, "Cancel");
2100 NextArg(XtNfromVert, below);
2101 NextArg(XtNborderWidth, INTERNAL_BW);
2102 NextArg(XtNtop, XtChainTop);
2103 NextArg(XtNbottom, XtChainTop);
2104 NextArg(XtNleft, XtChainLeft);
2105 NextArg(XtNright, XtChainLeft);
2106 cancel = XtCreateManagedWidget("cancel", commandWidgetClass,
2107 form, Args, ArgCount);
2108 XtAddEventHandler(cancel, ButtonReleaseMask, False,
2109 (XtEventHandler) flags_panel_cancel, (XtPointer) NULL);
2110
2111 FirstArg(XtNlabel, " Set ");
2112 NextArg(XtNfromVert, below);
2113 NextArg(XtNfromHoriz, cancel);
2114 NextArg(XtNborderWidth, INTERNAL_BW);
2115 NextArg(XtNtop, XtChainTop);
2116 NextArg(XtNbottom, XtChainTop);
2117 NextArg(XtNleft, XtChainLeft);
2118 NextArg(XtNright, XtChainLeft);
2119 set = XtCreateManagedWidget("set", commandWidgetClass,
2120 form, Args, ArgCount);
2121 XtAddEventHandler(set, ButtonReleaseMask, False,
2122 (XtEventHandler) flags_panel_set, (XtPointer) NULL);
2123
2124 XtPopup(nval_popup, XtGrabExclusive);
2125 /* if the file message window is up add it to the grab */
2126 file_msg_add_grab();
2127 (void) XSetWMProtocols(tool_d, XtWindow(nval_popup), &wm_delete_window, 1);
2128 /* insure that the most recent colormap is installed */
2129 set_cmap(XtWindow(nval_popup));
2130
2131 XtInstallAccelerators(form, cancel);
2132 }
2133
2134 /* handle integer and floating point settings */
2135
2136 static void
nval_panel_dismiss(void)2137 nval_panel_dismiss(void)
2138 {
2139 XtDestroyWidget(nval_popup);
2140 XtSetSensitive(nval_i->button, True);
2141 }
2142
2143 Widget zoomcheck;
2144
2145 static void
toggle_int_zoom(Widget w,XtPointer closure,XtPointer call_data)2146 toggle_int_zoom(Widget w, XtPointer closure, XtPointer call_data)
2147 {
2148 integral_zoom = !integral_zoom;
2149 if ( integral_zoom ) {
2150 FirstArg(XtNbitmap, check_pm);
2151 } else {
2152 FirstArg(XtNbitmap, null_check_pm);
2153 }
2154 SetValues(zoomcheck);
2155 }
2156
2157 static void
nval_panel_cancel(Widget w,XButtonEvent * ev)2158 nval_panel_cancel(Widget w, XButtonEvent *ev)
2159 {
2160 nval_panel_dismiss();
2161 }
2162
2163 static void
nval_panel_set(Widget w,XButtonEvent * ev)2164 nval_panel_set(Widget w, XButtonEvent *ev)
2165 {
2166 int new_i_value;
2167 float new_f_value;
2168
2169 if (nval_i->type == I_IVAL) {
2170 new_i_value = atoi(panel_get_value(newvalue));
2171 (*nval_i->i_varadr) = new_i_value;
2172 } else {
2173 new_f_value = (float) atof(panel_get_value(newvalue));
2174 (*nval_i->f_varadr) = new_f_value;
2175 }
2176 nval_panel_dismiss();
2177 show_action(nval_i);
2178 }
2179
2180
popup_nval_panel(ind_sw_info * isw)2181 void popup_nval_panel(ind_sw_info *isw)
2182 {
2183 Position x_val, y_val;
2184 Dimension width, height;
2185 char buf[50];
2186 static Boolean actions_added=False;
2187 int vdist;
2188
2189 nval_i = isw;
2190 XtSetSensitive(nval_i->button, False);
2191
2192 FirstArg(XtNwidth, &width);
2193 NextArg(XtNheight, &height);
2194 GetValues(tool);
2195 /* position the popup 1/3 in from left and 2/3 down from top */
2196 XtTranslateCoords(tool, (Position) (width / 3), (Position) (2 * height / 3),
2197 &x_val, &y_val);
2198
2199 FirstArg(XtNx, x_val);
2200 NextArg(XtNy, y_val);
2201 /* make a title for the panel */
2202 sprintf(buf,"Xfig: %s %s Panel",isw->line1,isw->line2);
2203 NextArg(XtNtitle, buf);
2204 NextArg(XtNcolormap, tool_cm);
2205
2206 nval_popup = XtCreatePopupShell("set_nval_panel",
2207 transientShellWidgetClass, tool,
2208 Args, ArgCount);
2209
2210 XtOverrideTranslations(nval_popup,
2211 XtParseTranslationTable(nval_translations));
2212 if (!actions_added) {
2213 XtAppAddActions(tool_app, nval_actions, XtNumber(nval_actions));
2214 actions_added = True;
2215 }
2216 form = XtCreateManagedWidget("nval_form", formWidgetClass, nval_popup, NULL, 0);
2217
2218 FirstArg(XtNborderWidth, 0);
2219 sprintf(buf, "%s %s", isw->line1, isw->line2);
2220 NextArg(XtNtop, XtChainTop);
2221 NextArg(XtNbottom, XtChainTop);
2222 NextArg(XtNleft, XtChainLeft);
2223 NextArg(XtNright, XtChainLeft);
2224 label = XtCreateManagedWidget(buf, labelWidgetClass, form, Args, ArgCount);
2225
2226 FirstArg(XtNfromVert, label);
2227 NextArg(XtNborderWidth, 0);
2228 NextArg(XtNlabel, "Value");
2229 NextArg(XtNtop, XtChainTop);
2230 NextArg(XtNbottom, XtChainTop);
2231 NextArg(XtNleft, XtChainLeft);
2232 NextArg(XtNright, XtChainLeft);
2233 newvalue = XtCreateManagedWidget("valueLabel", labelWidgetClass,
2234 form, Args, ArgCount);
2235 /* int or float? */
2236 if (isw->type == I_IVAL) {
2237 sprintf(buf, "%d", (*isw->i_varadr));
2238 below = MakeIntSpinnerEntry(form, &newvalue, "value", label, newvalue,
2239 (XtCallbackProc) 0, buf, isw->min, isw->max, (int)isw->inc, 45);
2240 } else {
2241 sprintf(buf, "%.2f", (*isw->f_varadr));
2242 below = MakeFloatSpinnerEntry(form, &newvalue, "value", label, newvalue,
2243 (XtCallbackProc) 0, buf, (float)isw->min, (float)isw->max, isw->inc, 55);
2244 }
2245 /* focus keyboard on text widget */
2246 XtSetKeyboardFocus(form, newvalue);
2247
2248 /* set value on carriage return */
2249 XtOverrideTranslations(newvalue, XtParseTranslationTable(set_translations));
2250 /* enable mousefun kbd icon */
2251 XtAugmentTranslations(newvalue, XtParseTranslationTable(kbd_translations));
2252
2253 /* for the zoom panel, make an "integer zoom checkbutton" and
2254 a "Fit to canvas" button */
2255
2256 vdist = 4;
2257 if (strcasecmp(isw->line1,"zoom")==0) {
2258 FirstArg(XtNlabel, " Fit to canvas ");
2259 NextArg(XtNfromVert, below);
2260 NextArg(XtNvertDistance, 10);
2261 NextArg(XtNborderWidth, INTERNAL_BW);
2262 NextArg(XtNtop, XtChainTop);
2263 NextArg(XtNbottom, XtChainTop);
2264 NextArg(XtNleft, XtChainLeft);
2265 NextArg(XtNright, XtChainLeft);
2266 below = XtCreateManagedWidget("fit_to_canvas", commandWidgetClass,
2267 form, Args, ArgCount);
2268 XtAddCallback(below, XtNcallback, zoom_to_fit, (XtPointer) NULL);
2269
2270 FirstArg(XtNwidth, 20);
2271 NextArg(XtNheight, 20);
2272 NextArg(XtNfont, bold_font);
2273 NextArg(XtNfromVert, below);
2274 if ( integral_zoom ) {
2275 NextArg(XtNbitmap, check_pm);
2276 } else {
2277 NextArg(XtNbitmap, null_check_pm);
2278 }
2279 NextArg(XtNlabel, " ");
2280 NextArg(XtNstate, integral_zoom);
2281 NextArg(XtNinternalWidth, 1);
2282 NextArg(XtNinternalHeight, 1);
2283 NextArg(XtNtop, XtChainTop);
2284 NextArg(XtNbottom, XtChainTop);
2285 NextArg(XtNleft, XtChainLeft);
2286 NextArg(XtNright, XtChainLeft);
2287 zoomcheck = XtCreateManagedWidget("intzoom_check", toggleWidgetClass,
2288 form, Args, ArgCount);
2289
2290 FirstArg(XtNlabel,"Integer zoom");
2291 NextArg(XtNheight, 18);
2292 NextArg(XtNfromHoriz, zoomcheck);
2293 NextArg(XtNhorizDistance, 2);
2294 NextArg(XtNfromVert, below);
2295 NextArg(XtNtop, XtChainTop);
2296 NextArg(XtNbottom, XtChainTop);
2297 NextArg(XtNleft, XtChainLeft);
2298 NextArg(XtNright, XtChainLeft);
2299 below = XtCreateManagedWidget("intzoom_label", labelWidgetClass,
2300 form, Args, ArgCount);
2301 XtAddCallback(zoomcheck, XtNcallback, toggle_int_zoom, (XtPointer) NULL);
2302 /* make more space before the set/cancel buttons */
2303 vdist = 10;
2304 }
2305
2306 FirstArg(XtNlabel, "Cancel");
2307 NextArg(XtNfromVert, below);
2308 NextArg(XtNvertDistance, vdist);
2309 NextArg(XtNborderWidth, INTERNAL_BW);
2310 NextArg(XtNtop, XtChainTop);
2311 NextArg(XtNbottom, XtChainTop);
2312 NextArg(XtNleft, XtChainLeft);
2313 NextArg(XtNright, XtChainLeft);
2314 cancel = XtCreateManagedWidget("cancel", commandWidgetClass,
2315 form, Args, ArgCount);
2316 XtAddEventHandler(cancel, ButtonReleaseMask, False,
2317 (XtEventHandler) nval_panel_cancel, (XtPointer) NULL);
2318
2319 FirstArg(XtNlabel, " Set ");
2320 NextArg(XtNfromVert, below);
2321 NextArg(XtNfromHoriz, cancel);
2322 NextArg(XtNvertDistance, vdist);
2323 NextArg(XtNborderWidth, INTERNAL_BW);
2324 NextArg(XtNtop, XtChainTop);
2325 NextArg(XtNbottom, XtChainTop);
2326 NextArg(XtNleft, XtChainLeft);
2327 NextArg(XtNright, XtChainLeft);
2328 set = XtCreateManagedWidget("set", commandWidgetClass,
2329 form, Args, ArgCount);
2330 XtAddEventHandler(set, ButtonReleaseMask, False,
2331 (XtEventHandler) nval_panel_set, (XtPointer) NULL);
2332
2333 XtPopup(nval_popup, XtGrabExclusive);
2334 /* if the file message window is up add it to the grab */
2335 file_msg_add_grab();
2336 (void) XSetWMProtocols(tool_d, XtWindow(nval_popup), &wm_delete_window, 1);
2337 /* insure that the most recent colormap is installed */
2338 set_cmap(XtWindow(nval_popup));
2339
2340 XtInstallAccelerators(form, cancel);
2341 }
2342
2343 /**********************/
2344 /* DIMENSION LINE */
2345 /**********************/
2346
2347 static int dimline_thick;
2348 static int dimline_style;
2349 static int dimline_color;
2350 static int dimline_leftarrow;
2351 static int dimline_rightarrow;
2352 static float dimline_arrowlength;
2353 static float dimline_arrowwidth;
2354 static Boolean dimline_ticks;
2355 static int dimline_tickthick;
2356 static int dimline_boxthick;
2357 static int dimline_boxcolor;
2358 static int dimline_textcolor;
2359 static int dimline_font;
2360 static int dimline_fontsize;
2361 static int dimline_psflag;
2362 static Boolean dimline_fixed, dimline_actual;
2363 static int dim_ps_font, dim_latex_font;
2364 static int dimline_prec;
2365
2366 static int savecur_dimline_thick;
2367 static int savecur_dimline_style;
2368 static int savecur_dimline_color;
2369 static int savecur_dimline_leftarrow;
2370 static int savecur_dimline_rightarrow;
2371 static float savecur_dimline_arrowlength;
2372 static float savecur_dimline_arrowwidth;
2373 static Boolean savecur_dimline_ticks;
2374 static int savecur_dimline_tickthick;
2375 static int savecur_dimline_boxthick;
2376 static int savecur_dimline_boxcolor;
2377 static int savecur_dimline_textcolor;
2378 static int savecur_dimline_font;
2379 static int savecur_dimline_fontsize;
2380 static int savecur_dimline_psflag;
2381 static Boolean savecur_dimline_fixed;
2382 static int savecur_dimline_prec;
2383
2384 static Widget line_thick_w, arrow_width_w, arrow_length_w;
2385 static Widget tick_thick_w;
2386 static Widget box_thick_w, font_size_w, dimline_style_panel;
2387 static Widget left_arrow_type_panel, right_arrow_type_panel;
2388 static Widget font_button;
2389 static Pixmap dimline_examp_pixmap = (Pixmap) 0;
2390 static Widget exampline;
2391 static Widget fixed_chk, actual_chk;
2392 static Widget dimline_precw;
2393
2394 static void left_arrow_type_select(Widget w, XtPointer new_type, XtPointer call_data);
2395 static void right_arrow_type_select(Widget w, XtPointer new_type, XtPointer call_data);
2396 static void dimline_font_popup(Widget w, XtPointer user_data, XtPointer call_data);
2397 static void dimline_set_font_image(Widget widget);
2398 static void set_fixed_text(Widget w, XtPointer fixed, XtPointer dum);
2399 static void set_actual_text(Widget w, XtPointer actual, XtPointer dum);
2400 static void dimline_panel_preview(Widget w, XtPointer user_data, XtPointer call_data);
2401
2402
2403 static void line_color_select(Widget w, XtPointer new_color, XtPointer call_data);
2404 static Widget line_color_button, line_color_panel;
2405
2406 static void box_color_select(Widget w, XtPointer new_color, XtPointer call_data);
2407 static Widget box_color_button, box_color_panel;
2408
2409 static void text_color_select(Widget w, XtPointer new_color, XtPointer call_data);
2410 static Widget text_color_button, text_color_panel;
2411
2412 /* length of example dimension line for IP and SI units */
2413
2414 #define DIMLINE_IP_LENGTH 3.75
2415 #define DIMLINE_SI_LENGTH 9.5
2416 #define DIMLINE_PIXMAP_WIDTH (int)(max2(DIMLINE_IP_LENGTH*DISPLAY_PIX_PER_INCH, \
2417 DIMLINE_SI_LENGTH*DISPLAY_PIX_PER_INCH/2.54) + 10)
2418 #define DIMLINE_PIXMAP_HEIGHT 40
2419
popup_dimline_panel(ind_sw_info * isw)2420 void popup_dimline_panel(ind_sw_info *isw)
2421 {
2422 Position x_val, y_val;
2423 Dimension width, height;
2424 Widget lineform, arrowform, boxform, tickform, textform, stringform;
2425 static Boolean actions_added=False;
2426
2427 choice_i = isw;
2428 XtSetSensitive(choice_i->button, False);
2429
2430 /* get current settings for dimension lines */
2431 dimline_thick = cur_dimline_thick;
2432 dimline_style = cur_dimline_style;
2433 dimline_color = cur_dimline_color;
2434 dimline_leftarrow = cur_dimline_leftarrow;
2435 dimline_rightarrow = cur_dimline_rightarrow;
2436 dimline_arrowlength = cur_dimline_arrowlength;
2437 dimline_arrowwidth = cur_dimline_arrowwidth;
2438 dimline_ticks = cur_dimline_ticks;
2439 dimline_tickthick = cur_dimline_tickthick;
2440 dimline_boxthick = cur_dimline_boxthick;
2441 dimline_boxcolor = cur_dimline_boxcolor;
2442 dimline_textcolor = cur_dimline_textcolor;
2443 dimline_font = cur_dimline_font;
2444 dimline_fontsize = cur_dimline_fontsize;
2445 dimline_psflag = cur_dimline_psflag;
2446 dimline_fixed = cur_dimline_fixed;
2447 dimline_actual = !dimline_fixed;
2448 dimline_prec = cur_dimline_prec;
2449
2450 FirstArg(XtNwidth, &width);
2451 NextArg(XtNheight, &height);
2452 GetValues(tool);
2453 /* initially position the popup 1/3 in from left and 1/4 down from top */
2454 XtTranslateCoords(tool, (Position) (width / 3), (Position) (height / 4),
2455 &x_val, &y_val);
2456
2457 FirstArg(XtNx, x_val);
2458 NextArg(XtNy, y_val);
2459 NextArg(XtNresize, False);
2460 NextArg(XtNresizable, False);
2461 NextArg(XtNtitle, "Xfig: Dimension Line Settings");
2462 NextArg(XtNcolormap, tool_cm);
2463
2464 choice_popup = XtCreatePopupShell("set_dimline_panel",
2465 transientShellWidgetClass, tool,
2466 Args, ArgCount);
2467
2468 /* put in the widget so we don't have to create it next time */
2469 isw->panel = choice_popup;
2470
2471 /* the main form */
2472 form = XtCreateManagedWidget("dimline_form", formWidgetClass, choice_popup, NULL, 0);
2473
2474 /* label for title - "Dimension Line Settings" */
2475 FirstArg(XtNborderWidth, 0);
2476 NextArg(XtNresizable, True);
2477 NextArg(XtNlabel, "Dimension Line Settings");
2478 NextArg(XtNtop, XtChainTop);
2479 NextArg(XtNbottom, XtChainTop);
2480 NextArg(XtNleft, XtChainLeft);
2481 NextArg(XtNright, XtChainLeft);
2482 below = XtCreateManagedWidget("dimension_line_panel", labelWidgetClass,
2483 form, Args, ArgCount);
2484
2485 /* make an example line that shows current settings as a label */
2486
2487 /* make a pixmap to draw it into */
2488 if (dimline_examp_pixmap == (Pixmap) 0)
2489 dimline_examp_pixmap = XCreatePixmap(tool_d, canvas_win,
2490 DIMLINE_PIXMAP_WIDTH, DIMLINE_PIXMAP_HEIGHT, tool_dpth);
2491 /* clear it */
2492 XFillRectangle(tool_d, dimline_examp_pixmap, ind_blank_gc, 0, 0,
2493 DIMLINE_PIXMAP_WIDTH, 30);
2494
2495 /* now make the label widget to display the pixmap */
2496 FirstArg(XtNfromVert, below);
2497 NextArg(XtNborderWidth, 0);
2498 NextArg(XtNwidth, DIMLINE_PIXMAP_WIDTH);
2499 NextArg(XtNheight, 30);
2500 NextArg(XtNtop, XtChainTop);
2501 NextArg(XtNbottom, XtChainTop);
2502 NextArg(XtNleft, XtChainLeft);
2503 NextArg(XtNright, XtChainLeft);
2504 exampline = XtCreateManagedWidget("", labelWidgetClass,
2505 form, Args, ArgCount);
2506 draw_cur_dimline(); /* this draws it into dimline_examp_pixmap */
2507
2508 /******************************/
2509 /* frame for Line information */
2510 /******************************/
2511
2512 FirstArg(XtNborderWidth, 1);
2513 NextArg(XtNfromVert, exampline);
2514 NextArg(XtNtop, XtChainTop);
2515 NextArg(XtNbottom, XtChainTop);
2516 NextArg(XtNleft, XtChainLeft);
2517 NextArg(XtNright, XtChainLeft);
2518 lineform = XtCreateManagedWidget("lineform", formWidgetClass, form, Args, ArgCount);
2519
2520 /* "Line" label */
2521 FirstArg(XtNlabel, "Line");
2522 below = XtCreateManagedWidget("dimension_line_panel", labelWidgetClass,
2523 lineform, Args, ArgCount);
2524
2525 /* thickness label */
2526 FirstArg(XtNlabel, "Thickness");
2527 NextArg(XtNborderWidth, 0);
2528 NextArg(XtNfromVert, below);
2529 NextArg(XtNhorizDistance, 4);
2530 beside = XtCreateManagedWidget("thickness_label", labelWidgetClass,
2531 lineform, Args, ArgCount);
2532 /* thickness spinner */
2533 sprintf(indbuf,"%d",dimline_thick);
2534 beside = MakeIntSpinnerEntry(lineform, &line_thick_w, "line_thickness",
2535 below, beside, dimline_panel_preview, indbuf, 0, MAX_LINE_WIDTH, 1, 30);
2536
2537 below = beside;
2538
2539 /* Style label */
2540 FirstArg(XtNlabel, "Style ");
2541 NextArg(XtNborderWidth, 0);
2542 NextArg(XtNfromVert, below);
2543 NextArg(XtNvertDistance, 4);
2544 NextArg(XtNhorizDistance, 4);
2545 beside = XtCreateManagedWidget("style_label", labelWidgetClass,
2546 lineform, Args, ArgCount);
2547
2548 FirstArg(XtNfromVert, below);
2549 NextArg(XtNfromHoriz, beside);
2550 NextArg(XtNbitmap, linestyle_pixmaps[dimline_style]);
2551 dimline_style_panel = XtCreateManagedWidget("dimline_style", menuButtonWidgetClass,
2552 lineform, Args, ArgCount);
2553 below = dimline_style_panel;
2554 make_pulldown_menu_images(linestyle_choices, NUM_LINESTYLE_TYPES,
2555 linestyle_pixmaps, NULL, dimline_style_panel, dimline_style_select);
2556
2557 (void) color_selection_panel("Color ","line_color", "Line color", lineform, below, beside,
2558 &line_color_button, &line_color_panel, dimline_color,
2559 line_color_select);
2560
2561 /*************************/
2562 /* now form for Box info */
2563 /*************************/
2564
2565 FirstArg(XtNborderWidth, 1);
2566 NextArg(XtNfromVert, lineform);
2567 NextArg(XtNvertDistance, 4);
2568 NextArg(XtNtop, XtChainTop);
2569 NextArg(XtNbottom, XtChainTop);
2570 NextArg(XtNleft, XtChainLeft);
2571 NextArg(XtNright, XtChainLeft);
2572 boxform = XtCreateManagedWidget("boxform", formWidgetClass, form, Args, ArgCount);
2573
2574 /* "Box" label */
2575 FirstArg(XtNlabel, "Box");
2576 below = XtCreateManagedWidget("box_label", labelWidgetClass,
2577 boxform, Args, ArgCount);
2578
2579 /* Thickness label */
2580 FirstArg(XtNlabel, "Thickness");
2581 NextArg(XtNborderWidth, 0);
2582 NextArg(XtNfromVert, below);
2583 NextArg(XtNhorizDistance, 4);
2584 beside = XtCreateManagedWidget("box_thickness_label", labelWidgetClass,
2585 boxform, Args, ArgCount);
2586 /* thickness spinner */
2587 sprintf(indbuf,"%d",dimline_boxthick);
2588 beside = MakeIntSpinnerEntry(boxform, &box_thick_w, "box_line_thickness",
2589 below, beside, dimline_panel_preview, indbuf, 0, MAX_LINE_WIDTH, 1, 30);
2590
2591 below = beside;
2592
2593 (void) color_selection_panel("Color ","box_color", "Box color", boxform, below, beside,
2594 &box_color_button, &box_color_panel, dimline_boxcolor,
2595 box_color_select);
2596
2597 /********************************/
2598 /* now frame for Arrowhead info */
2599 /********************************/
2600
2601 FirstArg(XtNborderWidth, 1);
2602 NextArg(XtNfromVert, exampline);
2603 NextArg(XtNvertDistance, 4);
2604 NextArg(XtNfromHoriz, lineform);
2605 NextArg(XtNhorizDistance, 4);
2606 NextArg(XtNtop, XtChainTop);
2607 NextArg(XtNbottom, XtChainTop);
2608 NextArg(XtNleft, XtChainLeft);
2609 NextArg(XtNright, XtChainLeft);
2610 arrowform = XtCreateManagedWidget("arrowform", formWidgetClass, form, Args, ArgCount);
2611
2612 /* "Arrows" label */
2613 FirstArg(XtNlabel, "Arrows");
2614 below = XtCreateManagedWidget("arrow_label", labelWidgetClass,
2615 arrowform, Args, ArgCount);
2616
2617 /* Types label */
2618 FirstArg(XtNlabel, "Types");
2619 NextArg(XtNborderWidth, 0);
2620 NextArg(XtNfromVert, below);
2621 NextArg(XtNhorizDistance, 4);
2622 beside = XtCreateManagedWidget("types_arrow_label", labelWidgetClass,
2623 arrowform, Args, ArgCount);
2624
2625 /* Left arrow menu button */
2626 FirstArg(XtNfromVert, below);
2627 NextArg(XtNfromHoriz, beside);
2628 NextArg(XtNlabel, "");
2629 NextArg(XtNinternalWidth, 0);
2630 NextArg(XtNinternalHeight, 0);
2631 NextArg(XtNbitmap, arrow_pixmaps[dimline_leftarrow+1]);
2632 left_arrow_type_panel = XtCreateManagedWidget("Arrowtype",
2633 menuButtonWidgetClass,
2634 arrowform, Args, ArgCount);
2635 beside = left_arrow_type_panel;
2636
2637 /* make pulldown menu with arrow type images */
2638
2639 make_pulldown_menu_images(dim_arrowtype_choices,
2640 NUM_DIM_ARROWTYPE_CHOICES, arrow_pixmaps, NULL,
2641 left_arrow_type_panel, left_arrow_type_select);
2642
2643 /* Right arrow menu button */
2644 FirstArg(XtNfromVert, below);
2645 NextArg(XtNfromHoriz, beside);
2646 NextArg(XtNlabel, "");
2647 NextArg(XtNinternalWidth, 0);
2648 NextArg(XtNinternalHeight, 0);
2649 NextArg(XtNbitmap, arrow_pixmaps[dimline_rightarrow+1]);
2650 right_arrow_type_panel = XtCreateManagedWidget("Arrowtype",
2651 menuButtonWidgetClass,
2652 arrowform, Args, ArgCount);
2653 below = right_arrow_type_panel;
2654
2655 /* make pulldown menu with arrow type images */
2656 make_pulldown_menu_images(dim_arrowtype_choices,
2657 NUM_DIM_ARROWTYPE_CHOICES, arrow_pixmaps, NULL,
2658 right_arrow_type_panel, right_arrow_type_select);
2659
2660 /* Length label */
2661 FirstArg(XtNlabel, "Length");
2662 NextArg(XtNborderWidth, 0);
2663 NextArg(XtNfromVert, below);
2664 NextArg(XtNvertDistance, 6);
2665 NextArg(XtNhorizDistance, 4);
2666 beside = XtCreateManagedWidget("arrow_length_label", labelWidgetClass,
2667 arrowform, Args, ArgCount);
2668 /* length spinner */
2669 sprintf(indbuf,"%.1f",dimline_arrowlength);
2670 beside = MakeFloatSpinnerEntry(arrowform, &arrow_length_w, "arrow_length",
2671 below, beside, dimline_panel_preview, indbuf, 0.1, 200.0, 1.0, 50);
2672
2673 below = beside;
2674
2675 /* Width label */
2676 FirstArg(XtNlabel, "Width ");
2677 NextArg(XtNborderWidth, 0);
2678 NextArg(XtNfromVert, below);
2679 NextArg(XtNhorizDistance, 4);
2680 beside = XtCreateManagedWidget("arrow_width_label", labelWidgetClass,
2681 arrowform, Args, ArgCount);
2682 /* width spinner */
2683 sprintf(indbuf,"%.1f",dimline_arrowwidth);
2684 beside = MakeFloatSpinnerEntry(arrowform, &arrow_width_w, "arrow_width",
2685 below, beside, dimline_panel_preview, indbuf, 0.1, 200.0, 1.0, 50);
2686
2687 /****************************/
2688 /* now frame for Ticks info */
2689 /****************************/
2690
2691 FirstArg(XtNborderWidth, 1);
2692 NextArg(XtNfromVert, lineform);
2693 NextArg(XtNvertDistance, 4);
2694 NextArg(XtNfromHoriz, boxform);
2695 NextArg(XtNhorizDistance, 4);
2696 NextArg(XtNtop, XtChainTop);
2697 NextArg(XtNbottom, XtChainTop);
2698 NextArg(XtNleft, XtChainLeft);
2699 NextArg(XtNright, XtChainLeft);
2700 tickform = XtCreateManagedWidget("tickform", formWidgetClass, form, Args, ArgCount);
2701
2702 /* "Ticks" label */
2703 FirstArg(XtNlabel, "Ticks");
2704 below = XtCreateManagedWidget("ticks_label", labelWidgetClass,
2705 tickform, Args, ArgCount);
2706
2707 /* "Ticks" checkbutton */
2708 below = CreateCheckbutton("Show ticks", "ticks", tickform, below, (Widget) NULL,
2709 MANAGE, LARGE_CHK, &dimline_ticks,
2710 dimline_panel_preview, (Widget *) NULL);
2711
2712 /* Tick Thickness label */
2713 FirstArg(XtNlabel, "Thickness");
2714 NextArg(XtNborderWidth, 0);
2715 NextArg(XtNfromVert, below);
2716 NextArg(XtNhorizDistance, 4);
2717 beside = XtCreateManagedWidget("tick_thickness_label", labelWidgetClass,
2718 tickform, Args, ArgCount);
2719 /* thickness spinner */
2720 sprintf(indbuf,"%d",dimline_tickthick);
2721 (void) MakeIntSpinnerEntry(tickform, &tick_thick_w, "tick_line_thickness",
2722 below, beside, dimline_panel_preview, indbuf, 0, MAX_LINE_WIDTH, 1, 28);
2723
2724 /***************************/
2725 /* now frame for Text info */
2726 /***************************/
2727
2728 FirstArg(XtNborderWidth, 1);
2729 NextArg(XtNfromVert, boxform);
2730 NextArg(XtNvertDistance, 4);
2731 NextArg(XtNtop, XtChainTop);
2732 NextArg(XtNbottom, XtChainTop);
2733 NextArg(XtNleft, XtChainLeft);
2734 NextArg(XtNright, XtChainLeft);
2735 textform = XtCreateManagedWidget("textform", formWidgetClass, form, Args, ArgCount);
2736
2737 /* "Text" label */
2738 FirstArg(XtNlabel, "Text");
2739 below = XtCreateManagedWidget("text_label", labelWidgetClass,
2740 textform, Args, ArgCount);
2741
2742 /* Font label */
2743 FirstArg(XtNlabel, "Font ");
2744 NextArg(XtNborderWidth, 0);
2745 NextArg(XtNfromVert, below);
2746 NextArg(XtNhorizDistance, 4);
2747 beside = XtCreateManagedWidget("font_label", labelWidgetClass,
2748 textform, Args, ArgCount);
2749 /* make the popup font menu */
2750 FirstArg(XtNfromVert, below);
2751 NextArg(XtNvertDistance, 2);
2752 NextArg(XtNfromHoriz, beside);
2753 NextArg(XtNwidth, MAX_FONTIMAGE_WIDTH);
2754 NextArg(XtNinternalWidth, 2);
2755 NextArg(XtNbitmap, dimline_psflag?
2756 psfont_menu_bitmaps[dimline_font + 1] :
2757 latexfont_menu_bitmaps[dimline_font]);
2758 font_button = XtCreateManagedWidget("font", commandWidgetClass, textform, Args, ArgCount);
2759 XtAddCallback(font_button, XtNcallback, dimline_font_popup, (XtPointer) NULL);
2760
2761 below = font_button;
2762
2763 /* Size label */
2764 FirstArg(XtNlabel, "Size ");
2765 NextArg(XtNborderWidth, 0);
2766 NextArg(XtNfromVert, below);
2767 NextArg(XtNvertDistance, 4);
2768 NextArg(XtNhorizDistance, 4);
2769 beside = XtCreateManagedWidget("font_size_label", labelWidgetClass,
2770 textform, Args, ArgCount);
2771 /* size spinner */
2772 sprintf(indbuf,"%d",dimline_fontsize);
2773 beside = MakeIntSpinnerEntry(textform, &font_size_w, "font_size",
2774 below, beside, dimline_panel_preview, indbuf,
2775 MIN_FONT_SIZE, MAX_FONT_SIZE, 1, 30);
2776
2777 below = beside;
2778
2779 below = color_selection_panel("Color","text_color", "Text color", textform, below, beside,
2780 &text_color_button, &text_color_panel, dimline_textcolor,
2781 text_color_select);
2782
2783 /* String label */
2784 FirstArg(XtNlabel, "String");
2785 NextArg(XtNborderWidth, 0);
2786 NextArg(XtNfromVert, below);
2787 NextArg(XtNvertDistance, 6);
2788 NextArg(XtNhorizDistance, 4);
2789 below = XtCreateManagedWidget("string_label", labelWidgetClass,
2790 textform, Args, ArgCount);
2791
2792 /* make a borderless form so that we may shift the checkboxes a little */
2793 FirstArg(XtNborderWidth, 0);
2794 NextArg(XtNfromVert, below);
2795 NextArg(XtNvertDistance, 2);
2796 NextArg(XtNhorizDistance, 6);
2797 NextArg(XtNtop, XtChainTop);
2798 NextArg(XtNbottom, XtChainTop);
2799 NextArg(XtNleft, XtChainLeft);
2800 NextArg(XtNright, XtChainLeft);
2801 stringform = XtCreateManagedWidget("stringform", formWidgetClass, textform, Args, ArgCount);
2802
2803 /* Actual dimension text checkbutton */
2804 below = CreateCheckbutton("Actual dimension shown ", "actual_chk", stringform,
2805 (Widget) NULL, (Widget) NULL, MANAGE, LARGE_CHK, &dimline_actual,
2806 (XtCallbackProc) set_actual_text, &actual_chk);
2807
2808 /* Decimal places label */
2809 FirstArg(XtNlabel, "Decimal places");
2810 NextArg(XtNborderWidth, 0);
2811 NextArg(XtNfromVert, below);
2812 NextArg(XtNhorizDistance, 26);
2813 beside = XtCreateManagedWidget("precision_label", labelWidgetClass,
2814 stringform, Args, ArgCount);
2815 /* number of decimal places spinner */
2816 sprintf(indbuf,"%d",dimline_prec);
2817 below = MakeIntSpinnerEntry(stringform, &dimline_precw, "precision",
2818 below, beside, dimline_panel_preview, indbuf,
2819 0, 10, 1, 30);
2820
2821 /* Fixed text checkbutton */
2822 below = CreateCheckbutton("User defined text (not actual length)", "fixed_chk", stringform,
2823 below, (Widget) NULL, MANAGE, LARGE_CHK, &dimline_fixed,
2824 (XtCallbackProc) set_fixed_text, &fixed_chk);
2825
2826 /* make the checkbox NOT checked sensitive and vice versa */
2827 XtSetSensitive(actual_chk, dimline_fixed);
2828 XtSetSensitive(fixed_chk, !dimline_fixed);
2829
2830 /***************************************/
2831 /* finally, the Set and Cancel buttons */
2832 /***************************************/
2833
2834 FirstArg(XtNlabel, "Cancel");
2835 NextArg(XtNfromVert, textform);
2836 NextArg(XtNborderWidth, INTERNAL_BW);
2837 NextArg(XtNtop, XtChainTop);
2838 NextArg(XtNbottom, XtChainTop);
2839 NextArg(XtNleft, XtChainLeft);
2840 NextArg(XtNright, XtChainLeft);
2841 cancel = XtCreateManagedWidget("cancel", commandWidgetClass,
2842 form, Args, ArgCount);
2843 XtAddEventHandler(cancel, ButtonReleaseMask, False,
2844 (XtEventHandler) choice_panel_dismiss, (XtPointer) NULL);
2845
2846 FirstArg(XtNlabel, " Ok ");
2847 NextArg(XtNfromVert, textform);
2848 NextArg(XtNfromHoriz, cancel);
2849 NextArg(XtNhorizDistance, 10);
2850 NextArg(XtNborderWidth, INTERNAL_BW);
2851 NextArg(XtNtop, XtChainTop);
2852 NextArg(XtNbottom, XtChainTop);
2853 NextArg(XtNleft, XtChainLeft);
2854 NextArg(XtNright, XtChainLeft);
2855 set = XtCreateManagedWidget("ok", commandWidgetClass,
2856 form, Args, ArgCount);
2857 XtAddEventHandler(set, ButtonReleaseMask, False,
2858 (XtEventHandler) dimline_panel_ok, (XtPointer) NULL);
2859
2860 XtOverrideTranslations(choice_popup,
2861 XtParseTranslationTable(dimline_translations));
2862 if (!actions_added) {
2863 XtAppAddActions(tool_app, dimline_actions, XtNumber(dimline_actions));
2864 actions_added = True;
2865 }
2866
2867 if (appres.DEBUG)
2868 XtPopup(choice_popup, XtGrabNone); /* makes debugging easier */
2869 else
2870 XtPopup(choice_popup, XtGrabExclusive);
2871 /* if the file message window is up add it to the grab */
2872 file_msg_add_grab();
2873 (void) XSetWMProtocols(tool_d, XtWindow(choice_popup), &wm_delete_window, 1);
2874 /* insure that the most recent colormap is installed */
2875 set_cmap(XtWindow(choice_popup));
2876
2877 XtInstallAccelerators(form, cancel);
2878 }
2879
2880 static void
line_color_select(Widget w,XtPointer client_data,XtPointer call_data)2881 line_color_select(Widget w, XtPointer client_data, XtPointer call_data)
2882 {
2883 ptr_int new_color = {client_data};
2884
2885 dimline_color = (Color) new_color.val;
2886 color_select(line_color_button, dimline_color);
2887 if (line_color_panel) {
2888 XtPopdown(line_color_panel);
2889 dimline_panel_preview(NULL,NULL,NULL);
2890 }
2891 }
2892
2893 static void
box_color_select(Widget w,XtPointer client_data,XtPointer call_data)2894 box_color_select(Widget w, XtPointer client_data, XtPointer call_data)
2895 {
2896 ptr_int new_color = {client_data};
2897
2898 dimline_boxcolor = (Color) new_color.val;
2899 color_select(box_color_button, dimline_boxcolor);
2900 if (box_color_panel) {
2901 XtPopdown(box_color_panel);
2902 dimline_panel_preview(NULL,NULL,NULL);
2903 }
2904 }
2905
2906 static void
text_color_select(Widget w,XtPointer client_data,XtPointer call_data)2907 text_color_select(Widget w, XtPointer client_data, XtPointer call_data)
2908 {
2909 ptr_int new_color = {client_data};
2910
2911 dimline_textcolor = (Color) new_color.val;
2912 color_select(text_color_button, dimline_textcolor);
2913 if (text_color_panel) {
2914 XtPopdown(text_color_panel);
2915 dimline_panel_preview(NULL,NULL,NULL);
2916 }
2917 }
2918
2919 static void
set_fixed_text(Widget w,XtPointer fixed,XtPointer dum)2920 set_fixed_text(Widget w, XtPointer fixed, XtPointer dum)
2921 {
2922 Boolean *fixed_text = (Boolean *) fixed;
2923
2924 dimline_fixed = *fixed_text;
2925 /* make this checkbox insensitive so the user will have to check the other one */
2926 XtSetSensitive(w, False);
2927 /* and make the other sensitive */
2928 XtSetSensitive(actual_chk, True);
2929 /* toggle other checkbox now */
2930 toggle_checkbutton(actual_chk, (XtPointer) &dimline_actual, (XtPointer) 0);
2931 dimline_panel_preview(NULL,NULL,NULL);
2932 }
2933
2934 static void
set_actual_text(Widget w,XtPointer actual,XtPointer dum)2935 set_actual_text(Widget w, XtPointer actual, XtPointer dum)
2936 {
2937 Boolean *actual_text = (Boolean *) actual;
2938
2939 dimline_actual = *actual_text;
2940 /* make this checkbox insensitive so the user will have to check the other one */
2941 XtSetSensitive(w, False);
2942 /* and make the other sensitive */
2943 XtSetSensitive(fixed_chk, True);
2944 /* toggle other checkbox now */
2945 toggle_checkbutton(fixed_chk, (XtPointer) &dimline_fixed, (XtPointer) 0);
2946 dimline_panel_preview(NULL,NULL,NULL);
2947 }
2948
draw_cur_dimline(void)2949 void draw_cur_dimline(void)
2950 {
2951 F_line *line, *tick1, *tick2, *poly;
2952 F_compound *dimline_example;
2953 F_point *point;
2954 Boolean save_showlen, save_shownums;
2955
2956 /* make the a dimension line */
2957 line = create_line();
2958 /* we'll fill in some parms - create_dimension_line() will do the rest */
2959 line->type = T_POLYLINE;
2960 line->fill_color = DEFAULT;
2961 line->cap_style = CAP_BUTT;
2962 line->join_style = JOIN_MITER;
2963 line->pen_style = DEFAULT;
2964 point = create_point();
2965 point->x = 75;
2966 point->y = 275;
2967 line->points = point;
2968 /* make it 3-3/4 inches long */
2969 append_point((int)((appres.INCHES? DIMLINE_IP_LENGTH*PIX_PER_INCH:
2970 DIMLINE_SI_LENGTH*PIX_PER_CM)+75), 275, &point);
2971 /* make a dimension line from that line */
2972 dimline_example = create_dimension_line(line, False);
2973
2974 /* clear it */
2975 XFillRectangle(tool_d, dimline_examp_pixmap, ind_blank_gc, 0, 0,
2976 DIMLINE_PIXMAP_WIDTH, DIMLINE_PIXMAP_HEIGHT);
2977
2978 /* temporarily turn off any "show line lengths" or "show vertex numbers" */
2979 save_showlen = appres.showlengths;
2980 save_shownums = appres.shownums;
2981 appres.showlengths = appres.shownums = False;
2982
2983 /* now draw it into our pixmap */
2984 canvas_win = (Window) dimline_examp_pixmap;
2985 preview_in_progress = True;
2986 /* locate the line components of the dimension line */
2987 dimline_components(dimline_example, &line, &tick1, &tick2, &poly);
2988 draw_line(line,PAINT);
2989 if (tick1)
2990 draw_line(tick1,PAINT);
2991 if (tick2)
2992 draw_line(tick2,PAINT);
2993 draw_line(poly,PAINT);
2994 draw_text(dimline_example->texts,PAINT);
2995
2996 /* restore the canvas */
2997 canvas_win = main_canvas;
2998 /* and the showlengths and shownums settings */
2999 appres.showlengths = save_showlen;
3000 appres.shownums = save_shownums;
3001 preview_in_progress = False;
3002
3003 /* fool the toolkit... you know the drill by now */
3004 XtUnmanageChild(exampline);
3005 FirstArg(XtNbitmap, (Pixmap) 0);
3006 SetValues(exampline);
3007 FirstArg(XtNbitmap, dimline_examp_pixmap);
3008 SetValues(exampline);
3009 XtManageChild(exampline);
3010 /* finally, free the dimline */
3011 free_compound(&dimline_example);
3012 }
3013
3014 static void
dimline_style_select(Widget w,XtPointer new_style,XtPointer call_data)3015 dimline_style_select(Widget w, XtPointer new_style, XtPointer call_data)
3016 {
3017 choice_info *choice;
3018
3019 choice = (choice_info *) new_style;
3020 FirstArg(XtNbitmap, choice->pixmap);
3021 SetValues(dimline_style_panel);
3022
3023 dimline_style = choice->value;
3024 dimline_panel_preview(NULL,NULL,NULL);
3025 }
3026
3027 static void
left_arrow_type_select(Widget w,XtPointer new_type,XtPointer call_data)3028 left_arrow_type_select(Widget w, XtPointer new_type, XtPointer call_data)
3029 {
3030 choice_info *choice = (choice_info*) new_type;
3031
3032 FirstArg(XtNbitmap, arrow_pixmaps[choice->value+1]);
3033 SetValues(left_arrow_type_panel);
3034
3035 dimline_leftarrow = choice->value;
3036 dimline_panel_preview(NULL,NULL,NULL);
3037 }
3038
3039 static void
right_arrow_type_select(Widget w,XtPointer new_type,XtPointer call_data)3040 right_arrow_type_select(Widget w, XtPointer new_type, XtPointer call_data)
3041 {
3042 choice_info *choice = (choice_info*) new_type;
3043
3044 FirstArg(XtNbitmap, arrow_pixmaps[choice->value+1]);
3045 SetValues(right_arrow_type_panel);
3046
3047 dimline_rightarrow = choice->value;
3048 dimline_panel_preview(NULL,NULL,NULL);
3049 }
3050
3051 /* come here when user presses font menu button */
3052
3053 static void
dimline_font_popup(Widget w,XtPointer user_data,XtPointer call_data)3054 dimline_font_popup(Widget w, XtPointer user_data, XtPointer call_data)
3055 {
3056 fontpane_popup(&dim_ps_font, &dim_latex_font, &dimline_psflag,
3057 dimline_set_font_image, font_button);
3058 }
3059
3060 static void
dimline_set_font_image(Widget widget)3061 dimline_set_font_image(Widget widget)
3062 {
3063 dimline_font = dimline_psflag? dim_ps_font: dim_latex_font;
3064 FirstArg(XtNbitmap, dimline_psflag ?
3065 psfont_menu_bitmaps[dimline_font + 1] :
3066 latexfont_menu_bitmaps[dimline_font]);
3067 SetValues(widget);
3068 dimline_panel_preview(NULL,NULL,NULL);
3069 }
3070
3071 /* Dimension line preview */
3072
3073 static void
dimline_panel_preview(Widget w,XtPointer new_type,XtPointer call_data)3074 dimline_panel_preview(Widget w, XtPointer new_type, XtPointer call_data)
3075 {
3076 /* save current global settings */
3077 savecur_dimline_thick = cur_dimline_thick;
3078 savecur_dimline_style = cur_dimline_style;
3079 savecur_dimline_color = cur_dimline_color;
3080 savecur_dimline_leftarrow = cur_dimline_leftarrow;
3081 savecur_dimline_rightarrow = cur_dimline_rightarrow;
3082 savecur_dimline_arrowlength = cur_dimline_arrowlength;
3083 savecur_dimline_arrowwidth = cur_dimline_arrowwidth;
3084 savecur_dimline_ticks = cur_dimline_ticks;
3085 savecur_dimline_tickthick = cur_dimline_tickthick;
3086 savecur_dimline_boxthick = cur_dimline_boxthick;
3087 savecur_dimline_boxcolor = cur_dimline_boxcolor;
3088 savecur_dimline_textcolor = cur_dimline_textcolor;
3089 savecur_dimline_font = cur_dimline_font;
3090 savecur_dimline_fontsize = cur_dimline_fontsize;
3091 savecur_dimline_psflag = cur_dimline_psflag;
3092 savecur_dimline_fixed = cur_dimline_fixed;
3093 savecur_dimline_prec = cur_dimline_prec;
3094
3095 /* get current values from spinners */
3096 get_dimline_values();
3097
3098 /* just update the example dimension line pixmap */
3099 draw_cur_dimline();
3100
3101 /* restore current global settings */
3102 cur_dimline_thick = savecur_dimline_thick;
3103 cur_dimline_style = savecur_dimline_style;
3104 cur_dimline_color = savecur_dimline_color;
3105 cur_dimline_leftarrow = savecur_dimline_leftarrow;
3106 cur_dimline_rightarrow = savecur_dimline_rightarrow;
3107 cur_dimline_arrowlength = savecur_dimline_arrowlength;
3108 cur_dimline_arrowwidth = savecur_dimline_arrowwidth;
3109 cur_dimline_ticks = savecur_dimline_ticks;
3110 cur_dimline_tickthick = savecur_dimline_tickthick;
3111 cur_dimline_boxthick = savecur_dimline_boxthick;
3112 cur_dimline_boxcolor = savecur_dimline_boxcolor;
3113 cur_dimline_textcolor = savecur_dimline_textcolor;
3114 cur_dimline_font = savecur_dimline_font;
3115 cur_dimline_fontsize = savecur_dimline_fontsize;
3116 cur_dimline_psflag = savecur_dimline_psflag;
3117 cur_dimline_fixed = savecur_dimline_fixed;
3118 cur_dimline_prec = savecur_dimline_prec;
3119 }
3120
3121 /* Dimension line "Ok" button callback */
3122
3123 static void
dimline_panel_ok(Widget w,XButtonEvent * ev)3124 dimline_panel_ok(Widget w, XButtonEvent *ev)
3125 {
3126 get_dimline_values();
3127 show_dimline(choice_i);
3128 dimline_panel_cancel(w, ev);
3129 }
3130
3131 /* Dimension line "Cancel" button callback */
3132
3133 static void
dimline_panel_cancel(Widget w,XButtonEvent * ev)3134 dimline_panel_cancel(Widget w, XButtonEvent *ev)
3135 {
3136 XtDestroyWidget(choice_popup);
3137 line_color_panel = (Widget) 0;
3138 box_color_panel = (Widget) 0;
3139 text_color_panel = (Widget) 0;
3140 XtSetSensitive(choice_i->button, True);
3141 }
3142
3143 /* copy new settings for dimension lines to global */
3144
get_dimline_values(void)3145 void get_dimline_values(void)
3146 {
3147 cur_dimline_thick = atoi(panel_get_value(line_thick_w));
3148 cur_dimline_style = dimline_style;
3149 cur_dimline_color = dimline_color;
3150 cur_dimline_leftarrow = dimline_leftarrow;
3151 cur_dimline_rightarrow = dimline_rightarrow;
3152 cur_dimline_arrowlength = atof(panel_get_value(arrow_length_w));
3153 cur_dimline_arrowwidth = atof(panel_get_value(arrow_width_w));
3154 cur_dimline_ticks = dimline_ticks;
3155 cur_dimline_tickthick = atoi(panel_get_value(tick_thick_w));
3156 cur_dimline_boxthick = atoi(panel_get_value(box_thick_w));
3157 cur_dimline_boxcolor = dimline_boxcolor;
3158 cur_dimline_textcolor = dimline_textcolor;
3159 cur_dimline_font = dimline_font;
3160 cur_dimline_fontsize = atoi(panel_get_value(font_size_w));
3161 cur_dimline_psflag = dimline_psflag;
3162 cur_dimline_fixed = dimline_fixed;
3163 cur_dimline_prec = atoi(panel_get_value(dimline_precw));
3164 }
3165
3166 /********************************************************
3167
3168 commands to change indicator settings
3169
3170 ********************************************************/
3171
update_current_settings(void)3172 void update_current_settings(void)
3173 {
3174 int i;
3175 ind_sw_info *isw;
3176
3177 for (i = 0; i < NUM_IND_SW; ++i) {
3178 isw = &ind_switches[i];
3179 show_action(isw);
3180 }
3181 }
3182
3183 static void
dec_choice(ind_sw_info * sw)3184 dec_choice(ind_sw_info *sw)
3185 {
3186 if (--(*sw->i_varadr) < 0)
3187 (*sw->i_varadr) = sw->numchoices - 1;
3188 show_action(sw);
3189 }
3190
3191 static void
inc_choice(ind_sw_info * sw)3192 inc_choice(ind_sw_info *sw)
3193 {
3194 if (++(*sw->i_varadr) > sw->numchoices - 1)
3195 (*sw->i_varadr) = 0;
3196 show_action(sw);
3197 }
3198
3199 /* ARROW MODE */
3200
3201 static void
show_arrowmode(ind_sw_info * sw)3202 show_arrowmode(ind_sw_info *sw)
3203 {
3204 update_choice_pixmap(sw, cur_arrowmode);
3205 switch (cur_arrowmode) {
3206 case L_NOARROWS:
3207 autobackwardarrow_mode = 0;
3208 autoforwardarrow_mode = 0;
3209 put_msg("NO ARROWS");
3210 break;
3211 case L_FARROWS:
3212 autobackwardarrow_mode = 0;
3213 autoforwardarrow_mode = 1;
3214 put_msg("Auto FORWARD ARROWS");
3215 break;
3216 case L_FBARROWS:
3217 autobackwardarrow_mode = 1;
3218 autoforwardarrow_mode = 1;
3219 put_msg("Auto FORWARD and BACKWARD ARROWS");
3220 break;
3221 case L_BARROWS:
3222 autobackwardarrow_mode = 1;
3223 autoforwardarrow_mode = 0;
3224 put_msg("Auto BACKWARD ARROWS");
3225 break;
3226 }
3227 }
3228 /* ARROW TYPE */
3229
3230 static void
show_arrowtype(ind_sw_info * sw)3231 show_arrowtype(ind_sw_info *sw)
3232 {
3233 update_choice_pixmap(sw, cur_arrowtype);
3234 if (cur_arrowtype == -1)
3235 cur_arrowtype = 0;
3236 if (cur_arrowtype == 0)
3237 put_msg("Arrow type 0");
3238 else if (cur_arrowtype % 2)
3239 put_msg("Hollow arrow type %d",cur_arrowtype/2);
3240 else
3241 put_msg("Solid arrow type %d",cur_arrowtype/2);
3242 }
3243
3244 /* ARROW SIZES */
3245
3246 static void
inc_arrowsize(ind_sw_info * sw)3247 inc_arrowsize(ind_sw_info *sw)
3248 {
3249 if (++cur_arrowsizeshown >= MAX_ARROWPARMS)
3250 cur_arrowsizeshown = 0;
3251 show_arrowsize(sw);
3252 }
3253
3254 static void
dec_arrowsize(ind_sw_info * sw)3255 dec_arrowsize(ind_sw_info *sw)
3256 {
3257 if (--cur_arrowsizeshown < 0)
3258 cur_arrowsizeshown = MAX_ARROWPARMS-1;
3259 show_arrowsize(sw);
3260 }
3261
3262 static void
show_arrowsize(ind_sw_info * sw)3263 show_arrowsize(ind_sw_info *sw)
3264 {
3265 char c;
3266 float thick, width, height;
3267 if (use_abs_arrowvals) {
3268 c = ' ';
3269 thick = cur_arrowthick;
3270 width = cur_arrowwidth;
3271 height = cur_arrowheight;
3272 } else {
3273 thick = cur_arrow_multthick;
3274 width = cur_arrow_multwidth;
3275 height = cur_arrow_multheight;
3276 c = 'x';
3277 }
3278
3279 put_msg("Arrows: Thickness=%.1f, Width=%.1f, Length=%.1f (Button 1 to change)",
3280 thick, width, height);
3281
3282 /* write the current setting in the background pixmap */
3283 switch(cur_arrowsizeshown) {
3284 case 0:
3285 sprintf(indbuf, "Thk=%.1f %c ",thick,c);
3286 break;
3287 case 1:
3288 sprintf(indbuf, "Wid=%.1f %c ",width,c);
3289 break;
3290 default:
3291 sprintf(indbuf, "Len=%.1f %c ",height,c);
3292 }
3293 update_string_pixmap(sw, indbuf, 6, 26);
3294 }
3295
3296 /* DIMENSION LINE SETTINGS */
3297
3298 static void
inc_dimline(ind_sw_info * sw)3299 inc_dimline(ind_sw_info *sw)
3300 {
3301 if (++cur_dimlineshown >= MAX_DIMLINEPARMS)
3302 cur_dimlineshown = 0;
3303 show_dimline(sw);
3304 }
3305
3306 static void
dec_dimline(ind_sw_info * sw)3307 dec_dimline(ind_sw_info *sw)
3308 {
3309 if (--cur_dimlineshown < 0)
3310 cur_dimlineshown = MAX_DIMLINEPARMS-1;
3311 show_dimline(sw);
3312 }
3313
3314 static void
show_dimline(ind_sw_info * sw)3315 show_dimline(ind_sw_info *sw)
3316 {
3317
3318 /* first check if the user's font number is consistent with the using_ps flag */
3319 if (!using_ps && (cur_dimline_font >= NUM_LATEX_FONTS))
3320 cur_dimline_font = DEF_LATEX_FONT;
3321
3322 put_msg("Dimension lines: Thick=%d, Ticks=%s, Font=%s, Size=%d (Button 1 to change)",
3323 cur_dimline_thick, cur_dimline_ticks? "yes": "no",
3324 using_ps? ps_fontinfo[cur_dimline_font].name: latex_fontinfo[cur_dimline_font].name,
3325 cur_dimline_fontsize);
3326 switch(cur_dimlineshown) {
3327 case 0:
3328 sprintf(indbuf, "Line thick=%d", cur_dimline_thick);
3329 break;
3330 case 1:
3331 if (cur_dimline_color < NUM_STD_COLS)
3332 sprintf(indbuf, "Line col=%s", short_clrNames[cur_dimline_color+1]);
3333 else
3334 sprintf(indbuf, "Line col=%d", cur_dimline_color);
3335 break;
3336 case 2:
3337 sprintf(indbuf, "L arrow typ=%d", cur_dimline_leftarrow);
3338 break;
3339 case 3:
3340 sprintf(indbuf, "R arrow typ=%d", cur_dimline_rightarrow);
3341 break;
3342 case 4:
3343 sprintf(indbuf, "Arrow len=%.2f", cur_dimline_arrowlength);
3344 break;
3345 case 5:
3346 sprintf(indbuf, "Arrow wid=%.2f", cur_dimline_arrowwidth);
3347 break;
3348 case 6:
3349 sprintf(indbuf, "Ticks: %s", cur_dimline_ticks? "yes": "no");
3350 break;
3351 case 7:
3352 sprintf(indbuf, "Tick thk=%d", cur_dimline_tickthick);
3353 break;
3354 case 8:
3355 sprintf(indbuf, "Box thk=%d", cur_dimline_boxthick);
3356 break;
3357 case 9:
3358 if (cur_dimline_boxcolor < NUM_STD_COLS)
3359 sprintf(indbuf, "Box col=%s", short_clrNames[cur_dimline_boxcolor+1]);
3360 else
3361 sprintf(indbuf, "Box col=%d", cur_dimline_boxcolor);
3362 break;
3363 case 10:
3364 if (cur_dimline_textcolor < NUM_STD_COLS)
3365 sprintf(indbuf, "Text col=%s", short_clrNames[cur_dimline_textcolor+1]);
3366 else
3367 sprintf(indbuf, "Text col=%d", cur_dimline_textcolor);
3368 break;
3369 case 11:
3370 sprintf(indbuf, "Text font=%d", cur_dimline_font);
3371 break;
3372 case 12:
3373 sprintf(indbuf, "Text size=%d", cur_dimline_fontsize);
3374 break;
3375 case 13:
3376 sprintf(indbuf, "Text fixed: %s", cur_dimline_fixed? "yes": "no");
3377 break;
3378 case 14:
3379 sprintf(indbuf, "Dec. place: %d", cur_dimline_prec);
3380 break;
3381 }
3382 /* pad out */
3383 strcat(indbuf," ");
3384
3385 update_string_pixmap(sw, indbuf, 3, 26);
3386 }
3387
3388 /* LINE WIDTH */
3389
3390 static void
dec_linewidth(ind_sw_info * sw)3391 dec_linewidth(ind_sw_info *sw)
3392 {
3393 --cur_linewidth;
3394 show_linewidth(sw);
3395 }
3396
3397 static void
inc_linewidth(ind_sw_info * sw)3398 inc_linewidth(ind_sw_info *sw)
3399 {
3400 ++cur_linewidth;
3401 show_linewidth(sw);
3402 }
3403
3404 static void
show_linewidth(ind_sw_info * sw)3405 show_linewidth(ind_sw_info *sw)
3406 {
3407 XGCValues gcv;
3408 XCharStruct size;
3409 int dum, height;
3410
3411 if (cur_linewidth > MAX_LINE_WIDTH)
3412 cur_linewidth = MAX_LINE_WIDTH;
3413 else if (cur_linewidth < 0)
3414 cur_linewidth = 0;
3415
3416 /* erase by drawing wide, inverted (white) line */
3417 pw_vector(sw->pixmap, DEF_IND_SW_WD / 2 + 2, DEF_IND_SW_HT / 2,
3418 sw->sw_width - 2, DEF_IND_SW_HT / 2, ERASE,
3419 DEF_IND_SW_HT, PANEL_LINE, 0.0, DEFAULT);
3420 /* draw current line thickness into pixmap */
3421 if (cur_linewidth > 0) /* don't draw line for zero-thickness */
3422 pw_vector(sw->pixmap, DEF_IND_SW_WD / 2 + 2, DEF_IND_SW_HT / 2,
3423 sw->sw_width - 2, DEF_IND_SW_HT / 2, PAINT,
3424 cur_linewidth, PANEL_LINE, 0.0, DEFAULT);
3425
3426 /* now write the width in the middle of the line */
3427 if (cur_linewidth < 10)
3428 sprintf(indbuf, " %0d", cur_linewidth);
3429 else
3430 sprintf(indbuf, "%0d", cur_linewidth);
3431 /* get size of string for positioning */
3432 XTextExtents(button_font, indbuf, strlen(indbuf), &dum, &dum, &dum, &size);
3433 height = size.ascent+size.descent;
3434 /* if the line width if small, draw black text with white background around it.
3435 Otherwise, draw it xor'ed on the thick line we just drew */
3436 if (cur_linewidth < 10) {
3437 gcv.foreground = x_color(BLACK);
3438 gcv.background = x_color(WHITE);
3439 XChangeGC(tool_d, ind_button_gc, GCForeground|GCBackground, &gcv);
3440 XDrawImageString(tool_d, sw->pixmap, ind_button_gc,
3441 DEF_IND_SW_WD-size.width-6, (DEF_IND_SW_HT+height)/2,
3442 indbuf, strlen(indbuf));
3443 } else {
3444 gcv.foreground = x_color(WHITE) ^ x_color(BLACK);
3445 gcv.background = x_color(WHITE);
3446 gcv.function = GXxor;
3447 XChangeGC(tool_d, ind_button_gc, GCForeground|GCBackground|GCFunction, &gcv);
3448 XDrawString(tool_d, sw->pixmap, ind_button_gc,
3449 DEF_IND_SW_WD-size.width-6, (DEF_IND_SW_HT+height)/2,
3450 indbuf, strlen(indbuf));
3451 }
3452 /*
3453 * Fool the toolkit by changing the background pixmap to 0 then giving it
3454 * the modified one again. Otherwise, it sees that the pixmap ID is not
3455 * changed and doesn't actually draw it into the widget window
3456 */
3457 if (sw->updbut && update_buts_managed)
3458 XtUnmanageChild(sw->updbut);
3459 FirstArg(XtNbackgroundPixmap, 0);
3460 SetValues(sw->button);
3461 /* put the pixmap in the widget background */
3462 FirstArg(XtNbackgroundPixmap, sw->pixmap);
3463 SetValues(sw->button);
3464 if (sw->updbut && update_buts_managed)
3465 XtManageChild(sw->updbut);
3466
3467 /* restore indicator button gc colors and function */
3468 gcv.foreground = ind_but_fg;
3469 gcv.background = ind_but_bg;
3470 gcv.function = GXcopy;
3471 XChangeGC(tool_d, ind_button_gc, GCForeground|GCBackground|GCFunction, &gcv);
3472
3473 put_msg("LINE Thickness = %d", cur_linewidth);
3474 }
3475
3476 /* TANGENT/NORMAL line length */
3477
3478 static void
inc_tangnormlen(ind_sw_info * sw)3479 inc_tangnormlen(ind_sw_info *sw)
3480 {
3481 cur_tangnormlen += 0.1;
3482 show_tangnormlen(sw);
3483 }
3484
3485 static void
dec_tangnormlen(ind_sw_info * sw)3486 dec_tangnormlen(ind_sw_info *sw)
3487 {
3488 cur_tangnormlen -= 0.1;
3489 show_tangnormlen(sw);
3490 }
3491
3492 static void
show_tangnormlen(ind_sw_info * sw)3493 show_tangnormlen(ind_sw_info *sw)
3494 {
3495 if (cur_tangnormlen < 0)
3496 cur_tangnormlen = 0;
3497 else if (cur_tangnormlen > MAX_TANGNORMLEN)
3498 cur_tangnormlen = MAX_TANGNORMLEN;
3499
3500 put_msg("Tangent/normal line length %.2f %s", cur_tangnormlen, appres.INCHES? "in": "cm");
3501
3502 /* write the length in the background pixmap */
3503 indbuf[0] = indbuf[1] = indbuf[2] = indbuf[3] = indbuf[4] = '\0';
3504 sprintf(indbuf, "%5.2f", cur_tangnormlen);
3505 update_string_pixmap(sw, indbuf, sw->sw_width - 33, 25);
3506 }
3507
3508 /* ANGLE GEOMETRY */
3509
3510 static void
show_anglegeom(ind_sw_info * sw)3511 show_anglegeom(ind_sw_info *sw)
3512 {
3513 update_choice_pixmap(sw, cur_anglegeom);
3514 switch (cur_anglegeom) {
3515 case L_UNCONSTRAINED:
3516 manhattan_mode = 0;
3517 mountain_mode = 0;
3518 latexline_mode = 0;
3519 latexarrow_mode = 0;
3520 put_msg("UNCONSTRAINED geometry (for POLYLINE and SPLINE)");
3521 break;
3522 case L_MOUNTHATTAN:
3523 mountain_mode = 1;
3524 manhattan_mode = 1;
3525 latexline_mode = 0;
3526 latexarrow_mode = 0;
3527 put_msg("MOUNT-HATTAN geometry (for POLYLINE and SPLINE)");
3528 break;
3529 case L_MANHATTAN:
3530 manhattan_mode = 1;
3531 mountain_mode = 0;
3532 latexline_mode = 0;
3533 latexarrow_mode = 0;
3534 put_msg("MANHATTAN geometry (for POLYLINE and SPLINE)");
3535 break;
3536 case L_MOUNTAIN:
3537 mountain_mode = 1;
3538 manhattan_mode = 0;
3539 latexline_mode = 0;
3540 latexarrow_mode = 0;
3541 put_msg("MOUNTAIN geometry (for POLYLINE and SPLINE)");
3542 break;
3543 case L_LATEXLINE:
3544 latexline_mode = 1;
3545 manhattan_mode = 0;
3546 mountain_mode = 0;
3547 latexarrow_mode = 0;
3548 put_msg("LATEX LINE geometry: allow only LaTeX line slopes");
3549 break;
3550 case L_LATEXARROW:
3551 latexarrow_mode = 1;
3552 manhattan_mode = 0;
3553 mountain_mode = 0;
3554 latexline_mode = 0;
3555 put_msg("LATEX ARROW geometry: allow only LaTeX arrow slopes");
3556 break;
3557 }
3558 }
3559
3560 /* ARC TYPE */
3561
3562 static void
show_arctype(ind_sw_info * sw)3563 show_arctype(ind_sw_info *sw)
3564 {
3565 update_choice_pixmap(sw, cur_arctype);
3566 switch (cur_arctype) {
3567 case T_OPEN_ARC:
3568 put_msg("OPEN arc");
3569 break;
3570 case T_PIE_WEDGE_ARC:
3571 put_msg("PIE WEDGE (closed) arc");
3572 break;
3573 }
3574 }
3575
3576
3577 /* JOIN STYLE */
3578
3579 static void
show_joinstyle(ind_sw_info * sw)3580 show_joinstyle(ind_sw_info *sw)
3581 {
3582 update_choice_pixmap(sw, cur_joinstyle);
3583 switch (cur_joinstyle) {
3584 case JOIN_MITER:
3585 put_msg("MITER line join style");
3586 break;
3587 case JOIN_ROUND:
3588 put_msg("ROUND line join style");
3589 break;
3590 case JOIN_BEVEL:
3591 put_msg("BEVEL line join style");
3592 break;
3593 }
3594 }
3595
3596 /* CAP STYLE */
3597
3598 static void
show_capstyle(ind_sw_info * sw)3599 show_capstyle(ind_sw_info *sw)
3600 {
3601 update_choice_pixmap(sw, cur_capstyle);
3602 switch (cur_capstyle) {
3603 case CAP_BUTT:
3604 put_msg("BUTT line cap style");
3605 break;
3606 case CAP_ROUND:
3607 put_msg("ROUND line cap style");
3608 break;
3609 case CAP_PROJECT:
3610 put_msg("PROJECTING line cap style");
3611 break;
3612 }
3613 }
3614
3615 /* LINE STYLE */
3616
3617 static void
show_linestyle(ind_sw_info * sw)3618 show_linestyle(ind_sw_info *sw)
3619 {
3620 if (cur_dashlength <= 0.0)
3621 cur_dashlength = DEF_DASHLENGTH;
3622 if (cur_dotgap <= 0.0)
3623 cur_dotgap = DEF_DOTGAP;
3624 update_choice_pixmap(sw, cur_linestyle);
3625 switch (cur_linestyle) {
3626 case SOLID_LINE:
3627 put_msg("SOLID LINE STYLE");
3628 break;
3629 case DASH_LINE:
3630 cur_styleval = cur_dashlength;
3631 put_msg("DASH LINE STYLE");
3632 break;
3633 case DOTTED_LINE:
3634 cur_styleval = cur_dotgap;
3635 put_msg("DOTTED LINE STYLE");
3636 break;
3637 case DASH_DOT_LINE:
3638 cur_styleval = cur_dashlength;
3639 put_msg("DASH-DOT LINE STYLE");
3640 break;
3641 case DASH_2_DOTS_LINE:
3642 cur_styleval = cur_dashlength;
3643 put_msg("DASH-DOT-DOT LINE STYLE");
3644 break;
3645 case DASH_3_DOTS_LINE:
3646 cur_styleval = cur_dashlength;
3647 put_msg("DASH-DOT-DOT-DOT LINE STYLE");
3648 break;
3649 }
3650 }
3651
3652 /* VERTICAL ALIGNMENT */
3653
3654 static void
show_valign(ind_sw_info * sw)3655 show_valign(ind_sw_info *sw)
3656 {
3657 update_choice_pixmap(sw, cur_valign);
3658 switch (cur_valign) {
3659 case ALIGN_NONE:
3660 put_msg("No vertical alignment");
3661 break;
3662 case ALIGN_TOP:
3663 put_msg("Vertically align to TOP");
3664 break;
3665 case ALIGN_CENTER:
3666 put_msg("Center vertically when aligning");
3667 break;
3668 case ALIGN_BOTTOM:
3669 put_msg("Vertically align to BOTTOM");
3670 break;
3671 case ALIGN_DISTRIB_C:
3672 put_msg("Vertically DISTRIBUTE objects, equal distance between CENTRES");
3673 break;
3674 case ALIGN_DISTRIB_E:
3675 put_msg("Vertically DISTRIBUTE objects, equal distance between EDGES");
3676 break;
3677 case ALIGN_ABUT:
3678 put_msg("Vertically ABUT the objects together");
3679 break;
3680 }
3681 }
3682
3683 /* HORIZ ALIGNMENT */
3684
3685 static void
show_halign(ind_sw_info * sw)3686 show_halign(ind_sw_info *sw)
3687 {
3688 update_choice_pixmap(sw, cur_halign);
3689 switch (cur_halign) {
3690 case ALIGN_NONE:
3691 put_msg("No horizontal alignment");
3692 break;
3693 case ALIGN_LEFT:
3694 put_msg("Horizontally align to LEFT");
3695 break;
3696 case ALIGN_CENTER:
3697 put_msg("Center horizontally when aligning");
3698 break;
3699 case ALIGN_RIGHT:
3700 put_msg("Horizontally align to RIGHT");
3701 break;
3702 case ALIGN_DISTRIB_C:
3703 put_msg("Horizontally DISTRIBUTE objects, equal distance between CENTRES");
3704 break;
3705 case ALIGN_DISTRIB_E:
3706 put_msg("Horizontally DISTRIBUTE objects, equal distance between EDGES");
3707 break;
3708 case ALIGN_ABUT:
3709 put_msg("Horizontally ABUT the objects together");
3710 break;
3711 }
3712 }
3713
3714 /* GRID MODE */ // isometric grid
3715
3716 static void
show_gridmode(sw)3717 show_gridmode(sw)
3718 ind_sw_info *sw;
3719 {
3720 update_choice_pixmap(sw, cur_gridmode);
3721
3722 /* check the new mode */
3723 if (cur_gridmode == GRID_0) {
3724 put_msg("No grid");
3725 } else if( cur_gridmode <= GRID_4 ) {
3726 cur_gridtype = GRID_SQUARE;
3727 put_msg( "%s grid", grid_name[cur_gridunit][cur_gridmode] );
3728 } else {
3729 /*cur_gridmode = cur_gridmode - GRID_4;*/
3730 cur_gridtype = GRID_ISO;
3731 put_msg( "%s isometric grid", grid_name[cur_gridunit][cur_gridmode - GRID_4] );
3732 }
3733
3734 /* display new grid */
3735 setup_grid();
3736 }
3737
3738 /* POINT POSITION */
3739
3740 static void
show_pointposn(ind_sw_info * sw)3741 show_pointposn(ind_sw_info *sw)
3742 {
3743 char buf[80];
3744
3745 /* because of the weird numbering we're using, we have to check this here */
3746 if (cur_pointposn > P_GRID4)
3747 cur_pointposn = P_ANY;
3748
3749 update_choice_pixmap(sw, cur_pointposn);
3750 switch (cur_pointposn) {
3751 case P_ANY:
3752 put_msg("Arbitrary Positioning of Points");
3753 break;
3754 default:
3755 sprintf(buf,
3756 "MAGNET MODE: entered points rounded to the nearest %s increment",
3757 grid_name[cur_gridunit][cur_pointposn-1]);
3758 put_msg(buf);
3759 break;
3760 }
3761 }
3762
3763 /* SMART LINK MODE */
3764
3765 static void
show_linkmode(ind_sw_info * sw)3766 show_linkmode(ind_sw_info *sw)
3767 {
3768 update_choice_pixmap(sw, cur_linkmode);
3769 switch (cur_linkmode) {
3770 case SMART_OFF:
3771 put_msg("Do not adjust links automatically");
3772 break;
3773 case SMART_MOVE:
3774 put_msg("Adjust links automatically by moving endpoint");
3775 break;
3776 case SMART_SLIDE:
3777 put_msg("Adjust links automatically by sliding endlink");
3778 break;
3779 }
3780 }
3781
3782 /* TEXT JUSTIFICATION */
3783
3784 static void
show_textjust(ind_sw_info * sw)3785 show_textjust(ind_sw_info *sw)
3786 {
3787 update_choice_pixmap(sw, cur_textjust);
3788 switch (cur_textjust) {
3789 case T_LEFT_JUSTIFIED:
3790 put_msg("Left justify text");
3791 break;
3792 case T_CENTER_JUSTIFIED:
3793 put_msg("Center text");
3794 break;
3795 case T_RIGHT_JUSTIFIED:
3796 put_msg("Right justify text");
3797 break;
3798 }
3799 }
3800
3801 /* BOX RADIUS */
3802
3803 static void
dec_boxradius(ind_sw_info * sw)3804 dec_boxradius(ind_sw_info *sw)
3805 {
3806 --cur_boxradius;
3807 show_boxradius(sw);
3808 }
3809
3810 static void
inc_boxradius(ind_sw_info * sw)3811 inc_boxradius(ind_sw_info *sw)
3812 {
3813 ++cur_boxradius;
3814 show_boxradius(sw);
3815 }
3816
3817 #define MAXRADIUS 30
3818
3819 static void
show_boxradius(ind_sw_info * sw)3820 show_boxradius(ind_sw_info *sw)
3821 {
3822 if (cur_boxradius > MAXRADIUS)
3823 cur_boxradius = MAXRADIUS;
3824 else if (cur_boxradius < 3)
3825 cur_boxradius = 3;
3826 /* erase by drawing wide, inverted (white) line */
3827 pw_vector(sw->pixmap, DEF_IND_SW_WD / 2, DEF_IND_SW_HT / 2,
3828 DEF_IND_SW_WD, DEF_IND_SW_HT / 2, ERASE,
3829 DEF_IND_SW_HT, PANEL_LINE, 0.0, DEFAULT);
3830 /* draw current radius into pixmap */
3831 curve(sw->pixmap, MAX_DEPTH+1, 0, cur_boxradius, -cur_boxradius, 0,
3832 DRAW_POINTS, DONT_DRAW_CENTER, 1, cur_boxradius, cur_boxradius,
3833 DEF_IND_SW_WD - 2, DEF_IND_SW_HT - 2, PAINT, 1, PANEL_LINE, 0.0, UNFILLED,
3834 DEFAULT, DEFAULT, CAP_BUTT);
3835
3836 /*
3837 * Fool the toolkit by changing the background pixmap to 0 then giving it
3838 * the modified one again. Otherwise, it sees that the pixmap ID is not
3839 * changed and doesn't actually draw it into the widget window
3840 */
3841 if (sw->updbut && update_buts_managed)
3842 XtUnmanageChild(sw->updbut);
3843 FirstArg(XtNbackgroundPixmap, 0);
3844 SetValues(sw->button);
3845 /* put the pixmap in the widget background */
3846 FirstArg(XtNbackgroundPixmap, sw->pixmap);
3847 SetValues(sw->button);
3848 put_msg("ROUNDED-CORNER BOX Radius = %d", cur_boxradius);
3849 if (sw->updbut && update_buts_managed)
3850 XtManageChild(sw->updbut);
3851 }
3852
3853 /* FILL STYLE */
3854
3855 static void
darken_fill(ind_sw_info * sw)3856 darken_fill(ind_sw_info *sw)
3857 {
3858 cur_fillstyle++;
3859 if ((cur_fillcolor == BLACK || cur_fillcolor == DEFAULT ||
3860 cur_fillcolor == WHITE) && cur_fillstyle == NUMSHADEPATS)
3861 cur_fillstyle = NUMSHADEPATS+NUMTINTPATS; /* skip to patterns */
3862 else if (cur_fillstyle >= NUMFILLPATS)
3863 cur_fillstyle = UNFILLED;
3864 show_fillstyle(sw);
3865 }
3866
3867 static void
lighten_fill(ind_sw_info * sw)3868 lighten_fill(ind_sw_info *sw)
3869 {
3870 cur_fillstyle--;
3871 if (cur_fillstyle < UNFILLED)
3872 cur_fillstyle = NUMFILLPATS-1; /* set to patterns */
3873 if ((cur_fillcolor == BLACK || cur_fillcolor == DEFAULT ||
3874 cur_fillcolor == WHITE) && cur_fillstyle == NUMSHADEPATS+NUMTINTPATS-1)
3875 cur_fillstyle = NUMSHADEPATS-1; /* no tints */
3876 show_fillstyle(sw);
3877 }
3878
3879 void
show_fillstyle(ind_sw_info * sw)3880 show_fillstyle(ind_sw_info *sw)
3881 {
3882 /* we must check the validity of the fill style again in case the user changed
3883 colors. In that case, there may be an illegal fill value (e.g. for black
3884 there are no "tints" */
3885 if (cur_fillcolor == COLOR_NONE ||
3886 (cur_fillcolor == BLACK || cur_fillcolor == DEFAULT || cur_fillcolor == WHITE) &&
3887 (cur_fillstyle >= NUMSHADEPATS && cur_fillstyle < NUMSHADEPATS+NUMTINTPATS))
3888 cur_fillstyle = UNFILLED; /* no fill color or no tints, set unfilled */
3889 XSetFillStyle(tool_d, ind_button_gc, FillTiled);
3890 if (cur_fillstyle == UNFILLED) {
3891 XSetTile(tool_d, ind_button_gc, fillstyle_choices[0].pixmap);
3892 XFillRectangle(tool_d, sw->pixmap, ind_button_gc, 32, 0, 32, 32);
3893 put_msg("NO-FILL MODE");
3894 } else {
3895 /* put the pixmap in the widget background */
3896 XSetTile(tool_d, ind_button_gc, fillstyle_choices[cur_fillstyle+1].pixmap);
3897 XFillRectangle(tool_d, sw->pixmap, ind_button_gc, 35, 4, 26, 24);
3898 if (cur_fillstyle < NUMSHADEPATS+NUMTINTPATS)
3899 put_msg("FILL MODE (black density/color intensity = %d%%)",
3900 (cur_fillstyle * 200) / (NUMSHADEPATS+NUMTINTPATS - 1));
3901 else
3902 put_msg("FILL pattern %d",cur_fillstyle-NUMSHADEPATS-NUMTINTPATS);
3903 }
3904 XSetFillStyle(tool_d, ind_button_gc, FillSolid);
3905 if (sw->updbut && update_buts_managed)
3906 XtUnmanageChild(sw->updbut);
3907 FirstArg(XtNbackgroundPixmap, 0);
3908 SetValues(sw->button);
3909 /* put the pixmap in the widget background */
3910 FirstArg(XtNbackgroundPixmap, sw->pixmap);
3911 SetValues(sw->button);
3912 if (sw->updbut && update_buts_managed)
3913 XtManageChild(sw->updbut);
3914 }
3915
3916 /* change the colors of the fill style indicators */
3917
recolor_fillstyles(void)3918 void recolor_fillstyles(void)
3919 {
3920 int i,j;
3921 float save_dispzoom, savezoom;
3922 Pixmap savepm;
3923 float savepm_zoom;
3924
3925 save_dispzoom = display_zoomscale;
3926 savezoom = zoomscale;
3927 display_zoomscale = 1.0;
3928 zoomscale = display_zoomscale/ZOOM_FACTOR;
3929
3930 for (i = 0; i < NUMFILLPATS; i++) {
3931 j = i-(NUMTINTPATS+NUMSHADEPATS);
3932 if (j >= 0) { /* actual patterns */
3933 savepm = fill_pm[i];
3934 savepm_zoom = fill_pm_zoom[i];
3935 /* use the one create at zoom = 1 */
3936 fill_pm[i] = fill_but_pm[j];
3937 fill_pm_zoom[i] = fill_but_pm_zoom[j];
3938 }
3939 set_fill_gc(i, PAINT, cur_pencolor, cur_fillcolor, 0, 0);
3940 /* skip tints for black, white and default */
3941 if ((cur_fillcolor == WHITE || cur_fillcolor == BLACK || cur_fillcolor == DEFAULT) &&
3942 (i >= NUMSHADEPATS && i < NUMTINTPATS+NUMSHADEPATS))
3943 continue;
3944 XFillRectangle(tool_d, fillstyle_choices[i+1].pixmap, fillgc, 0, 0, 32, 32);
3945 if (j >= 0) {
3946 fill_pm[i] = savepm;
3947 fill_pm_zoom[i] = savepm_zoom;
3948 }
3949 }
3950 display_zoomscale = save_dispzoom;
3951 zoomscale = savezoom;
3952 }
3953
3954 /**********************/
3955 /* TEXT FLAGS */
3956 /**********************/
3957
3958 static void
inc_flags(ind_sw_info * sw)3959 inc_flags(ind_sw_info *sw)
3960 {
3961 if (++cur_flagshown >= MAX_FLAGS)
3962 cur_flagshown = 0;
3963 show_flags(sw);
3964 }
3965
3966 static void
dec_flags(ind_sw_info * sw)3967 dec_flags(ind_sw_info *sw)
3968 {
3969 if (--cur_flagshown < 0)
3970 cur_flagshown = MAX_FLAGS-1;
3971 show_flags(sw);
3972 }
3973
3974 static void
show_flags(ind_sw_info * sw)3975 show_flags(ind_sw_info *sw)
3976 {
3977 put_msg("Text flags: Hidden=%s, TeX=%s, Rigid=%s (Button 1 to change)",
3978 (cur_textflags & HIDDEN_TEXT) ? "on" : "off",
3979 (cur_textflags & SPECIAL_TEXT) ? "on" : "off",
3980 (cur_textflags & RIGID_TEXT) ? "on" : "off");
3981
3982 /* write the text/ellipse angle in the background pixmap */
3983 switch(cur_flagshown) {
3984 case 0:
3985 sprintf(indbuf, "hidden=%s",
3986 (cur_textflags & HIDDEN_TEXT) ? "on " : "off");
3987 break;
3988 case 1:
3989 sprintf(indbuf, "TeX=%s",
3990 (cur_textflags & SPECIAL_TEXT) ? "on " : "off ");
3991 break;
3992 default:
3993 sprintf(indbuf, "rigid=%s",
3994 (cur_textflags & RIGID_TEXT) ? "on " : "off ");
3995 }
3996 update_string_pixmap(sw, indbuf, 6, 26);
3997 }
3998
3999 /**********************/
4000 /* FONT */
4001 /**********************/
4002
4003 static void
inc_font(ind_sw_info * sw)4004 inc_font(ind_sw_info *sw)
4005 {
4006 if (using_ps)
4007 cur_ps_font++;
4008 else
4009 cur_latex_font++;
4010 show_font(sw);
4011 }
4012
4013 static void
dec_font(ind_sw_info * sw)4014 dec_font(ind_sw_info *sw)
4015 {
4016 if (using_ps)
4017 cur_ps_font--;
4018 else
4019 cur_latex_font--;
4020 show_font(sw);
4021 }
4022
4023 static void
show_font(ind_sw_info * sw)4024 show_font(ind_sw_info *sw)
4025 {
4026 if (using_ps) {
4027 if (cur_ps_font >= NUM_FONTS)
4028 cur_ps_font = DEFAULT;
4029 else if (cur_ps_font < DEFAULT)
4030 cur_ps_font = NUM_FONTS - 1;
4031 } else {
4032 if (cur_latex_font >= NUM_LATEX_FONTS)
4033 cur_latex_font = 0;
4034 else if (cur_latex_font < 0)
4035 cur_latex_font = NUM_LATEX_FONTS - 1;
4036 }
4037
4038 /* erase larger fontpane bits if we switched to smaller (Latex) */
4039 XFillRectangle(tool_d, sw->pixmap, ind_blank_gc, 0, 0,
4040 32 + max2(PS_FONTPANE_WD, LATEX_FONTPANE_WD), DEF_IND_SW_HT);
4041 /* and redraw info */
4042 XDrawImageString(tool_d, sw->pixmap, ind_button_gc, 3, 12, sw->line1,
4043 strlen(sw->line1));
4044 XDrawImageString(tool_d, sw->pixmap, ind_button_gc, 3, 25, sw->line2,
4045 strlen(sw->line2));
4046
4047 XCopyArea(tool_d, using_ps ? psfont_menu_bitmaps[cur_ps_font + 1] :
4048 latexfont_menu_bitmaps[cur_latex_font],
4049 sw->pixmap, ind_button_gc, 0, 0,
4050 using_ps ? PS_FONTPANE_WD : LATEX_FONTPANE_WD,
4051 using_ps ? PS_FONTPANE_HT : LATEX_FONTPANE_HT,
4052 using_ps ? 32 : 32 + (PS_FONTPANE_WD - LATEX_FONTPANE_WD) / 2, 6);
4053
4054 if (sw->updbut && update_buts_managed)
4055 XtUnmanageChild(sw->updbut);
4056 FirstArg(XtNbackgroundPixmap, 0);
4057 SetValues(sw->button);
4058 /* put the pixmap in the widget background */
4059 FirstArg(XtNbackgroundPixmap, sw->pixmap);
4060 SetValues(sw->button);
4061 put_msg("Font: %s", using_ps ? ps_fontinfo[cur_ps_font + 1].name :
4062 latex_fontinfo[cur_latex_font].name);
4063 if (sw->updbut && update_buts_managed)
4064 XtManageChild(sw->updbut);
4065 }
4066
4067 /* popup menu of fonts */
4068
4069 static int psflag;
4070 static ind_sw_info *return_sw;
4071
4072 static void show_font_return(Widget w);
4073
4074 static void
popup_fonts(ind_sw_info * sw)4075 popup_fonts(ind_sw_info *sw)
4076 {
4077 return_sw = sw;
4078 psflag = using_ps ? 1 : 0;
4079 fontpane_popup(&cur_ps_font, &cur_latex_font, &psflag,
4080 show_font_return, sw->button);
4081 }
4082
4083 static void
show_font_return(Widget w)4084 show_font_return(Widget w)
4085 {
4086 if (psflag)
4087 cur_textflags = cur_textflags | PSFONT_TEXT;
4088 else
4089 cur_textflags = cur_textflags & (~PSFONT_TEXT);
4090 show_font(return_sw);
4091 }
4092
4093 /* FONT SIZE */
4094
4095 static void
inc_fontsize(ind_sw_info * sw)4096 inc_fontsize(ind_sw_info *sw)
4097 {
4098 if (cur_fontsize >= 100) {
4099 cur_fontsize = (cur_fontsize / 10) * 10; /* round first */
4100 cur_fontsize += 10;
4101 } else if (cur_fontsize >= 50) {
4102 cur_fontsize = (cur_fontsize / 5) * 5;
4103 cur_fontsize += 5;
4104 } else if (cur_fontsize >= 20) {
4105 cur_fontsize = (cur_fontsize / 2) * 2;
4106 cur_fontsize += 2;
4107 } else
4108 cur_fontsize++;
4109 show_fontsize(sw);
4110 }
4111
4112 static void
dec_fontsize(ind_sw_info * sw)4113 dec_fontsize(ind_sw_info *sw)
4114 {
4115 if (cur_fontsize > 100) {
4116 cur_fontsize = (cur_fontsize / 10) * 10; /* round first */
4117 cur_fontsize -= 10;
4118 } else if (cur_fontsize > 50) {
4119 cur_fontsize = (cur_fontsize / 5) * 5;
4120 cur_fontsize -= 5;
4121 } else if (cur_fontsize > 20) {
4122 cur_fontsize = (cur_fontsize / 2) * 2;
4123 cur_fontsize -= 2;
4124 } else if (cur_fontsize > MIN_FONT_SIZE)
4125 cur_fontsize--;
4126 show_fontsize(sw);
4127 }
4128
4129 static void
show_fontsize(ind_sw_info * sw)4130 show_fontsize(ind_sw_info *sw)
4131 {
4132 if (cur_fontsize < MIN_FONT_SIZE)
4133 cur_fontsize = MIN_FONT_SIZE;
4134 else if (cur_fontsize > MAX_FONT_SIZE)
4135 cur_fontsize = MAX_FONT_SIZE;
4136
4137 put_msg("Font size %d", cur_fontsize);
4138 /* write the font size in the background pixmap */
4139 indbuf[0] = indbuf[1] = indbuf[2] = indbuf[3] = indbuf[4] = '\0';
4140 sprintf(indbuf, "%4d", cur_fontsize);
4141 update_string_pixmap(sw, indbuf, sw->sw_width - 28, 20);
4142 }
4143
4144 /* ELLIPSE/TEXT ANGLE */
4145
4146 static void
inc_elltextangle(ind_sw_info * sw)4147 inc_elltextangle(ind_sw_info *sw)
4148 {
4149
4150 if (cur_elltextangle < 0.0)
4151 cur_elltextangle = ((int) ((cur_elltextangle-14.999)/15.0))*15.0;
4152 else
4153 cur_elltextangle = ((int) (cur_elltextangle/15.0))*15.0;
4154 cur_elltextangle += 15.0;
4155 show_elltextangle(sw);
4156 }
4157
4158 static void
dec_elltextangle(ind_sw_info * sw)4159 dec_elltextangle(ind_sw_info *sw)
4160 {
4161 if (cur_elltextangle < 0.0)
4162 cur_elltextangle = ((int) (cur_elltextangle/15.0))*15.0;
4163 else
4164 cur_elltextangle = ((int) ((cur_elltextangle+14.999)/15.0))*15.0;
4165 cur_elltextangle -= 15.0;
4166 show_elltextangle(sw);
4167 }
4168
4169 static void
show_elltextangle(ind_sw_info * sw)4170 show_elltextangle(ind_sw_info *sw)
4171 {
4172 cur_elltextangle = round(cur_elltextangle*10.0)/10.0;
4173 if (cur_elltextangle <= -360.0 || cur_elltextangle >= 360)
4174 cur_elltextangle = 0.0;
4175
4176 put_msg("Text/Ellipse angle %.1f", cur_elltextangle);
4177 if (cur_elltextangle == old_elltextangle)
4178 return;
4179
4180 /* write the text/ellipse angle in the background pixmap */
4181 indbuf[0]=indbuf[1]=indbuf[2]=indbuf[3]=indbuf[4]=indbuf[5]=' ';
4182 sprintf(indbuf, "%5.1f", cur_elltextangle);
4183 update_string_pixmap(sw, indbuf, sw->sw_width - 40, 26);
4184 old_elltextangle = cur_elltextangle;
4185 }
4186
4187 /* ROTATION ANGLE */
4188
4189 static void
inc_rotnangle(ind_sw_info * sw)4190 inc_rotnangle(ind_sw_info *sw)
4191 {
4192 if (cur_rotnangle < 15.0 || cur_rotnangle >= 180.0)
4193 cur_rotnangle = 15.0;
4194 else if (cur_rotnangle < 30.0)
4195 cur_rotnangle = 30.0;
4196 else if (cur_rotnangle < 45.0)
4197 cur_rotnangle = 45.0;
4198 else if (cur_rotnangle < 60.0)
4199 cur_rotnangle = 60.0;
4200 else if (cur_rotnangle < 90.0)
4201 cur_rotnangle = 90.0;
4202 else if (cur_rotnangle < 120.0)
4203 cur_rotnangle = 120.0;
4204 else if (cur_rotnangle < 180.0)
4205 cur_rotnangle = 180.0;
4206 show_rotnangle(sw);
4207 }
4208
4209 static void
dec_rotnangle(ind_sw_info * sw)4210 dec_rotnangle(ind_sw_info *sw)
4211 {
4212 if (cur_rotnangle > 180.0 || cur_rotnangle <= 15.0)
4213 cur_rotnangle = 180.0;
4214 else if (cur_rotnangle > 120.0)
4215 cur_rotnangle = 120.0;
4216 else if (cur_rotnangle > 90.0)
4217 cur_rotnangle = 90.0;
4218 else if (cur_rotnangle > 60.0)
4219 cur_rotnangle = 60.0;
4220 else if (cur_rotnangle > 45.0)
4221 cur_rotnangle = 45.0;
4222 else if (cur_rotnangle > 30.0)
4223 cur_rotnangle = 30.0;
4224 else if (cur_rotnangle > 15.0)
4225 cur_rotnangle = 15.0;
4226 show_rotnangle(sw);
4227 }
4228
4229 static void
show_rotnangle(ind_sw_info * sw)4230 show_rotnangle(ind_sw_info *sw)
4231 {
4232 show_rotnangle_0(sw, 1);
4233 }
4234
4235 /* called by angle measuring &c */
4236
4237 static void
show_rotnangle_0(ind_sw_info * sw,int panel)4238 show_rotnangle_0(ind_sw_info *sw, int panel)
4239 /* called from panel? */
4240 {
4241 int i;
4242
4243 if (cur_rotnangle < -360.0)
4244 cur_rotnangle = -360.0;
4245 else if (cur_rotnangle > 360.0)
4246 cur_rotnangle = 360.0;
4247
4248 if (panel)
4249 put_msg("Angle of rotation %.2f", cur_rotnangle);
4250 if (cur_rotnangle == old_rotnangle)
4251 return;
4252
4253 /* write the rotation angle in the background pixmap */
4254 for (i = 0; i < 8; i++)
4255 indbuf[i] = '\0';
4256 sprintf(indbuf, "%6.2f", cur_rotnangle);
4257 update_string_pixmap(sw, indbuf, sw->sw_width - 40, 22);
4258
4259 if (panel) {
4260 /* change markers if we changed to or from 90/180 degrees (except at start) */
4261 if (old_rotnangle != -1.0) {
4262 if (fabs(cur_rotnangle) == 90.0 || fabs(cur_rotnangle) == 180.0)
4263 update_markers(M_ALL);
4264 else if (fabs(old_rotnangle) == 90.0 || fabs(old_rotnangle) == 180.0)
4265 update_markers(M_ROTATE_ANGLE);
4266 }
4267 }
4268 old_rotnangle = cur_rotnangle;
4269 }
4270
4271 void
set_and_show_rotnangle(float value)4272 set_and_show_rotnangle(float value)
4273 {
4274 int i;
4275 ind_sw_info *sw;
4276
4277 cur_rotnangle = value;
4278 for (i = 0; i < NUM_IND_SW; i++) {
4279 sw = ind_switches + i;
4280 if (sw->func == I_ROTNANGLE) {
4281 show_rotnangle_0(sw, 0);
4282 break;
4283 }
4284 }
4285 }
4286
4287 /* NUMSIDES */
4288
4289 static void
inc_numsides(ind_sw_info * sw)4290 inc_numsides(ind_sw_info *sw)
4291 {
4292 cur_numsides++;
4293 show_numsides(sw);
4294 }
4295
4296 static void
dec_numsides(ind_sw_info * sw)4297 dec_numsides(ind_sw_info *sw)
4298 {
4299 cur_numsides--;
4300 show_numsides(sw);
4301 }
4302
4303 static void
show_numsides(ind_sw_info * sw)4304 show_numsides(ind_sw_info *sw)
4305 {
4306 if (cur_numsides < 3)
4307 cur_numsides = 3;
4308 else if (cur_numsides > MAX_POLY_SIDES)
4309 cur_numsides = MAX_POLY_SIDES;
4310
4311 put_msg("Number of sides %3d", cur_numsides);
4312 /* write the number of sides in the background pixmap */
4313 indbuf[0] = indbuf[1] = indbuf[2] = indbuf[3] = indbuf[4] = '\0';
4314 sprintf(indbuf, "%3d", cur_numsides);
4315 update_string_pixmap(sw, indbuf, sw->sw_width - 22, 20);
4316 }
4317
4318 /* NUMCOPIES */
4319
4320 static void
inc_numcopies(ind_sw_info * sw)4321 inc_numcopies(ind_sw_info *sw)
4322 {
4323 cur_numcopies++;
4324 show_numcopies(sw);
4325 }
4326
4327 static void
dec_numcopies(ind_sw_info * sw)4328 dec_numcopies(ind_sw_info *sw)
4329 {
4330 cur_numcopies--;
4331 show_numcopies(sw);
4332 }
4333
4334 static void
show_numcopies(ind_sw_info * sw)4335 show_numcopies(ind_sw_info *sw)
4336 {
4337 if (cur_numcopies < 1)
4338 cur_numcopies = 1;
4339 else if (cur_numcopies > 99)
4340 cur_numcopies = 99;
4341
4342 put_msg("Number of copies %2d", cur_numcopies);
4343 /* write the number of copies in the background pixmap */
4344 indbuf[0] = indbuf[1] = indbuf[2] = indbuf[3] = indbuf[4] = '\0';
4345 sprintf(indbuf, "%2d", cur_numcopies);
4346 update_string_pixmap(sw, indbuf, sw->sw_width - 18, 20);
4347 }
4348
4349 /* NUMXCOPIES */
4350
4351 static void
inc_numxcopies(ind_sw_info * sw)4352 inc_numxcopies(ind_sw_info *sw)
4353 {
4354 cur_numxcopies++;
4355 show_numxcopies(sw);
4356 }
4357
4358 static void
dec_numxcopies(ind_sw_info * sw)4359 dec_numxcopies(ind_sw_info *sw)
4360 {
4361 cur_numxcopies--;
4362 show_numxcopies(sw);
4363 }
4364
4365 static void
show_numxcopies(ind_sw_info * sw)4366 show_numxcopies(ind_sw_info *sw)
4367 {
4368 if (cur_numxcopies < 0)
4369 cur_numxcopies = 0;
4370 else if (cur_numxcopies > 999)
4371 cur_numxcopies = 999;
4372
4373 if (!cur_numxcopies)
4374 put_msg("Number of copies %2d in x-direction", cur_numxcopies);
4375 /* write the number of x copies in the background pixmap */
4376 indbuf[0] = indbuf[1] = indbuf[2] = indbuf[3] = indbuf[4] = '\0';
4377 sprintf(indbuf, "%2d", cur_numxcopies);
4378 update_string_pixmap(sw, indbuf, sw->sw_width - 18, 20);
4379 }
4380
4381 /* NUMYCOPIES */
4382
4383 static void
inc_numycopies(ind_sw_info * sw)4384 inc_numycopies(ind_sw_info *sw)
4385 {
4386 cur_numycopies++;
4387 show_numycopies(sw);
4388 }
4389
4390 static void
dec_numycopies(ind_sw_info * sw)4391 dec_numycopies(ind_sw_info *sw)
4392 {
4393 cur_numycopies--;
4394 show_numycopies(sw);
4395 }
4396
4397 static void
show_numycopies(ind_sw_info * sw)4398 show_numycopies(ind_sw_info *sw)
4399 {
4400 if (cur_numycopies < 0)
4401 cur_numycopies = 0;
4402 else if (cur_numycopies > 999)
4403 cur_numycopies = 999;
4404
4405 if (!cur_numycopies)
4406 put_msg("Number of copies %2d in y-direction", cur_numycopies);
4407 /* write the number of y copies in the background pixmap */
4408 indbuf[0] = indbuf[1] = indbuf[2] = indbuf[3] = indbuf[4] = '\0';
4409 sprintf(indbuf, "%2d", cur_numycopies);
4410 update_string_pixmap(sw, indbuf, sw->sw_width - 18, 20);
4411 }
4412
4413 /* ZOOM */
4414
4415 /* zoom in */
4416 void
inc_zoom(void)4417 inc_zoom(void)
4418 {
4419 float intzoom;
4420
4421 /* don't allow zooming while previewing */
4422 if (preview_in_progress || check_action_on())
4423 return;
4424
4425 if (display_zoomscale < (float) 0.1) {
4426 display_zoomscale = (int)(display_zoomscale * 100.0 + 0.1) + 1.0;
4427 display_zoomscale /= 100.0;
4428 } else if (display_zoomscale < 1.0) {
4429 if (display_zoomscale < 0.1)
4430 display_zoomscale = 0.1;
4431 else
4432 display_zoomscale += 0.1; /* always quantized */
4433 display_zoomscale = (int)(display_zoomscale*10.0+0.01);
4434 display_zoomscale /= 10.0;
4435 } else {
4436 if (integral_zoom) {
4437 intzoom = round(display_zoomscale * 1.5);
4438 /* if user wants integral zoom, but 1.5 factor isn't enough, just increment zoom by 1 */
4439 if (intzoom == display_zoomscale)
4440 intzoom++;
4441 display_zoomscale = intzoom;
4442 } else
4443 display_zoomscale = display_zoomscale * 1.5;
4444 }
4445 }
4446
4447 /* zoom out */
4448 void
dec_zoom(void)4449 dec_zoom(void)
4450 {
4451 float intzoom;
4452
4453 /* don't allow zooming while previewing */
4454 if (preview_in_progress || check_action_on())
4455 return;
4456
4457 if (display_zoomscale <= (float) 0.1) {
4458 display_zoomscale = ((int)(display_zoomscale * 100.0 + 0.1)) - 1.0;
4459 display_zoomscale /= 100.0;
4460 if (display_zoomscale <= MIN_ZOOM)
4461 display_zoomscale = MIN_ZOOM;
4462 } else if (display_zoomscale < (float) 0.3) {
4463 display_zoomscale = 0.1; /* always quantized */
4464 } else if (display_zoomscale <= (float) 1.0) {
4465 display_zoomscale -= 0.1; /* always quantized */
4466 display_zoomscale = (int)(display_zoomscale*10.0+0.01);
4467 display_zoomscale /= 10.0;
4468 } else {
4469 if (integral_zoom) {
4470 intzoom = round(display_zoomscale / 1.5);
4471 /* if user wants integral zoom, but 1.5 factor isn't enough, just decrement zoom by 1 */
4472 if (intzoom == display_zoomscale)
4473 intzoom--;
4474 display_zoomscale = intzoom;
4475 } else
4476 display_zoomscale = display_zoomscale / 1.5;
4477 if (display_zoomscale < (float) 1.0)
4478 display_zoomscale = 1.0;
4479 }
4480 }
4481
4482 /* zoom in or out, keeping location x,y fixed */
4483 void
zoom_focus(int x,int y,void (* zoom)())4484 zoom_focus(int x, int y, void(* zoom)())
4485 {
4486 double stretch;
4487
4488 /*
4489 * zoomxoff = -(CANVAS_WD/2.)*ZOOM_FACTOR/prev_zoom + zoomxoff +
4490 * (CANVAS_WD/2.)*ZOOM_FACTOR/display_zoomscale;
4491 * stretch = 0.5*ZOOM_FACTOR*(-1./prev_zoom + 1./display_zoomscale);
4492 * and: zoomscale = display_zoomscale / ZOOM_FACTOR;
4493 */
4494
4495 stretch = 1. / display_zoomscale; /* previous zoomscale */
4496 zoom();
4497 stretch -= 1. / display_zoomscale; /* new zoomscale */
4498 stretch *= ZOOM_FACTOR;
4499 zoomxoff += stretch * x;
4500 zoomyoff += stretch * y;
4501
4502 /* use zoom_sw instead of one passed to us because we might have come
4503 here from an accelerator */
4504 show_zoom(zoom_sw);
4505 }
4506
4507 void
inc_zoom_centered(ind_sw_info * sw)4508 inc_zoom_centered(ind_sw_info *sw)
4509 {
4510 zoom_focus(CANVAS_WD/2, CANVAS_HT/2, inc_zoom);
4511 }
4512
4513 void
dec_zoom_centered(ind_sw_info * sw)4514 dec_zoom_centered(ind_sw_info *sw)
4515 {
4516 zoom_focus(CANVAS_WD/2, CANVAS_HT/2, dec_zoom);
4517 }
4518
4519 /* zoom in either from wheel or accelerator, centering canvas on mouse */
4520 void
wheel_inc_zoom()4521 wheel_inc_zoom()
4522 {
4523 Window root, child;
4524 int x1, y1, junk;
4525
4526 /* don't allow zooming while previewing */
4527 if (preview_in_progress || check_action_on())
4528 return;
4529
4530 XQueryPointer(tool_d, canvas_win, &root, &child,
4531 &junk, &junk, &x1, &y1, (unsigned int*) &junk);
4532
4533 if (x1 < 0 || x1 > CANVAS_WD || y1 < 0 || y1 > CANVAS_HT) {
4534 x1 = CANVAS_WD / 2;
4535 y1 = CANVAS_HT / 2;
4536 }
4537 zoom_focus(x1, y1, inc_zoom);
4538 }
4539
4540
4541 /* zoom out either from wheel or accelerator, centering canvas on mouse */
4542 void
wheel_dec_zoom()4543 wheel_dec_zoom()
4544 {
4545 Window root, child;
4546 int x1, y1, junk;
4547
4548 /* don't allow zooming while previewing */
4549 if (preview_in_progress || check_action_on())
4550 return;
4551
4552 XQueryPointer(tool_d, canvas_win, &root, &child,
4553 &junk, &junk, &x1, &y1, (unsigned int *) &junk);
4554
4555 if (x1 < 0 || x1 > CANVAS_WD || y1 < 0|| y1 > CANVAS_HT) {
4556 x1 = CANVAS_WD / 2;
4557 y1 = CANVAS_HT / 2;
4558 }
4559 zoom_focus(x1, y1, dec_zoom);
4560 }
4561
4562 /* zoom figure to fully fit in canvas */
4563
4564 void
fit_zoom(ind_sw_info * sw)4565 fit_zoom(ind_sw_info *sw)
4566 {
4567 int width, height;
4568 double zoomx, zoomy;
4569
4570 /* turn off Compose key LED */
4571 setCompLED(0);
4572
4573 /* don't allow zooming while previewing */
4574 if (preview_in_progress || check_action_on())
4575 return;
4576
4577 /* get the figure bounds */
4578 compound_bound(&objects, &objects.nwcorner.x, &objects.nwcorner.y,
4579 &objects.secorner.x, &objects.secorner.y);
4580 width = objects.secorner.x - objects.nwcorner.x;
4581 height = objects.secorner.y - objects.nwcorner.y;
4582 if (width == 0 && height == 0)
4583 return; /* no objects? */
4584
4585 /* leave a border */
4586 width = 1.05 * width/ZOOM_FACTOR;
4587 height = 1.05 * height/ZOOM_FACTOR;
4588
4589 if (width != 0)
4590 zoomx = 1.0 * CANVAS_WD / width;
4591 else
4592 zoomx = 1e6;
4593 if (height != 0)
4594 zoomy = 1.0 * CANVAS_HT / height;
4595 else
4596 zoomy = 1e6;
4597 zoomx = min2(zoomx, zoomy);
4598 zoomx = min2(zoomx, MAX_ZOOM);
4599 if (zoomx < MIN_ZOOM)
4600 zoomx = MIN_ZOOM;
4601 if (integral_zoom && zoomx > 1.0)
4602 zoomx = (double) ((int) zoomx);
4603 /* round to 2 decimal places */
4604 display_zoomscale = (double) ((int) (zoomx*100.0))/100.0;
4605 if (display_zoomscale < MIN_ZOOM)
4606 display_zoomscale = MIN_ZOOM;
4607
4608 /* keep it on the canvas */
4609 zoomxoff = objects.nwcorner.x - 100/display_zoomscale;
4610 zoomyoff = objects.nwcorner.y - 100/display_zoomscale;
4611 if (!appres.allownegcoords) {
4612 if (zoomxoff < 0)
4613 zoomxoff = 0;
4614 if (zoomyoff < 0)
4615 zoomyoff = 0;
4616 }
4617
4618 if (display_zoomscale == old_display_zoomscale) {
4619 /* if the zoom hasn't changed, just make sure it's centered */
4620 /* fix up the rulers and grid */
4621 reset_rulers();
4622 redisplay_canvas();
4623 } else {
4624 /* update the zoom indicator */
4625 show_zoom(zoom_sw);
4626 }
4627 }
4628
4629 void
show_zoom(ind_sw_info * sw)4630 show_zoom(ind_sw_info *sw)
4631 {
4632 /* turn off Compose key LED */
4633 setCompLED(0);
4634
4635 /* don't allow zooming while previewing */
4636 if (preview_in_progress || check_action_on())
4637 return;
4638
4639 if (display_zoomscale < MIN_ZOOM)
4640 display_zoomscale = MIN_ZOOM;
4641 else if (display_zoomscale > MAX_ZOOM)
4642 display_zoomscale = MAX_ZOOM;
4643
4644 /* write the zoom value in the background pixmap */
4645 indbuf[0] = indbuf[1] = indbuf[2] = indbuf[3] = indbuf[4] = '\0';
4646 if (display_zoomscale == (int) display_zoomscale) {
4647 if (display_zoomscale < 10.0) {
4648 sprintf(indbuf, " %.0f",display_zoomscale);
4649 } else if (display_zoomscale < 100.0) {
4650 sprintf(indbuf, " %.0f",display_zoomscale);
4651 } else {
4652 sprintf(indbuf, " %.0f",display_zoomscale);
4653 }
4654 } else if (display_zoomscale < 10.0) {
4655 display_zoomscale = (double) ((int) (display_zoomscale*100.0+0.5))/100.0;
4656 sprintf(indbuf, " %.2f", display_zoomscale);
4657 } else if (display_zoomscale < 100.0) {
4658 display_zoomscale = (double) ((int) (display_zoomscale*10.0+0.5))/10.0;
4659 sprintf(indbuf, " %.1f", display_zoomscale);
4660 } else {
4661 display_zoomscale = (double) ((int) display_zoomscale+0.5);
4662 sprintf(indbuf, "%.0f",display_zoomscale);
4663 }
4664
4665 put_msg("Zoom scale %s", indbuf);
4666
4667 update_string_pixmap(sw, indbuf, sw->sw_width - 35, 24);
4668
4669 zoomscale=display_zoomscale/ZOOM_FACTOR;
4670
4671 /* fix up the rulers and grid */
4672 reset_rulers();
4673 /* reload text objects' font structures since we need
4674 to load larger/smaller fonts */
4675 reload_text_fstructs();
4676 setup_grid();
4677 old_display_zoomscale = display_zoomscale;
4678 }
4679
4680 /* DEPTH */
4681
4682 static void
inc_depth(ind_sw_info * sw)4683 inc_depth(ind_sw_info *sw)
4684 {
4685 cur_depth++;
4686 show_depth(sw);
4687 }
4688
4689 static void
dec_depth(ind_sw_info * sw)4690 dec_depth(ind_sw_info *sw)
4691 {
4692 cur_depth--;
4693 show_depth(sw);
4694 }
4695
4696 void
show_depth(ind_sw_info * sw)4697 show_depth(ind_sw_info *sw)
4698 {
4699 if (cur_depth < 0)
4700 cur_depth = 0;
4701 else if (cur_depth > MAX_DEPTH)
4702 cur_depth = MAX_DEPTH;
4703
4704 put_msg("Depth %3d", cur_depth);
4705
4706 /* write the depth in the background pixmap */
4707 indbuf[0] = indbuf[1] = indbuf[2] = indbuf[3] = indbuf[4] = '\0';
4708 sprintf(indbuf, "%3d", cur_depth);
4709 update_string_pixmap(sw, indbuf, sw->sw_width - 22, 20);
4710 }
4711
4712 /* TEXTSTEP */
4713
4714 static void
inc_textstep(ind_sw_info * sw)4715 inc_textstep(ind_sw_info *sw)
4716 {
4717 if (cur_textstep >= 10.0) {
4718 cur_textstep = (int) cur_textstep; /* round first */
4719 cur_textstep += 1.0;
4720 } else if (cur_textstep >= 5.0) {
4721 cur_textstep = ((int)(cur_textstep*2.0+0.01))/2.0;
4722 cur_textstep += 0.5;
4723 } else if (cur_textstep >= 2.0) {
4724 cur_textstep = ((int)(cur_textstep*5.0+0.01))/5.0;
4725 cur_textstep += 0.2;
4726 } else
4727 cur_textstep += 0.1;
4728 show_textstep(sw);
4729 }
4730
4731 static void
dec_textstep(ind_sw_info * sw)4732 dec_textstep(ind_sw_info *sw)
4733 {
4734 if (cur_textstep > 10.0) {
4735 cur_textstep = (int)cur_textstep; /* round first */
4736 cur_textstep -= 1.0;
4737 } else if (cur_textstep > 5.0) {
4738 cur_textstep = ((int)(cur_textstep*2.0+0.01))/2.0;
4739 cur_textstep -= 0.5;
4740 } else if (cur_textstep > 2.0) {
4741 cur_textstep = ((int)(cur_textstep*5.0+0.01))/5.0;
4742 cur_textstep -= 0.2;
4743 } else if (cur_textstep > 0.4)
4744 cur_textstep -= 0.1;
4745 show_textstep(sw);
4746 }
4747
4748 /* could make this more generic - but a copy will do for font set JNT */
4749 static void
show_textstep(ind_sw_info * sw)4750 show_textstep(ind_sw_info *sw)
4751 {
4752 if (cur_textstep < (float) MIN_TEXT_STEP)
4753 cur_textstep = (float) MIN_TEXT_STEP;
4754 else if (cur_textstep > (float) MAX_TEXT_STEP)
4755 cur_textstep = (float) MAX_TEXT_STEP;
4756
4757 cur_textstep = round(cur_textstep*10.0)/10.0;
4758 put_msg("Text step %.1f", cur_textstep);
4759 /* write the text step in the background pixmap */
4760 indbuf[0] = indbuf[1] = indbuf[2] = indbuf[3] = indbuf[4] = '\0';
4761 sprintf(indbuf, "%4.1f", cur_textstep);
4762 update_string_pixmap(sw, indbuf, sw->sw_width - 28, 20);
4763 }
4764
4765 /* call fit_zoom() then dismiss zoom panel */
4766
4767 static void
zoom_to_fit(Widget w,XtPointer closure,XtPointer call_data)4768 zoom_to_fit(Widget w, XtPointer closure, XtPointer call_data)
4769 {
4770 ind_sw_info *sw = (ind_sw_info *) closure;
4771
4772 fit_zoom(sw);
4773 nval_panel_dismiss();
4774 }
4775
4776 /*
4777 * make a pulldown menu with "nent" button entries (PIXMAPS) that call "callback"
4778 * when pressed
4779 */
4780
4781 void
make_pulldown_menu_images(choice_info * entries,Cardinal nent,Pixmap * images,char ** texts,Widget parent,XtCallbackProc callback)4782 make_pulldown_menu_images(choice_info *entries, Cardinal nent, Pixmap *images, char **texts, Widget parent, XtCallbackProc callback)
4783 {
4784 Widget pulldown_menu, entry;
4785 char buf[64];
4786 int i;
4787
4788 pulldown_menu = XtCreatePopupShell("menu", simpleMenuWidgetClass, parent,
4789 NULL, ZERO);
4790
4791 for (i = 0; i < nent; i++) {
4792 FirstArg(XtNleftBitmap, images[i]); /* image of object */
4793 NextArg(XtNleftMargin, 32);
4794 NextArg(XtNvertSpace, 80); /* height 180% of font */
4795 NextArg(XtNlabel, texts? texts[i] : "");
4796 sprintf(buf,"%d",i);
4797 entry = XtCreateManagedWidget(buf, smeBSBObjectClass, pulldown_menu,
4798 Args, ArgCount);
4799 XtAddCallback(entry, XtNcallback, callback, (XtPointer) &entries[i]);
4800 }
4801 }
4802
4803 /* set the update switches according to the chosen named style */
4804
4805 void
tog_selective_update(long unsigned int mask)4806 tog_selective_update(long unsigned int mask)
4807 {
4808 int i;
4809
4810 for (i = 0; i < NUM_IND_SW; ++i) {
4811 if (ind_switches[i].updbut == NULL)
4812 continue;
4813
4814 if (ind_switches[i].func & mask)
4815 ind_switches[i].update = True;
4816 else
4817 ind_switches[i].update=False;
4818
4819 FirstArg(XtNstate, ind_switches[i].update);
4820 SetValues(ind_switches[i].updbut);
4821 }
4822 put_msg("Update command status SELECTIVELY toggled");
4823 cur_indmask=mask;
4824 cur_updatemask =mask;
4825 }
4826