Reimplemented CreateBitmapOptionChoice
[grace.git] / src / project_ui.c
blob90c1ec059ce4600c4b01022b165df35e961cb327
1 /*
2 * Grace - GRaphing, Advanced Computation and Exploration of data
3 *
4 * Home page: http://plasma-gate.weizmann.ac.il/Grace/
5 *
6 * Copyright (c) 1996-2004 Grace Development Team
7 *
8 * Maintained by Evgeny Stambulchik
9 *
11 * All Rights Reserved
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 /* Project UI */
30 #include <stdlib.h>
32 #include "explorer.h"
33 #include "utils.h"
34 #include "xprotos.h"
36 static void wrap_year_cb(Widget but, int onoff, void *data)
38 Widget wrap_year = (Widget) data;
40 WidgetSetSensitive(wrap_year, onoff);
43 #define PAGE_UNITS_PP 0
44 #define PAGE_UNITS_IN 1
45 #define PAGE_UNITS_CM 2
47 static void do_format_toggle(OptionStructure *opt, int value, void *data)
49 ProjectUI *ui = (ProjectUI *) data;
50 int orientation;
51 double px, py;
52 int page_units;
53 char buf[32];
55 if (value == PAGE_FORMAT_CUSTOM) {
56 WidgetSetSensitive(ui->page_x->form, TRUE);
57 WidgetSetSensitive(ui->page_y->form, TRUE);
58 WidgetSetSensitive(ui->page_orient->menu, FALSE);
59 return;
60 } else {
61 WidgetSetSensitive(ui->page_x->form, FALSE);
62 WidgetSetSensitive(ui->page_y->form, FALSE);
63 WidgetSetSensitive(ui->page_orient->menu, TRUE);
66 switch (value) {
67 case PAGE_FORMAT_USLETTER:
68 px = 612.0;
69 py = 792.0;
70 break;
71 case PAGE_FORMAT_A4:
72 px = 595.0;
73 py = 842.0;
74 break;
75 default:
76 return;
80 page_units = GetOptionChoice(ui->page_size_unit);
81 orientation = GetOptionChoice(ui->page_orient);
83 switch (page_units) {
84 case PAGE_UNITS_IN:
85 px /= 72.0;
86 py /= 72.0;
87 break;
88 case PAGE_UNITS_CM:
89 px /= 72.0/CM_PER_INCH;
90 py /= 72.0/CM_PER_INCH;
91 break;
94 if ((orientation == PAGE_ORIENT_LANDSCAPE && px > py) ||
95 (orientation == PAGE_ORIENT_PORTRAIT && px < py) ) {
96 sprintf (buf, "%.2f", px);
97 TextSetString(ui->page_x, buf);
98 sprintf (buf, "%.2f", py);
99 TextSetString(ui->page_y, buf);
100 } else {
101 sprintf (buf, "%.2f", py);
102 TextSetString(ui->page_x, buf);
103 sprintf (buf, "%.2f", px);
104 TextSetString(ui->page_y, buf);
108 static void do_orient_toggle(OptionStructure *opt, int value, void *data)
110 ProjectUI *ui = (ProjectUI *) data;
111 double px, py;
112 char buf[32];
113 int orientation = value;
115 if (xv_evalexpr(ui->page_x, &px) != RETURN_SUCCESS ||
116 xv_evalexpr(ui->page_y, &py) != RETURN_SUCCESS ) {
117 errmsg("Invalid page dimension(s)");
118 return;
121 if ((orientation == PAGE_ORIENT_LANDSCAPE && px < py) ||
122 (orientation == PAGE_ORIENT_PORTRAIT && px > py) ) {
123 sprintf (buf, "%.2f", py);
124 TextSetString(ui->page_x, buf);
125 sprintf (buf, "%.2f", px);
126 TextSetString(ui->page_y, buf);
130 static void do_units_toggle(OptionStructure *opt, int value, void *data)
132 ProjectUI *ui = (ProjectUI *) data;
133 char buf[32];
134 double page_x, page_y;
135 int page_units = value;
137 if (xv_evalexpr(ui->page_x, &page_x) != RETURN_SUCCESS ||
138 xv_evalexpr(ui->page_y, &page_y) != RETURN_SUCCESS ) {
139 errmsg("Invalid page dimension(s)");
140 return;
143 if (ui->current_page_units == page_units) {
144 return;
147 switch (ui->current_page_units) {
148 case PAGE_UNITS_IN:
149 page_x *= 72.0;
150 page_y *= 72.0;
151 break;
152 case PAGE_UNITS_CM:
153 page_x *= 72.0/CM_PER_INCH;
154 page_y *= 72.0/CM_PER_INCH;
155 break;
158 switch (page_units) {
159 case PAGE_UNITS_IN:
160 page_x /= 72.0;
161 page_y /= 72.0;
162 break;
163 case PAGE_UNITS_CM:
164 page_x /= 72.0/CM_PER_INCH;
165 page_y /= 72.0/CM_PER_INCH;
166 break;
169 ui->current_page_units = page_units;
171 sprintf (buf, "%.2f", page_x);
172 TextSetString(ui->page_x, buf);
173 sprintf (buf, "%.2f", page_y);
174 TextSetString(ui->page_y, buf);
177 ProjectUI *create_project_ui(ExplorerUI *eui)
179 ProjectUI *ui;
180 Widget form, fr, rc, rc1;
182 form = CreateVContainer(eui->scrolled_window);
183 AddHelpCB(form, "doc/UsersGuide.html#project-properties");
185 ui = xmalloc(sizeof(ProjectUI));
186 ui->current_page_units = PAGE_UNITS_PP;
188 fr = CreateFrame(form, "Project description");
189 ui->description = CreateScrolledText(fr, "", 5);
190 AddTextActivateCB(ui->description, text_explorer_cb, eui);
192 fr = CreateFrame(form, "Page dimensions");
193 rc1 = CreateVContainer(fr);
195 rc = CreateHContainer(rc1);
196 ui->page_orient = CreatePaperOrientationChoice(rc, "Orientation:");
197 AddOptionChoiceCB(ui->page_orient, do_orient_toggle, ui);
198 AddOptionChoiceCB(ui->page_orient, oc_explorer_cb, eui);
200 ui->page_format = CreatePaperFormatChoice(rc, "Size:");
201 AddOptionChoiceCB(ui->page_format, do_format_toggle, ui);
202 AddOptionChoiceCB(ui->page_format, oc_explorer_cb, eui);
204 rc = CreateHContainer(rc1);
205 ui->page_x = CreateText2(rc, "Dimensions:", 7);
206 AddTextActivateCB(ui->page_x, text_explorer_cb, eui);
207 ui->page_y = CreateText2(rc, "x ", 7);
208 AddTextActivateCB(ui->page_y, text_explorer_cb, eui);
209 ui->page_size_unit = CreateOptionChoiceVA(rc, " ",
210 "pp", PAGE_UNITS_PP,
211 "in", PAGE_UNITS_IN,
212 "cm", PAGE_UNITS_CM,
213 NULL);
214 SetOptionChoice(ui->page_size_unit, ui->current_page_units);
215 AddOptionChoiceCB(ui->page_size_unit, do_units_toggle, ui);
218 fr = CreateFrame(form, "Page background");
219 FormAddVChild(form, fr);
220 rc = CreateHContainer(fr);
221 ui->bg_color = CreateColorChoice(rc, "Color:");
222 AddOptionChoiceCB(ui->bg_color, oc_explorer_cb, eui);
223 ui->bg_fill = CreateToggleButton(rc, "Fill");
224 AddToggleButtonCB(ui->bg_fill, tb_explorer_cb, eui);
226 fr = CreateFrame(form, "Scaling factors");
227 FormAddVChild(form, fr);
228 rc = CreateVContainer(fr);
229 ui->fsize_scale = CreateSpinChoice(rc, "Font size:", 5,
230 SPIN_TYPE_FLOAT, 0.0, 1.0, 0.005);
231 AddSpinChoiceCB(ui->fsize_scale, sp_explorer_cb, eui);
232 ui->lwidth_scale = CreateSpinChoice(rc, "Line width:", 6,
233 SPIN_TYPE_FLOAT, 0.0, 1.0, 0.0005);
234 AddSpinChoiceCB(ui->lwidth_scale, sp_explorer_cb, eui);
236 fr = CreateFrame(form, "Data & Dates");
237 rc1 = CreateVContainer(fr);
238 ui->prec = CreateSpinChoice(rc1, "Data precision:", 3,
239 SPIN_TYPE_INT, DATA_PREC_MIN, DATA_PREC_MAX, 1);
240 AddSpinChoiceCB(ui->prec, sp_explorer_cb, eui);
241 ui->refdate = CreateText2(rc1, "Reference date:", 20);
242 AddTextActivateCB(ui->refdate, text_explorer_cb, eui);
243 rc = CreateHContainer(rc1);
244 ui->two_digits_years = CreateToggleButton(rc, "Two-digit year span");
245 AddToggleButtonCB(ui->two_digits_years, tb_explorer_cb, eui);
246 ui->wrap_year = CreateText2(rc, "Wrap year:", 4);
247 AddTextActivateCB(ui->wrap_year, text_explorer_cb, eui);
248 AddToggleButtonCB(ui->two_digits_years, wrap_year_cb, ui->wrap_year->form);
250 ui->top = form;
252 return ui;
255 void update_project_ui(ProjectUI *ui, Quark *q)
257 Project *pr = project_get_data(q);
258 if (pr) {
259 int y, m, d, h, mm, sec;
260 char date_string[64], wrap_year_string[64], buf[32];
261 double factor;
262 int format;
264 SpinChoiceSetValue(ui->prec, project_get_prec(q));
265 TextSetString(ui->description, project_get_description(q));
267 switch (GetOptionChoice(ui->page_size_unit)) {
268 case PAGE_UNITS_IN:
269 factor = 1.0/72.0;
270 break;
271 case PAGE_UNITS_CM:
272 factor = CM_PER_INCH/72.0;
273 break;
274 default:
275 factor = 1.0;
278 sprintf (buf, "%.2f", factor*pr->page_wpp);
279 TextSetString(ui->page_x, buf);
280 sprintf (buf, "%.2f", factor*pr->page_hpp);
281 TextSetString(ui->page_y, buf);
283 if ((pr->page_wpp == 612 && pr->page_hpp == 792) ||
284 (pr->page_hpp == 612 && pr->page_wpp == 792)) {
285 format = PAGE_FORMAT_USLETTER;
286 } else
287 if ((pr->page_wpp == 595 && pr->page_hpp == 842) ||
288 (pr->page_hpp == 595 && pr->page_wpp == 842)) {
289 format = PAGE_FORMAT_A4;
290 } else {
291 format = PAGE_FORMAT_CUSTOM;
293 if (format == PAGE_FORMAT_CUSTOM) {
294 WidgetSetSensitive(ui->page_x->form, TRUE);
295 WidgetSetSensitive(ui->page_y->form, TRUE);
296 WidgetSetSensitive(ui->page_orient->menu, FALSE);
297 } else {
298 WidgetSetSensitive(ui->page_x->form, FALSE);
299 WidgetSetSensitive(ui->page_y->form, FALSE);
300 WidgetSetSensitive(ui->page_orient->menu, TRUE);
302 SetOptionChoice(ui->page_format, format);
304 if (pr->page_wpp > pr->page_hpp) {
305 SetOptionChoice(ui->page_orient, PAGE_ORIENT_LANDSCAPE);
306 } else {
307 SetOptionChoice(ui->page_orient, PAGE_ORIENT_PORTRAIT);
310 SetOptionChoice(ui->bg_color, pr->bgcolor);
311 ToggleButtonSetState(ui->bg_fill, pr->bgfill);
313 SpinChoiceSetValue(ui->fsize_scale, pr->fscale);
314 SpinChoiceSetValue(ui->lwidth_scale, pr->lscale);
316 jdate_to_datetime(q, 0.0, ROUND_SECOND, &y, &m, &d, &h, &mm, &sec);
317 sprintf(date_string, "%d-%02d-%02d %02d:%02d:%02d",
318 y, m, d, h, mm, sec);
319 TextSetString(ui->refdate, date_string);
320 ToggleButtonSetState(ui->two_digits_years, pr->two_digits_years);
321 sprintf(wrap_year_string, "%04d", pr->wrap_year);
322 TextSetString(ui->wrap_year, wrap_year_string);
323 WidgetSetSensitive(ui->wrap_year->form, pr->two_digits_years ? TRUE:FALSE);
327 int set_project_data(ProjectUI *ui, Quark *q, void *caller)
329 Project *pr = project_get_data(q);
330 int retval = RETURN_SUCCESS;
332 if (ui && pr) {
333 GraceApp *gapp = gapp_from_quark(q);
334 double jul;
336 if (!caller || caller == ui->prec) {
337 project_set_prec(q, SpinChoiceGetValue(ui->prec));
339 if (!caller || caller == ui->description) {
340 char *s = TextGetString(ui->description);
341 project_set_description(q, s);
342 xfree(s);
345 if (caller == ui->page_orient) {
346 int wpp, hpp;
347 int orientation = GetOptionChoice(ui->page_orient);
348 project_get_page_dimensions(q, &wpp, &hpp);
349 if ((orientation == PAGE_ORIENT_LANDSCAPE && wpp < hpp) ||
350 (orientation == PAGE_ORIENT_PORTRAIT && wpp > hpp)) {
351 set_page_dimensions(gapp, hpp, wpp, TRUE);
354 if (caller == ui->page_format) {
355 int wpp, hpp;
356 int orientation = GetOptionChoice(ui->page_orient);
357 int format = GetOptionChoice(ui->page_format);
358 GraceApp *gapp = gapp_from_quark(q);
360 switch (format) {
361 case PAGE_FORMAT_USLETTER:
362 wpp = 792.0;
363 hpp = 612.0;
364 break;
365 case PAGE_FORMAT_A4:
366 wpp = 842.0;
367 hpp = 595.0;
368 break;
369 default:
370 return RETURN_SUCCESS;
373 if (orientation == PAGE_ORIENT_PORTRAIT) {
374 iswap(&wpp, &hpp);
377 set_page_dimensions(gapp, wpp, hpp, TRUE);
380 if (!caller || caller == ui->page_x || caller == ui->page_y) {
381 int page_units = GetOptionChoice(ui->page_size_unit);
382 double factor, page_x, page_y;
383 GraceApp *gapp = gapp_from_quark(q);
385 if (xv_evalexpr(ui->page_x, &page_x) != RETURN_SUCCESS ||
386 xv_evalexpr(ui->page_y, &page_y) != RETURN_SUCCESS) {
387 errmsg("Invalid page dimension(s)");
388 return RETURN_FAILURE;
391 switch (page_units) {
392 case PAGE_UNITS_IN:
393 factor = 72.0;
394 break;
395 case PAGE_UNITS_CM:
396 factor = 72.0/CM_PER_INCH;
397 break;
398 default:
399 factor = 1.0;
400 break;
403 page_x *= factor;
404 page_y *= factor;
406 set_page_dimensions(gapp, (int) rint(page_x), (int) rint(page_y),
407 TRUE);
410 if (!caller || caller == ui->bg_color) {
411 pr->bgcolor = GetOptionChoice(ui->bg_color);
413 if (!caller || caller == ui->bg_fill) {
414 pr->bgfill = ToggleButtonGetState(ui->bg_fill);
417 if (!caller || caller == ui->fsize_scale) {
418 pr->fscale = SpinChoiceGetValue(ui->fsize_scale);
420 if (!caller || caller == ui->lwidth_scale) {
421 pr->lscale = SpinChoiceGetValue(ui->lwidth_scale);
424 if (!caller || caller == ui->refdate) {
425 char *s = TextGetString(ui->refdate);
426 if (parse_date_or_number(q, s, TRUE,
427 get_date_hint(gapp), &jul) == RETURN_SUCCESS) {
428 pr->ref_date = jul;
429 } else {
430 errmsg("Invalid date");
431 retval = RETURN_FAILURE;
433 xfree(s);
435 if (!caller || caller == ui->two_digits_years) {
436 pr->two_digits_years = ToggleButtonGetState(ui->two_digits_years);
438 if (!caller || caller == ui->wrap_year) {
439 char *s = TextGetString(ui->wrap_year);
440 pr->wrap_year = atoi(s);
441 xfree(s);
444 quark_dirtystate_set(q, TRUE);
447 return retval;