1
//------------------------------------------------------------------------
2
// DIALOG : Unix/FLTK Pop-up dialogs
3
//------------------------------------------------------------------------
5
// GL-Friendly Node Builder (C) 2000-2005 Andrew Apted
7
// Based on 'BSP 2.3' by Colin Reed, Lee Killough and others.
9
// This program is free software; you can redistribute it and/or
10
// modify it under the terms of the GNU General Public License
11
// as published by the Free Software Foundation; either version 2
12
// of the License, or (at your option) any later version.
14
// This program is distributed in the hope that it will be useful,
15
// but WITHOUT ANY WARRANTY; without even the implied warranty of
16
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
// GNU General Public License for more details.
19
//------------------------------------------------------------------------
21
// this includes everything we need
25
Fl_Image *about_image;
26
Fl_Pixmap *pldie_image;
27
Fl_Pixmap *skull_image;
29
static unsigned char *about_image_rgb;
32
static Fl_Window *cur_diag;
33
static int cur_diag_result;
34
static boolean_g cur_diag_done;
35
static const char *cur_diag_guess_name;
38
static void UncompressAboutImage(unsigned char *& rgb)
40
int rgb_size = ABOUT_IMG_W * ABOUT_IMG_H * 3;
42
rgb = new unsigned char [rgb_size];
45
const unsigned char *src = about_image_data;
46
unsigned char *dest = rgb;
48
while (dest < (rgb + rgb_size))
52
*dest++ = about_image_pal[val*3 + 0]; // red
53
*dest++ = about_image_pal[val*3 + 1]; // green
54
*dest++ = about_image_pal[val*3 + 2]; // blue
62
// Should be called after WindowStartup.
64
void DialogLoadImages(void)
66
pldie_image = new Fl_Pixmap(pldie_image_data);
67
skull_image = new Fl_Pixmap(skull_image_data);
71
UncompressAboutImage(about_image_rgb);
73
about_image = new Fl_RGB_Image(about_image_rgb,
74
ABOUT_IMG_W, ABOUT_IMG_H, 3, (ABOUT_IMG_W * 3));
80
void DialogFreeImages(void)
83
delete[] about_image_rgb;
91
//------------------------------------------------------------------------
93
static void dialog_closed_CB(Fl_Widget *w, void *data)
99
static void dialog_left_button_CB(Fl_Widget *w, void *data)
102
cur_diag_done = TRUE;
105
static void dialog_middle_button_CB(Fl_Widget *w, void *data)
108
cur_diag_done = TRUE;
111
static void dialog_right_button_CB(Fl_Widget *w, void *data)
114
cur_diag_done = TRUE;
117
static void dialog_file_browse_CB(Fl_Widget *w, void *data)
119
Fl_Input *inp_box = (Fl_Input *) data;
120
const char *new_name;
122
new_name = fl_file_chooser("Select the log file", "*.log",
129
inp_box->value(new_name);
132
static void dialog_file_guess_CB(Fl_Widget *w, void *data)
134
Fl_Input *inp_box = (Fl_Input *) data;
136
if (cur_diag_guess_name)
138
inp_box->value(cur_diag_guess_name);
144
//------------------------------------------------------------------------
146
static void DialogRun()
148
cur_diag->set_modal();
151
// read initial pos (same logic as in Guix_MainWin)
153
int init_x = cur_diag->x();
154
int init_y = cur_diag->y();
156
// run the GUI and let user make their choice
157
while (! cur_diag_done)
162
// check if the user moved/resized the window
163
if (cur_diag->x() != init_x || cur_diag->y() != init_y)
165
guix_prefs.dialog_x = cur_diag->x();
166
guix_prefs.dialog_y = cur_diag->y();
172
// DialogShowAndGetChoice
174
// The 'pic' parameter is the picture to show on the left, or NULL for
175
// none. The message can contain newlines. The right/middle/left
176
// parameters allow up to three buttons.
178
// Returns the button number pressed (0 for right, 1 for middle, 2 for
179
// left) or -1 if escape was pressed or window manually closed.
181
int DialogShowAndGetChoice(const char *title, Fl_Pixmap *pic,
182
const char *message, const char *left, // = "OK",
183
const char *middle, // = NULL,
184
const char *right) // = NULL)
186
cur_diag_result = -1;
187
cur_diag_done = FALSE;
189
int but_width = right ? (120*3) : middle ? (120*2) : (120*1);
191
// determine required size
195
// set current font for fl_measure()
196
fl_font(FL_HELVETICA, FL_NORMAL_SIZE);
198
fl_measure(message, width, height);
200
if (width < but_width)
206
width += 60 + 20 + 16; // 16 extra, just in case
207
height += 10 + 40 + 16; //
210
cur_diag = new Fl_Window(0, 0, width, height, title);
212
cur_diag->size_range(width, height, width, height);
213
cur_diag->callback((Fl_Callback *) dialog_closed_CB);
215
cur_diag->position(guix_prefs.dialog_x, guix_prefs.dialog_y);
218
Fl_Box *box = new Fl_Box(60, 0, width - 3*120, height);
220
cur_diag->resizable(box);
222
// create the image, if any
225
box = new Fl_Box(5, 10, 50, 50);
230
// create the message area
231
box = new Fl_Box(60, 10, width-60 - 20, height-10 - 40, message);
232
box->align(FL_ALIGN_LEFT | FL_ALIGN_TOP | FL_ALIGN_INSIDE | FL_ALIGN_WRAP);
238
int CX = width - 120;
239
int CY = height - 40;
243
button = new Fl_Return_Button(CX, CY, 104, 30, right);
244
button->align(FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
245
button->callback((Fl_Callback *) dialog_right_button_CB);
246
cur_diag->add(button);
253
button = new Fl_Button(CX, CY, 104, 30, middle);
254
button->align(FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
255
button->callback((Fl_Callback *) dialog_middle_button_CB);
256
cur_diag->add(button);
263
button = new Fl_Button(CX, CY, 104, 30, left);
264
button->align(FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
265
button->callback((Fl_Callback *) dialog_left_button_CB);
266
cur_diag->add(button);
274
// delete window (automatically deletes child widgets)
278
return cur_diag_result;
283
// DialogQueryFilename
285
// Shows the current filename (name_ptr) in an input box, and provides
286
// a browse button to choose a new filename, and an optional button to
287
// guess the new filename (if 'guess_name' is NULL, then the button is
290
// This routine does NOT ensure that the filename is valid (or any
291
// other requirement, e.g. has a certain extension).
293
// Returns 0 if "OK" was pressed, 1 if "Cancel" was pressed, or -1 if
294
// escape was pressed or the window was manually closed.
296
int DialogQueryFilename(const char *message,
297
const char ** name_ptr, const char *guess_name)
299
cur_diag_result = -1;
300
cur_diag_done = FALSE;
301
cur_diag_guess_name = guess_name;
303
// determine required size
307
// set current font for fl_measure()
308
fl_font(FL_HELVETICA, FL_NORMAL_SIZE);
310
fl_measure(message, width, height);
318
width += 60 + 20 + 16; // 16 extra, just in case
319
height += 60 + 50 + 16; //
322
cur_diag = new Fl_Window(0, 0, width, height, "glBSP Query");
324
cur_diag->size_range(width, height, width, height);
325
cur_diag->callback((Fl_Callback *) dialog_closed_CB);
327
cur_diag->position(guix_prefs.dialog_x, guix_prefs.dialog_y);
330
Fl_Box *box = new Fl_Box(0, height-1, width, 1);
332
cur_diag->resizable(box);
334
// create the message area
335
box = new Fl_Box(14, 10, width-20 - 20, height-10 - 100, message);
336
box->align(FL_ALIGN_LEFT | FL_ALIGN_TOP | FL_ALIGN_INSIDE | FL_ALIGN_WRAP);
341
int CX = width - 120;
342
int CY = height - 50;
347
b_cancel = new Fl_Button(CX, CY, 104, 30, "Cancel");
348
b_cancel->align(FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
349
b_cancel->callback((Fl_Callback *) dialog_middle_button_CB);
350
cur_diag->add(b_cancel);
354
b_ok = new Fl_Return_Button(CX, CY, 104, 30, "OK");
355
b_ok->align(FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
356
b_ok->callback((Fl_Callback *) dialog_left_button_CB);
365
inp_box = new Fl_Input(20, CY, CX - 20 - 90, 26);
366
inp_box->value(*name_ptr);
367
cur_diag->add(inp_box);
369
// create the browse and guess button
373
b_guess = new Fl_Button(CX, CY, 70, 26, "Guess");
374
b_guess->align(FL_ALIGN_INSIDE);
375
b_guess->callback((Fl_Callback *) dialog_file_guess_CB, inp_box);
376
cur_diag->add(b_guess);
380
b_browse = new Fl_Button(CX, CY, 80, b_guess->h(), "Browse");
381
b_browse->align(FL_ALIGN_INSIDE);
382
b_browse->callback((Fl_Callback *) dialog_file_browse_CB, inp_box);
383
cur_diag->add(b_browse);
388
if (cur_diag_result == 0)
390
GlbspFree(*name_ptr);
392
*name_ptr = GlbspStrDup(inp_box->value());
395
// delete window (automatically deletes child widgets)
399
return cur_diag_result;
406
// Terminates the program reporting an error.
408
void GUI_FatalError(const char *str, ...)
418
vsprintf(main_err, str, args);
421
// remove leading and trailing whitespace
422
int len = strlen(main_err);
424
for (; len > 0 && isspace(main_err[len-1]); len--)
429
for (m_ptr = main_err; isspace(*m_ptr); m_ptr++)
430
{ /* nothing else needed */ }
432
if (HelperCaseCmpLen(m_ptr, "Error: ", 7) == 0)
436
"The following unexpected error occurred:\n"
440
"This may indicate a serious problem within the WAD you "
441
"were trying to build the nodes for. Check that the WAD "
442
"file isn't corrupt.\n"
444
"glBSPX will now shut down.",
447
DialogShowAndGetChoice("glBSP Fatal Error", pldie_image, buffer);
450
// A/ no, we save them before each build begins.