1 /* Print dialog for the X11 interface to Xconq.
2    Copyright (C) 1994, 1995 Massimo Campostrini & Stanley T. Shebs.
3 
4 Xconq is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.  See the file COPYING.  */
8 
9 /* This is a print setup dialog, originally written by
10    Massimo Campostrini <campo@sunthpi3.difi.unipi.it> in May 1994. */
11 
12 #include "conq.h"
13 #include "xtconq.h"
14 
15 typedef struct a_widgetId {
16   String      name;
17   int         newline;
18 } WidgetId;
19 
20 typedef struct a_choice {
21   int number;
22   String legends[5];
23 } Choice;
24 
25 Choice choices[N_CHOICE] = {
26   {3,
27      {"no names",
28       "interesting names",
29       "all names",
30       NULL, NULL}
31  }
32 };
33 
34 static void print_ok(Side *side);
35 static void print_skip(Side *side);
36 static void open_print_help(Side *side);
37 static int w_comm_ind(Side *side, Widget w);
38 static void update_values(Side *side);
39 static void read_all(Side *side);
40 
41 static void handle_do_print_dialog(Widget w, XEvent *event,
42 				   String *params, Cardinal *num_params);
43 
44 static void print_setup_button_callback(Widget w, XtPointer client_data,
45 					XtPointer call_data);
46 static void metric_convert_callback(Widget w, XtPointer client_data,
47 				    XtPointer call_data);
48 static void done_print_help_callback(Widget w, XtPointer client_data,
49 				     XtPointer call_data);
50 static void handle_done_print_help(Widget w, XEvent *event,
51 				   String *params, Cardinal *num_params);
52 
53 static XtActionsRec xprint_actions[] = {
54   { "DoPrintDialog", handle_do_print_dialog },
55   { "DonePrintHelp", handle_done_print_help },
56 };
57 
58 WidgetId w_table[N_WIDGET] = {
59   {"help",         1 },
60   {"print",        0 },
61   {"quit",         0 },
62   {"names",        1 },
63   {"coord",        0 },
64   {"dither",       0 },
65   {"double",       1 },
66   {"features",     0 },
67   {"summary",      0 },
68   {"metric",       0 },
69   {"cellSize",     1 },
70   {"gridSize",     0 },
71   {"borderWidth",  1 },
72   {"connWidth",    0 },
73   {"pageWidth",    1 },
74   {"pageHeight",   0 },
75   {"topMargin",    1 },
76   {"bottomMargin", 0 },
77   {"leftMargin",   1 },
78   {"rightMargin",  0 },
79   {"terrainGray",  1 },
80   {"enemyGray",    0 },
81 };
82 
83 static String helpText =
84 "Modify values, then press \"print\" (or \"quit\" to skip printing).\n\
85  \n\
86 Multiple choices (click to cycle)\n\
87 o    print unit names:  no names, interesting names, all names.\n\
88  \n\
89 Binary options (dark background = set)\n\
90 o    coord:    print coordinates of map corners\n\
91 o    dither:   use dithering to print terrain gray\n\
92 o    double:   map a pixel into 2x2 pixels wile dithering\n\
93 o    features: print geographical features\n\
94 o    summary:  print summary of units in cell\n\
95 o    metric:   print distances in centimetres (otherwise in inches)\n\
96  \n\
97 Numerical options (accept floating-point values)\n\
98 o    cell size:  printed size of hexagonal cells\n\
99 o    grid thick.:  thickness of cell grid (0 to suppress)\n\
100 o    border/conn thick.:  thickness of borders and connections\n\
101 o    page width/height:  dimension of sheets to print on\n\
102 o    top/bottom/left/right margin:  margins of the region where\n\
103 cells are printed; labels and titles are printed in the margins\n\
104 o    border/connection thickness\n\
105 o    terrain gray:  from 0 (black) to 1 (white)\n\
106 o    enemy gray:    from 0 (black) to 1 (white), [not implemented]";
107 
108 int
popup_print_setup_dialog(Side * side)109 popup_print_setup_dialog(Side *side)
110 {
111     int i;
112     Widget w_form, w_left, w_up, w_oldup;
113     WidgetClass Class;
114 
115     XtAppAddActions(thisapp, xprint_actions, XtNumber(xprint_actions));
116 
117     if (!side->ui->print_shell) {
118 	side->ui->print_shell =
119 	  XtVaCreatePopupShell("PrintSetup", topLevelShellWidgetClass,
120 			       side->ui->shell, NULL);
121 
122 	w_form = XtVaCreateManagedWidget ("form", formWidgetClass, side->ui->print_shell, NULL);
123 	w_left = w_up = w_oldup = NULL;
124 
125 	for (i = 0; i < N_WIDGET; i++) {
126 	    if (i < N_BUTTON)
127 	      Class = commandWidgetClass;
128 	    else if (i < N_BUTTON + N_TOGGLE)
129 	      Class = toggleWidgetClass;
130 	    else
131 	      Class = dialogWidgetClass;
132 
133 	    side->ui->print_cmds[i] =
134 	      XtVaCreateManagedWidget (w_table[i].name, Class, w_form,
135 				       NULL);
136 	    if (w_table[i].newline) {
137 		w_oldup = w_up;
138 		w_up = side->ui->print_cmds[i];
139 		w_left = NULL;
140 	    }
141 	    XtVaSetValues(side->ui->print_cmds[i],
142 			  XtNfromVert, w_oldup,
143 			  XtNfromHoriz, w_left,
144 			  NULL);
145 	    w_left = side->ui->print_cmds[i];
146 
147 	    if (strcmp(w_table[i].name, "metric") == 0) {
148 		XtAddCallback (side->ui->print_cmds[i], XtNcallback,
149 			       metric_convert_callback, NULL);
150 		side->ui->i_metric = i;
151 	    }
152 	    /* yes, we really need to cast commandWidgetClass into WidgetClass */
153 	    if (Class == (WidgetClass) commandWidgetClass) {
154 		XtAddCallback (side->ui->print_cmds[i], XtNcallback,
155 			       print_setup_button_callback, NULL);
156 	    }
157 	}
158 
159 	XtRealizeWidget (side->ui->print_shell);
160     }
161 
162     /* unelegant... */
163     side->ui->choi[ 0] = side->ui->ps_pp->names;
164     side->ui->flag[ 0] = side->ui->ps_pp->corner_coord;
165     side->ui->flag[ 1] = side->ui->ps_pp->terrain_dither;
166     side->ui->flag[ 2] = side->ui->ps_pp->terrain_double;
167     side->ui->flag[ 3] = side->ui->ps_pp->features;
168     side->ui->flag[ 4] = side->ui->ps_pp->cell_summary;
169     side->ui->flag[ 5] = side->ui->ps_pp->cm;
170     side->ui->parm[ 0] = side->ui->ps_pp->cell_size;
171     side->ui->parm[ 1] = side->ui->ps_pp->cell_grid_width;
172     side->ui->parm[ 2] = side->ui->ps_pp->border_width;
173     side->ui->parm[ 3] = side->ui->ps_pp->connection_width;
174     side->ui->parm[ 4] = side->ui->ps_pp->page_width;
175     side->ui->parm[ 5] = side->ui->ps_pp->page_height;
176     side->ui->parm[ 6] = side->ui->ps_pp->top_margin;
177     side->ui->parm[ 7] = side->ui->ps_pp->bottom_margin;
178     side->ui->parm[ 8] = side->ui->ps_pp->left_margin;
179     side->ui->parm[ 9] = side->ui->ps_pp->right_margin;
180     side->ui->parm[10] = side->ui->ps_pp->terrain_gray;
181     side->ui->parm[11] = side->ui->ps_pp->enemy_gray;
182     update_values(side);
183 
184     XtPopup(side->ui->print_shell, XtGrabNone);
185 
186     return 0;
187 }
188 
189 static void
print_ok(Side * side)190 print_ok(Side *side)
191 {
192     double conv;
193 
194     /* unelegant... */
195     side->ui->ps_pp->names =		side->ui->choi[ 0];
196     side->ui->ps_pp->corner_coord =		side->ui->flag[ 0];
197     side->ui->ps_pp->terrain_dither =	side->ui->flag[ 1];
198     side->ui->ps_pp->terrain_double =	side->ui->flag[ 2];
199     side->ui->ps_pp->features =		side->ui->flag[ 3];
200     side->ui->ps_pp->cell_summary =		side->ui->flag[ 4];
201     side->ui->ps_pp->cm =			side->ui->flag[ 5];
202     side->ui->ps_pp->cell_size =		side->ui->parm[ 0];
203     side->ui->ps_pp->cell_grid_width =	side->ui->parm[ 1];
204     side->ui->ps_pp->border_width =		side->ui->parm[ 2];
205     side->ui->ps_pp->connection_width =	side->ui->parm[ 3];
206     side->ui->ps_pp->page_width =		side->ui->parm[ 4];
207     side->ui->ps_pp->page_height =		side->ui->parm[ 5];
208     side->ui->ps_pp->top_margin =		side->ui->parm[ 6];
209     side->ui->ps_pp->bottom_margin =	side->ui->parm[ 7];
210     side->ui->ps_pp->left_margin =		side->ui->parm[ 8];
211     side->ui->ps_pp->right_margin =		side->ui->parm[ 9];
212     side->ui->ps_pp->terrain_gray =		side->ui->parm[10];
213     side->ui->ps_pp->enemy_gray =		side->ui->parm[11];
214     if (side->ui->print_shell) {
215 	XtPopdown (side->ui->print_shell);
216     }
217     if (side->ui->print_help_shell) {
218 	XtPopdown (side->ui->print_help_shell);
219     }
220     /* convert from cm or in */
221     if (side->ui->ps_pp->cm) {
222 	conv = 72/2.54;
223     } else {
224 	conv = 72;
225     }
226     side->ui->ps_pp->cell_size *= conv;
227     side->ui->ps_pp->cell_grid_width *= conv;
228     side->ui->ps_pp->border_width *= conv;
229     side->ui->ps_pp->connection_width *= conv;
230     side->ui->ps_pp->page_width *= conv;
231     side->ui->ps_pp->page_height *= conv;
232     side->ui->ps_pp->top_margin *= conv;
233     side->ui->ps_pp->bottom_margin *= conv;
234     side->ui->ps_pp->left_margin *= conv;
235     side->ui->ps_pp->right_margin *= conv;
236 
237     /* dump view */
238     notify(side, "dumping view to file \"view.xconq\" ...");
239     flush_output(side);
240     dump_ps_view(side, side->ui->ps_pp, "view.xconq");
241     notify(side, "... done.");
242 
243 }
244 
245 static void
print_skip(Side * side)246 print_skip(Side *side)
247 {
248     double conv;
249 
250     if (side->ui->print_shell)
251       XtPopdown (side->ui->print_shell);
252     if (side->ui->print_help_shell)
253       XtPopdown (side->ui->print_help_shell);
254 
255     /* Convert from cm or in. */
256     conv = 72;
257     if (side->ui->ps_pp->cm)
258       conv /= 2.54;
259 
260     side->ui->ps_pp->cell_size *= conv;
261     side->ui->ps_pp->cell_grid_width *= conv;
262     side->ui->ps_pp->border_width *= conv;
263     side->ui->ps_pp->connection_width *= conv;
264     side->ui->ps_pp->page_width *= conv;
265     side->ui->ps_pp->page_height *= conv;
266     side->ui->ps_pp->top_margin *= conv;
267     side->ui->ps_pp->bottom_margin *= conv;
268     side->ui->ps_pp->left_margin *= conv;
269     side->ui->ps_pp->right_margin *= conv;
270 }
271 
272 static void
update_values(Side * side)273 update_values(Side *side)
274 {
275     char buffer[80];
276     int i;
277     char flg;
278     Arg args[1];
279 
280     for (i = 0; i < N_CHOICE; i++) {
281 	XtSetArg(args[0], XtNlabel,
282 		 (XtArgVal) choices[i].legends[side->ui->choi[i]]);
283 	XtSetValues(side->ui->print_cmds[i + N_COMMAND], args, 1);
284     }
285     for (i = 0; i < N_TOGGLE; i++) {
286 	flg = side->ui->flag[i];
287 	XtSetArg(args[0], XtNstate, (XtArgVal) flg);
288 	XtSetValues(side->ui->print_cmds[i + N_BUTTON], args, 1);
289     }
290     for (i = 0; i < N_DIALOG; i++) {
291 	sprintf(buffer, "%.11g", side->ui->parm[i]);
292 	XtSetArg(args[0], XtNvalue, (XtArgVal) buffer);
293 	XtSetValues(side->ui->print_cmds[i + N_BUTTON + N_TOGGLE], args, 1);
294     }
295 }
296 
297 static int
w_comm_ind(Side * side,Widget w)298 w_comm_ind(Side *side, Widget w)
299 {
300     int i;
301 
302     for (i = 0; i <= N_WIDGET; i++) {
303 	if (w == side->ui->print_cmds[i])
304 	  return i;
305     }
306     fprintf(stderr, "w_comm_ind: widget not found\n");
307     return -1;
308 }
309 
310 static void
handle_do_print_dialog(Widget w,XEvent * event,String * params,Cardinal * numparms)311 handle_do_print_dialog(Widget w, XEvent *event, String *params, Cardinal *numparms)
312 {
313     Side *side;
314 
315     if (!find_side_via_widget(w, &side))
316       return;
317 
318     read_all(side);
319     update_values(side);
320 }
321 
322 static void
read_all(Side * side)323 read_all(Side *side)
324 {
325     String string;
326     int i;
327     double result;
328     char flg;
329     Arg args[1];
330 
331     for (i = 0; i < N_TOGGLE; i++) {
332 	XtSetArg(args[0], XtNstate, (XtArgVal) &flg);
333 	XtGetValues(side->ui->print_cmds[i + N_BUTTON], args, 1);
334 	side->ui->flag[i] = flg;
335     }
336     for (i = 0; i < N_DIALOG; i++) {
337 	string = XawDialogGetValueString(side->ui->print_cmds[i + N_BUTTON + N_TOGGLE]);
338 	sscanf(string, "%lf", &result);
339 	side->ui->parm[i] = result;
340     }
341 }
342 
343 static void
print_setup_button_callback(Widget w,XtPointer client_data,XtPointer call_data)344 print_setup_button_callback(Widget w, XtPointer client_data, XtPointer call_data)
345 {
346     int i;
347     Side *side;
348 
349     if (!find_side_via_widget(w, &side))
350       return;
351 
352     i = w_comm_ind(side, w);
353 
354     read_all(side);
355 
356     if (i == 0) {
357 	open_print_help(side);
358     } else if (i == 1) {
359 	print_ok(side);
360     } else if (i == 2) {
361         print_skip(side);
362     } else if (i >= N_COMMAND) {
363 	i -= N_COMMAND;
364 	side->ui->choi[i] = (side->ui->choi[i] + 1) % choices[i].number;
365     }
366     update_values(side);
367 }
368 
369 /* Convert in to cm, or vice versa. */
370 
371 static void
metric_convert_callback(Widget w,XtPointer client_data,XtPointer call_data)372 metric_convert_callback(Widget w, XtPointer client_data, XtPointer call_data)
373 {
374     char flg;
375     int i;
376     double conv;
377     Arg args[1];
378     Side *side;
379 
380     if (!find_side_via_widget(w, &side))
381       return;
382 
383     XtSetArg(args[0], XtNstate, (XtArgVal) &flg);
384     XtGetValues(side->ui->print_cmds[side->ui->i_metric], args, 1);
385     conv = flg ? 2.54 : (1 / 2.54);
386     read_all(side);
387     for (i = 0; i < N_DIMEN_D; i++) {
388 	side->ui->parm[i] *= conv;
389     }
390     update_values(side);
391 }
392 
393 static void
open_print_help(Side * side)394 open_print_help(Side *side)
395 {
396     Widget w_form, w_done, w_text;
397 
398     if (!side->ui->print_help_shell) {
399 	/* If first time, create it. */
400 	side->ui->print_help_shell =
401 	  XtVaCreatePopupShell("PrintSetupHelp", topLevelShellWidgetClass,
402 			       side->ui->shell,
403 			       NULL);
404 	w_form =
405 	  XtVaCreateManagedWidget("helpForm", formWidgetClass, side->ui->print_help_shell,
406 				  NULL);
407 	w_text =
408 	  XtVaCreateManagedWidget("helpText", labelWidgetClass, w_form,
409 				  XtNlabel, helpText,
410 				  NULL);
411 	w_done =
412 	  XtVaCreateManagedWidget("helpDone", commandWidgetClass, w_form,
413 				  XtNfromVert, w_text,
414 				  NULL);
415 	XtAddCallback(w_done, XtNcallback, done_print_help_callback, NULL);
416     }
417 
418     XtPopup(side->ui->print_help_shell, XtGrabNone);
419 }
420 
421 static void
done_print_help_callback(Widget w,XtPointer client_data,XtPointer call_data)422 done_print_help_callback(Widget w, XtPointer client_data, XtPointer call_data)
423 {
424     Side *side;
425 
426     if (!find_side_via_widget(w, &side))
427       return;
428 
429     if (side->ui->print_help_shell)
430       XtPopdown(side->ui->print_help_shell);
431 }
432 
433 
434 static void
handle_done_print_help(Widget w,XEvent * event,String * params,Cardinal * numparms)435 handle_done_print_help(Widget w, XEvent *event, String *params, Cardinal *numparms)
436 {
437     Side *side;
438 
439     if (!find_side_via_widget(w, &side))
440       return;
441 
442     if (side->ui->print_help_shell)
443       XtPopdown(side->ui->print_help_shell);
444 }
445