1
//------------------------------------------------------------------------
2
// DIALOG : Pop-up dialog boxes
3
//------------------------------------------------------------------------
5
// GL-Node Viewer (C) 2004-2007 Andrew Apted
7
// This program is free software; you can redistribute it and/or
8
// modify it under the terms of the GNU General Public License
9
// as published by the Free Software Foundation; either version 2
10
// of the License, or (at your option) any later version.
12
// This program is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
// GNU General Public License for more details.
17
//------------------------------------------------------------------------
19
// this includes everything we need
23
static Fl_Window *cur_diag;
24
static int cur_diag_result;
25
static bool cur_diag_done;
26
static const char *cur_diag_guess_name;
28
static int pref_dialog_x = -1;
29
static int pref_dialog_y = -1;
32
static void dialog_closed_CB(Fl_Widget *w, void *data)
38
static void dialog_left_button_CB(Fl_Widget *w, void *data)
44
static void dialog_middle_button_CB(Fl_Widget *w, void *data)
50
static void dialog_right_button_CB(Fl_Widget *w, void *data)
56
static void dialog_file_browse_CB(Fl_Widget *w, void *data)
58
Fl_Input *inp_box = (Fl_Input *) data;
61
new_name = fl_file_chooser("Select the log file", "*.log",
68
inp_box->value(new_name);
71
static void dialog_file_guess_CB(Fl_Widget *w, void *data)
73
Fl_Input *inp_box = (Fl_Input *) data;
75
if (cur_diag_guess_name)
77
inp_box->value(cur_diag_guess_name);
82
//------------------------------------------------------------------------
84
static void DialogRun()
86
cur_diag->set_modal();
89
// read initial pos (same logic as in Guix_MainWin)
91
int init_x = cur_diag->x();
92
int init_y = cur_diag->y();
94
// run the GUI and let user make their choice
95
while (! cur_diag_done)
100
// check if the user moved/resized the window
101
if (cur_diag->x() != init_x || cur_diag->y() != init_y)
103
pref_dialog_x = cur_diag->x();
104
pref_dialog_y = cur_diag->y();
110
// DialogShowAndGetChoice
112
// The `pic' parameter is the picture to show on the left, or NULL for
113
// none. The message can contain newlines. The right/middle/left
114
// parameters allow up to three buttons.
116
// Returns the button number pressed (0 for right, 1 for middle, 2 for
117
// left) or -1 if escape was pressed or window manually closed.
119
int DialogShowAndGetChoice(const char *title, Fl_Pixmap *pic,
120
const char *message, const char *left, // = "OK",
121
const char *middle, // = NULL,
122
const char *right) // = NULL)
124
cur_diag_result = -1;
125
cur_diag_done = false;
127
int but_width = right ? (120*3) : middle ? (120*2) : (120*1);
129
// determine required size
133
// set current font for fl_measure()
134
fl_font(FL_HELVETICA, FL_NORMAL_SIZE);
136
fl_measure(message, width, height);
138
if (width < but_width)
144
width += 60 + 20 + 16; // 16 extra, just in case
145
height += 10 + 40 + 16; //
148
cur_diag = new Fl_Window(0, 0, width, height, title);
150
cur_diag->size_range(width, height, width, height);
151
cur_diag->callback((Fl_Callback *) dialog_closed_CB);
153
if (pref_dialog_x >= 0)
154
cur_diag->position(pref_dialog_x, pref_dialog_y);
157
Fl_Box *box = new Fl_Box(60, 0, width - 3*120, height);
159
cur_diag->resizable(box);
161
// create the image, if any
164
box = new Fl_Box(5, 10, 50, 50);
169
// create the message area
170
box = new Fl_Box(60, 10, width-60 - 20, height-10 - 40, message);
171
box->align(FL_ALIGN_LEFT | FL_ALIGN_TOP | FL_ALIGN_INSIDE | FL_ALIGN_WRAP);
177
int CX = width - 120;
178
int CY = height - 40;
182
button = new Fl_Return_Button(CX, CY, 104, 30, right);
183
button->align(FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
184
button->callback((Fl_Callback *) dialog_right_button_CB);
185
cur_diag->add(button);
192
button = new Fl_Button(CX, CY, 104, 30, middle);
193
button->align(FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
194
button->callback((Fl_Callback *) dialog_middle_button_CB);
195
cur_diag->add(button);
202
button = new Fl_Button(CX, CY, 104, 30, left);
203
button->align(FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
204
button->callback((Fl_Callback *) dialog_left_button_CB);
205
cur_diag->add(button);
213
// delete window (automatically deletes child widgets)
217
return cur_diag_result;
222
// DialogQueryFilename
224
// Shows the current filename (name_ptr) in an input box, and provides
225
// a browse button to choose a new filename, and an optional button to
226
// guess the new filename (if `guess_name' is NULL, then the button is
229
// This routine does NOT ensure that the filename is valid (or any
230
// other requirement, e.g. has a certain extension).
232
// Returns 0 if "OK" was pressed, 1 if "Cancel" was pressed, or -1 if
233
// escape was pressed or the window was manually closed.
235
int DialogQueryFilename(const char *message,
236
const char ** name_ptr, const char *guess_name)
238
cur_diag_result = -1;
239
cur_diag_done = false;
240
cur_diag_guess_name = guess_name;
242
// determine required size
246
// set current font for fl_measure()
247
fl_font(FL_HELVETICA, FL_NORMAL_SIZE);
249
fl_measure(message, width, height);
257
width += 60 + 20 + 16; // 16 extra, just in case
258
height += 60 + 50 + 16; //
261
cur_diag = new Fl_Window(0, 0, width, height, PROG_NAME " Query");
263
cur_diag->size_range(width, height, width, height);
264
cur_diag->callback((Fl_Callback *) dialog_closed_CB);
266
if (pref_dialog_x >= 0)
267
cur_diag->position(pref_dialog_x, pref_dialog_y);
270
Fl_Box *box = new Fl_Box(0, height-1, width, 1);
272
cur_diag->resizable(box);
274
// create the message area
275
box = new Fl_Box(14, 10, width-20 - 20, height-10 - 100, message);
276
box->align(FL_ALIGN_LEFT | FL_ALIGN_TOP | FL_ALIGN_INSIDE | FL_ALIGN_WRAP);
281
int CX = width - 120;
282
int CY = height - 50;
287
b_cancel = new Fl_Button(CX, CY, 104, 30, "Cancel");
288
b_cancel->align(FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
289
b_cancel->callback((Fl_Callback *) dialog_middle_button_CB);
290
cur_diag->add(b_cancel);
294
b_ok = new Fl_Return_Button(CX, CY, 104, 30, "OK");
295
b_ok->align(FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
296
b_ok->callback((Fl_Callback *) dialog_left_button_CB);
305
inp_box = new Fl_Input(20, CY, CX - 20 - 90, 26);
306
inp_box->value(*name_ptr);
307
cur_diag->add(inp_box);
309
// create the browse and guess button
313
b_guess = new Fl_Button(CX, CY, 70, 26, "Guess");
314
b_guess->align(FL_ALIGN_INSIDE);
315
b_guess->callback((Fl_Callback *) dialog_file_guess_CB, inp_box);
316
cur_diag->add(b_guess);
320
b_browse = new Fl_Button(CX, CY, 80, b_guess->h(), "Browse");
321
b_browse->align(FL_ALIGN_INSIDE);
322
b_browse->callback((Fl_Callback *) dialog_file_browse_CB, inp_box);
323
cur_diag->add(b_browse);
328
if (cur_diag_result == 0)
330
UtilFree((void *) *name_ptr);
332
*name_ptr = UtilStrDup(inp_box->value());
335
// delete window (automatically deletes child widgets)
339
return cur_diag_result;
346
// Terminates the program reporting an error.
348
void GUI_FatalError(const char *str, ...)
358
vsprintf(main_err, str, args);
361
// remove leading and trailing whitespace
362
int len = strlen(main_err);
364
for (; len > 0 && isspace(main_err[len-1]); len--)
369
for (m_ptr = main_err; isspace(*m_ptr); m_ptr++)
370
{ /* nothing else needed */ }
373
"The following unexpected error occurred:\n"
377
PROG_NAME " will now shut down.",
380
DialogShowAndGetChoice(PROG_NAME " Fatal Error", 0, buffer);
383
// A/ no, we save them before each build begins.