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