more eol-style
[xonotic/netradiant.git] / plugins / surface / surfacedialog.cpp
1 /*
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 //
23 // Surface Dialog Module
24 //
25
26 //
27 // Nurail: Implemented to Module from the main Radiant Surface Dialog code
28 //
29
30
31 #include <gtk/gtk.h>
32 #include <gdk/gdkkeysyms.h>
33
34 #include "surfdlg_plugin.h"
35
36
37
38 #ifdef _DEBUG
39 //#define DBG_SI 1
40 #endif
41
42 #include "gtkr_vector.h"
43
44 vector<texdef_to_face_t> g_texdef_face_vector;
45
46 inline texdef_to_face_t* get_texdef_face_list()
47 {
48   return &(*g_texdef_face_vector.begin());
49 }
50
51 inline unsigned int texdef_face_list_empty()
52 {
53   return g_texdef_face_vector.empty();
54 }
55
56 inline unsigned int texdef_face_list_size()
57 {
58   return g_texdef_face_vector.size();
59 }
60
61 // For different faces having different values
62 bool is_HShift_conflicting;
63 bool is_VShift_conflicting;
64 bool is_HScale_conflicting;
65 bool is_VScale_conflicting;
66 bool is_Rotate_conflicting;
67 bool is_TextureName_conflicting;
68
69 void ShowDlg();
70 void HideDlg();
71 void SetTexMods();
72 void GetTexMods(bool b_SetUndoPoint = FALSE);
73 void BuildDialog();
74 void FitAll();
75 void InitDefaultIncrement(texdef_t *);
76 void DoSnapTToGrid(float hscale, float vscale);
77 // called to perform a fitting from the outside (shortcut key)
78 void SurfaceDialogFitAll();
79
80
81 // Dialog Data
82 int m_nHeight;
83 int m_nWidth;
84
85 // 0 is invalid, otherwise it's the Id of the last 'do' we are responsible for
86 int m_nUndoId;
87
88
89 texturewin_t *texturewin;
90 texdef_t *l_pIncrement;
91 texdef_t texdef_offset;
92 texdef_t texdef_SI_values;
93
94 // For Texture Entry, activate only on entry change
95 char old_texture_entry[128];
96
97 // the texdef to switch back to when the OnCancel is called
98 texdef_t        g_old_texdef;
99
100 // when TRUE, this thing means the surface inspector is currently being displayed
101 bool  g_surfwin = FALSE;
102 // turn on/off processing of the "changed" "value_changed" messages
103 // (need to turn off when we are feeding data in)
104 bool g_bListenChanged = true;
105 // turn on/off listening of the update messages
106 bool g_bListenUpdate = true;
107
108 GtkWidget* create_SurfaceInspector (void);
109 GtkWidget *SurfaceInspector = NULL;
110
111 GtkWidget *m_pWidget;
112 GtkWidget *GetWidget () { return SurfaceInspector; }
113 GtkWidget *Get_SI_Module_Widget () { return SurfaceInspector; }
114 void SetWidget(GtkWidget *new_widget) { m_pWidget = new_widget; }
115 GtkWidget *GetDlgWidget (const char* name)
116   { return GTK_WIDGET (g_object_get_data (G_OBJECT (SurfaceInspector), name)); }
117
118 // Spins for FitTexture
119 GtkWidget *spin_width;
120 GtkWidget *spin_height;
121
122
123 GtkWidget *texture_combo;
124 GtkWidget *texture_combo_entry;
125
126 GtkWidget *match_grid_button;
127 GtkWidget *lock_valuechange_togglebutton;
128
129 GtkObject *hshift_value_spinbutton_adj;
130 GtkWidget *hshift_value_spinbutton;
131 GtkObject *vshift_value_spinbutton_adj;
132 GtkWidget *vshift_value_spinbutton;
133 GtkObject *hscale_value_spinbutton_adj;
134 GtkWidget *hscale_value_spinbutton;
135 GtkObject *vscale_value_spinbutton_adj;
136 GtkWidget *vscale_value_spinbutton;
137 GtkObject *rotate_value_spinbutton_adj;
138 GtkWidget *rotate_value_spinbutton;
139
140 GtkObject *hshift_offset_spinbutton_adj;
141 GtkWidget *hshift_offset_spinbutton;
142 GtkObject *vshift_offset_spinbutton_adj;
143 GtkWidget *vshift_offset_spinbutton;
144 GtkObject *hscale_offset_spinbutton_adj;
145 GtkWidget *hscale_offset_spinbutton;
146 GtkObject *vscale_offset_spinbutton_adj;
147 GtkWidget *vscale_offset_spinbutton;
148 GtkObject *rotate_offset_spinbutton_adj;
149 GtkWidget *rotate_offset_spinbutton;
150
151 GtkObject *hshift_step_spinbutton_adj;
152 GtkWidget *hshift_step_spinbutton;
153 GtkObject *vshift_step_spinbutton_adj;
154 GtkWidget *vshift_step_spinbutton;
155 GtkObject *hscale_step_spinbutton_adj;
156 GtkWidget *hscale_step_spinbutton;
157 GtkObject *vscale_step_spinbutton_adj;
158 GtkWidget *vscale_step_spinbutton;
159 GtkObject *rotate_step_spinbutton_adj;
160 GtkWidget *rotate_step_spinbutton;
161
162 GtkObject *fit_width_spinbutton_adj;
163 GtkWidget *fit_width_spinbutton;
164 GtkObject *fit_height_spinbutton_adj;
165 GtkWidget *fit_height_spinbutton;
166 GtkWidget *fit_button;
167 GtkWidget *axial_button;
168
169 GtkWidget *done_button;
170 GtkWidget *apply_button;
171 GtkWidget *cancel_button;
172
173 // Callbacks
174 gboolean on_texture_combo_entry_key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer user_data);
175 void on_texture_combo_entry_activate (GtkEntry *entry, gpointer user_data);
176
177 static void on_match_grid_button_clicked (GtkButton *button, gpointer user_data);
178 static void on_lock_valuechange_togglebutton_toggled (GtkToggleButton *togglebutton, gpointer user_data);
179
180 static void on_hshift_value_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data);
181 static void on_vshift_value_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data);
182 static void on_hscale_value_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data);
183 static void on_vscale_value_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data);
184 static void on_rotate_value_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data);
185
186 static void on_hshift_offset_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data);
187 static void on_vshift_offset_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data);
188 static void on_hscale_offset_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data);
189 static void on_vscale_offset_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data);
190 static void on_rotate_offset_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data);
191
192 static void on_hshift_step_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data);
193 static void on_vshift_step_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data);
194 static void on_hscale_step_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data);
195 static void on_vscale_step_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data);
196 static void on_rotate_step_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data);
197
198 static void on_fit_width_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data);
199 static void on_fit_height_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data);
200 static void on_fit_button_clicked (GtkButton *button, gpointer user_data);
201 static void on_axial_button_clicked (GtkButton *button, gpointer user_data);
202
203 static void on_done_button_clicked (GtkButton *button, gpointer user_data);
204 static void on_apply_button_clicked (GtkButton *button, gpointer user_data);
205 static void on_cancel_button_clicked (GtkButton *button, gpointer user_data);
206
207
208 /*
209 ===================================================
210
211   SURFACE INSPECTOR
212
213 ===================================================
214 */
215
216
217 void IsFaceConflicting()
218 {
219   texdef_t* tmp_texdef;
220   texdef_to_face_t* temp_texdef_face_list;
221   char buf[12];
222   char texture_name[128];
223
224   if (texdef_face_list_empty())
225   {
226     gtk_entry_set_text( GTK_ENTRY (hshift_value_spinbutton), "");
227     gtk_entry_set_text( GTK_ENTRY (vshift_value_spinbutton), "");
228     gtk_entry_set_text( GTK_ENTRY (hscale_value_spinbutton), "");
229     gtk_entry_set_text( GTK_ENTRY (vscale_value_spinbutton), "");
230     gtk_entry_set_text( GTK_ENTRY (rotate_value_spinbutton), "");
231     gtk_entry_set_text( GTK_ENTRY (texture_combo_entry), "");
232     return;
233   }
234
235   g_bListenChanged = FALSE;
236
237   tmp_texdef = &get_texdef_face_list()->texdef;
238
239   strcpy(texture_name, tmp_texdef->GetName() );
240
241   texdef_SI_values.shift[0] = tmp_texdef->shift[0];
242   texdef_SI_values.shift[1] = tmp_texdef->shift[1];
243   texdef_SI_values.scale[0] = tmp_texdef->scale[0];
244   texdef_SI_values.scale[1] = tmp_texdef->scale[1];
245   texdef_SI_values.rotate = tmp_texdef->rotate;
246   texdef_SI_values.SetName( texture_name );
247
248   is_HShift_conflicting = FALSE;
249   is_VShift_conflicting = FALSE;
250   is_HScale_conflicting = FALSE;
251   is_VScale_conflicting = FALSE;
252   is_Rotate_conflicting = FALSE;
253   is_TextureName_conflicting = FALSE;
254
255   if (texdef_face_list_size() > 1)
256   {
257     temp_texdef_face_list = get_texdef_face_list()->next;
258
259     for (temp_texdef_face_list; temp_texdef_face_list; temp_texdef_face_list = temp_texdef_face_list->next)
260     {
261       tmp_texdef = &temp_texdef_face_list->texdef;
262       if ( texdef_SI_values.shift[0] != tmp_texdef->shift[0] )
263         is_HShift_conflicting = TRUE;
264
265       if ( texdef_SI_values.shift[1] != tmp_texdef->shift[1] )
266         is_VShift_conflicting = TRUE;
267
268       if ( texdef_SI_values.scale[0] != tmp_texdef->scale[0] )
269         is_HScale_conflicting = TRUE;
270
271       if ( texdef_SI_values.scale[1] != tmp_texdef->scale[1] )
272         is_VScale_conflicting = TRUE;
273
274       if ( texdef_SI_values.rotate != tmp_texdef->rotate )
275         is_Rotate_conflicting = TRUE;
276
277       if ( strcmp( texture_name, tmp_texdef->GetName() ) )
278         is_TextureName_conflicting = TRUE;
279     }
280   }
281
282   if(is_HShift_conflicting)
283     gtk_entry_set_text( GTK_ENTRY (hshift_value_spinbutton), "");
284   else
285     gtk_spin_button_set_value( GTK_SPIN_BUTTON(hshift_value_spinbutton) , texdef_SI_values.shift[0] );
286
287   if(is_VShift_conflicting)
288     gtk_entry_set_text( GTK_ENTRY (vshift_value_spinbutton), "");
289   else
290     gtk_spin_button_set_value( GTK_SPIN_BUTTON(vshift_value_spinbutton) , texdef_SI_values.shift[1] );
291
292   if(is_HScale_conflicting)
293     gtk_entry_set_text( GTK_ENTRY (hscale_value_spinbutton), "");
294   else
295     gtk_spin_button_set_value( GTK_SPIN_BUTTON(hscale_value_spinbutton) , texdef_SI_values.scale[0] );
296
297   if(is_VScale_conflicting)
298     gtk_entry_set_text( GTK_ENTRY (vscale_value_spinbutton), "");
299   else
300     gtk_spin_button_set_value( GTK_SPIN_BUTTON(vscale_value_spinbutton) , texdef_SI_values.scale[1] );
301
302   if(is_Rotate_conflicting)
303     gtk_entry_set_text( GTK_ENTRY (rotate_value_spinbutton), "");
304   else
305     gtk_spin_button_set_value( GTK_SPIN_BUTTON(rotate_value_spinbutton) , texdef_SI_values.rotate );
306
307   g_bListenChanged = TRUE;
308 }
309
310 #define MAX_NUM_LIST_ITEMS 15
311 static void PopulateTextureComboList()
312 {
313   texdef_t* tmp_texdef;
314   texdef_to_face_t* temp_texdef_face_list;
315   char blank[1];
316   GList *items = NULL;
317   GList *tmp_item;
318   int num_of_list_items = 0;
319
320   blank[0] = 0;
321   
322   if (texdef_face_list_empty())
323   {
324     items = g_list_append (items, (gpointer) blank);
325     // For Texture Entry, activate only on entry change
326     strcpy (old_texture_entry, blank);
327   }
328   else if ( !is_TextureName_conflicting )
329   {
330     temp_texdef_face_list = get_texdef_face_list(); 
331     tmp_texdef = (texdef_t *) &get_texdef_face_list()->texdef;
332     items = g_list_append( items, (gpointer) tmp_texdef->GetName() );
333     // For Texture Entry, activate only on entry change
334     strcpy (old_texture_entry, tmp_texdef->GetName());
335   }
336   else
337   {
338     for (temp_texdef_face_list = get_texdef_face_list(); temp_texdef_face_list; temp_texdef_face_list = temp_texdef_face_list->next)
339     {
340       tmp_texdef = (texdef_t *) &temp_texdef_face_list->texdef;
341       // Need to do a string compare, hence the custom search
342       if (!( g_list_find_custom (items, tmp_texdef->GetName(), (GCompareFunc) strcmp ) ))
343       {
344         items = g_list_append( items, (gpointer) tmp_texdef->GetName() );
345         num_of_list_items++;
346       }
347       // Make sure the combo list isn't too long
348       if (num_of_list_items >= MAX_NUM_LIST_ITEMS)
349         break;
350     }
351     // If this isn't added last (to the top of the list), g_list_find freaks.
352     items = g_list_prepend (items, (gpointer) blank);
353     // For Texture Entry, activate only on entry change
354     strcpy (old_texture_entry, blank);
355   }
356   
357   gtk_combo_set_popdown_strings (GTK_COMBO (texture_combo), items);
358   g_list_free(items);
359
360 }
361
362 static void ZeroOffsetValues()
363 {
364   texdef_offset.shift[0] = 0.0;
365   texdef_offset.shift[1] = 0.0;
366   texdef_offset.scale[0] = 0.0;
367   texdef_offset.scale[1] = 0.0;
368   texdef_offset.rotate = 0.0;
369 }
370
371 static void GetTexdefInfo_from_Radiant()
372 {
373   g_texdef_face_vector.clear();
374
375   unsigned int count = GetSelectedFaceCountfromBrushes();
376   if(count == 0)
377     count = GetSelectedFaceCount();
378     
379   g_texdef_face_vector.resize(count);
380
381   if (!texdef_face_list_empty())
382   {
383     texdef_to_face_t* p = get_texdef_face_list();
384     GetSelFacesTexdef( get_texdef_face_list() );
385   }
386   
387   IsFaceConflicting();
388   PopulateTextureComboList(); 
389   ZeroOffsetValues();
390 }
391
392 static gint delete_event_callback(GtkWidget *widget, GdkEvent* event, gpointer data)
393 {
394   HideDlg();
395   return TRUE;
396 }
397
398 // make the shift increments match the grid settings
399 // the objective being that the shift+arrows shortcuts move the texture by the corresponding grid size
400 // this depends on a scale value if you have selected a particular texture on which you want it to work:
401 // we move the textures in pixels, not world units. (i.e. increment values are in pixel)
402 // depending on the texture scale it doesn't take the same amount of pixels to move of g_qeglobals.d_gridsize
403 // increment * scale = gridsize
404 // hscale and vscale are optional parameters, if they are zero they will be set to the default scale
405 // NOTE: the default scale depends if you are using BP mode or regular.
406 // For regular it's 0.5f (128 pixels cover 64 world units), for BP it's simply 1.0f
407 // see fenris #2810
408 void DoSnapTToGrid(float hscale, float vscale)
409 {
410   l_pIncrement = Get_SI_Inc();
411
412   if (hscale == 0.0f)
413   {
414     hscale = 0.5f;
415   }
416   if (vscale == 0.0f)
417   {
418      vscale = 0.5f;
419   }
420 #ifdef _DEBUG
421   Sys_Printf ("DoSnapTToGrid: hscale %g vscale %g\n", hscale, vscale);
422 #endif
423   l_pIncrement->shift[0] = GridSize() / hscale;
424   l_pIncrement->shift[1] = GridSize() / vscale;
425   // now some update work
426   // FIXME: doesn't look good here, seems to be called several times
427   SetTexMods();
428 }
429
430 void UpdateSurfaceDialog()
431 {
432   if (!g_bListenUpdate)
433     return;
434     
435   if (!SurfaceInspector)
436     return;
437
438   // avoid long delays on slow computers
439   while (gtk_events_pending ())
440     gtk_main_iteration ();
441     
442   if (g_surfwin)
443   {
444 #ifdef DBG_SI
445     Sys_Printf("UpdateSurfaceDialog\n");
446 #endif
447     GetTexdefInfo_from_Radiant();
448     SetTexMods();
449   }
450
451 }
452
453 // DoSurface will always try to show the surface inspector
454 // or update it because something new has been selected
455 void DoSurface (void)
456 {
457 #ifdef DBG_SI
458   Sys_Printf("DoSurface\n");
459 #endif
460   if (!SurfaceInspector)
461     create_SurfaceInspector ();
462   
463   ShowDlg();
464   SetTexMods ();
465 }
466
467 void ToggleSurface()
468 {
469 #ifdef DBG_SI
470   Sys_Printf("ToggleSurface Module\n");
471 #endif
472   if (!g_surfwin)
473     DoSurface ();
474   else
475     on_cancel_button_clicked(NULL, NULL);
476 }
477
478 // NOTE: will raise and show the Surface inspector and exec fit for patches and brushes
479 void SurfaceDlgFitAll()
480 {
481   DoSurface();
482   FitAll();
483 }
484
485 // =============================================================================
486 // SurfaceDialog class
487
488 void ShowDlg()
489 {
490
491   if(!SurfaceInspector)
492     create_SurfaceInspector();
493   else
494     gtk_widget_show (SurfaceInspector);
495
496   GetTexdefInfo_from_Radiant();
497   GetTexMods(TRUE); // Set Initial Undo Point
498   g_surfwin = TRUE;
499 }
500
501 void HideDlg()
502 {
503   g_surfwin = FALSE;
504   gtk_widget_hide (SurfaceInspector);
505 }
506
507
508 // set default values for increments (shift scale and rot)
509 // this is called by the prefs code if can't find the values
510 void InitDefaultIncrement(texdef_t *tex)
511 {
512   tex->SetName("foo");
513   tex->shift[0] = 8;
514   tex->shift[1] = 8;
515   tex->scale[0] = 0.25;
516   tex->scale[1] = 0.25;
517   tex->rotate = 10;
518 }
519
520 void BuildDialog ()
521 {
522    if ( !SurfaceInspector )
523     create_SurfaceInspector();
524 }
525
526 /*
527 ==============
528 SetTexMods
529
530 Set the fields to the current texdef (i.e. map/texdef -> dialog widgets)
531 ===============
532 */
533
534 void SetTexMods()
535 {
536   texdef_t *pt;
537   GtkSpinButton *spin;
538   GtkAdjustment *adjust;
539
540   texturewin = Texturewin ();
541   l_pIncrement = Get_SI_Inc();
542
543 #ifdef DBG_SI
544   Sys_Printf("SurfaceDlg SetTexMods\n");
545 #endif
546
547   if (!g_surfwin)
548     return;
549     
550   pt = &texturewin->texdef;
551
552   g_bListenChanged = false;
553
554   if(strncmp(pt->GetName(), "textures/", 9) != 0)
555     texdef_offset.SetName(SHADER_NOT_FOUND);
556
557  
558   spin = GTK_SPIN_BUTTON (hshift_offset_spinbutton);
559   gtk_spin_button_set_value (spin, texdef_offset.shift[0]);
560   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));
561   adjust->step_increment = l_pIncrement->shift[0];
562   gtk_spin_button_set_value (GTK_SPIN_BUTTON(hshift_step_spinbutton), l_pIncrement->shift[0]);
563   
564   spin = GTK_SPIN_BUTTON (hshift_value_spinbutton);
565   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));
566   adjust->step_increment = l_pIncrement->shift[0];
567   
568
569   spin = GTK_SPIN_BUTTON (vshift_offset_spinbutton);
570   gtk_spin_button_set_value (spin, texdef_offset.shift[1]);
571   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));
572   adjust->step_increment = l_pIncrement->shift[1];
573   gtk_spin_button_set_value (GTK_SPIN_BUTTON(vshift_step_spinbutton), l_pIncrement->shift[1]);
574   
575   spin = GTK_SPIN_BUTTON (vshift_value_spinbutton);
576   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));
577   adjust->step_increment = l_pIncrement->shift[1];
578
579
580   spin = GTK_SPIN_BUTTON (hscale_offset_spinbutton);
581   gtk_spin_button_set_value (spin, texdef_offset.scale[0]);
582   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));
583   adjust->step_increment = l_pIncrement->scale[0];
584   gtk_spin_button_set_value (GTK_SPIN_BUTTON(hscale_step_spinbutton), l_pIncrement->scale[0]);
585
586   spin = GTK_SPIN_BUTTON (hscale_value_spinbutton);
587   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));
588   adjust->step_increment = l_pIncrement->scale[0];
589
590   
591   spin = GTK_SPIN_BUTTON (vscale_offset_spinbutton);
592   gtk_spin_button_set_value (spin, texdef_offset.scale[1]);
593   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));
594   adjust->step_increment = l_pIncrement->scale[1];
595   gtk_spin_button_set_value (GTK_SPIN_BUTTON(vscale_step_spinbutton), l_pIncrement->scale[1]);
596   
597   spin = GTK_SPIN_BUTTON (vscale_value_spinbutton);
598   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));
599   adjust->step_increment = l_pIncrement->scale[1];
600   
601
602   spin = GTK_SPIN_BUTTON (rotate_offset_spinbutton);
603   gtk_spin_button_set_value (spin, texdef_offset.rotate);
604   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));
605   adjust->step_increment = l_pIncrement->rotate;
606   gtk_spin_button_set_value (GTK_SPIN_BUTTON(rotate_step_spinbutton), l_pIncrement->rotate);
607   
608   spin = GTK_SPIN_BUTTON (rotate_value_spinbutton);
609   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));
610   adjust->step_increment = l_pIncrement->rotate;
611
612   
613   g_bListenChanged = true;
614
615   // store the current texdef as our escape route if user hits OnCancel
616   g_old_texdef = texturewin->texdef;
617 }
618
619 /*
620 ==============
621 GetTexMods
622
623 Shows any changes to the main Radiant windows
624 ===============
625 */
626 void GetTexMods(bool b_SetUndoPoint)
627 {
628
629 #ifdef DBG_SI
630   Sys_Printf("SurfaceDlg GetTexMods\n");
631 #endif
632
633   if ( !texdef_face_list_empty() )
634   {
635     g_bListenUpdate=FALSE;
636     SetTexdef_FaceList( get_texdef_face_list(), b_SetUndoPoint, false );
637     g_bListenUpdate=TRUE;
638
639     if (b_SetUndoPoint)
640       m_nUndoId = Undo_GetUndoId();
641   }
642 }
643
644 void FitAll()
645 {
646   on_fit_button_clicked(NULL, NULL);
647 }
648
649
650 ////////////////////////////////////////////////////////////////////
651 //
652 //  GUI Section
653 //
654 ////////////////////////////////////////////////////////////////////
655
656 GtkWidget* create_SurfaceInspector (void)
657 {
658   
659   GtkWidget *label;
660   GtkWidget *hseparator;
661   GtkWidget *eventbox;
662
663   GtkWidget *viewport8;
664   GtkWidget *viewport9;
665   GtkWidget *viewport2;
666   GtkWidget *viewport7;
667   GtkWidget *viewport5;
668   GtkWidget *viewport6;
669   GtkWidget *viewport10;
670
671   GtkWidget *table1;
672   GtkWidget *table4;
673   GtkWidget *table5;
674   GtkWidget *table7;
675
676   GtkWidget *alignment1;
677   GtkWidget *alignment2;
678   GtkWidget *alignment3;
679
680   GtkWidget *vbox7;
681
682   GtkWidget *hbox1;
683   GtkWidget *hbox2;
684   GtkWidget *hbox3;
685   GtkWidget *hbox4;
686
687   GtkWidget *image1;
688   GtkWidget *image2;
689   GtkWidget *image3;
690
691   GtkWidget *hbuttonbox1;
692
693   SurfaceInspector = gtk_window_new (GTK_WINDOW_TOPLEVEL);
694   gtk_container_set_border_width (GTK_CONTAINER (SurfaceInspector), 4);
695   gtk_window_set_title (GTK_WINDOW (SurfaceInspector), "Surface Inspector");
696   
697   SetWinPos_from_Prefs(SurfaceInspector);
698
699   viewport8 = gtk_viewport_new (NULL, NULL);
700   gtk_widget_show (viewport8);
701   gtk_container_add (GTK_CONTAINER (SurfaceInspector), viewport8);
702   gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport8), GTK_SHADOW_NONE);
703
704   vbox7 = gtk_vbox_new (FALSE, 0);
705   gtk_widget_show (vbox7);
706   gtk_container_add (GTK_CONTAINER (viewport8), vbox7);
707
708   viewport9 = gtk_viewport_new (NULL, NULL);
709   gtk_widget_show (viewport9);
710   gtk_box_pack_start (GTK_BOX (vbox7), viewport9, FALSE, FALSE, 0);
711   gtk_container_set_border_width (GTK_CONTAINER (viewport9), 2);
712   gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport9), GTK_SHADOW_ETCHED_IN);
713
714   hbox1 = gtk_hbox_new (FALSE, 0);
715   gtk_widget_show (hbox1);
716   gtk_container_add (GTK_CONTAINER (viewport9), hbox1);
717   gtk_container_set_border_width (GTK_CONTAINER (hbox1), 4);
718
719   label = gtk_label_new ("Texture: ");
720   gtk_widget_show (label);
721   gtk_box_pack_start (GTK_BOX (hbox1), label, FALSE, FALSE, 0);
722   gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
723
724   texture_combo = gtk_combo_new ();
725   g_object_set_data (G_OBJECT (GTK_COMBO (texture_combo)->popwin),
726                      "KeepMeAround", texture_combo);
727   gtk_combo_disable_activate ( (GtkCombo*) texture_combo);                   
728   gtk_widget_show (texture_combo);
729   gtk_box_pack_start (GTK_BOX (hbox1), texture_combo, TRUE, TRUE, 0);
730
731   texture_combo_entry = GTK_COMBO (texture_combo)->entry;
732   gtk_widget_show (texture_combo_entry);
733   gtk_entry_set_max_length (GTK_ENTRY (texture_combo_entry), 128);
734
735   viewport2 = gtk_viewport_new (NULL, NULL);
736   gtk_widget_show (viewport2);
737   gtk_box_pack_start (GTK_BOX (vbox7), viewport2, FALSE, TRUE, 0);
738   gtk_container_set_border_width (GTK_CONTAINER (viewport2), 2);
739   gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport2), GTK_SHADOW_ETCHED_IN);
740
741   table1 = gtk_table_new (13, 4, FALSE);
742   gtk_widget_show (table1);
743   gtk_container_add (GTK_CONTAINER (viewport2), table1);
744
745   hseparator = gtk_hseparator_new ();
746   gtk_widget_show (hseparator);
747   gtk_table_attach (GTK_TABLE (table1), hseparator, 1, 2, 1, 2,
748                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
749                     (GtkAttachOptions) (GTK_FILL), 0, 0);
750
751   hseparator = gtk_hseparator_new ();
752   gtk_widget_show (hseparator);
753   gtk_table_attach (GTK_TABLE (table1), hseparator, 2, 3, 1, 2,
754                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
755                     (GtkAttachOptions) (GTK_FILL), 0, 0);
756
757   hseparator = gtk_hseparator_new ();
758   gtk_widget_show (hseparator);
759   gtk_table_attach (GTK_TABLE (table1), hseparator, 3, 4, 1, 2,
760                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
761                     (GtkAttachOptions) (GTK_FILL), 0, 0);
762
763   hseparator = gtk_hseparator_new ();
764   gtk_widget_show (hseparator);
765   gtk_table_attach (GTK_TABLE (table1), hseparator, 1, 2, 3, 4,
766                     (GtkAttachOptions) (GTK_FILL),
767                     (GtkAttachOptions) (GTK_FILL), 0, 0);
768
769   hseparator = gtk_hseparator_new ();
770   gtk_widget_show (hseparator);
771   gtk_table_attach (GTK_TABLE (table1), hseparator, 2, 3, 3, 4,
772                     (GtkAttachOptions) (GTK_FILL),
773                     (GtkAttachOptions) (GTK_FILL), 0, 0);
774
775   hseparator = gtk_hseparator_new ();
776   gtk_widget_show (hseparator);
777   gtk_table_attach (GTK_TABLE (table1), hseparator, 3, 4, 3, 4,
778                     (GtkAttachOptions) (GTK_FILL),
779                     (GtkAttachOptions) (GTK_FILL), 0, 0);
780
781   hseparator = gtk_hseparator_new ();
782   gtk_widget_show (hseparator);
783   gtk_table_attach (GTK_TABLE (table1), hseparator, 1, 2, 5, 6,
784                     (GtkAttachOptions) (GTK_FILL),
785                     (GtkAttachOptions) (GTK_FILL), 0, 0);
786
787   hseparator = gtk_hseparator_new ();
788   gtk_widget_show (hseparator);
789   gtk_table_attach (GTK_TABLE (table1), hseparator, 2, 3, 5, 6,
790                     (GtkAttachOptions) (GTK_FILL),
791                     (GtkAttachOptions) (GTK_FILL), 0, 0);
792
793   hseparator = gtk_hseparator_new ();
794   gtk_widget_show (hseparator);
795   gtk_table_attach (GTK_TABLE (table1), hseparator, 3, 4, 5, 6,
796                     (GtkAttachOptions) (GTK_FILL),
797                     (GtkAttachOptions) (GTK_FILL), 0, 0);
798
799   hseparator = gtk_hseparator_new ();
800   gtk_widget_show (hseparator);
801   gtk_table_attach (GTK_TABLE (table1), hseparator, 1, 2, 7, 8,
802                     (GtkAttachOptions) (GTK_FILL),
803                     (GtkAttachOptions) (GTK_FILL), 0, 0);
804
805   hseparator = gtk_hseparator_new ();
806   gtk_widget_show (hseparator);
807   gtk_table_attach (GTK_TABLE (table1), hseparator, 2, 3, 7, 8,
808                     (GtkAttachOptions) (GTK_FILL),
809                     (GtkAttachOptions) (GTK_FILL), 0, 0);
810
811   hseparator = gtk_hseparator_new ();
812   gtk_widget_show (hseparator);
813   gtk_table_attach (GTK_TABLE (table1), hseparator, 3, 4, 7, 8,
814                     (GtkAttachOptions) (GTK_FILL),
815                     (GtkAttachOptions) (GTK_FILL), 0, 0);
816
817   hseparator = gtk_hseparator_new ();
818   gtk_widget_show (hseparator);
819   gtk_table_attach (GTK_TABLE (table1), hseparator, 1, 2, 9, 10,
820                     (GtkAttachOptions) (GTK_FILL),
821                     (GtkAttachOptions) (GTK_FILL), 0, 0);
822
823   hseparator = gtk_hseparator_new ();
824   gtk_widget_show (hseparator);
825   gtk_table_attach (GTK_TABLE (table1), hseparator, 2, 3, 9, 10,
826                     (GtkAttachOptions) (GTK_FILL),
827                     (GtkAttachOptions) (GTK_FILL), 0, 0);
828
829   hseparator = gtk_hseparator_new ();
830   gtk_widget_show (hseparator);
831   gtk_table_attach (GTK_TABLE (table1), hseparator, 3, 4, 9, 10,
832                     (GtkAttachOptions) (GTK_FILL),
833                     (GtkAttachOptions) (GTK_FILL), 0, 0);
834
835   hseparator = gtk_hseparator_new ();
836   gtk_widget_show (hseparator);
837   gtk_table_attach (GTK_TABLE (table1), hseparator, 1, 2, 11, 12,
838                     (GtkAttachOptions) (GTK_FILL),
839                     (GtkAttachOptions) (GTK_FILL), 0, 0);
840
841   hseparator = gtk_hseparator_new ();
842   gtk_widget_show (hseparator);
843   gtk_table_attach (GTK_TABLE (table1), hseparator, 2, 3, 11, 12,
844                     (GtkAttachOptions) (GTK_FILL),
845                     (GtkAttachOptions) (GTK_FILL), 0, 0);
846
847   hseparator = gtk_hseparator_new ();
848   gtk_widget_show (hseparator);
849   gtk_table_attach (GTK_TABLE (table1), hseparator, 3, 4, 11, 12,
850                     (GtkAttachOptions) (GTK_FILL),
851                     (GtkAttachOptions) (GTK_FILL), 0, 0);
852
853   label = gtk_label_new ("Offset");
854   gtk_widget_show (label);
855   gtk_table_attach (GTK_TABLE (table1), label, 2, 3, 0, 1,
856                     (GtkAttachOptions) (GTK_FILL),
857                     (GtkAttachOptions) (0), 0, 0);
858
859   label = gtk_label_new ("Step");
860   gtk_widget_show (label);
861   gtk_table_attach (GTK_TABLE (table1), label, 3, 4, 0, 1,
862                     (GtkAttachOptions) (GTK_FILL),
863                     (GtkAttachOptions) (0), 0, 0);
864
865   eventbox = gtk_event_box_new ();
866   gtk_widget_show (eventbox);
867   gtk_table_attach (GTK_TABLE (table1), eventbox, 3, 4, 12, 13,
868                     (GtkAttachOptions) (GTK_FILL),
869                     (GtkAttachOptions) (GTK_FILL), 0, 0);
870
871   match_grid_button = gtk_button_new_with_mnemonic ("Match Grid");
872   gtk_widget_show (match_grid_button);
873   gtk_container_add (GTK_CONTAINER (eventbox), match_grid_button);
874
875   label = gtk_label_new ("Value");
876   gtk_widget_show (label);
877   gtk_table_attach (GTK_TABLE (table1), label, 1, 2, 0, 1,
878                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
879                     (GtkAttachOptions) (0), 0, 0);
880   gtk_misc_set_alignment (GTK_MISC (label), 0.5, 1);
881
882   hseparator = gtk_hseparator_new ();
883   gtk_widget_show (hseparator);
884   gtk_table_attach (GTK_TABLE (table1), hseparator, 0, 1, 3, 4,
885                     (GtkAttachOptions) (GTK_SHRINK | GTK_FILL),
886                     (GtkAttachOptions) (GTK_FILL), 0, 0);
887
888   hseparator = gtk_hseparator_new ();
889   gtk_widget_show (hseparator);
890   gtk_table_attach (GTK_TABLE (table1), hseparator, 0, 1, 5, 6,
891                     (GtkAttachOptions) (GTK_FILL),
892                     (GtkAttachOptions) (GTK_FILL), 0, 0);
893
894   hseparator = gtk_hseparator_new ();
895   gtk_widget_show (hseparator);
896   gtk_table_attach (GTK_TABLE (table1), hseparator, 0, 1, 7, 8,
897                     (GtkAttachOptions) (GTK_FILL),
898                     (GtkAttachOptions) (GTK_FILL), 0, 0);
899
900   hseparator = gtk_hseparator_new ();
901   gtk_widget_show (hseparator);
902   gtk_table_attach (GTK_TABLE (table1), hseparator, 0, 1, 9, 10,
903                     (GtkAttachOptions) (GTK_FILL),
904                     (GtkAttachOptions) (GTK_FILL), 0, 0);
905
906   hseparator = gtk_hseparator_new ();
907   gtk_widget_show (hseparator);
908   gtk_table_attach (GTK_TABLE (table1), hseparator, 0, 1, 11, 12,
909                     (GtkAttachOptions) (GTK_FILL),
910                     (GtkAttachOptions) (GTK_FILL), 0, 0);
911
912   eventbox = gtk_event_box_new ();
913   gtk_widget_show (eventbox);
914   gtk_table_attach (GTK_TABLE (table1), eventbox, 0, 1, 4, 5,
915                     (GtkAttachOptions) (GTK_FILL),
916                     (GtkAttachOptions) (GTK_FILL), 0, 0);
917
918   label = gtk_label_new ("V Shift: ");
919   gtk_widget_show (label);
920   gtk_container_add (GTK_CONTAINER (eventbox), label);
921   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
922   gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
923
924   eventbox = gtk_event_box_new ();
925   gtk_widget_show (eventbox);
926   gtk_table_attach (GTK_TABLE (table1), eventbox, 0, 1, 6, 7,
927                     (GtkAttachOptions) (GTK_FILL),
928                     (GtkAttachOptions) (GTK_FILL), 0, 0);
929
930   label = gtk_label_new (" H Scale: ");
931   gtk_widget_show (label);
932   gtk_container_add (GTK_CONTAINER (eventbox), label);
933   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
934   gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
935
936   eventbox = gtk_event_box_new ();
937   gtk_widget_show (eventbox);
938   gtk_table_attach (GTK_TABLE (table1), eventbox, 0, 1, 8, 9,
939                     (GtkAttachOptions) (GTK_FILL),
940                     (GtkAttachOptions) (GTK_FILL), 0, 0);
941
942   label = gtk_label_new ("V Scale: ");
943   gtk_widget_show (label);
944   gtk_container_add (GTK_CONTAINER (eventbox), label);
945   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
946   gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
947
948   eventbox = gtk_event_box_new ();
949   gtk_widget_show (eventbox);
950   gtk_table_attach (GTK_TABLE (table1), eventbox, 0, 1, 10, 11,
951                     (GtkAttachOptions) (GTK_FILL),
952                     (GtkAttachOptions) (GTK_FILL), 0, 0);
953
954   label = gtk_label_new ("Rotate: ");
955   gtk_widget_show (label);
956   gtk_container_add (GTK_CONTAINER (eventbox), label);
957   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
958   gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
959
960   eventbox = gtk_event_box_new ();
961   gtk_widget_show (eventbox);
962   gtk_table_attach (GTK_TABLE (table1), eventbox, 0, 1, 2, 3,
963                     (GtkAttachOptions) (GTK_FILL),
964                     (GtkAttachOptions) (GTK_FILL), 0, 0);
965
966   label = gtk_label_new ("H Shift: ");
967   gtk_widget_show (label);
968   gtk_container_add (GTK_CONTAINER (eventbox), label);
969   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
970   gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
971
972   hseparator = gtk_hseparator_new ();
973   gtk_widget_show (hseparator);
974   gtk_table_attach (GTK_TABLE (table1), hseparator, 0, 1, 1, 2,
975                     (GtkAttachOptions) (GTK_FILL),
976                     (GtkAttachOptions) (GTK_FILL), 0, 0);
977
978   eventbox = gtk_event_box_new ();
979   gtk_widget_show (eventbox);
980   gtk_table_attach (GTK_TABLE (table1), eventbox, 1, 2, 12, 13,
981                     (GtkAttachOptions) (GTK_FILL),
982                     (GtkAttachOptions) (GTK_FILL), 0, 0);
983
984   lock_valuechange_togglebutton = gtk_toggle_button_new_with_mnemonic ("UNLOCK");
985   gtk_widget_show (lock_valuechange_togglebutton);
986   gtk_container_add (GTK_CONTAINER (eventbox), lock_valuechange_togglebutton);
987
988   // Value Spins
989   hshift_value_spinbutton_adj = gtk_adjustment_new (0.0, -8192.0, 8192.0, 2.0, 8.0, 8.0);
990   hshift_value_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (hshift_value_spinbutton_adj), 1, 2);
991   gtk_widget_show (hshift_value_spinbutton);
992   gtk_table_attach (GTK_TABLE (table1), hshift_value_spinbutton, 1, 2, 2, 3,
993                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
994                     (GtkAttachOptions) (0), 0, 0);
995   gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (hshift_value_spinbutton), GTK_UPDATE_IF_VALID);
996   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (hshift_value_spinbutton), TRUE);
997   gtk_widget_set_sensitive( GTK_WIDGET( hshift_value_spinbutton ), FALSE );
998
999   vshift_value_spinbutton_adj = gtk_adjustment_new (0.0, -8192.0, 8192.0, 2.0, 8.0, 8.0);
1000   vshift_value_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (vshift_value_spinbutton_adj), 1, 2);
1001   gtk_widget_show (vshift_value_spinbutton);
1002   gtk_table_attach (GTK_TABLE (table1), vshift_value_spinbutton, 1, 2, 4, 5,
1003                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1004                     (GtkAttachOptions) (0), 0, 0);
1005   gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (vshift_value_spinbutton), GTK_UPDATE_IF_VALID);
1006   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (vshift_value_spinbutton), TRUE);
1007   gtk_widget_set_sensitive( GTK_WIDGET( vshift_value_spinbutton ), FALSE );
1008
1009   hscale_value_spinbutton_adj = gtk_adjustment_new (0.0, -1024.0, 1024.0, 1.0, 4.0, 4.0);
1010   hscale_value_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (hscale_value_spinbutton_adj), 1, 4);
1011   gtk_widget_show (hscale_value_spinbutton);
1012   gtk_table_attach (GTK_TABLE (table1), hscale_value_spinbutton, 1, 2, 6, 7,
1013                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1014                     (GtkAttachOptions) (0), 0, 0);
1015   gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (hscale_value_spinbutton), GTK_UPDATE_IF_VALID);
1016   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (hscale_value_spinbutton), TRUE);
1017   gtk_widget_set_sensitive( GTK_WIDGET( hscale_value_spinbutton ), FALSE );
1018
1019   vscale_value_spinbutton_adj = gtk_adjustment_new (0.0, -1024.0, 1024.0, 1.0, 4.0, 4.0);
1020   vscale_value_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (vscale_value_spinbutton_adj), 1, 4);
1021   gtk_widget_show (vscale_value_spinbutton);
1022   gtk_table_attach (GTK_TABLE (table1), vscale_value_spinbutton, 1, 2, 8, 9,
1023                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1024                     (GtkAttachOptions) (0), 0, 0);
1025   gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (vscale_value_spinbutton), GTK_UPDATE_IF_VALID);
1026   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (vscale_value_spinbutton), TRUE);
1027   gtk_widget_set_sensitive( GTK_WIDGET( vscale_value_spinbutton ), FALSE );
1028   
1029   rotate_value_spinbutton_adj = gtk_adjustment_new (0.0, -360.0, 360.0, 1.0, 10.0, 10.0);
1030   rotate_value_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (rotate_value_spinbutton_adj), 1, 0);
1031   gtk_widget_show (rotate_value_spinbutton);
1032   gtk_table_attach (GTK_TABLE (table1), rotate_value_spinbutton, 1, 2, 10, 11,
1033                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1034                     (GtkAttachOptions) (0), 0, 0);
1035   gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (rotate_value_spinbutton), GTK_UPDATE_IF_VALID);
1036   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (rotate_value_spinbutton), TRUE);
1037   gtk_widget_set_sensitive( GTK_WIDGET( rotate_value_spinbutton ), FALSE );
1038
1039   // Offset Spins                  
1040   hshift_offset_spinbutton_adj = gtk_adjustment_new (0.0, -8192.0, 8192.0, 2.0, 8.0, 8.0);
1041   hshift_offset_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (hshift_offset_spinbutton_adj), 0, 2);
1042   gtk_widget_show (hshift_offset_spinbutton);
1043   gtk_table_attach (GTK_TABLE (table1), hshift_offset_spinbutton, 2, 3, 2, 3,
1044                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1045                     (GtkAttachOptions) (0), 4, 0);
1046   gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (hshift_offset_spinbutton), TRUE);
1047   gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (hshift_offset_spinbutton), GTK_UPDATE_IF_VALID);
1048   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (hshift_offset_spinbutton), TRUE);
1049
1050   vshift_offset_spinbutton_adj = gtk_adjustment_new (0.0, -8192.0, 8192.0, 2.0, 8.0, 8.0);
1051   vshift_offset_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (vshift_offset_spinbutton_adj), 0, 2);
1052   gtk_widget_show (vshift_offset_spinbutton);
1053   gtk_table_attach (GTK_TABLE (table1), vshift_offset_spinbutton, 2, 3, 4, 5,
1054                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1055                     (GtkAttachOptions) (0), 4, 0);
1056   gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (vshift_offset_spinbutton), TRUE);
1057   gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (vshift_offset_spinbutton), GTK_UPDATE_IF_VALID);
1058   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (vshift_offset_spinbutton), TRUE);
1059
1060   hscale_offset_spinbutton_adj = gtk_adjustment_new (0.0, -1024.0, 1024.0, 1.0, 4.0, 4.0);
1061   hscale_offset_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (hscale_offset_spinbutton_adj), 0, 4);
1062   gtk_widget_show (hscale_offset_spinbutton);
1063   gtk_table_attach (GTK_TABLE (table1), hscale_offset_spinbutton, 2, 3, 6, 7,
1064                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1065                     (GtkAttachOptions) (0), 4, 0);
1066   gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (hscale_offset_spinbutton), TRUE);
1067   gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (hscale_offset_spinbutton), GTK_UPDATE_IF_VALID);
1068   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (hscale_offset_spinbutton), TRUE);
1069
1070   vscale_offset_spinbutton_adj = gtk_adjustment_new (0.0, -1024.0, 1024.0, 1.0, 4.0, 4.0);
1071   vscale_offset_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (vscale_offset_spinbutton_adj), 0, 4);
1072   gtk_widget_show (vscale_offset_spinbutton);
1073   gtk_table_attach (GTK_TABLE (table1), vscale_offset_spinbutton, 2, 3, 8, 9,
1074                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1075                     (GtkAttachOptions) (0), 4, 0);
1076   gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (vscale_offset_spinbutton), TRUE);
1077   gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (vscale_offset_spinbutton), GTK_UPDATE_IF_VALID);
1078   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (vscale_offset_spinbutton), TRUE);
1079
1080   rotate_offset_spinbutton_adj = gtk_adjustment_new (0.0, -360.0, 360.0, 1.0, 10.0, 10.0);
1081   rotate_offset_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (rotate_offset_spinbutton_adj), 0, 2);
1082   gtk_widget_show (rotate_offset_spinbutton);
1083   gtk_table_attach (GTK_TABLE (table1), rotate_offset_spinbutton, 2, 3, 10, 11,
1084                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1085                     (GtkAttachOptions) (0), 4, 0);
1086   gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (rotate_offset_spinbutton), TRUE);
1087   gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (rotate_offset_spinbutton), GTK_UPDATE_IF_VALID);
1088   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (rotate_offset_spinbutton), TRUE);
1089
1090     // Step Spins
1091   hshift_step_spinbutton_adj = gtk_adjustment_new (0.0, -8192.0, 8192.0, 2.0, 8.0, 8.0);
1092   hshift_step_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (hshift_step_spinbutton_adj), 1, 2);
1093   gtk_widget_show (hshift_step_spinbutton);
1094   gtk_table_attach (GTK_TABLE (table1), hshift_step_spinbutton, 3, 4, 2, 3,
1095                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1096                     (GtkAttachOptions) (0), 0, 0);
1097   gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (hshift_step_spinbutton), GTK_UPDATE_IF_VALID);
1098
1099   vshift_step_spinbutton_adj = gtk_adjustment_new (0.0, -8192.0, 8192.0, 2.0, 8.0, 8.0);
1100   vshift_step_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (vshift_step_spinbutton_adj), 1, 2);
1101   gtk_widget_show (vshift_step_spinbutton);
1102   gtk_table_attach (GTK_TABLE (table1), vshift_step_spinbutton, 3, 4, 4, 5,
1103                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1104                     (GtkAttachOptions) (0), 0, 0);
1105   gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (vshift_step_spinbutton), GTK_UPDATE_IF_VALID);
1106
1107   hscale_step_spinbutton_adj = gtk_adjustment_new (0.0, -1024.0, 1024.0, 1.0, 4.0, 4.0);
1108   hscale_step_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (hscale_step_spinbutton_adj), 1, 4);
1109   gtk_widget_show (hscale_step_spinbutton);
1110   gtk_table_attach (GTK_TABLE (table1), hscale_step_spinbutton, 3, 4, 6, 7,
1111                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1112                     (GtkAttachOptions) (0), 0, 0);
1113   gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (hscale_step_spinbutton), GTK_UPDATE_IF_VALID);
1114
1115   vscale_step_spinbutton_adj = gtk_adjustment_new (0.0, -1024.0, 1024.0, 1.0, 4.0, 4.0);
1116   vscale_step_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (vscale_step_spinbutton_adj), 1, 4);
1117   gtk_widget_show (vscale_step_spinbutton);
1118   gtk_table_attach (GTK_TABLE (table1), vscale_step_spinbutton, 3, 4, 8, 9,
1119                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1120                     (GtkAttachOptions) (0), 0, 0);
1121   gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (vscale_step_spinbutton), GTK_UPDATE_IF_VALID);
1122
1123   rotate_step_spinbutton_adj = gtk_adjustment_new (0.0, -360.0, 360.0, 1.0, 10.0, 10.0);
1124   rotate_step_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (rotate_step_spinbutton_adj), 1, 2);
1125   gtk_widget_show (rotate_step_spinbutton);
1126   gtk_table_attach (GTK_TABLE (table1), rotate_step_spinbutton, 3, 4, 10, 11,
1127                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1128                     (GtkAttachOptions) (0), 0, 0);
1129   gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (rotate_step_spinbutton), GTK_UPDATE_IF_VALID);
1130
1131   eventbox = gtk_event_box_new ();
1132   gtk_widget_show (eventbox);
1133   gtk_table_attach (GTK_TABLE (table1), eventbox, 2, 3, 12, 13,
1134                     (GtkAttachOptions) (0),
1135                     (GtkAttachOptions) (0), 0, 0);
1136
1137   eventbox = gtk_event_box_new ();
1138   gtk_widget_show (eventbox);
1139   gtk_table_attach (GTK_TABLE (table1), eventbox, 0, 1, 12, 13,
1140                     (GtkAttachOptions) (0),
1141                     (GtkAttachOptions) (0), 0, 0);
1142
1143   eventbox = gtk_event_box_new ();
1144   gtk_widget_show (eventbox);
1145   gtk_table_attach (GTK_TABLE (table1), eventbox, 0, 1, 0, 1,
1146                     (GtkAttachOptions) (0),
1147                     (GtkAttachOptions) (0), 0, 0);
1148
1149   viewport7 = gtk_viewport_new (NULL, NULL);
1150   gtk_widget_show (viewport7);
1151   gtk_box_pack_start (GTK_BOX (vbox7), viewport7, FALSE, TRUE, 0);
1152   gtk_container_set_border_width (GTK_CONTAINER (viewport7), 2);
1153   gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport7), GTK_SHADOW_ETCHED_IN);
1154
1155   table4 = gtk_table_new (4, 7, FALSE);
1156   gtk_widget_show (table4);
1157   gtk_container_add (GTK_CONTAINER (viewport7), table4);
1158
1159   viewport5 = gtk_viewport_new (NULL, NULL);
1160   gtk_widget_show (viewport5);
1161   gtk_table_attach (GTK_TABLE (table4), viewport5, 1, 7, 0, 4,
1162                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1163                     (GtkAttachOptions) (0), 0, 0);
1164   gtk_container_set_border_width (GTK_CONTAINER (viewport5), 6);
1165   gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport5), GTK_SHADOW_ETCHED_OUT);
1166
1167   table5 = gtk_table_new (2, 3, FALSE);
1168   gtk_widget_show (table5);
1169   gtk_container_add (GTK_CONTAINER (viewport5), table5);
1170   gtk_container_set_border_width (GTK_CONTAINER (table5), 5);
1171   gtk_table_set_col_spacings (GTK_TABLE (table5), 2);
1172
1173   label = gtk_label_new ("Height");
1174   gtk_widget_show (label);
1175   gtk_table_attach (GTK_TABLE (table5), label, 2, 3, 0, 1,
1176                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1177                     (GtkAttachOptions) (GTK_FILL), 0, 0);
1178   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1179   gtk_misc_set_alignment (GTK_MISC (label), 0.5, 1);
1180
1181   label = gtk_label_new ("Width");
1182   gtk_widget_show (label);
1183   gtk_table_attach (GTK_TABLE (table5), label, 1, 2, 0, 1,
1184                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1185                     (GtkAttachOptions) (GTK_FILL), 0, 0);
1186   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1187   gtk_misc_set_alignment (GTK_MISC (label), 0.5, 1);
1188
1189   fit_width_spinbutton_adj = gtk_adjustment_new (1, 1, 32, 1, 10, 10);
1190   fit_width_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (fit_width_spinbutton_adj), 1, 0);
1191   gtk_widget_show (fit_width_spinbutton);
1192   gtk_table_attach (GTK_TABLE (table5), fit_width_spinbutton, 1, 2, 1, 2,
1193                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1194                     (GtkAttachOptions) (GTK_FILL), 0, 0);
1195   gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (fit_width_spinbutton), TRUE);
1196   gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (fit_width_spinbutton), GTK_UPDATE_IF_VALID);
1197
1198   fit_height_spinbutton_adj = gtk_adjustment_new (1, 1, 32, 1, 10, 10);
1199   fit_height_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (fit_height_spinbutton_adj), 1, 0);
1200   gtk_widget_show (fit_height_spinbutton);
1201   gtk_table_attach (GTK_TABLE (table5), fit_height_spinbutton, 2, 3, 1, 2,
1202                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1203                     (GtkAttachOptions) (GTK_FILL), 3, 0);
1204   gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (fit_height_spinbutton), TRUE);
1205   gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (fit_height_spinbutton), GTK_UPDATE_IF_VALID);
1206
1207   eventbox = gtk_event_box_new ();
1208   gtk_widget_show (eventbox);
1209   gtk_table_attach (GTK_TABLE (table5), eventbox, 0, 1, 0, 1,
1210                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1211                     (GtkAttachOptions) (GTK_FILL), 0, 0);
1212
1213   eventbox = gtk_event_box_new ();
1214   gtk_widget_show (eventbox);
1215   gtk_table_attach (GTK_TABLE (table5), eventbox, 0, 1, 1, 2,
1216                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1217                     (GtkAttachOptions) (GTK_FILL), 4, 0);
1218
1219   fit_button = gtk_button_new_with_mnemonic ("    Fit    ");
1220   gtk_widget_show (fit_button);
1221   gtk_container_add (GTK_CONTAINER (eventbox), fit_button);
1222
1223   viewport6 = gtk_viewport_new (NULL, NULL);
1224   gtk_widget_show (viewport6);
1225   gtk_table_attach (GTK_TABLE (table4), viewport6, 0, 1, 0, 4,
1226                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1227                     (GtkAttachOptions) (0), 0, 0);
1228   gtk_container_set_border_width (GTK_CONTAINER (viewport6), 4);
1229   gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport6), GTK_SHADOW_NONE);
1230
1231   table7 = gtk_table_new (2, 1, FALSE);
1232   gtk_widget_show (table7);
1233   gtk_container_add (GTK_CONTAINER (viewport6), table7);
1234
1235   eventbox = gtk_event_box_new ();
1236   gtk_widget_show (eventbox);
1237   gtk_table_attach (GTK_TABLE (table7), eventbox, 0, 1, 0, 2,
1238                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1239                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
1240
1241   axial_button = gtk_button_new_with_mnemonic ("Axial");
1242   gtk_widget_show (axial_button);
1243   gtk_container_add (GTK_CONTAINER (eventbox), axial_button);
1244   gtk_widget_set_size_request (axial_button, 56, 29);
1245   gtk_container_set_border_width (GTK_CONTAINER (axial_button), 4);
1246
1247   viewport10 = gtk_viewport_new (NULL, NULL);
1248   gtk_widget_show (viewport10);
1249   gtk_box_pack_start (GTK_BOX (vbox7), viewport10, FALSE, TRUE, 0);
1250   gtk_container_set_border_width (GTK_CONTAINER (viewport10), 2);
1251   gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport10), GTK_SHADOW_ETCHED_IN);
1252
1253   hbuttonbox1 = gtk_hbutton_box_new ();
1254   gtk_widget_show (hbuttonbox1);
1255   gtk_container_add (GTK_CONTAINER (viewport10), hbuttonbox1);
1256   gtk_container_set_border_width (GTK_CONTAINER (hbuttonbox1), 4);
1257   gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox1), GTK_BUTTONBOX_SPREAD);
1258
1259   done_button = gtk_button_new ();
1260   gtk_widget_show (done_button);
1261   gtk_container_add (GTK_CONTAINER (hbuttonbox1), done_button);
1262   GTK_WIDGET_SET_FLAGS (done_button, GTK_CAN_DEFAULT);
1263
1264   alignment1 = gtk_alignment_new (0.5, 0.5, 0, 0);
1265   gtk_widget_show (alignment1);
1266   gtk_container_add (GTK_CONTAINER (done_button), alignment1);
1267
1268   hbox2 = gtk_hbox_new (FALSE, 2);
1269   gtk_widget_show (hbox2);
1270   gtk_container_add (GTK_CONTAINER (alignment1), hbox2);
1271
1272   image1 = gtk_image_new_from_stock ("gtk-yes", GTK_ICON_SIZE_BUTTON);
1273   gtk_widget_show (image1);
1274   gtk_box_pack_start (GTK_BOX (hbox2), image1, FALSE, FALSE, 0);
1275
1276   label = gtk_label_new_with_mnemonic ("Done");
1277   gtk_widget_show (label);
1278   gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
1279   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1280
1281   apply_button = gtk_button_new ();
1282   gtk_widget_show (apply_button);
1283   gtk_container_add (GTK_CONTAINER (hbuttonbox1), apply_button);
1284   GTK_WIDGET_SET_FLAGS (apply_button, GTK_CAN_DEFAULT);
1285
1286   alignment3 = gtk_alignment_new (0.5, 0.5, 0, 0);
1287   gtk_widget_show (alignment3);
1288   gtk_container_add (GTK_CONTAINER (apply_button), alignment3);
1289
1290   hbox4 = gtk_hbox_new (FALSE, 2);
1291   gtk_widget_show (hbox4);
1292   gtk_container_add (GTK_CONTAINER (alignment3), hbox4);
1293
1294   image3 = gtk_image_new_from_stock ("gtk-apply", GTK_ICON_SIZE_BUTTON);
1295   gtk_widget_show (image3);
1296   gtk_box_pack_start (GTK_BOX (hbox4), image3, FALSE, FALSE, 0);
1297
1298   label = gtk_label_new_with_mnemonic ("Apply");
1299   gtk_widget_show (label);
1300   gtk_box_pack_start (GTK_BOX (hbox4), label, FALSE, FALSE, 0);
1301   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1302
1303   cancel_button = gtk_button_new ();
1304   gtk_widget_show (cancel_button);
1305   gtk_container_add (GTK_CONTAINER (hbuttonbox1), cancel_button);
1306   GTK_WIDGET_SET_FLAGS (cancel_button, GTK_CAN_DEFAULT);
1307
1308   alignment2 = gtk_alignment_new (0.5, 0.5, 0, 0);
1309   gtk_widget_show (alignment2);
1310   gtk_container_add (GTK_CONTAINER (cancel_button), alignment2);
1311
1312   hbox3 = gtk_hbox_new (FALSE, 2);
1313   gtk_widget_show (hbox3);
1314   gtk_container_add (GTK_CONTAINER (alignment2), hbox3);
1315
1316   image2 = gtk_image_new_from_stock ("gtk-no", GTK_ICON_SIZE_BUTTON);
1317   gtk_widget_show (image2);
1318   gtk_box_pack_start (GTK_BOX (hbox3), image2, FALSE, FALSE, 0);
1319
1320   label = gtk_label_new_with_mnemonic ("Cancel");
1321   gtk_widget_show (label);
1322   gtk_box_pack_start (GTK_BOX (hbox3), label, FALSE, FALSE, 0);
1323   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1324
1325
1326   g_signal_connect ( (gpointer) SurfaceInspector, 
1327                       "delete_event", 
1328                       G_CALLBACK (delete_event_callback), 
1329                       NULL );
1330   g_signal_connect ((gpointer) SurfaceInspector, "destroy",
1331                     G_CALLBACK (gtk_widget_destroy),
1332                     NULL);
1333   
1334   g_signal_connect ((gpointer) texture_combo_entry, "key_press_event",
1335                     G_CALLBACK (on_texture_combo_entry_key_press_event),
1336                     NULL);
1337   g_signal_connect ((gpointer) texture_combo_entry, "activate",
1338                     G_CALLBACK (on_texture_combo_entry_activate),
1339                     NULL);
1340                     
1341   
1342   g_signal_connect ((gpointer) hshift_offset_spinbutton, "value_changed",
1343                     G_CALLBACK (on_hshift_offset_spinbutton_value_changed),
1344                     NULL);
1345   g_signal_connect ((gpointer) vshift_offset_spinbutton, "value_changed",
1346                     G_CALLBACK (on_vshift_offset_spinbutton_value_changed),
1347                     NULL);
1348   g_signal_connect ((gpointer) hscale_offset_spinbutton, "value_changed",
1349                     G_CALLBACK (on_hscale_offset_spinbutton_value_changed),
1350                     NULL);
1351   g_signal_connect ((gpointer) vscale_offset_spinbutton, "value_changed",
1352                     G_CALLBACK (on_vscale_offset_spinbutton_value_changed),
1353                     NULL);
1354   g_signal_connect ((gpointer) rotate_offset_spinbutton, "value_changed",
1355                     G_CALLBACK (on_rotate_offset_spinbutton_value_changed),
1356                     NULL);
1357   
1358   g_signal_connect ((gpointer) hshift_value_spinbutton, "value_changed",
1359                     G_CALLBACK (on_hshift_value_spinbutton_value_changed),
1360                     NULL);
1361   g_signal_connect ((gpointer) vshift_value_spinbutton, "value_changed",
1362                     G_CALLBACK (on_vshift_value_spinbutton_value_changed),
1363                     NULL);
1364   g_signal_connect ((gpointer) hscale_value_spinbutton, "value_changed",
1365                     G_CALLBACK (on_hscale_value_spinbutton_value_changed),
1366                     NULL);
1367   g_signal_connect ((gpointer) vscale_value_spinbutton, "value_changed",
1368                     G_CALLBACK (on_vscale_value_spinbutton_value_changed),
1369                     NULL);
1370   g_signal_connect ((gpointer) rotate_value_spinbutton, "value_changed",
1371                     G_CALLBACK (on_rotate_value_spinbutton_value_changed),
1372                     NULL);
1373   
1374   g_signal_connect ((gpointer) hshift_step_spinbutton, "value_changed",
1375                     G_CALLBACK (on_hshift_step_spinbutton_value_changed),
1376                     NULL);
1377   g_signal_connect ((gpointer) vshift_step_spinbutton, "value_changed",
1378                     G_CALLBACK (on_vshift_step_spinbutton_value_changed),
1379                     NULL);
1380   g_signal_connect ((gpointer) hscale_step_spinbutton, "value_changed",
1381                     G_CALLBACK (on_hscale_step_spinbutton_value_changed),
1382                     NULL);
1383   g_signal_connect ((gpointer) vscale_step_spinbutton, "value_changed",
1384                     G_CALLBACK (on_vscale_step_spinbutton_value_changed),
1385                     NULL);
1386   g_signal_connect ((gpointer) rotate_step_spinbutton, "value_changed",
1387                     G_CALLBACK (on_rotate_step_spinbutton_value_changed),
1388                     NULL);
1389   
1390   g_signal_connect ((gpointer) match_grid_button, "clicked",
1391                     G_CALLBACK (on_match_grid_button_clicked),
1392                     NULL);
1393   g_signal_connect ((gpointer) lock_valuechange_togglebutton, "toggled",
1394                     G_CALLBACK (on_lock_valuechange_togglebutton_toggled),
1395                     NULL);
1396   
1397   g_signal_connect ((gpointer) fit_width_spinbutton, "value_changed",
1398                     G_CALLBACK (on_fit_width_spinbutton_value_changed),
1399                     NULL);
1400   g_signal_connect ((gpointer) fit_height_spinbutton, "value_changed",
1401                     G_CALLBACK (on_fit_height_spinbutton_value_changed),
1402                     NULL);
1403   g_signal_connect ((gpointer) fit_button, "clicked",
1404                     G_CALLBACK (on_fit_button_clicked),
1405                     NULL);
1406   
1407   g_signal_connect ((gpointer) axial_button, "clicked",
1408                     G_CALLBACK (on_axial_button_clicked),
1409                     NULL);
1410   
1411   g_signal_connect ((gpointer) done_button, "clicked",
1412                     G_CALLBACK (on_done_button_clicked),
1413                     NULL);
1414   g_signal_connect ((gpointer) apply_button, "clicked",
1415                     G_CALLBACK (on_apply_button_clicked),
1416                     NULL);
1417   g_signal_connect ((gpointer) cancel_button, "clicked",
1418                     G_CALLBACK (on_cancel_button_clicked),
1419                     NULL);
1420   
1421   
1422   return SurfaceInspector;
1423 }
1424
1425
1426 // Texture Combo
1427 gboolean on_texture_combo_entry_key_press_event (GtkWidget *widget, GdkEventKey *event,
1428                                                  gpointer user_data)
1429 {
1430   // Have Tab activate selection as well as Return
1431   if (event->keyval == GDK_Tab)
1432     g_signal_emit_by_name ( texture_combo_entry, "activate" );
1433
1434   return FALSE;
1435 }
1436
1437 void on_texture_combo_entry_activate (GtkEntry *entry, gpointer user_data)
1438 {
1439   texdef_t* tmp_texdef;
1440   texdef_t* tmp_orig_texdef;
1441   texdef_to_face_t* temp_texdef_face_list;
1442   char text[128] = { 0 };
1443   
1444   if (!texdef_face_list_empty() && g_bListenChanged)
1445   {
1446     // activate only on entry change
1447     strcpy( text, gtk_entry_get_text(entry));
1448     if ( strcmp( old_texture_entry, text ))
1449     {
1450       // Check for spaces in shader name
1451       if (text[0] <= ' ' || strchr(text, ' '))
1452         Sys_FPrintf(SYS_WRN, "WARNING: spaces in shader names are not allowed, ignoring '%s'\n", text);
1453       else
1454       {  
1455         for (temp_texdef_face_list = get_texdef_face_list(); temp_texdef_face_list; temp_texdef_face_list = temp_texdef_face_list->next)
1456         {
1457           tmp_texdef = (texdef_t *) &temp_texdef_face_list->texdef;
1458           tmp_orig_texdef = (texdef_t *) &temp_texdef_face_list->orig_texdef;
1459           strcpy( old_texture_entry, text );
1460           tmp_texdef->SetName( text );
1461         }
1462         GetTexMods();
1463       }
1464     }
1465   }
1466 }
1467
1468 // Offset Spins
1469 static void on_hshift_offset_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data)
1470 {
1471   texdef_t* tmp_texdef;
1472   texdef_t* tmp_orig_texdef;
1473   texdef_to_face_t* temp_texdef_face_list;
1474   
1475   texdef_offset.shift[0] = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(hshift_offset_spinbutton) );
1476   
1477   if (!texdef_face_list_empty() && g_bListenChanged)
1478   {
1479     for (temp_texdef_face_list = get_texdef_face_list(); temp_texdef_face_list; temp_texdef_face_list = temp_texdef_face_list->next)
1480     {
1481       tmp_texdef = (texdef_t *) &temp_texdef_face_list->texdef;
1482       tmp_orig_texdef = (texdef_t *) &temp_texdef_face_list->orig_texdef;
1483       if (is_HShift_conflicting)
1484         tmp_texdef->shift[0] = tmp_orig_texdef->shift[0] + texdef_offset.shift[0];
1485       else
1486         tmp_texdef->shift[0] = texdef_SI_values.shift[0] + texdef_offset.shift[0];
1487     }
1488     GetTexMods();
1489   }
1490 }
1491
1492 static void on_vshift_offset_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data)
1493 {
1494   texdef_t* tmp_texdef;
1495   texdef_t* tmp_orig_texdef;
1496   texdef_to_face_t* temp_texdef_face_list;
1497   
1498   texdef_offset.shift[1] = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(vshift_offset_spinbutton) );
1499   
1500   if (!texdef_face_list_empty() && g_bListenChanged)
1501   {
1502     for (temp_texdef_face_list = get_texdef_face_list(); temp_texdef_face_list; temp_texdef_face_list = temp_texdef_face_list->next)
1503     {
1504       tmp_texdef = (texdef_t *) &temp_texdef_face_list->texdef;
1505       tmp_orig_texdef = (texdef_t *) &temp_texdef_face_list->orig_texdef;
1506       if (is_VShift_conflicting)
1507         tmp_texdef->shift[1] = tmp_orig_texdef->shift[1] + texdef_offset.shift[1];
1508       else
1509         tmp_texdef->shift[1] = texdef_SI_values.shift[1] + texdef_offset.shift[1];
1510     }
1511     GetTexMods();
1512   }
1513   
1514 }
1515
1516 static void on_hscale_offset_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data)
1517 {
1518   texdef_t* tmp_texdef;
1519   texdef_t* tmp_orig_texdef;
1520   texdef_to_face_t* temp_texdef_face_list;
1521   
1522   texdef_offset.scale[0] = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(hscale_offset_spinbutton) );
1523   
1524   if (!texdef_face_list_empty() && g_bListenChanged)
1525   {
1526     for (temp_texdef_face_list = get_texdef_face_list(); temp_texdef_face_list; temp_texdef_face_list = temp_texdef_face_list->next)
1527     {
1528       tmp_texdef = (texdef_t *) &temp_texdef_face_list->texdef;
1529       tmp_orig_texdef = (texdef_t *) &temp_texdef_face_list->orig_texdef;
1530       if (is_HScale_conflicting)
1531         tmp_texdef->scale[0] = tmp_orig_texdef->scale[0] + texdef_offset.scale[0];
1532       else
1533         tmp_texdef->scale[0] = texdef_SI_values.scale[0] + texdef_offset.scale[0];
1534     }
1535     GetTexMods();
1536   }
1537   
1538   
1539 }
1540
1541 static void on_vscale_offset_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data)
1542 {
1543   texdef_t* tmp_texdef;
1544   texdef_t* tmp_orig_texdef;
1545   texdef_to_face_t* temp_texdef_face_list;
1546   
1547   texdef_offset.scale[1] = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(vscale_offset_spinbutton) );
1548   
1549   if (!texdef_face_list_empty() && g_bListenChanged)
1550   {
1551     for (temp_texdef_face_list = get_texdef_face_list(); temp_texdef_face_list; temp_texdef_face_list = temp_texdef_face_list->next)
1552     {
1553       tmp_texdef = (texdef_t *) &temp_texdef_face_list->texdef;
1554       tmp_orig_texdef = (texdef_t *) &temp_texdef_face_list->orig_texdef;
1555       if (is_VScale_conflicting)
1556         tmp_texdef->scale[1] = tmp_orig_texdef->scale[1] + texdef_offset.scale[1];
1557       else
1558         tmp_texdef->scale[1] = texdef_SI_values.scale[1] + texdef_offset.scale[1];
1559     }
1560     GetTexMods();
1561   }
1562   
1563 }
1564
1565 static void on_rotate_offset_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data)
1566 {
1567   texdef_t* tmp_texdef;
1568   texdef_t* tmp_orig_texdef;
1569   texdef_to_face_t* temp_texdef_face_list;
1570   
1571   texdef_offset.rotate = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(rotate_offset_spinbutton) );
1572   
1573   if (!texdef_face_list_empty() && g_bListenChanged)
1574   {
1575     for (temp_texdef_face_list = get_texdef_face_list(); temp_texdef_face_list; temp_texdef_face_list = temp_texdef_face_list->next)
1576     {
1577       tmp_texdef = (texdef_t *) &temp_texdef_face_list->texdef;
1578       tmp_orig_texdef = (texdef_t *) &temp_texdef_face_list->orig_texdef;
1579       if (is_Rotate_conflicting)
1580         tmp_texdef->rotate = tmp_orig_texdef->rotate + texdef_offset.rotate;
1581       else
1582         tmp_texdef->rotate = texdef_SI_values.rotate + texdef_offset.rotate;
1583     }
1584     GetTexMods();
1585   }
1586  
1587 }
1588
1589
1590 // Match Grid
1591 static void on_match_grid_button_clicked (GtkButton *button, gpointer user_data)
1592 {
1593   float hscale, vscale;
1594
1595   if( !strcmp(gtk_entry_get_text (GTK_ENTRY (hscale_value_spinbutton)), "") )
1596     hscale = 0.0;
1597   else
1598     hscale = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(hscale_value_spinbutton) );
1599
1600   if( !strcmp( gtk_entry_get_text (GTK_ENTRY (vscale_value_spinbutton)), "") )
1601     vscale = 0.0;
1602   else
1603     vscale = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(vscale_value_spinbutton) );
1604   DoSnapTToGrid (hscale, vscale);
1605 }
1606
1607
1608 // Lock out changes to Value
1609 static void on_lock_valuechange_togglebutton_toggled (GtkToggleButton *togglebutton, gpointer user_data)
1610 {
1611   bool is_Locked;
1612
1613   is_Locked = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lock_valuechange_togglebutton));
1614
1615   gtk_widget_set_sensitive( GTK_WIDGET( hscale_value_spinbutton ), is_Locked );
1616   gtk_widget_set_sensitive( GTK_WIDGET( vscale_value_spinbutton ), is_Locked );
1617   gtk_widget_set_sensitive( GTK_WIDGET( hshift_value_spinbutton ), is_Locked );
1618   gtk_widget_set_sensitive( GTK_WIDGET( vshift_value_spinbutton ), is_Locked );
1619   gtk_widget_set_sensitive( GTK_WIDGET( rotate_value_spinbutton ), is_Locked );
1620 }
1621
1622
1623 // Value Spins
1624 static void on_hshift_value_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data)
1625 {
1626   texdef_t* tmp_texdef;
1627   texdef_t* tmp_orig_texdef;
1628   texdef_to_face_t* temp_texdef_face_list;
1629
1630   texdef_SI_values.shift[0] = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(hshift_value_spinbutton) );
1631
1632   if (!texdef_face_list_empty() && g_bListenChanged)
1633   {
1634     for (temp_texdef_face_list = get_texdef_face_list(); temp_texdef_face_list; temp_texdef_face_list = temp_texdef_face_list->next)
1635     {
1636       tmp_texdef = (texdef_t *) &temp_texdef_face_list->texdef;
1637       tmp_orig_texdef = (texdef_t *) &temp_texdef_face_list->orig_texdef;
1638       tmp_texdef->shift[0] = texdef_SI_values.shift[0] + texdef_offset.shift[0];
1639       is_HShift_conflicting = FALSE;
1640     }
1641     GetTexMods();
1642   }
1643 }
1644
1645 static void on_vshift_value_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data)
1646 {
1647   texdef_t* tmp_texdef;
1648   texdef_t* tmp_orig_texdef;
1649   texdef_to_face_t* temp_texdef_face_list;
1650   
1651   texdef_SI_values.shift[1]  = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(vshift_value_spinbutton) );
1652   
1653   if (!texdef_face_list_empty() && g_bListenChanged)
1654   {
1655     for (temp_texdef_face_list = get_texdef_face_list(); temp_texdef_face_list; temp_texdef_face_list = temp_texdef_face_list->next)
1656     {
1657       tmp_texdef = (texdef_t *) &temp_texdef_face_list->texdef;
1658       tmp_orig_texdef = (texdef_t *) &temp_texdef_face_list->orig_texdef;
1659       tmp_texdef->shift[1] = texdef_SI_values.shift[1] + texdef_offset.shift[1];
1660       is_VShift_conflicting = FALSE;
1661     }
1662     GetTexMods();
1663   }
1664 }
1665
1666 static void on_hscale_value_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data)
1667 {
1668   texdef_t* tmp_texdef;
1669   texdef_t* tmp_orig_texdef;
1670   texdef_to_face_t* temp_texdef_face_list;
1671   
1672   texdef_SI_values.scale[0] = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(hscale_value_spinbutton) );
1673   
1674   if (!texdef_face_list_empty() && g_bListenChanged)
1675   {
1676     for (temp_texdef_face_list = get_texdef_face_list(); temp_texdef_face_list; temp_texdef_face_list = temp_texdef_face_list->next)
1677     {
1678       tmp_texdef = (texdef_t *) &temp_texdef_face_list->texdef;
1679       tmp_orig_texdef = (texdef_t *) &temp_texdef_face_list->orig_texdef;
1680       tmp_texdef->scale[0] = texdef_SI_values.scale[0] + texdef_offset.scale[0];
1681       is_HScale_conflicting = FALSE;
1682     }
1683     GetTexMods();
1684   }
1685 }
1686
1687 static void on_vscale_value_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data)
1688 {
1689   texdef_t* tmp_texdef;
1690   texdef_t* tmp_orig_texdef;
1691   texdef_to_face_t* temp_texdef_face_list;
1692   
1693   texdef_SI_values.scale[1] = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(vscale_value_spinbutton) );
1694   
1695   if (!texdef_face_list_empty() && g_bListenChanged)
1696   {
1697     for (temp_texdef_face_list = get_texdef_face_list(); temp_texdef_face_list; temp_texdef_face_list = temp_texdef_face_list->next)
1698     {
1699       tmp_texdef = (texdef_t *) &temp_texdef_face_list->texdef;
1700       tmp_orig_texdef = (texdef_t *) &temp_texdef_face_list->orig_texdef;
1701       tmp_texdef->scale[1] = texdef_SI_values.scale[1] + texdef_offset.scale[1];
1702       is_VScale_conflicting = FALSE;
1703     }
1704     GetTexMods();
1705   }
1706 }
1707
1708 static void on_rotate_value_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data)
1709 {
1710   texdef_t* tmp_texdef;
1711   texdef_t* tmp_orig_texdef;
1712   texdef_to_face_t* temp_texdef_face_list;
1713   
1714   texdef_SI_values.rotate = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(rotate_value_spinbutton) );
1715   
1716   if (!texdef_face_list_empty() && g_bListenChanged)
1717   {
1718     for (temp_texdef_face_list = get_texdef_face_list(); temp_texdef_face_list; temp_texdef_face_list = temp_texdef_face_list->next)
1719     {
1720       tmp_texdef = (texdef_t *) &temp_texdef_face_list->texdef;
1721       tmp_orig_texdef = (texdef_t *) &temp_texdef_face_list->orig_texdef;
1722       tmp_texdef->rotate = texdef_SI_values.rotate + texdef_offset.rotate;
1723       is_Rotate_conflicting = FALSE;
1724     }
1725     GetTexMods();
1726   }
1727 }
1728
1729
1730 // Step Spins
1731 static void on_hshift_step_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data)
1732 {
1733   gfloat val;
1734   GtkAdjustment * adjust;
1735
1736   if (!g_bListenChanged)
1737     return;
1738
1739   l_pIncrement = Get_SI_Inc();
1740
1741 #ifdef DBG_SI
1742   Sys_Printf("OnIncrementChanged HShift\n");
1743 #endif
1744
1745   val = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(hshift_step_spinbutton) ) ;
1746   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON ( hshift_offset_spinbutton ));
1747   adjust->step_increment = val;
1748   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON ( hshift_value_spinbutton ));
1749   adjust->step_increment = val;
1750   l_pIncrement->shift[0] = val;
1751 }
1752
1753 static void on_vshift_step_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data)
1754 {
1755   gfloat val;
1756   GtkAdjustment * adjust;
1757
1758   if (!g_bListenChanged)
1759     return;
1760
1761   l_pIncrement = Get_SI_Inc();
1762
1763 #ifdef DBG_SI
1764   Sys_Printf("OnIncrementChanged VShift\n");
1765 #endif
1766
1767   val = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(vshift_step_spinbutton) ) ;
1768   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON ( vshift_offset_spinbutton ));
1769   adjust->step_increment = val;
1770   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON ( vshift_value_spinbutton ));
1771   adjust->step_increment = val;
1772   l_pIncrement->shift[1] = val;
1773 }
1774
1775 static void on_hscale_step_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data)
1776 {
1777   gfloat val;
1778   GtkAdjustment * adjust;
1779
1780   if (!g_bListenChanged)
1781     return;
1782
1783   l_pIncrement = Get_SI_Inc();
1784
1785 #ifdef DBG_SI
1786   Sys_Printf("OnIncrementChanged HShift\n");
1787 #endif
1788
1789   val = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(hscale_step_spinbutton) ) ;
1790   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON ( hscale_offset_spinbutton ));
1791   adjust->step_increment = val;
1792   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON ( hscale_value_spinbutton ));
1793   adjust->step_increment = val;
1794   l_pIncrement->scale[0] = val;
1795 }
1796
1797 static void on_vscale_step_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data)
1798 {
1799   gfloat val;
1800   GtkAdjustment * adjust;
1801
1802   if (!g_bListenChanged)
1803     return;
1804
1805   l_pIncrement = Get_SI_Inc();
1806
1807 #ifdef DBG_SI
1808   Sys_Printf("OnIncrementChanged HShift\n");
1809 #endif
1810
1811   val = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(vscale_step_spinbutton) ) ;
1812   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON ( vscale_offset_spinbutton ));
1813   adjust->step_increment = val;
1814   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON ( vscale_value_spinbutton ));
1815   adjust->step_increment = val;
1816   l_pIncrement->scale[1] = val;
1817 }
1818
1819 static void on_rotate_step_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data)
1820 {
1821   gfloat val;
1822   GtkAdjustment * adjust;
1823
1824   if (!g_bListenChanged)
1825     return;
1826
1827   l_pIncrement = Get_SI_Inc();
1828
1829 #ifdef DBG_SI
1830   Sys_Printf("OnIncrementChanged HShift\n");
1831 #endif
1832
1833   val = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(rotate_step_spinbutton) ) ;
1834   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON ( rotate_offset_spinbutton ));
1835   adjust->step_increment = val;
1836   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON ( rotate_value_spinbutton ));
1837   adjust->step_increment = val;
1838   l_pIncrement->rotate = val;
1839 }
1840
1841
1842 // Fit Texture
1843 static void on_fit_width_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data)
1844 {
1845   m_nWidth = gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(fit_width_spinbutton) );
1846 }
1847
1848 static void on_fit_height_spinbutton_value_changed (GtkSpinButton *spinbutton, gpointer user_data)
1849 {
1850   m_nHeight = gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(fit_height_spinbutton) );
1851 }
1852
1853 static void on_fit_button_clicked (GtkButton *button, gpointer user_data)
1854 {
1855   FaceList_FitTexture(get_texdef_face_list(), m_nHeight, m_nWidth);
1856   Sys_UpdateWindows(W_ALL);
1857 }
1858
1859
1860 // Axial Button
1861 static void on_axial_button_clicked (GtkButton *button, gpointer user_data)
1862 {
1863   texdef_t* tmp_texdef;
1864   texdef_t* tmp_orig_texdef;
1865   texdef_to_face_t* temp_texdef_face_list;
1866
1867   if (!texdef_face_list_empty() && g_bListenChanged)
1868   {
1869     for (temp_texdef_face_list = get_texdef_face_list(); temp_texdef_face_list; temp_texdef_face_list = temp_texdef_face_list->next)
1870     {
1871       tmp_texdef = (texdef_t *) &temp_texdef_face_list->texdef;
1872       tmp_texdef->shift[0] = 0.0;
1873       tmp_texdef->shift[1] = 0.0;
1874       tmp_texdef->scale[0] = 0.5;
1875       tmp_texdef->scale[1] = 0.5;
1876       tmp_texdef->rotate = 0.0;
1877     }
1878   }
1879
1880   SetTexdef_FaceList( get_texdef_face_list(), FALSE, TRUE );
1881   Sys_UpdateWindows(W_ALL);
1882 }
1883
1884
1885 // Action Buttons
1886 static void on_done_button_clicked (GtkButton *button, gpointer user_data)
1887 {
1888   if ( !texdef_face_list_empty() )
1889     GetTexMods(TRUE);
1890   HideDlg();
1891   Sys_UpdateWindows(W_ALL);
1892 }
1893
1894 static void on_apply_button_clicked (GtkButton *button, gpointer user_data)
1895 {
1896   if (!g_bListenChanged)
1897     return;
1898   if ( !texdef_face_list_empty() )
1899   {
1900     GetTexMods (TRUE);
1901     Sys_UpdateWindows(W_CAMERA);
1902     GetTexdefInfo_from_Radiant();
1903     SetTexMods();
1904   }
1905 }
1906
1907 static void on_cancel_button_clicked (GtkButton *button, gpointer user_data)
1908 {
1909   texturewin = Texturewin ();
1910   texturewin->texdef = g_old_texdef;
1911   // cancel the last do if we own it
1912   if ( (m_nUndoId == Undo_GetUndoId()) && ( m_nUndoId != 0 ))
1913   {
1914 #ifdef DBG_SI
1915     Sys_Printf("OnCancel calling Undo_Undo\n");
1916 #endif
1917     g_bListenUpdate = false;
1918     Undo_Undo(TRUE);
1919     g_bListenUpdate = true;
1920     m_nUndoId = 0;
1921   }
1922   HideDlg();
1923 }
1924
1925