]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/gtkgensurf/gendlgs.cpp
reformat code! now the code is only ugly on the *inside*
[xonotic/netradiant.git] / contrib / gtkgensurf / gendlgs.cpp
1 /*
2    GenSurf plugin for GtkRadiant
3    Copyright (C) 2001 David Hyde, Loki software and qeradiant.com
4
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with this library; if not, write to the Free Software
17    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 #include <gtk/gtk.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <math.h>
25 #include "gensurf.h"
26
27 #define GENERAL_TAB   0
28 #define EXTENTS_TAB   1
29 #define BITMAP_TAB    2
30 #define FIXPOINTS_TAB 3
31 #define TEXTURE_TAB   4
32 //#define BUFF_SIZE     32768
33
34 #define ENABLE_WIDGET(name, enable) \
35     gtk_widget_set_sensitive( g_object_get_data( G_OBJECT( g_pWnd , ( name ) ) ), ( enable ) )
36 #define CHECK_WIDGET(name, check) \
37     gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( g_object_get_data( G_OBJECT( g_pWnd ), name ) ), check )
38
39 static GtkWidget *game_radios[NUMGAMES];
40 static GtkWidget *wave_radios[5];
41 static GtkWidget *plane_radios[6];
42 static guint current_tab;
43 static int OldPreview;
44 static int WasDetail;
45 static GtkTooltips *tooltips;
46 static int FirstPassComplete = 0;
47
48 void About(GtkWidget *parent)
49 {
50 /*
51    char *icon_xpm[] = {
52    "32 32 4 1",
53    "    c None",
54    ".   c #000000",
55    "+   c #FFFFFF",
56    "@   c #838183",
57    "................................",
58    "................................",
59    "................................",
60    "................................",
61    "................................",
62    "................................",
63    "................................",
64    "...............++...............",
65    ".............++++++.............",
66    "............++@+++@+............",
67    "..........+++..++..+++..........",
68    "........++.+.++..++.+.@+........",
69    ".......+..+..+.++.+..+..++......",
70    ".....++..++.+..++..+.++..++.....",
71    "...++..++...+.+..+.++..++..++...",
72    "..++.+.++....++..++....++.+..+..",
73    ".+.+..+..++....++....++..++.+.+.",
74    "..+++....+.++++++++++.+....+++..",
75    "....++.@@+++++.++.++++@++.++....",
76    "......+++++++......++@+++++.....",
77    ".......+++.+.++..++.+..++.......",
78    ".........++..+.++.+..++.........",
79    "...........++..++..++...........",
80    ".............++..+.+............",
81    "..............+..+@.............",
82    "...............@@...............",
83    "................................",
84    "................................",
85    "................................",
86    "................................",
87    "................................",
88    "................................"
89    };
90  */
91     // leo: I'm too lazy to create a nice about box
92     // ^Fishman - I am lazy too :P.
93     g_FuncTable.m_pfnMessageBox(parent, "GtkGenSurf 1.05\n\n"
94                                         "Original version\n"
95                                         "David Hyde (rascal@vicksburg.com)\n\n"
96                                         "Porting\n"
97                                         "Leonardo Zide (leo@lokigames.com)\n\n"
98                                         "Enhancements\n"
99                                         "Pablo Zurita (pablo@qeradiant.com)\n"
100                                         "Hydra (hydra@hydras-world.com)",
101                                 "About GtkGenSurf", eMB_OK);
102 }
103
104 // =============================================================================
105 // main dialog
106
107 static void SetupControls()
108 {
109     switch (current_tab) {
110         case GENERAL_TAB:
111             break;
112
113         case EXTENTS_TAB:
114             if (Game != QUAKE3) {
115                 gtk_widget_hide(g_object_get_data(G_OBJECT(g_pWnd, "use_patches")));
116                 ENABLE_WIDGET("use_patches", FALSE);
117             } else {
118                 gtk_widget_show(g_object_get_data(G_OBJECT(g_pWnd, "use_patches")));
119                 ENABLE_WIDGET("use_patches", TRUE);
120             }
121
122             if (Game == QUAKE3 && UsePatches != 0) {
123                 ENABLE_WIDGET("decimate", FALSE);
124             }
125             gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "snap_text")),
126                                "Snap to grid:"); // ^Fishman - Snap to grid.
127             break;
128
129         case BITMAP_TAB:
130             if (WaveType != WAVE_BITMAP) {
131                 ENABLE_WIDGET("bmp_file", FALSE);
132                 ENABLE_WIDGET("bmp_file_browse", FALSE);
133                 ENABLE_WIDGET("bmp_black", FALSE);
134                 ENABLE_WIDGET("bmp_white", FALSE);
135                 ENABLE_WIDGET("bmp_text1", FALSE);
136                 ENABLE_WIDGET("bmp_text2", FALSE);
137                 ENABLE_WIDGET("bmp_text3", FALSE);
138                 ENABLE_WIDGET("bmp_reload", FALSE);
139                 gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "bmp_note")),
140                                    "These options are disabled unless \"From Bitmap\"\n"
141                                            "is selected as the Waveform on the General tab.");
142             } else {
143                 ENABLE_WIDGET("bmp_file", TRUE);
144                 ENABLE_WIDGET("bmp_file_browse", TRUE);
145                 ENABLE_WIDGET("bmp_black", TRUE);
146                 ENABLE_WIDGET("bmp_white", TRUE);
147                 ENABLE_WIDGET("bmp_text1", TRUE);
148                 ENABLE_WIDGET("bmp_text2", TRUE);
149                 ENABLE_WIDGET("bmp_text3", TRUE);
150                 ENABLE_WIDGET("bmp_reload", strlen(gbmp.name) != 0);
151                 gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "bmp_note")),
152                                    "GenSurf works only with 8-bit bitmaps. Color indices are\n"
153                                            "mapped to values for each vertex. Generally, gray scale\n"
154                                            "images are stored with black as color 0, white as color 255.");
155             }
156             break;
157
158         case FIXPOINTS_TAB:
159             ENABLE_WIDGET("fix_value", (NumVerticesSelected != 0));
160             ENABLE_WIDGET("fix_value_text", (NumVerticesSelected != 0));
161             ENABLE_WIDGET("fix_free", (NumVerticesSelected != 0));
162             ENABLE_WIDGET("fix_range", ((NumVerticesSelected != 0) && (WaveType != WAVE_ROUGH_ONLY)));
163             ENABLE_WIDGET("fix_range_text", ((NumVerticesSelected != 0) && (WaveType != WAVE_ROUGH_ONLY)));
164             ENABLE_WIDGET("fix_rate", ((NumVerticesSelected != 0) && (WaveType != WAVE_ROUGH_ONLY)));
165             ENABLE_WIDGET("fix_rate_text", ((NumVerticesSelected != 0) && (WaveType != WAVE_ROUGH_ONLY)));
166             break;
167
168         case TEXTURE_TAB:
169             ENABLE_WIDGET("texture2", (UsePatches == 0));
170             ENABLE_WIDGET("texture3", (UsePatches == 0));
171             ENABLE_WIDGET("tex_slant", (UsePatches == 0));
172             ENABLE_WIDGET("detail", (UsePatches == 0));
173             if (Game != QUAKE3) {
174                 ENABLE_WIDGET("terrain_ent", FALSE); // ^Fishman - Adds terrain key to func_group.
175                 ENABLE_WIDGET("hint", (UsePatches == 0));
176             }
177             break;
178     }
179
180     switch (WaveType) {
181         case WAVE_HCYLINDER:
182         case WAVE_VCYLINDER:
183             ENABLE_WIDGET("amplitude", TRUE);
184             ENABLE_WIDGET("wavelength", TRUE);
185             ENABLE_WIDGET("z00", TRUE);
186             ENABLE_WIDGET("z01", TRUE);
187             ENABLE_WIDGET("z10", TRUE);
188             ENABLE_WIDGET("z11", TRUE);
189             ENABLE_WIDGET("linearborder", TRUE);
190             ENABLE_WIDGET("go", TRUE);
191             break;
192         case WAVE_BITMAP:
193             ENABLE_WIDGET("amplitude", FALSE);
194             ENABLE_WIDGET("wavelength", FALSE);
195             ENABLE_WIDGET("z00", FALSE);
196             ENABLE_WIDGET("z01", FALSE);
197             ENABLE_WIDGET("z10", FALSE);
198             ENABLE_WIDGET("z11", FALSE);
199             ENABLE_WIDGET("linearborder", FALSE);
200             ENABLE_WIDGET("go", (gbmp.colors != NULL ? TRUE : FALSE));
201             break;
202         case WAVE_ROUGH_ONLY:
203             ENABLE_WIDGET("amplitude", FALSE);
204             ENABLE_WIDGET("wavelength", FALSE);
205             ENABLE_WIDGET("z00", TRUE);
206             ENABLE_WIDGET("z01", TRUE);
207             ENABLE_WIDGET("z10", TRUE);
208             ENABLE_WIDGET("z11", TRUE);
209             ENABLE_WIDGET("linearborder", TRUE);
210             ENABLE_WIDGET("go", TRUE);
211             break;
212         default:
213             ENABLE_WIDGET("amplitude", TRUE);
214             ENABLE_WIDGET("wavelength", TRUE);
215             ENABLE_WIDGET("z00", TRUE);
216             ENABLE_WIDGET("z01", TRUE);
217             ENABLE_WIDGET("z10", TRUE);
218             ENABLE_WIDGET("z11", TRUE);
219             ENABLE_WIDGET("linearborder", TRUE);
220             ENABLE_WIDGET("go", TRUE);
221     }
222
223     switch (Plane) {
224         case PLANE_XZ0:
225         case PLANE_XZ1:
226             gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "hmin_text")), "X:");
227             gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "hmax_text")), "X:");
228             gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "vmin_text")), "Z:");
229             gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "vmax_text")), "Z:");
230             gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "nh_text")), "X:");
231             gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "nv_text")), "Z:");
232             break;
233         case PLANE_YZ0:
234         case PLANE_YZ1:
235             gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "hmin_text")), "Y:");
236             gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "hmax_text")), "Y:");
237             gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "vmin_text")), "Z:");
238             gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "vmax_text")), "Z:");
239             gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "nh_text")), "Y:");
240             gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "nv_text")), "Z:");
241             break;
242         default:
243             gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "hmin_text")), "X:");
244             gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "hmax_text")), "X:");
245             gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "vmin_text")), "Y:");
246             gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "vmax_text")), "Y:");
247             gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "nh_text")), "X:");
248             gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "nv_text")), "Y:");
249             break;
250     }
251 }
252
253 // SetDlgValues fills in text boxes and initializes other input controls
254 static void SetDlgValues(int tab)
255 {
256     char Text[256];
257     char RForm[16] = "%.5g";
258     int i;
259
260     switch (tab) {
261         case GENERAL_TAB:
262             // Hell if I know why, but in the release build the 2nd pass thru the
263             // set_sensitive loop for game_radios crashes. No need to do this more
264             // than once anyhow.
265             if (!FirstPassComplete) {
266                 for (i = 0; i < NUMGAMES; i++) {
267                     gtk_widget_set_sensitive(game_radios[i], (i == Game ? TRUE : FALSE));
268                 }
269                 for (i = 0; i < 6; i++) {
270                     gtk_widget_set_sensitive(plane_radios[i], (i == Plane ? TRUE : FALSE));
271                 }
272             }
273             gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(game_radios[Game]), TRUE);
274             gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(plane_radios[Plane]), TRUE);
275             gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(wave_radios[WaveType]), TRUE);
276             gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(g_pWnd), "random")),
277                                       RandomSeed);
278             sprintf(Text, RForm, WaveLength);
279             gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "wavelength")), Text);
280             sprintf(Text, RForm, Amplitude);
281             gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "amplitude")), Text);
282             sprintf(Text, RForm, Roughness);
283             gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "roughness")), Text);
284             gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data
285                                                                    (G_OBJECT(g_pWnd), "main_antialiasing")),
286                                          Antialiasing);
287             break;
288
289         case EXTENTS_TAB:
290             sprintf(Text, RForm, Hll);
291             gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "hmin")), Text);
292             sprintf(Text, RForm, Vll);
293             gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "vmin")), Text);
294             sprintf(Text, RForm, Hur);
295             gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "hmax")), Text);
296             sprintf(Text, RForm, Vur);
297             gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "vmax")), Text);
298             sprintf(Text, RForm, Z00);
299             gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "z00")), Text);
300             sprintf(Text, RForm, Z01);
301             gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "z01")), Text);
302             sprintf(Text, RForm, Z10);
303             gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "z10")), Text);
304             sprintf(Text, RForm, Z11);
305             gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "z11")), Text);
306             gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(g_pWnd), "nh")), NH);
307             gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(g_pWnd), "nv")), NV);
308             gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(g_pWnd), "sp")),
309                                       SP); // ^Fishman - Snap to grid.
310
311             gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data
312                                                                    (G_OBJECT(g_pWnd), "linearborder")), FixBorders);
313             gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data
314                                                                    (G_OBJECT(g_pWnd), "use_patches")), UsePatches);
315             gtk_adjustment_set_value(GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(g_pWnd), "decimate_adj")),
316                                      Decimate);
317
318             if (Game == QUAKE3 && UsePatches) {
319                 gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(g_pWnd, "decimate")), FALSE);
320
321                 if (NH % 2) {
322                     NH++;
323                     if (NH > MAX_ROWS) {
324                         NH -= 2;
325                     }
326                     SetDlgValues(current_tab);
327                 }
328
329                 if (NV % 2) {
330                     NV++;
331                     if (NV > MAX_ROWS) {
332                         NV -= 2;
333                     }
334                     SetDlgValues(current_tab);
335                 }
336                 if (NH % 2) {
337                     NH++;
338                 }
339                 if (NH < 2) {
340                     NH = 2;
341                 }
342                 if (NH > MAX_ROWS) {
343                     NH = MAX_ROWS;
344                 }
345                 if (NV % 2) {
346                     NV++;
347                 }
348                 if (NV < 2) {
349                     NV = 2;
350                 }
351                 if (NV > MAX_ROWS) {
352                     NV = MAX_ROWS;
353                 }
354
355                 gpointer spin = g_object_get_data(G_OBJECT(g_pWnd), "nh");
356                 GtkAdjustment *adj = gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(spin));
357                 adj->lower = 2;
358                 gtk_adjustment_changed(adj);
359                 spin = g_object_get_data(G_OBJECT(g_pWnd), "nv");
360                 adj = gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(spin));
361                 adj->lower = 2;
362                 gtk_adjustment_changed(adj);
363             } else {
364                 gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(g_pWnd, "decimate")), TRUE);
365
366                 gpointer spin = g_object_get_data(G_OBJECT(g_pWnd), "nh");
367                 GtkAdjustment *adj = gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(spin));
368                 adj->lower = 1;
369                 gtk_adjustment_changed(adj);
370                 spin = g_object_get_data(G_OBJECT(g_pWnd), "nv");
371                 adj = gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(spin));
372                 adj->lower = 1;
373                 gtk_adjustment_changed(adj);
374             }
375
376             gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(g_pWnd), "nh")), NH);
377             gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(g_pWnd), "nv")), NV);
378
379             break;
380
381         case BITMAP_TAB:
382             gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "bmp_file")), gbmp.name);
383             sprintf(Text, "%g", gbmp.black_value);
384             gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "bmp_black")), Text);
385             sprintf(Text, "%g", gbmp.white_value);
386             gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "bmp_white")), Text);
387             break;
388
389         case FIXPOINTS_TAB:
390             break;
391
392         case TEXTURE_TAB:
393             gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "texture1")), Texture[Game][0]);
394             gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "texture2")), Texture[Game][1]);
395             gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "texture3")), Texture[Game][2]);
396             gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(g_pWnd), "tex_slant")),
397                                       SlantAngle);
398             sprintf(Text, RForm, TexOffset[0]);
399             gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "texoffsetx")), Text);
400             sprintf(Text, RForm, TexOffset[1]);
401             gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "texoffsety")), Text);
402             sprintf(Text, RForm, TexScale[0]);
403             gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "texscalex")), Text);
404             sprintf(Text, RForm, TexScale[1]);
405             gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "texscaley")), Text);
406             CHECK_WIDGET("detail", UseDetail);
407
408             if (Game == QUAKE3) {
409                 ENABLE_WIDGET("hint", FALSE);
410                 AddHints = 0;
411             } else {
412                 ENABLE_WIDGET("hint", TRUE);
413             }
414             CHECK_WIDGET("hint", AddHints);
415
416             /*
417                    if (Game==SIN)
418                    {
419                    // ArghRad doesn't currently support SiN
420                    EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2),       0);
421                    EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN),  0);
422                    ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_TEXT),  SW_HIDE);
423                    ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2),       SW_HIDE);
424                    ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN),  SW_HIDE);
425                    SetDlgItemText(hwndDisplay,DLG_TEX_USEPAK,"Use sin file");
426                    SetDlgItemText(hwndDisplay,DLG_TEX_PAK_TEXT,"Sin:");
427                    }
428                  */
429
430             if (Game == QUAKE3) {
431                 /*
432                            // ArghRad sun is inapplicable (so far)
433                            EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2),       0);
434                            EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN),  0);
435                            ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_TEXT),  SW_HIDE);
436                            ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2),       SW_HIDE);
437                            ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN),  SW_HIDE);
438                            // No ladders in Q3
439                            EnableWindow(GetDlgItem(hwndDisplay,DLG_LADDER),         0);
440                            ShowWindow(GetDlgItem(hwndDisplay,DLG_LADDER),         SW_HIDE);
441                            SetDlgItemText(hwndDisplay,DLG_TEX_USEPAK,"Use pk3 file");
442                            SetDlgItemText(hwndDisplay,DLG_TEX_PAK_TEXT,"PK3:");
443                          */
444             }
445
446 /*trix  if(Game==HERETIC2)
447         {
448             // ArghRad doesn't currently support Heretic2
449             EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2),       0);
450             EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN),  0);
451             ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_TEXT),  SW_HIDE);
452             ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2),       SW_HIDE);
453             ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN),  SW_HIDE);
454
455             SetDlgItemText(hwndDisplay,DLG_TEX_USEPAK,"Use pak file");
456             SetDlgItemText(hwndDisplay,DLG_TEX_PAK_TEXT,"Pak:");
457         } */
458             /*
459                     if(Game==HALFLIFE)
460                     {
461                         // A bunch of controls aren't applicable to HL
462                         EnableWindow(GetDlgItem(hwndDisplay,DLG_TEXTURE_BROWSE), 0);
463                         EnableWindow(GetDlgItem(hwndDisplay,DLG_TEXTURE2_BROWSE),0);
464                         EnableWindow(GetDlgItem(hwndDisplay,DLG_TEXTURE3_BROWSE),0);
465                         EnableWindow(GetDlgItem(hwndDisplay,DLG_DETAIL),         0);
466                         EnableWindow(GetDlgItem(hwndDisplay,DLG_LADDER),         0);
467                         EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2),       0);
468                         EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN),  0);
469                         ShowWindow(GetDlgItem(hwndDisplay,DLG_TEXTURE_BROWSE), SW_HIDE);
470                         ShowWindow(GetDlgItem(hwndDisplay,DLG_TEXTURE2_BROWSE),SW_HIDE);
471                         ShowWindow(GetDlgItem(hwndDisplay,DLG_TEXTURE3_BROWSE),SW_HIDE);
472                         ShowWindow(GetDlgItem(hwndDisplay,DLG_DETAIL),         SW_HIDE);
473                         ShowWindow(GetDlgItem(hwndDisplay,DLG_LADDER),         SW_HIDE);
474                         ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_TEXT),  SW_HIDE);
475                         ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2),       SW_HIDE);
476                         ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN),  SW_HIDE);
477
478                         SetDlgItemText(hwndDisplay,DLG_TEX_USEPAK,"Use wad file");
479                         SetDlgItemText(hwndDisplay,DLG_TEX_PAK_TEXT,"Wad:");
480                         SetDlgItemText(hwndDisplay,DLG_HINT,"Hint brushes");
481                     }
482
483                     if(Game==GENESIS3D)
484                     {
485                         // No Q2-type compilers support Genesis3D (including ArghRad)
486                         EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2),       0);
487                         EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN),  0);
488                         ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_TEXT),  SW_HIDE);
489                         ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2),       SW_HIDE);
490                         ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN),  SW_HIDE);
491
492                         SetDlgItemText(hwndDisplay,DLG_TEX_USEPAK,"Use sin file");
493                         SetDlgItemText(hwndDisplay,DLG_TEX_PAK_TEXT,"Sin:");
494                     }
495                  */
496             break;
497     }
498     SetupControls();
499 }
500
501 static void ReadDlgValues(int tab)
502 {
503     //  char Text[256];
504     //  int i;
505
506     switch (tab) {
507         case GENERAL_TAB:
508             gpointer spin;
509             Roughness = atof(gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "roughness"))));
510             WaveLength = atof(gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "wavelength"))));
511             Amplitude = atof(gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "amplitude"))));
512             spin = g_object_get_data(G_OBJECT(g_pWnd), "random");
513             RandomSeed = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spin));
514             break;
515
516         case EXTENTS_TAB:
517             SP = atoi(gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "sp"))));
518             NH = atoi(gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "nh"))));
519             NV = atoi(gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "nv"))));
520
521             if (Game == QUAKE3 && UsePatches != 0) {
522                 if (NH % 2) {
523                     NH++;
524                 }
525                 if (NH < 2) {
526                     NH = 2;
527                 }
528                 if (NH > MAX_ROWS) {
529                     NH = MAX_ROWS;
530                 }
531                 if (NV % 2) {
532                     NV++;
533                 }
534                 if (NV < 2) {
535                     NV = 2;
536                 }
537                 if (NV > MAX_ROWS) {
538                     NV = MAX_ROWS;
539                 }
540             }
541             break;
542
543 #if 0
544                                                                                                                                 case BITMAP_TAB:
545
546                 if ( WaveType == WAVE_BITMAP ) {
547                         GetDlgItemText( hwnd,DLG_BMP_FILE,gbmp.name,sizeof( gbmp.name ) );
548                         CheckValidDIB( hwnd );
549                         GetDlgItemText( hwnd,DLG_BMP_BLACK,Text,sizeof( Text ) );
550                         gbmp.black_value = atof( Text );
551                         GetDlgItemText( hwnd,DLG_BMP_WHITE,Text,sizeof( Text ) );
552                         gbmp.white_value = atof( Text );
553                         UpdatePreview( TRUE );
554                 }
555                 break;
556
557         case FIXPOINTS_TAB:
558                 GetDlgItemText( hwnd,DLG_FIX_VALUE,Text,sizeof( Text ) );
559                 temp.fixed_value = atoi( Text );
560                 GetDlgItemText( hwnd,DLG_FIX_RANGE,Text,sizeof( Text ) );
561                 temp.range = atoi( Text );
562                 GetDlgItemText( hwnd,DLG_FIX_RATE, Text,sizeof( Text ) );
563                 temp.rate = atof( Text );
564                 for ( k = 0; k < NumVerticesSelected; k++ )
565                 {
566                         xyz[Vertex[k].i][Vertex[k].j].fixed_value = temp.fixed_value;
567                         xyz[Vertex[k].i][Vertex[k].j].range       = temp.range;
568                         xyz[Vertex[k].i][Vertex[k].j].rate        = temp.rate;
569                 }
570                 if ( !OldPreview ) {
571                         Preview = 0;
572                         CheckDlgButton( ghwnd,DLG_PREVIEW,0 );
573                         SendMessage( ghwnd,WM_COMMAND,DLG_PREVIEW,0 );
574                 }
575                 VertexMode = 0;
576                 UpdatePreview( TRUE );
577                 break;
578
579         case TEXTURE_TAB:
580                 if ( UsePak[Game] ) {
581                         i = SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST1, CB_GETCURSEL, 0, 0 );
582                         if ( i == CB_ERR ) {
583                                 Texture[Game][0][0] = '\0';
584                         }
585                         else{
586                                 SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST1, CB_GETLBTEXT, i,
587                                                                         (LPARAM)(LPCSTR)Texture[Game][0] );
588                         }
589
590                         i = SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST2, CB_GETCURSEL, 0, 0 );
591                         if ( i == CB_ERR ) {
592                                 Texture[Game][1][0] = '\0';
593                         }
594                         else{
595                                 SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST2, CB_GETLBTEXT, i,
596                                                                         (LPARAM)(LPCSTR)Texture[Game][1] );
597                         }
598
599                         i = SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST3, CB_GETCURSEL, 0, 0 );
600                         if ( i == CB_ERR ) {
601                                 Texture[Game][2][0] = '\0';
602                         }
603                         else{
604                                 SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST3, CB_GETLBTEXT, i,
605                                                                         (LPARAM)(LPCSTR)Texture[Game][2] );
606                         }
607                 }
608                 else
609                 {
610                         GetDlgItemText( hwndDisplay,DLG_TEXTURE, Texture[Game][0],sizeof( Texture[Game][0] ) );
611                         GetDlgItemText( hwndDisplay,DLG_TEXTURE2,Texture[Game][1],sizeof( Texture[Game][1] ) );
612                         GetDlgItemText( hwndDisplay,DLG_TEXTURE3,Texture[Game][2],sizeof( Texture[Game][2] ) );
613                 }
614                 GetDlgItemText( hwndDisplay,DLG_TEX_SLANT,Text,sizeof( Text ) );
615                 SlantAngle = atoi( Text );
616                 SlantAngle = max( 0,min( SlantAngle,90 ) );
617                 GetDlgItemText( hwndDisplay,DLG_TEXOFFSETX,Text,sizeof( Text ) );
618                 TexOffset[0] = atof( Text );
619                 GetDlgItemText( hwndDisplay,DLG_TEXOFFSETY,Text,sizeof( Text ) );
620                 TexOffset[1] = atof( Text );
621                 GetDlgItemText( hwndDisplay,DLG_TEXSCALEX,Text,sizeof( Text ) );
622                 TexScale[0] = atof( Text );
623                 if ( TexScale[0] == 0. ) {
624                         TexScale[0] = 1.0;
625                 }
626                 GetDlgItemText( hwndDisplay,DLG_TEXSCALEY,Text,sizeof( Text ) );
627                 TexScale[1] = atof( Text );
628                 if ( TexScale[1] == 0. ) {
629                         TexScale[1] = 1.0;
630                 }
631                 GetDlgItemText( hwndDisplay,DLG_ARGHRAD2,Text,sizeof( Text ) );
632                 ArghRad2 = atoi( Text );
633                 break;
634 #endif
635     }
636 }
637
638 // =============================================================================
639 // main dialog callbacks
640
641 static void switch_page(GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, gpointer data)
642 {
643     if (current_tab != page_num) {
644         if (page_num == FIXPOINTS_TAB) {
645             OldPreview = Preview;
646             gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(G_OBJECT(g_pWnd),
647                                                                              "main_preview")), TRUE);
648             VertexMode = 1;
649             UpdatePreview(true);
650             NumVerticesSelected = 0;
651         }
652
653         if (current_tab == FIXPOINTS_TAB) {
654             if (!OldPreview) {
655                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(G_OBJECT(g_pWnd),
656                                                                                  "main_preview")), FALSE);
657             }
658             VertexMode = 0;
659             UpdatePreview(true);
660             NumVerticesSelected = 0;
661         }
662
663         if (page_num == TEXTURE_TAB) {
664             WasDetail = UseDetail;
665             if (AddHints) {
666                 UseDetail = 1;
667                 ENABLE_WIDGET("detail", FALSE);
668             }
669         }
670
671         ReadDlgValues(current_tab);
672         current_tab = page_num;
673         SetDlgValues(current_tab);
674     }
675 }
676
677 static gint main_close(GtkWidget *widget, gpointer data)
678 {
679     gtk_widget_hide(g_pWnd);
680     gtk_widget_hide(g_pWndPreview);
681
682     return TRUE;
683 }
684
685 static void main_save(GtkWidget *widget, gpointer data)
686 {
687     ReadDlgValues(current_tab);
688     SaveSetup(g_pWnd);
689 }
690
691 static void main_open(GtkWidget *widget, gpointer data)
692 {
693     OpenSetup(g_pWnd, 0);
694     for (int i = 0; i < 5; i++) {
695         SetDlgValues(i);
696     }
697     ShowPreview();
698 }
699
700 static void main_defaults(GtkWidget *widget, gpointer data)
701 {
702     OpenSetup(g_pWnd, 1);
703     for (int i = 0; i < 5; i++) {
704         SetDlgValues(i);
705     }
706     ShowPreview();
707 }
708
709 static void main_preview(GtkWidget *widget, gpointer data)
710 {
711     Preview = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
712     ShowPreview();
713 }
714
715 // ^Fishman - Antializing for the preview window.
716 static void main_antialiasing(GtkWidget *widget, gpointer data)
717 {
718     Antialiasing = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
719     UpdatePreview(true);
720 }
721
722 static void main_about(GtkWidget *widget, gpointer data)
723 {
724     About(g_pWnd);
725 }
726
727 static void main_go(GtkWidget *widget, gpointer data)
728 {
729     GtkWidget *notebook = g_object_get_data(G_OBJECT(g_pWnd, "notebook"));
730     char Text[256];
731
732     ReadDlgValues(current_tab);
733     if (NH < 1 || NH > MAX_ROWS) {
734         sprintf(Text, "The number of divisions must be > 0 and no greater than %d.", MAX_ROWS);
735         g_FuncTable.m_pfnMessageBox(g_pWnd, Text, "GenSurf", eMB_OK, eMB_ICONWARNING);
736         gtk_notebook_set_page(GTK_NOTEBOOK(notebook), EXTENTS_TAB);
737         return;
738     }
739
740     if (NV < 1 || NV > MAX_ROWS) {
741         sprintf(Text, "The number of divisions must be > 0 and no greater than %d.", MAX_ROWS);
742         g_FuncTable.m_pfnMessageBox(g_pWnd, Text, "GenSurf", eMB_OK, eMB_ICONWARNING);
743         gtk_notebook_set_page(GTK_NOTEBOOK(notebook), EXTENTS_TAB);
744         return;
745     }
746
747     if (Hll >= Hur) {
748         g_FuncTable.m_pfnMessageBox(g_pWnd, "The \"lower-left\" values must be less than "
749                 "the corresponding \"upper-right\" values in "
750                 "the \"Extent\" box.", "GenSurf", eMB_OK, eMB_ICONWARNING);
751         gtk_notebook_set_page(GTK_NOTEBOOK(notebook), EXTENTS_TAB);
752         return;
753     }
754
755     if (Vll >= Vur) {
756         g_FuncTable.m_pfnMessageBox(g_pWnd, "The \"lower-left\" values must be less than "
757                 "the corresponding \"upper-right\" values in "
758                 "the \"Extent\" box.", "GenSurf", eMB_OK, eMB_ICONWARNING);
759         gtk_notebook_set_page(GTK_NOTEBOOK(notebook), EXTENTS_TAB);
760         return;
761     }
762
763     if (!strlen(Texture[Game][0])) {
764         g_FuncTable.m_pfnMessageBox(g_pWnd, "You must supply a texture name.", "GenSurf", eMB_OK, eMB_ICONWARNING);
765         gtk_notebook_set_page(GTK_NOTEBOOK(notebook), EXTENTS_TAB);
766         return;
767     }
768
769 /*  if (Decimate>0 && GimpHints!=0)
770    {
771     MessageBox(hwnd,"You've elected to use a decimated grid and gimp's non-detail hint brushes. "
772                "This combination usually produces bizarre visual errors in the game, "
773                "so GenSurf has turned off the hint brush option.",
774                "GenSurf",eMB_ICONWARNING);
775     GimpHints = 0;
776    } */
777
778     gtk_widget_hide(g_pWnd);
779     if (g_pWndPreview) {
780         gtk_widget_hide(g_pWndPreview);
781     }
782
783     GenerateMap();
784     WriteIniFile(gszIni);
785 }
786
787 // =============================================================================
788 // general tab callbacks
789
790 static void general_game(GtkToggleButton *widget, gpointer data)
791 {
792     if (gtk_toggle_button_get_active(widget)) {
793         Game = GPOINTER_TO_INT(data);
794         UpdatePreview(TRUE);
795     }
796 }
797
798 static void general_plane(GtkToggleButton *widget, gpointer data)
799 {
800     if (gtk_toggle_button_get_active(widget)) {
801         Plane = GPOINTER_TO_INT(data);
802         SetupControls();
803         UpdatePreview(TRUE);
804     }
805 }
806
807 static void general_wave(GtkToggleButton *widget, gpointer data)
808 {
809     if (gtk_toggle_button_get_active(widget)) {
810         WaveType = GPOINTER_TO_INT(data);
811         SetupControls();
812         UpdatePreview(TRUE);
813     }
814 }
815
816 static void general_random(GtkAdjustment *adj, gpointer data)
817 {
818     int nPos = (int) adj->value;
819
820     if (RandomSeed != nPos) {
821         RandomSeed = nPos;
822         UpdatePreview(true);
823     }
824 }
825
826 // =============================================================================
827 // extents tab callbacks
828
829 static void extents_linearborder(GtkToggleButton *check, gpointer data)
830 {
831     FixBorders = gtk_toggle_button_get_active(check);
832     UpdatePreview(true);
833 }
834
835 static void extents_use_patches(GtkToggleButton *check, gpointer data)
836 {
837     if (Game != QUAKE3) {
838         return;
839     }
840
841     UsePatches = gtk_toggle_button_get_active(check);
842     SetDlgValues(current_tab);
843     SetupControls();
844     UpdatePreview(true);
845 }
846
847 static void extents_nhnv_spin(GtkAdjustment *adj, int *data)
848 {
849     int nPos = (int) adj->value;
850
851     if (*data != nPos) {
852         if (Game == QUAKE3 && UsePatches && (nPos % 2)) {
853             if (*data < nPos) {
854                 *data += 2;
855             } else {
856                 *data -= 2;
857             }
858             gtk_adjustment_set_value(adj, *data);
859         } else {
860             *data = nPos;
861         }
862         UpdatePreview(true);
863     }
864 }
865
866 static void extents_decimate(GtkAdjustment *adj, gpointer data)
867 {
868     int nPos = (int) adj->value;
869
870     Decimate = nPos;
871     UpdatePreview(true);
872 }
873
874 // Hydra : snap to grid begin
875 /*static void extents_snaptogrid (GtkAdjustment *adj, gpointer data)
876    {
877    int nPos = (int)adj->value;
878
879    SnapToGrid = nPos;
880    UpdatePreview (true);
881    }*/
882
883 // ^Fishman - Modified version of Hydra's snap to grid code.
884 static void extents_snaptogrid_spin(GtkAdjustment *adj, int *data)
885 {
886     int nPos = (int) adj->value;
887     SnapToGrid = nPos;
888     UpdatePreview(true);
889 }
890
891 // =============================================================================
892 // bitmap tab callbacks
893
894 static gint bitmap_file_entryfocusout(GtkWidget *widget, GdkEventFocus *event, gpointer data)
895 {
896     char filename[NAME_MAX];
897
898     strcpy(filename, gtk_entry_get_text(GTK_ENTRY(widget)));
899     if (strcmp(filename, gbmp.name)) {
900         strcpy(gbmp.name, filename);
901         if (strlen(gbmp.name)) {
902             OpenBitmap();
903         }
904         ENABLE_WIDGET("go", (gbmp.colors != NULL ? TRUE : FALSE));
905     }
906     return FALSE;
907 }
908
909 static void bitmap_browse(GtkWidget *widget, gpointer data)
910 {
911     const char *filename;
912     char *ptr;
913
914     filename = g_FuncTable.m_pfnFileDialog(g_pWnd, TRUE, "Bitmap File", gbmp.defpath);
915
916     if (filename != NULL) {
917         strcpy(gbmp.name, filename);
918
919         ptr = strrchr(filename, G_DIR_SEPARATOR);
920         if (ptr != NULL) {
921             *(ptr + 1) = '\0';
922             strcpy(gbmp.defpath, filename);
923         }
924
925         OpenBitmap();
926         ENABLE_WIDGET("go", (gbmp.colors != NULL ? TRUE : FALSE));
927     }
928 }
929
930 static void bitmap_reload(GtkWidget *widget, gpointer data)
931 {
932     strcpy(gbmp.name, gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "bmp_file"))));
933     if (strlen(gbmp.name)) {
934         OpenBitmap();
935         ENABLE_WIDGET("go", (gbmp.colors != NULL ? TRUE : FALSE));
936     } else {
937         ENABLE_WIDGET("go", FALSE);
938     }
939 }
940
941 // =============================================================================
942 // fix points tab callbacks
943
944 static gint fix_value_entryfocusout(GtkWidget *widget, GdkEventFocus *event, gpointer data)
945 {
946     int i = atoi(gtk_entry_get_text(GTK_ENTRY(widget))), k;
947     char Text[32];
948
949     if (i < -65536 || i > 65536) {
950         gdk_beep();
951         g_FuncTable.m_pfnMessageBox(g_pWnd, "The value must be between -65536 and 65536, inclusive.",
952                                     "GenSurf", eMB_OK, eMB_ICONWARNING);
953         sprintf(Text, "%d", (int) xyz[Vertex[0].i][Vertex[0].j].fixed_value);
954         gtk_entry_set_text(GTK_ENTRY(widget), Text);
955         gtk_window_set_focus(widget.window(), widget);
956     } else if (i != xyz[Vertex[0].i][Vertex[0].j].fixed_value) {
957         for (k = 0; k < NumVerticesSelected; k++) {
958             xyz[Vertex[k].i][Vertex[k].j].fixed_value = i;
959         }
960
961         gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(g_pWnd), "fix_value")),
962                                   (int) xyz[Vertex[0].i][Vertex[0].j].fixed_value);
963         UpdatePreview(true);
964     }
965     return FALSE;
966 }
967
968 static void fix_value_changed(GtkAdjustment *adj, gpointer data)
969 {
970     int k, i = (int) adj->value;
971
972     if (xyz[Vertex[0].i][Vertex[0].j].fixed_value != i) {
973         for (k = 0; k < NumVerticesSelected; k++) {
974             xyz[Vertex[k].i][Vertex[k].j].fixed_value = i;
975         }
976         UpdatePreview(true);
977     }
978 }
979
980 static gint fix_range_entryfocusout(GtkWidget *widget, GdkEventFocus *event, gpointer data)
981 {
982     int i = atoi(gtk_entry_get_text(GTK_ENTRY(widget))), k;
983
984     if (i != xyz[Vertex[0].i][Vertex[0].j].range) {
985         for (k = 0; k < NumVerticesSelected; k++) {
986             xyz[Vertex[k].i][Vertex[k].j].range = i;
987         }
988         UpdatePreview(true);
989     }
990     return FALSE;
991 }
992
993 static gint fix_rate_entryfocusout(GtkWidget *widget, GdkEventFocus *event, gpointer data)
994 {
995     double r = atof(gtk_entry_get_text(GTK_ENTRY(widget)));
996     int k;
997
998     if (r != xyz[Vertex[0].i][Vertex[0].j].rate) {
999         for (k = 0; k < NumVerticesSelected; k++) {
1000             xyz[Vertex[k].i][Vertex[k].j].rate = r;
1001         }
1002         UpdatePreview(true);
1003     }
1004     return FALSE;
1005 }
1006
1007 static void fix_free(GtkWidget *widget, gpointer data)
1008 {
1009     int k;
1010
1011     for (k = 0; k < NumVerticesSelected; k++) {
1012         xyz[Vertex[k].i][Vertex[k].j].fixed = 0;
1013     }
1014     NumVerticesSelected = 0;
1015     SetupControls();
1016     UpdatePreview(true);
1017 }
1018
1019 static void fix_freeall(GtkWidget *widget, gpointer data)
1020 {
1021     int i, j;
1022
1023     for (i = 0; i <= NH; i++) {
1024         for (j = 0; j <= NV; j++) {
1025             xyz[i][j].fixed = 0;
1026         }
1027     }
1028     fix_free(NULL, data); // keep these together
1029 }
1030
1031 void vertex_selected()
1032 {
1033     char Text[32];
1034     int k;
1035
1036     SetupControls();
1037
1038     switch (Plane) {
1039         case PLANE_XZ0:
1040         case PLANE_XZ1:
1041             for (k = 0; k < NumVerticesSelected; k++) {
1042                 xyz[Vertex[k].i][Vertex[k].j].fixed_value = xyz[Vertex[0].i][Vertex[0].j].p[1];
1043             }
1044             break;
1045         case PLANE_YZ0:
1046         case PLANE_YZ1:
1047             for (k = 0; k < NumVerticesSelected; k++) {
1048                 xyz[Vertex[k].i][Vertex[k].j].fixed_value = xyz[Vertex[0].i][Vertex[0].j].p[0];
1049             }
1050             break;
1051         default:
1052             for (k = 0; k < NumVerticesSelected; k++) {
1053                 xyz[Vertex[k].i][Vertex[k].j].fixed_value = xyz[Vertex[0].i][Vertex[0].j].p[2];
1054             }
1055             break;
1056     }
1057
1058     gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(g_pWnd), "fix_value")),
1059                               (int) xyz[Vertex[0].i][Vertex[0].j].fixed_value);
1060
1061     sprintf(Text, "%d", (int) xyz[Vertex[0].i][Vertex[0].j].range);
1062     gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "fix_range")), Text);
1063     sprintf(Text, "%.5g", xyz[Vertex[0].i][Vertex[0].j].rate);
1064     gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "fix_rate")), Text);
1065
1066     for (k = 0; k < NumVerticesSelected; k++) {
1067         xyz[Vertex[k].i][Vertex[k].j].fixed = 1;
1068     }
1069
1070     UpdatePreview(true);
1071 }
1072
1073 // =============================================================================
1074 // texture tab callbacks
1075
1076 static void texture_detail(GtkToggleButton *check, gpointer data)
1077 {
1078     UseDetail = gtk_toggle_button_get_active(check);
1079     WasDetail = UseDetail;
1080 }
1081
1082 static void texture_hint(GtkToggleButton *check, gpointer data)
1083 {
1084     AddHints = gtk_toggle_button_get_active(check);
1085     if (AddHints == 1) {
1086         UseDetail = 1;
1087         ENABLE_WIDGET("detail", FALSE);
1088     } else {
1089         UseDetail = WasDetail;
1090         ENABLE_WIDGET("detail", FALSE);
1091     }
1092     CHECK_WIDGET("detail", UseDetail);
1093 }
1094
1095 // ^Fishman - Add terrain key to func_group.
1096 static void texture_terrainent(GtkToggleButton *check, gpointer data)
1097 {
1098     AddTerrainKey = gtk_toggle_button_get_active(check);
1099 }
1100
1101 static void texture_set(int index, const char *name)
1102 {
1103     strcpy(Texture[Game][index], name);
1104 }
1105
1106 static gint texture_entryfocusout(GtkWidget *widget, GdkEventFocus *event, gpointer data)
1107 {
1108     texture_set(GPOINTER_TO_INT(data), gtk_entry_get_text(GTK_ENTRY(widget)));
1109     return FALSE;
1110 }
1111
1112 // =============================================================================
1113 // misc stuff
1114
1115 static void UpdateVariable(GtkEntry *entry, GdkEventFocus *event, double *data)
1116 {
1117     double x = atof(gtk_entry_get_text(entry));
1118
1119     if (x != *data) {
1120         *data = x;
1121         UpdatePreview(true);
1122     }
1123 }
1124
1125 static gint doublevariable_entryfocusout(GtkWidget *widget, GdkEventFocus *event, gpointer data)
1126 {
1127     UpdateVariable(GTK_ENTRY(widget), event, reinterpret_cast<double *>( data ));
1128     return FALSE;
1129 }
1130
1131 // =============================================================================
1132 // create tooltips
1133
1134 void create_tooltips()
1135 {
1136     tooltips = gtk_tooltips_new();
1137
1138     // Main
1139     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1140                          g_object_get_data(G_OBJECT(g_pWnd, "go")),
1141                          "Accept all input and generate a surface in Q3Radiant",
1142                          "");
1143     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1144                          g_object_get_data(G_OBJECT(g_pWnd, "open")),
1145                          "Open a previously saved GenSurf settings file.",
1146                          "");
1147     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1148                          g_object_get_data(G_OBJECT(g_pWnd, "save")),
1149                          "Save all settings to a file.",
1150                          "");
1151     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1152                          g_object_get_data(G_OBJECT(g_pWnd, "defaults")),
1153                          "Restore default values from DEFAULTS.SRF. If this file does not exist, GenSurf "
1154                                  "initializes all input parameters to reasonable values. You can create your own "
1155                                  "default surface by setting all parameters to your liking, then saving a settings "
1156                                  "file as DEFAULTS.SRF with the Save As button.",
1157                          "");
1158
1159     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1160                          g_object_get_data(G_OBJECT(g_pWnd, "main_preview")),
1161                          "View a wire-frame representation of the surface",
1162                          "");
1163
1164     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1165                          g_object_get_data(G_OBJECT(g_pWnd, "main_antialiasing")),
1166                          "The lines in the preview window are antialiased for better quality",
1167                          "");
1168
1169     // General tab
1170     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1171                          wave_radios[0],
1172                          "Builds a surface with alternating hills and valleys. Uses the general form Z=cos(X) "
1173                                  "x sin(Y)",
1174                          "");
1175     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1176                          wave_radios[1],
1177                          "Builds a surface with ridges parallel to the vertical axis.",
1178                          "");
1179     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1180                          wave_radios[2],
1181                          "Builds a surface with ridges parallel to the horizontal axis.",
1182                          "");
1183     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1184                          wave_radios[3],
1185                          "Builds a map from a bitmap image representing a contour plot. Click the \"Bitmap\" "
1186                                  "tab to select the image. GenSurf only supports 256-color (8 bit) "
1187                                  "bitmaps. GenSurf will work with any 256-color bitmap, but gray scale bitmaps are a bit "
1188                                  "more intuitive.",
1189                          "");
1190     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1191                          wave_radios[4],
1192                          "Builds a random surface using the Plasma Cloud technique. Variance is controlled "
1193                                  "by the Roughness input. To build a surface with completely random values not "
1194                                  "dependent on neighboring vertices, use one of the other waveforms with 0 amplitude.",
1195                          "");
1196     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1197                          g_object_get_data(G_OBJECT(g_pWnd, "wavelength")),
1198                          "Enter the wavelength (distance between crests). NOTE: Wavelengths equal to the grid "
1199                                  "size or 2 times the grid size will result in 0 amplitudes. For best results, the "
1200                                  "wavelength value should be at least 4 times the grid size (extents divided by the "
1201                                  "number of divisions",
1202                          "");
1203     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1204                          g_object_get_data(G_OBJECT(g_pWnd, "amplitude")),
1205                          "Enter the height of hills/ridges.",
1206                          "");
1207     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1208                          g_object_get_data(G_OBJECT(g_pWnd, "roughness")),
1209                          "Enter the roughness value (noise) for the surface. For fractal surfaces, this value "
1210                                  "is used as a variance in the fractal calculations.",
1211                          "");
1212     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1213                          g_object_get_data(G_OBJECT(g_pWnd, "random")),
1214                          "Seed value for the pseudo-random number generator.",
1215                          "");
1216     // Extents tab
1217     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1218                          g_object_get_data(G_OBJECT(g_pWnd, "hmin")),
1219                          "Minimum horizontal coordinate of the surface, i.e. X for a surface parallel to "
1220                                  "the XY or XZ planes, Y for a surface parallel to the YZ plane. For best results, "
1221                                  "the extents (maximum-minimum values) in a given direction should be evenly "
1222                                  "divisible by the number of divisions in that direction.",
1223                          "");
1224     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1225                          g_object_get_data(G_OBJECT(g_pWnd, "hmax")),
1226                          "Maximum horizontal coordinate of the surface, i.e. X for a surface parallel to "
1227                                  "the XY or XZ planes, Y for a surface parallel to the YZ plane. For best results, "
1228                                  "the extents (maximum-minimum values) in a given direction should be evenly "
1229                                  "divisible by the number of divisions in that direction.",
1230                          "");
1231     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1232                          g_object_get_data(G_OBJECT(g_pWnd, "vmin")),
1233                          "Minimum vertical coordinate of the surface, i.e. Y for a surface parallel to "
1234                                  "the XY plane, Z for a surface parallel to the XZ or YZ planes. For best results, "
1235                                  "the extents (maximum-minimum values) in a given direction should be evenly "
1236                                  "divisible by the number of divisions in that direction.",
1237                          "");
1238     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1239                          g_object_get_data(G_OBJECT(g_pWnd, "vmax")),
1240                          "Maximum vertical coordinate of the surface, i.e. Y for a surface parallel to "
1241                                  "the XY plane, Z for a surface parallel to the XZ or YZ planes. For best results, "
1242                                  "the extents (maximum-minimum values) in a given direction should be evenly "
1243                                  "divisible by the number of divisions in that direction.",
1244                          "");
1245     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1246                          g_object_get_data(G_OBJECT(g_pWnd, "nh")),
1247                          "Number of divisions in the horizontal direction. For best results, the extents "
1248                                  "in a given direction should be evenly divisible by the number of divisions in "
1249                                  "that direction.",
1250                          "");
1251     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1252                          g_object_get_data(G_OBJECT(g_pWnd, "nv")),
1253                          "Number of divisions in the vertical direction. For best results, the extents "
1254                                  "in a given direction should be evenly divisible by the number of divisions in "
1255                                  "that direction.",
1256                          "");
1257     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1258                          g_object_get_data(G_OBJECT(g_pWnd, "use_patches")),
1259                          "Produce one or more curved patches in the shape of your selected surface rather "
1260                                  "than producing solid brushes. Depending on the size of your surface (and the "
1261                                  "user's graphic detail settings, which you cannot control), curved surfaces will "
1262                                  "be represented in the game by a very large number of polygons. Read the warnings "
1263                                  "concerning curved surfaces on the GenSurf web page before using this feature.",
1264                          "");
1265     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1266                          g_object_get_data(G_OBJECT(g_pWnd, "decimate")),
1267                          "Use the slider to control the number of vertices discarded by GenSurf. For many "
1268                                  "surfaces, you can produce roughly the same shape surface with a high decimation "
1269                                  "value. This will generally result in a map with lower polygon counts (and better "
1270                                  "in-game performance). However, this feature should NOT be used for large terrain "
1271                                  "surfaces in Q3",
1272                          "");
1273     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1274                          g_object_get_data(G_OBJECT(g_pWnd, "z00")),
1275                          "Enter the height of the surface at the lower left corner. This value will likely "
1276                                  "be modified unless \"Linear Borders\" is checked.",
1277                          "");
1278     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1279                          g_object_get_data(G_OBJECT(g_pWnd, "z01")),
1280                          "Enter the height of the surface at the upper left corner. This value will likely "
1281                                  "be modified unless \"Linear Borders\" is checked.",
1282                          "");
1283     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1284                          g_object_get_data(G_OBJECT(g_pWnd, "z10")),
1285                          "Enter the height of the surface at the lower right corner. This value will likely "
1286                                  "be modified unless \"Linear Borders\" is checked.",
1287                          "");
1288     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1289                          g_object_get_data(G_OBJECT(g_pWnd, "z11")),
1290                          "Enter the height of the surface at the upper right corner. This value will likely "
1291                                  "be modified unless \"Linear Borders\" is checked.",
1292                          "");
1293     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1294                          g_object_get_data(G_OBJECT(g_pWnd, "linearborder")),
1295                          "Restrict the edges of the surface to a straight line. This will help match up "
1296                                  "brush edges if you drop this surface into another map.",
1297                          "");
1298     // Bitmap tab
1299     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1300                          g_object_get_data(G_OBJECT(g_pWnd, "bmp_file")),
1301                          "Type the name of an 8-bit bitmap image file, or click Browse to select an image "
1302                                  "from a list of those available on your system.",
1303                          "");
1304     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1305                          g_object_get_data(G_OBJECT(g_pWnd, "bmp_file_browse")),
1306                          "Select a bitmap image file from a list of those available on your system.",
1307                          "");
1308     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1309                          g_object_get_data(G_OBJECT(g_pWnd, "bmp_reload")),
1310                          "Reload the selected bitmap file after making changes in an external image editor.",
1311                          "");
1312     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1313                          g_object_get_data(G_OBJECT(g_pWnd, "bmp_black")),
1314                          "Enter the value corresponding to color index 0 in the bitmap file. For gray scale "
1315                                  "images, color 0 is normally black.",
1316                          "");
1317     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1318                          g_object_get_data(G_OBJECT(g_pWnd, "bmp_white")),
1319                          "Enter the value corresponding to color index 255 in the bitmap file. For gray scale "
1320                                  "images, color 255 is normally white.",
1321                          "");
1322     // Fixpoints tab
1323     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1324                          g_object_get_data(G_OBJECT(g_pWnd, "fix_value")),
1325                          "Enter a value for the selected vertex. This value will not be adjusted when applying "
1326                                  "a waveform or roughness to the surface. Unlock this vertex (so that it will be "
1327                                  "adjusted normally) by clicking \"Free\". This vertex will influence vertices within "
1328                                  "the \"Range affected\" of this vertex.",
1329                          "");
1330     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1331                          g_object_get_data(G_OBJECT(g_pWnd, "fix_range")),
1332                          "Enter the range away from the selected vertex that other vertices will be affected. "
1333                                  "Use 0 if you don't want other vertices to be influenced by the currently selected "
1334                                  "one. Note: this box is disabled if you've chosen the fractal generator, as it uses "
1335                                  "a completely different method for determining values.",
1336                          "");
1337     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1338                          g_object_get_data(G_OBJECT(g_pWnd, "fix_rate")),
1339                          "Enter a rate of change for the surface affected by the fixed value. 0 gives a smooth "
1340                                  "sinusoidal curve, values less than 0 give progressively sharper spikes, and values "
1341                                  "greater than 0 take on a square shape. Values less than -30 or greater than 30 are "
1342                                  "set to -30 and 30, respectively. Note that this entry will have no effect unless "
1343                                  "you also specify a \"range affected\".",
1344                          "");
1345     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1346                          g_object_get_data(G_OBJECT(g_pWnd, "fix_free")),
1347                          "Click this to free (unlock the value of) the currently selected vertex.",
1348                          "");
1349     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1350                          g_object_get_data(G_OBJECT(g_pWnd, "fix_freeall")),
1351                          "Click this to free (unlock the values of) all vertices.",
1352                          "");
1353     // Texture tab
1354     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1355                          g_object_get_data(G_OBJECT(g_pWnd, "texture1")),
1356                          "Enter the name of the texture or shader used for the surface faces.",
1357                          "");
1358     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1359                          g_object_get_data(G_OBJECT(g_pWnd, "texture2")),
1360                          "Enter the name of the texture or shader used for faces other than the surface. Under "
1361                                  "normal circumstances this should be \"common/caulk\"",
1362                          "");
1363     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1364                          g_object_get_data(G_OBJECT(g_pWnd, "texture3")),
1365                          "Enter the name of the texture or shader used for \"steep\" surface faces, where \"steep\" "
1366                                  "is the angle specified below. If this entry is left blank or if the \"steep\" angle is 0, "
1367                                  "all surface faces will use the texture specified by \"Surface\".",
1368                          "");
1369
1370     gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1371                          g_object_get_data(G_OBJECT(g_pWnd, "detail")),
1372                          "Check this box to use the detail content property on the generated brushes. Compile "
1373                                  "times will be considerably shorter if the detail property is used, though the surface "
1374                                  "will not block visibility at all. If you use the detail property, you should make sure "
1375                                  "that \"common/caulk\" is used for the non-surface faces, or the polygon count will be "
1376                                  "much higher than necessary.",
1377                          "");
1378 }
1379
1380 // =============================================================================
1381 // create main dialog
1382
1383 GtkWidget *create_main_dialog()
1384 {
1385     GtkWidget *hbox2, *button, *notebook, *table2;
1386     GtkWidget *check, *spin, *radio, *label, *entry, *scale;
1387     ui::Adjustment adj;
1388     GSList *group;
1389     int i;
1390     const char *games[] = {"Quake 2", "Half-Life", "SiN", "Heretic 2", "Kingpin", "Genesis3D", "Quake 3 Arena"};
1391     const char *waveforms[] = {"Alternating hill/valley", "Cylindrical left-to-right", "Cylindrical top-to-bottom",
1392                                "From bitmap", "Fractal"};
1393     const char *orientations[] = {"Ground surface", "Ceiling", "Wall facing 0", "Wall facing 90",
1394                                   "Wall facing 180", "Wall facing 270"};
1395
1396     auto dlg = g_pWnd = ui::Window(ui::window_type::TOP);
1397     gtk_window_set_title(dlg, gszCaption);
1398     dlg.connect("delete_event", G_CALLBACK(main_close), NULL);
1399     //  dlg.connect( "destroy", G_CALLBACK (gtk_widget_destroy), NULL);
1400     gtk_window_set_transient_for(dlg, g_pRadiantWnd);
1401
1402     auto hbox = ui::HBox(FALSE, 5);
1403     hbox.show();
1404     dlg.add(hbox);
1405     gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
1406
1407     notebook = gtk_notebook_new();
1408     notebook.show();
1409     hbox.pack_start(notebook, TRUE, TRUE, 0);
1410     notebook.connect("switch_page",
1411                      G_CALLBACK(switch_page), NULL);
1412     gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
1413     g_object_set_data(G_OBJECT(dlg), "notebook", notebook);
1414
1415     table = ui::Table(2, 2, FALSE);
1416     table.show();
1417     gtk_container_set_border_width(GTK_CONTAINER(table), 5);
1418     gtk_table_set_row_spacings(table, 5);
1419     gtk_table_set_col_spacings(table, 5);
1420
1421     label = ui::Label("General");
1422     label.show();
1423     gtk_notebook_append_page(GTK_NOTEBOOK(notebook), table, label);
1424
1425     auto frame = ui::Frame("Game");
1426     frame.show();
1427     table.attach(frame, {0, 1, 0, 1});
1428
1429     auto vbox = ui::VBox(TRUE, 5);
1430     vbox.show();
1431     frame.add(vbox);
1432     gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1433
1434     for (i = 0, group = NULL; i < NUMGAMES; i++) {
1435         radio = gtk_radio_button_new_with_label(group, games[i]);
1436         radio.show();
1437         vbox.pack_start(radio, TRUE, TRUE, 0);
1438         group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio));
1439         game_radios[i] = radio;
1440         radio.connect("toggled", G_CALLBACK(general_game), GINT_TO_POINTER(i));
1441     }
1442
1443     frame = ui::Frame("Waveform");
1444     frame.show();
1445     table.attach(frame, {1, 2, 0, 1});
1446
1447     vbox = ui::VBox(TRUE, 5);
1448     vbox.show();
1449     frame.add(vbox);
1450     gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1451
1452     for (i = 0, group = NULL; i < 5; i++) {
1453         radio = gtk_radio_button_new_with_label(group, waveforms[i]);
1454         radio.show();
1455         vbox.pack_start(radio, TRUE, TRUE, 0);
1456         group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio));
1457         wave_radios[i] = radio;
1458         radio.connect("toggled", G_CALLBACK(general_wave), GINT_TO_POINTER(i));
1459     }
1460
1461     frame = ui::Frame("Orientation");
1462     frame.show();
1463     table.attach(frame, {0, 1, 1, 2});
1464
1465     vbox = ui::VBox(TRUE, 5);
1466     vbox.show();
1467     frame.add(vbox);
1468     gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1469
1470     for (i = 0, group = NULL; i < 6; i++) {
1471         radio = gtk_radio_button_new_with_label(group, orientations[i]);
1472         radio.show();
1473         vbox.pack_start(radio, TRUE, TRUE, 0);
1474         group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio));
1475         plane_radios[i] = radio;
1476         radio.connect("toggled", G_CALLBACK(general_plane), GINT_TO_POINTER(i));
1477     }
1478
1479     table2 = ui::Table(4, 2, FALSE);
1480     table2.show();
1481     gtk_table_set_row_spacings(table2, 5);
1482     gtk_table_set_col_spacings(table2, 5);
1483     table.attach(table2, {1, 2, 1, 2});
1484
1485     label = ui::Label("Wavelength:");
1486     label.show();
1487     table2.attach(label, {0, 1, 0, 1});
1488     gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1489     gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT);
1490
1491     label = ui::Label("Max. amplitude:");
1492     label.show();
1493     table2.attach(label, {0, 1, 1, 2});
1494     gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1495     gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT);
1496
1497     label = ui::Label("Roughness:");
1498     label.show();
1499     table2.attach(label, {0, 1, 2, 3});
1500     gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1501     gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT);
1502
1503     label = ui::Label("Random seed:");
1504     label.show();
1505     table2.attach(label, {0, 1, 3, 4});
1506     gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1507     gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT);
1508
1509     entry = ui::Entry();
1510     entry.show();
1511     table2.attach(entry, {1, 2, 0, 1});
1512     entry.dimensions(50, -1);
1513     g_object_set_data(G_OBJECT(dlg), "wavelength", entry);
1514     entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &WaveLength);
1515
1516     entry = ui::Entry();
1517     entry.show();
1518     table2.attach(entry, {1, 2, 1, 2});
1519     entry.dimensions(50, -1);
1520     g_object_set_data(G_OBJECT(dlg), "amplitude", entry);
1521     entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &Amplitude);
1522
1523     entry = ui::Entry();
1524     entry.show();
1525     table2.attach(entry, {1, 2, 2, 3});
1526     entry.dimensions(50, -1);
1527     g_object_set_data(G_OBJECT(dlg), "roughness", entry);
1528     entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &Roughness);
1529
1530     adj = ui::Adjustment(1, 1, 32767, 1, 10, 0);
1531     adj.connect("value_changed", G_CALLBACK(general_random), NULL);
1532     spin = ui::SpinButton(adj, 1, 0);
1533     spin.show();
1534     table2.attach(spin, {1, 2, 3, 4});
1535     spin.dimensions(60, -1);
1536     g_object_set_data(G_OBJECT(dlg), "random", spin);
1537
1538     vbox = ui::VBox(FALSE, 5);
1539     vbox.show();
1540     gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1541
1542     label = ui::Label("Extents");
1543     label.show();
1544     gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, label);
1545
1546     hbox2 = ui::HBox(FALSE, 5);
1547     hbox2.show();
1548     vbox.pack_start(hbox2, FALSE, TRUE, 0);
1549
1550     frame = ui::Frame("Extents");
1551     frame.show();
1552     hbox2.pack_start(frame, TRUE, TRUE, 0);
1553
1554     auto table = ui::Table(3, 4, FALSE);
1555     table.show();
1556     gtk_container_set_border_width(GTK_CONTAINER(table), 5);
1557     frame.add(table);
1558     gtk_table_set_row_spacings(table, 5);
1559     gtk_table_set_col_spacings(table, 5);
1560
1561     label = ui::Label("X:");
1562     label.show();
1563     table.attach(label, {0, 1, 1, 2}, {GTK_FILL, GTK_FILL});
1564     g_object_set_data(G_OBJECT(dlg), "hmin_text", label);
1565
1566     label = ui::Label("X:");
1567     label.show();
1568     table.attach(label, {2, 3, 1, 2}, {GTK_FILL, GTK_FILL});
1569     g_object_set_data(G_OBJECT(dlg), "hmax_text", label);
1570
1571     label = ui::Label("Y:");
1572     label.show();
1573     table.attach(label, {0, 1, 2, 3}, {GTK_FILL, GTK_FILL});
1574     g_object_set_data(G_OBJECT(dlg), "vmin_text", label);
1575
1576     label = ui::Label("Y:");
1577     label.show();
1578     table.attach(label, {2, 3, 2, 3}, {GTK_FILL, GTK_FILL});
1579     g_object_set_data(G_OBJECT(dlg), "vmax_text", label);
1580
1581     label = ui::Label("Lower-left");
1582     label.show();
1583     table.attach(label, {1, 2, 0, 1}, {GTK_FILL, GTK_FILL});
1584
1585     label = ui::Label("Upper-right");
1586     label.show();
1587     table.attach(label, {3, 4, 0, 1}, , {GTK_FILL, GTK_FILL});
1588
1589     entry = ui::Entry();
1590     entry.show();
1591     table.attach(entry, {1, 2, 1, 2});
1592     entry.dimensions(50, -1);
1593     g_object_set_data(G_OBJECT(dlg), "hmin", entry);
1594     entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &Hll);
1595
1596     entry = ui::Entry();
1597     entry.show();
1598     table.attach(entry, {3, 4, 1, 2});
1599     entry.dimensions(50, -1);
1600     g_object_set_data(G_OBJECT(dlg), "hmax", entry);
1601     entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &Hur);
1602
1603     entry = ui::Entry();
1604     entry.show();
1605     table.attach(entry, {1, 2, 2, 3});
1606     entry.dimensions(50, -1);
1607     g_object_set_data(G_OBJECT(dlg), "vmin", entry);
1608     entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &Vll);
1609
1610     entry = ui::Entry();
1611     entry.show();
1612     table.attach(entry, {3, 4, 2, 3});
1613     entry.dimensions(50, -1);
1614     g_object_set_data(G_OBJECT(dlg), "vmax", entry);
1615     entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &Vur);
1616
1617     frame = ui::Frame("Divisions");
1618     frame.show();
1619     hbox2.pack_start(frame, TRUE, TRUE, 0);
1620
1621     table = ui::Table(2, 2, FALSE);
1622     table.show();
1623     gtk_container_set_border_width(GTK_CONTAINER(table), 5);
1624     frame.add(table);
1625     gtk_table_set_row_spacings(table, 5);
1626     gtk_table_set_col_spacings(table, 5);
1627
1628     label = ui::Label("X:");
1629     label.show();
1630     table.attach(label, {0, 1, 0, 1}, {GTK_FILL, GTK_EXPAND | GTK_FILL});
1631     g_object_set_data(G_OBJECT(dlg), "nh_text", label);
1632
1633     label = ui::Label("Y:");
1634     label.show();
1635     table.attach(label, {0, 1, 1, 2}, {GTK_FILL, GTK_EXPAND | GTK_FILL});
1636     g_object_set_data(G_OBJECT(dlg), "nv_text", label);
1637
1638     adj = ui::Adjustment(8, 1, MAX_ROWS, 1, 10, 0);
1639     adj.connect("value_changed", G_CALLBACK(extents_nhnv_spin), &NH);
1640     spin = ui::SpinButton(adj, 1, 0);
1641     spin.show();
1642     table.attach(spin, {1, 2, 0, 1});
1643     spin.dimensions(60, -1);
1644     g_object_set_data(G_OBJECT(dlg), "nh", spin);
1645
1646     adj = ui::Adjustment(8, 1, MAX_ROWS, 1, 10, 0);
1647     adj.connect("value_changed", G_CALLBACK(extents_nhnv_spin), &NV);
1648     spin = ui::SpinButton(adj, 1, 0);
1649     spin.show();
1650     table.attach(spin, {1, 2, 1, 2});
1651     spin.dimensions(60, -1);
1652     g_object_set_data(G_OBJECT(dlg), "nv", spin);
1653
1654     check = ui::CheckButton("Use Bezier patches");
1655     check.show();
1656     vbox.pack_start(check, FALSE, TRUE, 0);
1657     g_object_set_data(G_OBJECT(dlg), "use_patches", check);
1658     check.connect("toggled", G_CALLBACK(extents_use_patches), NULL);
1659
1660     // ^Fishman - Snap to grid, replaced scroll bar with a texbox.
1661     label = ui::Label("Snap to grid:");
1662     label.show();
1663     vbox.pack_start(label, FALSE, TRUE, 0);
1664     gtk_object_set_data(GTK_OBJECT(dlg), "snap_text", label);
1665
1666     adj = ui::Adjustment(8, 0, 256, 1, 10, 0);
1667     adj.connect("value_changed", G_CALLBACK(extents_snaptogrid_spin), &SP);
1668     spin = ui::SpinButton(adj, 1, 0);
1669     spin.show();
1670     vbox.pack_start(spin, FALSE, TRUE, 0);
1671     spin.dimensions(60, -1);
1672     g_object_set_data(G_OBJECT(dlg), "sp", spin);
1673     // ^Fishman - End of Snap to grid code.
1674
1675     hbox2 = ui::HBox(FALSE, 5);
1676     hbox2.show();
1677     vbox.pack_start(hbox2, FALSE, TRUE, 10);
1678
1679     label = ui::Label("Decimate:");
1680     label.show();
1681     hbox2.pack_start(label, FALSE, TRUE, 0);
1682
1683     adj = ui::Adjustment(0, 0, 110, 1, 10, 0);
1684     adj.connect("value_changed", G_CALLBACK(extents_decimate), NULL);
1685     g_object_set_data(G_OBJECT(dlg), "decimate_adj", adj);
1686     scale = ui::HScale(adj);
1687     scale.show();
1688     hbox2.pack_start(scale, TRUE, TRUE, 0);
1689     gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_RIGHT);
1690     gtk_scale_set_digits(GTK_SCALE(scale), 0);
1691     g_object_set_data(G_OBJECT(dlg), "decimate", scale);
1692
1693     frame = ui::Frame("Corner values");
1694     frame.show();
1695     vbox.pack_start(frame, FALSE, TRUE, 0);
1696
1697     table = ui::Table(3, 4, FALSE);
1698     table.show();
1699     gtk_container_set_border_width(GTK_CONTAINER(table), 5);
1700     frame.add(table);
1701     gtk_table_set_row_spacings(table, 5);
1702     gtk_table_set_col_spacings(table, 5);
1703
1704     label = ui::Label("Upper-left:");
1705     label.show();
1706     table.attach(label, {0, 1, 0, 1}, {GTK_FILL, GTK_FILL});
1707
1708     label = ui::Label("Lower-left:");
1709     label.show();
1710     table.attach(label, {0, 1, 1, 2}, {GTK_FILL, GTK_FILL});
1711
1712     label = ui::Label("Upper-right:");
1713     label.show();
1714     table.attach(label, {2, 3, 0, 1}, {GTK_FILL, GTK_FILL});
1715
1716     label = ui::Label("Lower-right:");
1717     label.show();
1718     table.attach(label, {2, 3, 1, 2}, {GTK_FILL, GTK_FILL});
1719
1720     entry = ui::Entry();
1721     entry.show();
1722     table.attach(entry, {1, 2, 0, 1});
1723     entry.dimensions(50, -1);
1724     g_object_set_data(G_OBJECT(dlg), "z01", entry);
1725     entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &Z01);
1726
1727     entry = ui::Entry();
1728     entry.show();
1729     table.attach(entry, {1, 2, 1, 2});
1730     entry.dimensions(50, -1);
1731     g_object_set_data(G_OBJECT(dlg), "z00", entry);
1732     entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &Z00);
1733
1734     entry = ui::Entry();
1735     entry.show();
1736     table.attach(entry, {3, 4, 0, 1});
1737     entry.dimensions(50, -1);
1738     g_object_set_data(G_OBJECT(dlg), "z11", entry);
1739     entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &Z11);
1740
1741     entry = ui::Entry();
1742     entry.show();
1743     table.attach(entry, {3, 4, 1, 2});
1744     entry.dimensions(50, -1);
1745     g_object_set_data(G_OBJECT(dlg), "z10", entry);
1746     entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &Z10);
1747
1748     check = ui::CheckButton("Linear borders");
1749     check.show();
1750     table.attach(check, {0, 4, 2, 3});
1751     g_object_set_data(G_OBJECT(dlg), "linearborder", check);
1752     check.connect("toggled", G_CALLBACK(extents_linearborder), NULL);
1753
1754     vbox = ui::VBox(FALSE, 10);
1755     vbox.show();
1756     gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1757
1758     label = ui::Label("Bitmap");
1759     label.show();
1760     gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, label);
1761
1762     label = ui::Label("");
1763     label.show();
1764     vbox.pack_start(label, FALSE, TRUE, 0);
1765     g_object_set_data(G_OBJECT(dlg), "bmp_note", label);
1766
1767     table = ui::Table(2, 2, FALSE);
1768     table.show();
1769     gtk_container_set_border_width(GTK_CONTAINER(table), 5);
1770     vbox.pack_start(table, FALSE, TRUE, 0);
1771     gtk_table_set_row_spacings(table, 5);
1772     gtk_table_set_col_spacings(table, 5);
1773
1774     label = ui::Label("Filename:");
1775     label.show();
1776     table.attach(label, {0, 1, 0, 1}, {GTK_FILL, GTK_FILL});
1777     g_object_set_data(G_OBJECT(dlg), "bmp_text1", label);
1778
1779     entry = ui::Entry();
1780     entry.show();
1781     table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
1782     g_object_set_data(G_OBJECT(dlg), "bmp_file", entry);
1783     entry.connect("focus_out_event", G_CALLBACK(bitmap_file_entryfocusout), NULL);
1784
1785     hbox2 = ui::HBox(TRUE, 5);
1786     hbox2.show();
1787     table.attach(hbox2, {1, 2, 1, 2}, {0, GTK_EXPAND | GTK_FILL});
1788
1789     button = ui::Button("Browse...");
1790     button.show();
1791     hbox2.pack_start(button, FALSE, FALSE, 0);
1792     button.dimensions(60, -1);
1793     g_object_set_data(G_OBJECT(dlg), "bmp_file_browse", button);
1794     button.connect("clicked", G_CALLBACK(bitmap_browse), NULL);
1795
1796     button = ui::Button("Reload");
1797     button.show();
1798     hbox2.pack_start(button, FALSE, FALSE, 0);
1799     button.dimensions(60, -1);
1800     g_object_set_data(G_OBJECT(dlg), "bmp_reload", button);
1801     button.connect("clicked", G_CALLBACK(bitmap_reload), NULL);
1802
1803     table = ui::Table(2, 2, TRUE);
1804     table.show();
1805     gtk_container_set_border_width(GTK_CONTAINER(table), 5);
1806     vbox.pack_start(table, FALSE, TRUE, 0);
1807     gtk_table_set_row_spacings(table, 5);
1808     gtk_table_set_col_spacings(table, 5);
1809
1810     label = ui::Label("Map color 0 to:");
1811     label.show();
1812     table.attach(label, {0, 1, 0, 1}, {GTK_FILL | GTK_EXPAND, GTK_FILL});
1813     g_object_set_data(G_OBJECT(dlg), "bmp_text2", label);
1814     gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1815     gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT);
1816
1817     label = ui::Label("Map color 255 to:");
1818     label.show();
1819     table.attach(label, {0, 1, 1, 2}, {GTK_FILL | GTK_EXPAND, GTK_FILL});
1820     g_object_set_data(G_OBJECT(dlg), "bmp_text3", label);
1821     gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1822     gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT);
1823
1824     hbox2 = ui::HBox(FALSE, 5);
1825     hbox2.show();
1826     table.attach(hbox2, {1, 2, 0, 1});
1827
1828     entry = ui::Entry();
1829     entry.show();
1830     hbox2.pack_start(entry, FALSE, FALSE, 0);
1831     entry.dimensions(50, -1);
1832     g_object_set_data(G_OBJECT(dlg), "bmp_black", entry);
1833     entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &gbmp.black_value);
1834
1835     hbox2 = ui::HBox(FALSE, 5);
1836     hbox2.show();
1837     table.attach(hbox2, {1, 2, 1, 2});
1838
1839     entry = ui::Entry();
1840     entry.show();
1841     hbox2.pack_start(entry, FALSE, FALSE, 0);
1842     entry.dimensions(50, -1);
1843     g_object_set_data(G_OBJECT(dlg), "bmp_white", entry);
1844     entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &gbmp.white_value);
1845
1846     vbox = ui::VBox(FALSE, 10);
1847     vbox.show();
1848     gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1849
1850     label = ui::Label("Fix Points");
1851     label.show();
1852     gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, label);
1853
1854     label = ui::Label("Click on a vertex in the lower half of the preview window,\n"
1855                               "then use the arrow keys or text box to assign a value.\n"
1856                               "Use Ctrl+Click to select multiple vertices/toggle a\n"
1857                               "selection. Use Shift+Click to select a range of vertices.\n\n"
1858                               "Click \"Free\" to unlock a vertex. Vertices within \"Range\n"
1859                               "affected\" will be influenced by this vertex.");
1860     label.show();
1861     vbox.pack_start(label, FALSE, TRUE, 0);
1862
1863     table = ui::Table(3, 3, FALSE);
1864     table.show();
1865     gtk_container_set_border_width(GTK_CONTAINER(table), 5);
1866     vbox.pack_start(table, FALSE, TRUE, 0);
1867     gtk_table_set_row_spacings(table, 5);
1868     gtk_table_set_col_spacings(table, 5);
1869
1870     label = ui::Label("Value:");
1871     label.show();
1872     table.attach(label, {0, 1, 0, 1}, {GTK_FILL, GTK_FILL});
1873     gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1874     g_object_set_data(G_OBJECT(dlg), "fix_value_text", label);
1875
1876     label = ui::Label("Range affected:");
1877     label.show();
1878     table.attach(label, {0, 1, 1, 2}, {GTK_FILL, GTK_FILL});
1879     gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1880     g_object_set_data(G_OBJECT(dlg), "fix_range_text", label);
1881
1882     label = ui::Label("Rate of change:");
1883     label.show();
1884     table.attach(label, {0, 1, 2, 3}, {GTK_FILL, GTK_FILL});
1885     gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1886     g_object_set_data(G_OBJECT(dlg), "fix_rate_text", label);
1887
1888     adj = ui::Adjustment(0, -65536, 65536, 1, 16, 0);
1889     adj.connect("value_changed", G_CALLBACK(fix_value_changed), NULL);
1890     spin = ui::SpinButton(adj, 1, 0);
1891     spin.show();
1892     table.attach(spin, {1, 2, 0, 1}, {GTK_EXPAND, GTK_EXPAND});
1893     spin.dimensions(60, -1);
1894     g_object_set_data(G_OBJECT(dlg), "fix_value", spin);
1895     spin.connect("focus_out_event", G_CALLBACK(fix_value_entryfocusout), NULL);
1896
1897     entry = ui::Entry();
1898     entry.show();
1899     table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND, GTK_FILL});
1900     entry.dimensions(60, -1);
1901     g_object_set_data(G_OBJECT(dlg), "fix_range", entry);
1902     entry.connect("focus_out_event", G_CALLBACK(fix_range_entryfocusout), NULL);
1903
1904     entry = ui::Entry();
1905     entry.show();
1906     table.attach(entry, {1, 2, 2, 3}, {GTK_EXPAND, GTK_FILL});
1907     entry.dimensions(60, -1);
1908     g_object_set_data(G_OBJECT(dlg), "fix_rate", entry);
1909     entry.connect("focus_out_event", G_CALLBACK(fix_rate_entryfocusout), NULL);
1910
1911     button = ui::Button("Free");
1912     button.show();
1913     table.attach(button, {2, 3, 0, 1}, {GTK_EXPAND, GTK_FILL});
1914     button.dimensions(60, -1);
1915     g_object_set_data(G_OBJECT(dlg), "fix_free", button);
1916     button.connect("clicked", G_CALLBACK(fix_free), NULL);
1917
1918     button = ui::Button("Free All");
1919     button.show();
1920     table.attach(button, {2, 3, 1, 2}, {GTK_EXPAND, GTK_FILL});
1921     button.dimensions(60, -1);
1922     g_object_set_data(G_OBJECT(dlg), "fix_freeall", button);
1923     button.connect("clicked", G_CALLBACK(fix_freeall), NULL);
1924
1925     vbox = ui::VBox(FALSE, 10);
1926     vbox.show();
1927     gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1928
1929     label = ui::Label("Texture");
1930     label.show();
1931     gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, label);
1932
1933     // ^Fishman - Modified to add more labels and textboxes.
1934     table = ui::Table(5, 2, FALSE);
1935     table.show();
1936     vbox.pack_start(table, FALSE, TRUE, 0);
1937     gtk_table_set_row_spacings(table, 5);
1938     gtk_table_set_col_spacings(table, 5);
1939
1940     label = ui::Label("Surface:");
1941     label.show();
1942     table.attach(label, {0, 1, 0, 1}, {GTK_FILL, GTK_FILL});
1943     gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1944
1945     label = ui::Label("Other:");
1946     label.show();
1947     table.attach(label, {0, 1, 1, 2}, {GTK_FILL, GTK_FILL});
1948     gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1949
1950     label = ui::Label("Steep:");
1951     label.show();
1952     table.attach(label, {0, 1, 2, 3}, {GTK_FILL, GTK_FILL});
1953     gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1954
1955     entry = ui::Entry();
1956     entry.show();
1957     table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
1958     entry.dimensions(60, -1);
1959     g_object_set_data(G_OBJECT(dlg), "texture1", entry);
1960     entry.connect("focus_out_event", G_CALLBACK(texture_entryfocusout), GINT_TO_POINTER(0));
1961
1962     entry = ui::Entry();
1963     entry.show();
1964     table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
1965     entry.dimensions(60, -1);
1966     g_object_set_data(G_OBJECT(dlg), "texture2", entry);
1967     entry.connect("focus_out_event", G_CALLBACK(texture_entryfocusout), GINT_TO_POINTER(1));
1968
1969     entry = ui::Entry();
1970     entry.show();
1971     table.attach(entry, {1, 2, 2, 3}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
1972     entry.dimensions(60, -1);
1973     g_object_set_data(G_OBJECT(dlg), "texture3", entry);
1974
1975     hbox2 = ui::HBox(FALSE, 5);
1976     hbox2.show();
1977     vbox.pack_start(hbox2, FALSE, TRUE, 0);
1978
1979     label = ui::Label("\"Steep\" angle:");
1980     label.show();
1981     hbox2.pack_start(label, FALSE, TRUE, 0);
1982
1983     adj = ui::Adjustment(60, 0, 90, 1, 10, 0);
1984     spin = ui::SpinButton(adj, 1, 0);
1985     spin.show();
1986     hbox2.pack_start(spin, FALSE, TRUE, 0);
1987     g_object_set_data(G_OBJECT(dlg), "tex_slant", spin);
1988
1989     table = ui::Table(2, 4, TRUE);
1990     table.show();
1991     vbox.pack_start(table, FALSE, TRUE, 0);
1992     gtk_table_set_row_spacings(table, 5);
1993     gtk_table_set_col_spacings(table, 5);
1994
1995     label = ui::Label("Offset <h,v>");
1996     label.show();
1997     table.attach(label, {0, 2, 0, 1}, {GTK_FILL, GTK_FILL});
1998
1999     label = ui::Label("Scale <h,v>");
2000     label.show();
2001     table.attach(label, {2, 4, 0, 1}, {GTK_FILL, GTK_FILL});
2002
2003     entry = ui::Entry();
2004     entry.show();
2005     table.attach(entry, {0, 1, 1, 2}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
2006     entry.dimensions(60, -1);
2007     g_object_set_data(G_OBJECT(dlg), "texoffsetx", entry);
2008
2009     entry = ui::Entry();
2010     entry.show();
2011     table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
2012     entry.dimensions(60, -1);
2013     g_object_set_data(G_OBJECT(dlg), "texoffsety", entry);
2014
2015     entry = ui::Entry();
2016     entry.show();
2017     table.attach(entry, {2, 3, 1, 2}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
2018     entry.dimensions(60, -1);
2019     g_object_set_data(G_OBJECT(dlg), "texscalex", entry);
2020
2021     entry = ui::Entry();
2022     entry.show();
2023     table.attach(entry, {3, 4, 1, 2}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
2024     entry.dimensions(60, -1);
2025     g_object_set_data(G_OBJECT(dlg), "texscaley", entry);
2026
2027
2028     check = ui::CheckButton("Use detail brushes");
2029     check.show();
2030     vbox.pack_start(check, FALSE, TRUE, 0);
2031     g_object_set_data(G_OBJECT(dlg), "detail", check);
2032     check.connect("toggled", G_CALLBACK(texture_detail), NULL);
2033
2034     check = ui::CheckButton("Detail hint brushes");
2035     check.show();
2036     vbox.pack_start(check, FALSE, TRUE, 0);
2037     g_object_set_data(G_OBJECT(dlg), "hint", check);
2038     check.connect("toggled", G_CALLBACK(texture_hint), NULL);
2039
2040     // ^Fishman - Add terrain key to func_group.
2041     check = ui::CheckButton("Add terrain key");
2042     check.show();
2043     vbox.pack_start(check, FALSE, TRUE, 0);
2044     g_object_set_data(G_OBJECT(dlg), "terrain_ent", check);
2045     check.connect("toggled", G_CALLBACK(texture_terrainent), NULL);
2046
2047     vbox = ui::VBox(FALSE, 5);
2048     vbox.show();
2049     hbox.pack_start(vbox, FALSE, TRUE, 0);
2050
2051     button = ui::Button("OK");
2052     button.show();
2053     vbox.pack_start(button, FALSE, TRUE, 0);
2054     button.dimensions(60, -1);
2055     g_object_set_data(G_OBJECT(dlg), "go", button);
2056     button.connect("clicked", G_CALLBACK(main_go), NULL);
2057
2058     label = ui::Label("Settings:");
2059     label.show();
2060     vbox.pack_start(label, FALSE, TRUE, 0);
2061
2062     button = ui::Button("Open...");
2063     button.show();
2064     vbox.pack_start(button, FALSE, TRUE, 0);
2065     g_object_set_data(G_OBJECT(dlg), "open", button);
2066     button.connect("clicked", G_CALLBACK(main_open), NULL);
2067
2068     button = ui::Button("Save as...");
2069     button.show();
2070     vbox.pack_start(button, FALSE, TRUE, 0);
2071     g_object_set_data(G_OBJECT(dlg), "save", button);
2072     button.connect("clicked", G_CALLBACK(main_save), NULL);
2073
2074     button = ui::Button("Defaults");
2075     button.show();
2076     vbox.pack_start(button, FALSE, TRUE, 0);
2077     g_object_set_data(G_OBJECT(dlg), "defaults", button);
2078     button.connect("clicked", G_CALLBACK(main_defaults), NULL);
2079
2080     button = ui::Button("About...");
2081     button.show();
2082     vbox.pack_start(button, FALSE, TRUE, 0);
2083     button.connect("clicked", G_CALLBACK(main_about), NULL);
2084
2085     check = ui::CheckButton("Preview");
2086     check.show();
2087     vbox.pack_start(check, FALSE, TRUE, 0);
2088     check.connect("toggled", G_CALLBACK(main_preview), NULL);
2089     g_object_set_data(G_OBJECT(dlg), "main_preview", check);
2090
2091     // ^Fishman - Antializing for the preview window.
2092     check = ui::CheckButton("Antialised lines");
2093     check.show();
2094     vbox.pack_start(check, FALSE, TRUE, 0);
2095     g_object_set_data(G_OBJECT(dlg), "main_antialiasing", check);
2096     check.connect("toggled", G_CALLBACK(main_antialiasing), NULL);
2097
2098     for (i = 0; i < 5; i++) {
2099         SetDlgValues(i);
2100     }
2101
2102     CreateViewWindow();
2103
2104     create_tooltips();
2105
2106     FirstPassComplete = 1;
2107
2108     return dlg;
2109 }
2110
2111
2112 #if 0
2113
2114                                                                                                                         HWND hwndDisplay = (HWND)NULL;
2115 HWND ghwndTab    = (HWND)NULL;
2116 int iTab = 0;
2117 Rect rcTab;
2118 FILE *ftex;
2119
2120 char GenSurfURL[40] = {"http://tarot.telefragged.com/gensurf"};
2121 char GenSurfBoard[40] = {"http://tarot.telefragged.com/board"};
2122
2123 /*
2124  * AboutDlgProc - processes messages for the about dialog.
2125  */
2126
2127 qboolean CALLBACK AboutDlgProc( HWND hwnd, unsigned msg, UINT wparam, LONG lparam ){
2128         char szText[256];
2129         DRAWITEMSTRUCT *dis;
2130         HDC hdc;
2131         HPEN hpen;
2132         HWND hwndURL;
2133         Rect rc;
2134         SIZE size;
2135
2136         lparam = lparam;                    /* turn off warning */
2137
2138         switch ( msg ) {
2139         case WM_INITDIALOG:
2140                 strcpy( szText,"About " );
2141                 strcat( szText,gszCaption );
2142                 SetWindowText( hwnd,gszCaption );
2143                 SetDlgItemText( hwnd,DLG_ABOUT_APP,szText );
2144                 /*      Application icon: */
2145                 SendDlgItemMessage( hwnd, DLG_ABOUT_ICON,
2146                                                         STM_SETICON, (WPARAM)(HICON)LoadIcon( ghInst,"GENSURF" ),
2147                                                         (LPARAM) NULL );
2148
2149                 hwndURL = GetDlgItem( hwnd,DLG_ABOUT_URL );
2150                 hdc = GetDC( hwndURL );
2151                 GetTextExtentPoint( hdc,GenSurfURL,strlen( GenSurfURL ),&size );
2152                 ReleaseDC( hwndURL,hdc );
2153                 GetWindowRect( hwndURL,&rc );
2154                 SetWindowPos( hwndURL,(HWND)NULL,0,0,size.cx,size.cy + 2,
2155                                           SWP_NOMOVE | SWP_NOZORDER );
2156
2157                 hwndURL = GetDlgItem( hwnd,DLG_ABOUT_BOARD );
2158                 hdc = GetDC( hwndURL );
2159                 GetTextExtentPoint( hdc,GenSurfBoard,strlen( GenSurfBoard ),&size );
2160                 ReleaseDC( hwndURL,hdc );
2161                 GetWindowRect( hwndURL,&rc );
2162                 SetWindowPos( hwndURL,(HWND)NULL,0,0,size.cx,size.cy + 2,
2163                                           SWP_NOMOVE | SWP_NOZORDER );
2164
2165                 return TRUE;
2166
2167         case WM_COMMAND:
2168                 switch ( LOWORD( wparam ) )
2169                 {
2170                 case DLG_ABOUT_URL:
2171                         HTTP( GenSurfURL );
2172                         break;
2173                 case DLG_ABOUT_BOARD:
2174                         HTTP( GenSurfBoard );
2175                         break;
2176                 case IDOK:
2177                         EndDialog( hwnd,1 );
2178                         return TRUE;
2179                 }
2180                 break;
2181
2182         case WM_DRAWITEM:
2183                 if ( wparam == DLG_ABOUT_URL ) {
2184                         dis = (LPDRAWITEMSTRUCT)lparam;
2185                         SetTextColor( dis->hDC,RGB( 0,0,255 ) );
2186                         TextOut( dis->hDC,0,0,GenSurfURL,strlen( GenSurfURL ) );
2187                         GetWindowRect( dis->hwndItem,&rc );
2188                         GetTextExtentPoint( dis->hDC,GenSurfURL,strlen( GenSurfURL ),&size );
2189                         hpen = CreatePen( PS_SOLID,0,RGB( 0,0,255 ) );
2190                         SelectObject( dis->hDC,hpen );
2191                         MoveToEx( dis->hDC,0,size.cy,NULL );
2192                         LineTo( dis->hDC,size.cx,size.cy );
2193                         SelectObject( dis->hDC,GetStockObject( BLACK_PEN ) );
2194                         DeleteObject( hpen );
2195                 }
2196                 else if ( wparam == DLG_ABOUT_BOARD ) {
2197                         dis = (LPDRAWITEMSTRUCT)lparam;
2198                         SetTextColor( dis->hDC,RGB( 0,0,255 ) );
2199                         TextOut( dis->hDC,0,0,GenSurfBoard,strlen( GenSurfBoard ) );
2200                         GetWindowRect( dis->hwndItem,&rc );
2201                         GetTextExtentPoint( dis->hDC,GenSurfBoard,strlen( GenSurfBoard ),&size );
2202                         hpen = CreatePen( PS_SOLID,0,RGB( 0,0,255 ) );
2203                         SelectObject( dis->hDC,hpen );
2204                         MoveToEx( dis->hDC,0,size.cy,NULL );
2205                         LineTo( dis->hDC,size.cx,size.cy );
2206                         SelectObject( dis->hDC,GetStockObject( BLACK_PEN ) );
2207                         DeleteObject( hpen );
2208                 }
2209                 break;
2210
2211         case WM_CLOSE:
2212                 EndDialog( hwnd,1 );
2213                 return TRUE;
2214
2215         default:
2216                 return FALSE;
2217         }
2218         return FALSE;
2219
2220 } /* AboutDlgProc */
2221
2222 void About(){
2223         if ( DialogBox( ghInst,"About", ghwnd_main, (DLGPROC)AboutDlgProc ) < 0 ) {
2224                 char Text[256];
2225                 sprintf( Text,"In About(), GetLastError()=0x%08x",GetLastError() );
2226                 MessageBox( ghwnd_main,Text,"GenSurf",eMB_ICONWARNING );
2227         }
2228 }
2229
2230 #endif