]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - radiant/surfacedialog.cpp
rebuilt gtk binary dependencies file
[xonotic/netradiant.git] / radiant / 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
24 //
25 // Leonardo Zide (leo@lokigames.com)
26 //
27
28 #include <gdk/gdkkeysyms.h>
29 #include "stdafx.h"
30 #include "surfacedialog.h"
31 #include <glib/gi18n.h>
32
33 SurfaceDlg g_dlgSurface;
34
35 /////////////////////////////////////////////////////////////////////////////
36 // surface properties plugin
37
38 /*
39 ===================================================
40
41   SURFACE INSPECTOR
42
43 ===================================================
44 */
45
46 // the texdef to switch back to when the OnCancel is called
47 texdef_t        g_old_texdef;
48 // when != NULL, this thing means the surface inspector is currently being displayed
49 // NOTE a boolean flag would have been more explicit, this is totally so ugly
50 GtkWidget*  g_surfwin = NULL;
51 // turn on/off processing of the "changed" "value_changed" messages
52 // (need to turn off when we are feeding data in)
53 bool g_bListenChanged = true;
54 // the struct used to store the increments (saved in registry)
55 texdef_t *l_pIncrement = &g_qeglobals.d_savedinfo.m_SIIncrement;
56 // turn on/off listening of the update messages
57 bool g_bListenUpdate = true;
58
59 #ifdef _DEBUG
60 // experimental stuff, work directly on BP
61 static void OnTest(GtkWidget *widget, gpointer data)
62 {
63   if (!g_qeglobals.m_bBrushPrimitMode)
64   {
65     Sys_FPrintf(SYS_WRN, "BP mode required\n");
66     return;
67   }
68   if (g_ptrSelectedFaces.GetSize() != 1)
69   {
70     Sys_FPrintf(SYS_WRN, "Expected single face selection\n");
71     return;
72   }
73   brush_t *b = reinterpret_cast<brush_t*>(g_ptrSelectedFaceBrushes.GetAt(0));
74   face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(0));
75   // get the ST axis base for the face
76   vec3_t texS,texT;
77   ComputeAxisBase(selFace->plane.normal, texS, texT);
78   // find ST coordinates for the center of the face
79   float Os=0,Ot=0;
80   int i;
81   for (i=0; i<selFace->face_winding->numpoints; i++)
82   {
83     Os += DotProduct(selFace->face_winding->points[i],texS);
84     Ot += DotProduct(selFace->face_winding->points[i],texT);
85   }
86   Os /= selFace->face_winding->numpoints;
87   Ot /= selFace->face_winding->numpoints;
88   brushprimit_texdef_t *pBP = &selFace->brushprimit_texdef;
89
90   // (FIXME: initial version, before axis base change optimize)
91
92   // we need to compute our BP matrix in this new axis base (O,texS,texT)
93   // the general case if BPO = M * BP * M^-1
94   //   where BPO is transformation expressed in (O,texS,texT)
95   //         M is the axis base change from (origin,texS,texT) to (O,texS,texT)
96   // here we have a special case, M is a translation and it's inverse is easy
97   vec_t BPO[2][3];
98   vec_t aux[2][3];
99   vec_t m[2][3];
100   memset(&m, 0, sizeof(vec_t)*6);
101   m[0][0] = 1; m[1][1] = 1; m[0][2] = -Os; m[1][2] = -Ot;
102   BPMatMul(m, pBP->coords, aux);
103   m[0][2] = Os; m[1][2] = Ot; // now M^-1
104   BPMatMul(aux, m, BPO);
105
106 #if 0
107   // apply a scaling
108   // scale factors against S and T axis, we apply on top of the existing matrix
109   // <1 will decrease the texel/world resolution, >1 will increase
110   float sS = 1.025,sT = 1.025;
111   BPMatScale(BPO,sS,sT);
112 #endif
113 #if 0
114   // apply a rotation
115   float theta = 5;
116   BPMatRotate(BPO,theta);
117 #endif
118 #if 0
119   // read the scale
120   ConvertTexMatWithQTexture(BPO, selFace->d_texture, aux, NULL);
121   // reset the scale (normalize the matrix)
122   vec_t v1,v2;
123   v1 = sqrt(aux[0][0]*aux[0][0]+aux[1][0]*aux[1][0]);
124   v2 = sqrt(aux[0][1]*aux[0][1]+aux[1][1]*aux[1][1]);
125   // if reading the scale values, we have them here:
126   Sys_Printf("Current Scale: S: %g T: %g\n", v1, v2);
127   return;
128 #endif
129 #if 1
130   // apply a given scale (on S and T)
131   ConvertTexMatWithQTexture(BPO, selFace->d_texture, aux, NULL);
132   // reset the scale (normalize the matrix)
133   vec_t v1,v2;
134   v1 = sqrt(aux[0][0]*aux[0][0]+aux[1][0]*aux[1][0]);
135   v2 = sqrt(aux[0][1]*aux[0][1]+aux[1][1]*aux[1][1]);
136   vec_t sS,sT;
137   // put the values for scale on S and T here:
138   sS = 1.2 / v1;
139   sT = 0.8 / v2;
140   aux[0][0] *= sS; aux[1][0] *= sS;
141   aux[0][1] *= sT; aux[1][1] *= sT;
142   ConvertTexMatWithQTexture(aux, NULL, BPO, selFace->d_texture);
143 #endif
144
145   // now BPO must be expressed back in (origin,texS,texT) axis base BP = M^-1 * BPO * M
146   BPMatMul(m, BPO, aux); // m is M^-1
147   m[0][2] = -Os; m[1][2] = -Ot;
148   BPMatMul(aux, m, pBP->coords);
149
150   // now emit the coordinates on the winding
151   EmitBrushPrimitTextureCoordinates(selFace, selFace->face_winding);
152   Sys_UpdateWindows(W_CAMERA);
153 }
154
155 /*
156   FIXME: try again, there must be a silly mistake in the formula expansion
157   // we need to compute our BP matrix in this new axis base (O,texS,texT)
158   // the general case is BPO = M * BP * M^-1
159   //   where BPO is transformation expressed in (O,texS,texT)
160   //         M is the axis base change from (origin,texS,texT) to (O,texS,texT)
161   // here we have a special case, M is a translation and it's inverse is easy
162   // the M * BP * M^-1 formula can be expanded and simplified
163   vec_t BPO[2][3];
164   memcpy(&BPO, &pBP->coords, sizeof(vec_t)*6);
165   BPO[0][2] = Os*(pBP->coords[0][0]-1.0) + Ot*pBP->coords[0][1] + pBP->coords[0][2];
166   BPO[1][2] = Os*pBP->coords[1][0] + Ot*(pBP->coords[1][1]-1.0) + Ot*pBP->coords[1][2];
167
168   // apply a scaling
169   // scale factors against S and T axis, we apply on top of the existing matrix
170   // <1 will decrease the texel/world resolution, >1 will increase
171   float sS = 1.025,sT = 1.025;
172   BPMatScale(BPO,sS,sT);
173
174   // now BPO must be expressed back in (origin,texS,texT) axis base BP = M^-1 * BPO * M
175   // same expanded formula as above
176   memcpy(&pBP->coords, &BPO, sizeof(vec_t)*6);
177   pBP->coords[0][2] = Os*(1.0-BPO[0][0]) - Ot*BPO[0][1] + BPO[0][2];
178   pBP->coords[1][2] = -Os*BPO[1][0] + Ot*(1.0-BPO[1][1]) + BPO[1][2];
179 */
180
181 /*
182   // initial version, before axis base change optimize
183
184   // we need to compute our BP matrix in this new axis base (O,texS,texT)
185   // the general case if BPO = M * BP * M^-1
186   //   where BPO is transformation expressed in (O,texS,texT)
187   //         M is the axis base change from (origin,texS,texT) to (O,texS,texT)
188   // here we have a special case, M is a translation and it's inverse is easy
189   vec_t BPO[2][3];
190   vec_t aux[2][3];
191   vec_t m[2][3];
192   memset(&m, 0, sizeof(vec_t)*6);
193   m[0][0] = 1; m[1][1] = 1; m[0][2] = -Os; m[1][2] = -Ot;
194   BPMatMul(m, pBP->coords, aux);
195   m[0][2] = Os; m[1][2] = Ot; // now M^-1
196   BPMatMul(aux, m, BPO);
197
198   // apply a scaling
199   // scale factors against S and T axis, we apply on top of the existing matrix
200   // <1 will decrease the texel/world resolution, >1 will increase
201   float sS = 1.025,sT = 1.025;
202   BPMatScale(BPO,sS,sT);
203
204   // now BPO must be expressed back in (origin,texS,texT) axis base BP = M^-1 * BPO * M
205   BPMatMul(m, BPO, aux); // m is M^-1
206   m[0][2] = -Os; m[1][2] = -Ot;
207   BPMatMul(aux, m, pBP->coords);
208 */
209 #endif
210
211 static void OnDone(GtkWidget *widget, gpointer data)
212 {
213   g_dlgSurface.GetTexMods();
214   g_dlgSurface.HideDlg ();
215   Sys_UpdateWindows(W_ALL);
216 }
217
218 // OnUpdate is called when something is changed in the dialog
219 // and must be reflected in the views. But it's not a change
220 // so important, so the system will try to undo our last do before applying the new changes
221 static void OnUpdate (GtkWidget *widget, gpointer data)
222 {
223   if (!g_bListenChanged)
224     return;
225
226   if (OnlyPatchesSelected())
227   {
228     //++timo possible bug or misfeature in our gtk_MessageBox here..
229 //    gtk_MessageBox("The surface inspector doesn't work for patches, use the patch inspector instead (Shift+S)", "Surface Inspector", MB_OK );
230     Sys_Printf("The surface inspector doesn't work for patches, use the patch inspector instead (Shift+S)\n");
231     return;
232   }
233
234   // avoid long delays on slow computers
235   while (gtk_events_pending ())
236     gtk_main_iteration ();
237
238   g_dlgSurface.GetTexMods ();
239   Sys_UpdateWindows(W_CAMERA);
240 }
241
242 // reflect the current changes in the views, and make sure
243 // the changes are stored in the undo.
244 static void OnApply (GtkWidget *widget, gpointer data)
245 {
246   if (!g_bListenChanged)
247     return;
248
249   g_dlgSurface.GetTexMods ();
250   g_dlgSurface.m_nUndoId = 0; // that way we are sure we won't call undo
251   Sys_UpdateWindows(W_CAMERA);
252 }
253
254 // we use OnTextureKey to detect when the user edits something in the texture widget
255 // in which case next 'Enter' will be interpreted as a OnApply instead of a OnDone
256 static gint OnTextureKey (GtkWidget* widget, GdkEventKey* event, gpointer data)
257 {
258 #ifdef DBG_SI
259   Sys_Printf("OnTextureKey\n");
260 #endif
261   if (event->keyval != GDK_Return)
262     g_dlgSurface.m_bEditingTextureWidget = true;
263   return FALSE;
264 }
265
266 static void OnCancel(GtkWidget *widget, gpointer data)
267 {
268   g_qeglobals.d_texturewin.texdef = g_old_texdef;
269   // cancel the last do if we own it
270   if (g_dlgSurface.m_nUndoId == Undo_GetUndoId())
271   {
272 #ifdef DBG_SI
273     Sys_Printf("OnCancel calling Undo_Undo\n");
274 #endif
275     g_bListenUpdate = false;
276     Undo_Undo();
277     g_bListenUpdate = true;
278     g_dlgSurface.m_nUndoId = 0;
279   }
280   g_dlgSurface.HideDlg ();
281 }
282
283 static gint OnDialogKey (GtkWidget* widget, GdkEventKey* event, gpointer data)
284 {
285   if (g_surfwin)
286   {
287     if (event->keyval == GDK_Return)
288     {
289       if (g_dlgSurface.m_bEditingTextureWidget)
290       {
291         OnApply (NULL, NULL);
292         g_dlgSurface.m_bEditingTextureWidget = false;
293       }
294       else
295       {
296         OnDone (NULL, NULL);
297       }
298       return TRUE;
299     }
300     if (event->keyval == GDK_Escape)
301     {
302       OnCancel (NULL, NULL);
303       return TRUE;
304     }
305   }
306   return FALSE;
307 }
308
309 // the widget can be one of hshift, vshift, hscale, vscale, rotate
310 // we use the g_bListenChanged flag to ignore when changing stuff ourselves
311 static void OnIncrementChanged(GtkWidget *widget, gpointer data)
312 {
313   if (!g_bListenChanged)
314     return;
315
316 #ifdef DBG_SI
317   Sys_Printf("OnIncrementChanged\n");
318 #endif
319
320   gfloat val = 0;
321   sscanf( gtk_entry_get_text (GTK_ENTRY (widget)), "%g", &val);
322   // now push it into the appropriate spin button
323   GtkAdjustment * adjust;
324   if (widget == g_dlgSurface.GetDlgWidget ("hshift_inc"))
325   {
326     l_pIncrement->shift[0] = val;
327     adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (g_dlgSurface.GetDlgWidget ("hshift")));
328     adjust->step_increment = l_pIncrement->shift[0];
329   }
330   else if (widget == g_dlgSurface.GetDlgWidget ("vshift_inc"))
331   {
332     l_pIncrement->shift[1] = val;
333     adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (g_dlgSurface.GetDlgWidget ("vshift")));
334     adjust->step_increment = l_pIncrement->shift[1];
335   }
336   else if (widget == g_dlgSurface.GetDlgWidget ("hscale_inc"))
337   {
338     l_pIncrement->scale[0] = val;
339     adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (g_dlgSurface.GetDlgWidget ("hscale")));
340     adjust->step_increment = l_pIncrement->scale[0];
341   }
342   else if (widget == g_dlgSurface.GetDlgWidget ("vscale_inc"))
343   {
344     l_pIncrement->scale[1] = val;
345     adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (g_dlgSurface.GetDlgWidget ("vscale")));
346     adjust->step_increment = l_pIncrement->scale[1];
347   }
348   else if (widget == g_dlgSurface.GetDlgWidget ("rotate_inc"))
349   {
350     l_pIncrement->rotate = val;
351     adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (g_dlgSurface.GetDlgWidget ("rotate")));
352     adjust->step_increment = l_pIncrement->rotate;
353   }
354 }
355
356 // make the shift increments match the grid settings
357 // the objective being that the shift+arrows shortcuts move the texture by the corresponding grid size
358 // this depends on a scale value if you have selected a particular texture on which you want it to work:
359 // we move the textures in pixels, not world units. (i.e. increment values are in pixel)
360 // depending on the texture scale it doesn't take the same amount of pixels to move of g_qeglobals.d_gridsize
361 // increment * scale = gridsize
362 // hscale and vscale are optional parameters, if they are zero they will be set to the default scale
363 // NOTE: the default scale depends if you are using BP mode or regular.
364 // For regular it's 0.5f (128 pixels cover 64 world units), for BP it's simply 1.0f
365 // see fenris #2810
366 void DoSnapTToGrid(float hscale, float vscale)
367 {
368   if (hscale == 0.0f)
369   {
370     (g_qeglobals.m_bBrushPrimitMode) ? hscale = 1.0f : hscale = 0.5f;
371   }
372   if (vscale == 0.0f)
373   {
374     (g_qeglobals.m_bBrushPrimitMode) ? vscale = 1.0f : vscale = 0.5f;
375   }
376 #ifdef _DEBUG
377   Sys_Printf ("DoSnapTToGrid: hscale %g vscale %g\n", hscale, vscale);
378 #endif
379   l_pIncrement->shift[0] = (int) ( (float)g_qeglobals.d_gridsize / hscale );
380   l_pIncrement->shift[1] = (int) ( (float)g_qeglobals.d_gridsize / vscale );
381   // now some update work
382   // FIXME: doesn't look good here, seems to be called several times
383   g_dlgSurface.SetTexMods();
384 }
385
386 // make the shift increments match the grid settings
387 // the objective being that the shift+arrows shortcuts move the texture by the corresponding grid size
388 // this depends on the current texture scale used?
389 // we move the textures in pixels, not world units. (i.e. increment values are in pixel)
390 // depending on the texture scale it doesn't take the same amount of pixels to move of g_qeglobals.d_gridsize
391 // increment * scale = gridsize
392 static void OnBtnMatchGrid(GtkWidget *widget, gpointer data)
393 {
394   float hscale, vscale;
395   hscale = gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (g_dlgSurface.GetDlgWidget ("hscale")));
396   vscale = gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (g_dlgSurface.GetDlgWidget ("vscale")));
397   if (hscale == 0.0f || vscale == 0.0f)
398   {
399     Sys_Printf("ERROR: unexpected scale == 0.0f\n");
400     return;
401   }
402   DoSnapTToGrid (hscale, vscale);
403 }
404
405 void UpdateSurfaceDialog()
406 {
407   if (!g_bListenUpdate)
408     return;
409
410   g_SurfaceTable.m_pfnUpdateSurfaceDialog();
411 }
412
413 // DoSurface will always try to show the surface inspector
414 // or update it because something new has been selected
415 void DoSurface (void)
416 {
417 #ifdef DBG_SI
418   Sys_Printf("DoSurface\n");
419 #endif
420   g_SurfaceTable.m_pfnDoSurface();
421   return;
422 }
423
424 void ToggleSurface()
425 {
426   g_SurfaceTable.m_pfnToggleSurface();
427   return;
428 }
429
430 // NOTE: will raise and show the Surface inspector and exec fit for patches and brushes
431 void SurfaceDlgFitAll()
432 {
433   g_SurfaceTable.m_pfnSurfaceDlgFitAll();
434   return;
435 }
436
437 static void OnBtnPatchdetails(GtkWidget *widget, gpointer data)
438 {
439   Patch_NaturalizeSelected(true);
440   Sys_UpdateWindows(W_ALL);
441 }
442
443 static void OnBtnPatchnatural(GtkWidget *widget, gpointer data)
444 {
445   Patch_NaturalizeSelected();
446   Sys_UpdateWindows(W_ALL);
447 }
448
449 static void OnBtnPatchreset(GtkWidget *widget, gpointer data)
450 {
451   float fx, fy;
452
453   if (DoTextureLayout (&fx, &fy) == IDOK)
454     Patch_ResetTexturing (fx, fy);
455   Sys_UpdateWindows(W_ALL);
456 }
457
458 static void OnBtnPatchFit(GtkWidget *widget, gpointer data)
459 {
460   Patch_ResetTexturing(1.0, 1.0);
461   Sys_UpdateWindows(W_ALL);
462 }
463
464 static void OnBtnAxial(GtkWidget *widget, gpointer data)
465 {
466   Select_SetTexture (&g_qeglobals.d_texturewin.texdef, &g_qeglobals.d_texturewin.brushprimit_texdef, true);
467   g_dlgSurface.SetTexMods();
468   Sys_UpdateWindows(W_ALL);
469 }
470
471 static void OnBtnFaceFit(GtkWidget *widget, gpointer data)
472 {
473   g_dlgSurface.UpdateData(TRUE);
474   if (g_ptrSelectedFaces.GetSize() == 0)
475   {
476     brush_t *b;
477     for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
478     {
479       for (face_t* pFace = b->brush_faces; pFace; pFace = pFace->next)
480       {
481         g_ptrSelectedFaces.Add(pFace);
482         g_ptrSelectedFaceBrushes.Add(b);
483       }
484     }
485     Select_FitTexture(g_dlgSurface.m_nHeight, g_dlgSurface.m_nWidth);
486     g_dlgSurface.SetTexMods();
487     g_ptrSelectedFaces.RemoveAll();
488   }
489   else
490   {
491     Select_FitTexture(g_dlgSurface.m_nHeight, g_dlgSurface.m_nWidth);
492     g_dlgSurface.SetTexMods();
493   }
494   Sys_UpdateWindows(W_ALL);
495 }
496
497 // =============================================================================
498 // SurfaceDialog class
499
500 SurfaceDlg::SurfaceDlg ()
501 {
502   m_nHeight = 1;
503   m_nWidth = 1;
504   m_nUndoId = 0;
505 }
506
507 void SurfaceDlg::ShowDlg()
508 {
509   Dialog::ShowDlg();
510   if(GetWidget() == NULL)
511     Create();
512   g_surfwin = GetWidget ();
513 }
514 void SurfaceDlg::HideDlg()
515 {
516   g_surfwin = NULL;
517   Dialog::HideDlg();
518 }
519
520 GtkWidget* SurfaceDlg::GetWidget()
521 {
522   return g_SurfaceTable.m_pfnGet_SI_Module_Widget();
523 }
524
525 // set default values for increments (shift scale and rot)
526 // this is called by the prefs code if can't find the values
527 void SurfaceDlg::InitDefaultIncrement(texdef_t *tex)
528 {
529   tex->SetName("foo");
530   tex->shift[0] = 8;
531   tex->shift[1] = 8;
532   tex->scale[0] = 0.25;
533   tex->scale[1] = 0.25;
534   tex->rotate = 10;
535 }
536
537 void SurfaceDlg::BuildDialog ()
538 {
539   GtkWidget *dlg, *vbox, *hbox2, *frame, *table, *label;
540   GtkWidget *button, *entry, *spin;
541
542   dlg = m_pWidget;
543
544   load_window_pos (dlg, g_PrefsDlg.mWindowInfo.posSurfaceWnd);
545
546   gtk_window_set_title (GTK_WINDOW (dlg), _("Surface inspector"));
547   //g_signal_connect (G_OBJECT (dlg), "delete_event", G_CALLBACK (OnCancel), NULL);
548   // we catch 'Enter' and interpret is as OnDone
549   gtk_signal_connect (GTK_OBJECT (dlg), "key_press_event", GTK_SIGNAL_FUNC (OnDialogKey), NULL);
550   gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (g_pParentWnd->m_pWidget));
551
552   // replaced by only the vbox:
553   vbox = gtk_vbox_new (FALSE, 5);
554   gtk_widget_show (vbox);
555   gtk_container_add (GTK_CONTAINER (dlg), vbox);
556   gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
557
558   hbox2 = gtk_hbox_new (FALSE, 5);
559   gtk_widget_show (hbox2);
560   gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, TRUE, 0);
561
562   label = gtk_label_new (_("Texture"));
563   gtk_widget_show (label);
564   gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
565
566   entry = gtk_entry_new ();
567   gtk_signal_connect (GTK_OBJECT (entry), "key_press_event", GTK_SIGNAL_FUNC (OnTextureKey), NULL);
568   gtk_widget_show (entry);
569   gtk_box_pack_start (GTK_BOX (hbox2), entry, TRUE, TRUE, 0);
570   g_object_set_data (G_OBJECT (m_pWidget), "texture", entry);
571
572 //  table = gtk_table_new (5, 4, FALSE);
573   table = gtk_table_new (6, 4, FALSE);
574   gtk_widget_show (table);
575   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
576   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
577   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
578
579   label = gtk_label_new (_("Horizontal shift"));
580   gtk_widget_show (label);
581   gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
582   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
583                     (GtkAttachOptions) (GTK_FILL),
584                     (GtkAttachOptions) (0), 0, 0);
585
586   spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, -8192, 8192, 2, 8, 8)), 0, 0);
587   g_object_set_data (G_OBJECT (dlg), "hshift", spin);
588   gtk_signal_connect (GTK_OBJECT (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin))), "value_changed",
589                       GTK_SIGNAL_FUNC (OnUpdate), NULL);
590   gtk_widget_show (spin);
591   gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 0, 1,
592                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
593                     (GtkAttachOptions) (0), 0, 0);
594   gtk_widget_set_usize (spin, 60, -2);
595
596   label = gtk_label_new (_("Step"));
597   gtk_widget_show (label);
598   gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
599   gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1,
600                     (GtkAttachOptions) (GTK_FILL),
601                     (GtkAttachOptions) (0), 0, 0);
602
603   entry = gtk_entry_new ();
604   g_object_set_data (G_OBJECT (dlg), "hshift_inc", entry);
605   gtk_signal_connect (GTK_OBJECT (entry), "changed",
606                       GTK_SIGNAL_FUNC (OnIncrementChanged), NULL);
607   gtk_widget_show (entry);
608   gtk_table_attach (GTK_TABLE (table), entry, 3, 4, 0, 1,
609                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
610                     (GtkAttachOptions) (0), 0, 0);
611   gtk_widget_set_usize (entry, 50, -2);
612
613   label = gtk_label_new (_("Vertical shift"));
614   gtk_widget_show (label);
615   gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
616   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
617                     (GtkAttachOptions) (GTK_FILL),
618                     (GtkAttachOptions) (0), 0, 0);
619
620   spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, -8192, 8192, 2, 8, 8)), 0, 0);
621   g_object_set_data (G_OBJECT (dlg), "vshift", spin);
622   gtk_signal_connect (GTK_OBJECT (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin))), "value_changed",
623                       GTK_SIGNAL_FUNC (OnUpdate), NULL);
624   gtk_widget_show (spin);
625   gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 1, 2,
626                     (GtkAttachOptions) (GTK_FILL),
627                     (GtkAttachOptions) (0), 0, 0);
628   gtk_widget_set_usize (spin, 60, -2);
629
630   label = gtk_label_new (_("Step"));
631   gtk_widget_show (label);
632   gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
633   gtk_table_attach (GTK_TABLE (table), label, 2, 3, 1, 2,
634                     (GtkAttachOptions) (GTK_FILL),
635                     (GtkAttachOptions) (0), 0, 0);
636
637   entry = gtk_entry_new ();
638   g_object_set_data (G_OBJECT (dlg), "vshift_inc", entry);
639   gtk_signal_connect (GTK_OBJECT (entry), "changed",
640                       GTK_SIGNAL_FUNC (OnIncrementChanged), NULL);
641   gtk_widget_show (entry);
642   gtk_table_attach (GTK_TABLE (table), entry, 3, 4, 1, 2,
643                     (GtkAttachOptions) (GTK_FILL),
644                     (GtkAttachOptions) (0), 0, 0);
645   gtk_widget_set_usize (entry, 50, -2);
646
647   label = gtk_label_new (_("Horizontal stretch"));
648   gtk_widget_show (label);
649   gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
650   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
651                     (GtkAttachOptions) (GTK_FILL),
652                     (GtkAttachOptions) (0), 0, 0);
653
654   spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, -1000, 1000, 1, 10, 10)), 0, 0);
655   g_object_set_data (G_OBJECT (dlg), "hscale", spin);
656   gtk_signal_connect (GTK_OBJECT (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin))), "value_changed",
657                       GTK_SIGNAL_FUNC (OnUpdate), NULL);
658   gtk_widget_show (spin);
659   gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 2, 3,
660                     (GtkAttachOptions) (GTK_FILL),
661                     (GtkAttachOptions) (0), 0, 0);
662   gtk_widget_set_usize (spin, 60, -2);
663
664   label = gtk_label_new (_("Step"));
665   gtk_widget_show (label);
666   gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
667   gtk_table_attach (GTK_TABLE (table), label, 2, 3, 2, 3,
668                     (GtkAttachOptions) (GTK_FILL),
669                     (GtkAttachOptions) (0), 2, 3);
670
671   entry = gtk_entry_new ();
672   g_object_set_data (G_OBJECT (dlg), "hscale_inc", entry);
673   gtk_signal_connect (GTK_OBJECT (entry), "changed",
674                       GTK_SIGNAL_FUNC (OnIncrementChanged), NULL);
675   gtk_widget_show (entry);
676   gtk_table_attach (GTK_TABLE (table), entry, 3, 4, 2, 3,
677                     (GtkAttachOptions) (GTK_FILL),
678                     (GtkAttachOptions) (0), 2, 3);
679   gtk_widget_set_usize (entry, 50, -2);
680
681   label = gtk_label_new (_("Vertical stretch"));
682   gtk_widget_show (label);
683   gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
684   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4,
685                     (GtkAttachOptions) (GTK_FILL),
686                     (GtkAttachOptions) (0), 0, 0);
687
688   spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, -1000, 1000, 1, 10, 10)), 0, 0);
689   g_object_set_data (G_OBJECT (dlg), "vscale", spin);
690   gtk_signal_connect (GTK_OBJECT (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin))), "value_changed",
691                       GTK_SIGNAL_FUNC (OnUpdate), NULL);
692   gtk_widget_show (spin);
693   gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 3, 4,
694                     (GtkAttachOptions) (GTK_FILL),
695                     (GtkAttachOptions) (0), 0, 0);
696   gtk_widget_set_usize (spin, 60, -2);
697
698   label = gtk_label_new (_("Step"));
699   gtk_widget_show (label);
700   gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
701   gtk_table_attach (GTK_TABLE (table), label, 2, 3, 3, 4,
702                     (GtkAttachOptions) (GTK_FILL),
703                     (GtkAttachOptions) (0), 0, 0);
704
705   entry = gtk_entry_new ();
706   g_object_set_data (G_OBJECT (dlg), "vscale_inc", entry);
707   gtk_signal_connect (GTK_OBJECT (entry), "changed",
708                       GTK_SIGNAL_FUNC (OnIncrementChanged), NULL);
709   gtk_widget_show (entry);
710   gtk_table_attach (GTK_TABLE (table), entry, 3, 4, 3, 4,
711                     (GtkAttachOptions) (GTK_FILL),
712                     (GtkAttachOptions) (0), 0, 0);
713   gtk_widget_set_usize (entry, 50, -2);
714
715   label = gtk_label_new (_("Rotate"));
716   gtk_widget_show (label);
717   gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
718   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 4, 5,
719                     (GtkAttachOptions) (GTK_FILL),
720                     (GtkAttachOptions) (0), 0, 0);
721
722   spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, -360, 360, 1, 10, 10)), 1, 0);
723   g_object_set_data (G_OBJECT (dlg), "rotate", spin);
724   gtk_signal_connect (GTK_OBJECT (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin))), "value_changed",
725                       GTK_SIGNAL_FUNC (OnUpdate), NULL);
726   gtk_widget_show (spin);
727   gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 4, 5,
728                     (GtkAttachOptions) (GTK_FILL),
729                     (GtkAttachOptions) (0), 0, 0);
730   gtk_widget_set_usize (spin, 60, -2);
731   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spin), TRUE);
732
733   label = gtk_label_new (_("Step"));
734   gtk_widget_show (label);
735   gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
736   gtk_table_attach (GTK_TABLE (table), label, 2, 3, 4, 5,
737                     (GtkAttachOptions) (GTK_FILL),
738                     (GtkAttachOptions) (0), 0, 0);
739
740   entry = gtk_entry_new ();
741   g_object_set_data (G_OBJECT (dlg), "rotate_inc", entry);
742   gtk_signal_connect (GTK_OBJECT (entry), "changed",
743                       GTK_SIGNAL_FUNC (OnIncrementChanged), NULL);
744   gtk_widget_show (entry);
745   gtk_table_attach (GTK_TABLE (table), entry, 3, 4, 4, 5,
746                     (GtkAttachOptions) (GTK_FILL),
747                     (GtkAttachOptions) (0), 0, 0);
748   gtk_widget_set_usize (entry, 50, -2);
749
750   // match grid button
751   button = gtk_button_new_with_label (_("Match Grid"));
752   gtk_widget_show (button);
753   gtk_table_attach (GTK_TABLE (table), button, 2, 4, 5, 6,
754                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
755                     (GtkAttachOptions) (0), 0, 0);
756   gtk_signal_connect (GTK_OBJECT (button), "clicked",
757                       GTK_SIGNAL_FUNC (OnBtnMatchGrid), NULL);
758
759   frame = gtk_frame_new (_("Texturing"));
760   gtk_widget_show (frame);
761   gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
762
763   table = gtk_table_new (4, 4, FALSE);
764   gtk_widget_show (table);
765   gtk_container_add (GTK_CONTAINER (frame), table);
766   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
767   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
768   gtk_container_set_border_width (GTK_CONTAINER (table), 5);
769
770   label = gtk_label_new ("Brush");
771   gtk_widget_show (label);
772   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
773                     (GtkAttachOptions) (GTK_FILL),
774                     (GtkAttachOptions) (0), 0, 0);
775
776   label = gtk_label_new ("Patch");
777   gtk_widget_show (label);
778   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
779                     (GtkAttachOptions) (GTK_FILL),
780                     (GtkAttachOptions) (0), 0, 0);
781
782   label = gtk_label_new ("Width");
783   gtk_widget_show (label);
784   gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1,
785                     (GtkAttachOptions) (GTK_FILL),
786                     (GtkAttachOptions) (0), 0, 0);
787
788   label = gtk_label_new (_("Height"));
789   gtk_widget_show (label);
790   gtk_table_attach (GTK_TABLE (table), label, 3, 4, 0, 1,
791                     (GtkAttachOptions) (GTK_FILL),
792                     (GtkAttachOptions) (0), 0, 0);
793
794   button = gtk_button_new_with_label (_("Axial"));
795   gtk_widget_show (button);
796   gtk_table_attach (GTK_TABLE (table), button, 0, 1, 1, 2,
797                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
798                     (GtkAttachOptions) (0), 0, 0);
799   gtk_signal_connect (GTK_OBJECT (button), "clicked",
800                       GTK_SIGNAL_FUNC (OnBtnAxial), NULL);
801   gtk_widget_set_usize (button, 60, -2);
802
803   button = gtk_button_new_with_label (_("Fit"));
804   gtk_widget_show (button);
805   gtk_table_attach (GTK_TABLE (table), button, 1, 2, 1, 2,
806                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
807                     (GtkAttachOptions) (0), 0, 0);
808   gtk_signal_connect (GTK_OBJECT (button), "clicked",
809                       GTK_SIGNAL_FUNC (OnBtnFaceFit), NULL);
810   gtk_widget_set_usize (button, 60, -2);
811
812   button = gtk_button_new_with_label (_("CAP"));
813   gtk_widget_show (button);
814   gtk_table_attach (GTK_TABLE (table), button, 0, 1, 3, 4,
815                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
816                     (GtkAttachOptions) (0), 0, 0);
817   gtk_signal_connect (GTK_OBJECT (button), "clicked",
818                       GTK_SIGNAL_FUNC (OnBtnPatchdetails), NULL);
819   gtk_widget_set_usize (button, 60, -2);
820
821   button = gtk_button_new_with_label (_("Set..."));
822   gtk_widget_show (button);
823   gtk_table_attach (GTK_TABLE (table), button, 1, 2, 3, 4,
824                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
825                     (GtkAttachOptions) (0), 0, 0);
826   gtk_signal_connect (GTK_OBJECT (button), "clicked",
827                       GTK_SIGNAL_FUNC (OnBtnPatchreset), NULL);
828   gtk_widget_set_usize (button, 60, -2);
829
830   button = gtk_button_new_with_label (_("Natural"));
831   gtk_widget_show (button);
832   gtk_table_attach (GTK_TABLE (table), button, 2, 3, 3, 4,
833                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
834                     (GtkAttachOptions) (0), 0, 0);
835   gtk_signal_connect (GTK_OBJECT (button), "clicked",
836                       GTK_SIGNAL_FUNC (OnBtnPatchnatural), NULL);
837   gtk_widget_set_usize (button, 60, -2);
838
839   button = gtk_button_new_with_label (_("Fit"));
840   gtk_widget_show (button);
841   gtk_table_attach (GTK_TABLE (table), button, 3, 4, 3, 4,
842                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
843                     (GtkAttachOptions) (0), 0, 0);
844   gtk_signal_connect (GTK_OBJECT (button), "clicked",
845                       GTK_SIGNAL_FUNC (OnBtnPatchFit), NULL);
846   gtk_widget_set_usize (button, 60, -2);
847
848   spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (1, 1, 32, 1, 10, 10)), 1, 0);
849   gtk_widget_show (spin);
850   gtk_table_attach (GTK_TABLE (table), spin, 2, 3, 1, 2,
851                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
852                     (GtkAttachOptions) (0), 0, 0);
853   gtk_widget_set_usize (spin, 60, -2);
854   AddDialogData (spin, &m_nWidth, DLG_SPIN_INT);
855
856   spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (1, 1, 32, 1, 10, 10)), 1, 0);
857   gtk_widget_show (spin);
858   gtk_table_attach (GTK_TABLE (table), spin, 3, 4, 1, 2,
859                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
860                     (GtkAttachOptions) (0), 0, 0);
861   gtk_widget_set_usize (spin, 60, -2);
862   AddDialogData (spin, &m_nHeight, DLG_SPIN_INT);
863
864   hbox2 = gtk_hbox_new (FALSE, 5);
865   gtk_widget_show (hbox2);
866   gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, TRUE, 0);
867
868   button = gtk_button_new_with_label (_("Done"));
869   gtk_widget_show (button);
870   gtk_box_pack_start (GTK_BOX (hbox2), button, FALSE, FALSE, 0);
871   gtk_signal_connect (GTK_OBJECT (button), "clicked",
872                       GTK_SIGNAL_FUNC (OnDone), NULL);
873   gtk_widget_set_usize (button, 60, -2);
874
875   button = gtk_button_new_with_label (_("Apply"));
876   gtk_widget_show (button);
877   gtk_box_pack_start (GTK_BOX (hbox2), button, FALSE, FALSE, 0);
878   gtk_signal_connect (GTK_OBJECT (button), "clicked",
879                       GTK_SIGNAL_FUNC (OnApply), NULL);
880   gtk_widget_set_usize (button, 60, -2);
881
882   button = gtk_button_new_with_label (_("Cancel"));
883   gtk_widget_show (button);
884   gtk_box_pack_start (GTK_BOX (hbox2), button, FALSE, FALSE, 0);
885   gtk_signal_connect (GTK_OBJECT (button), "clicked",
886                       GTK_SIGNAL_FUNC (OnCancel), NULL);
887   gtk_widget_set_usize (button, 60, -2);
888
889   // that's a bit of trashy stuff from Textool-v2 branch
890 #ifdef _DEBUG
891   // FIXME: testing only, scaling in BP mode
892   button = gtk_button_new_with_label (_("Test"));
893   gtk_widget_show (button);
894   gtk_box_pack_start (GTK_BOX (hbox2), button, FALSE, FALSE, 0);
895   gtk_signal_connect (GTK_OBJECT (button), "clicked",
896                       GTK_SIGNAL_FUNC (OnTest), NULL);
897   gtk_widget_set_usize (button, 60, -2);
898 #endif
899
900   // Initialize
901   SetTexMods ();
902 }
903
904 /*
905 ==============
906 SetTexMods
907
908 Set the fields to the current texdef (i.e. map/texdef -> dialog widgets)
909 if faces selected (instead of brushes) -> will read this face texdef, else current texdef
910 if only patches selected, will read the patch texdef
911 ===============
912 */
913
914 void SurfaceDlg::SetTexMods()
915 {
916   texdef_t *pt;
917   brushprimit_texdef_t  *bpt;
918   // local copy if a width=2 height=2 qtetxture_t is needed
919   brushprimit_texdef_t  local_bp;
920
921 #ifdef DBG_SI
922   Sys_Printf("SurfaceDlg::SetTexMods\n");
923 #endif
924
925   if (!g_surfwin)
926     return;
927
928   if (g_ptrSelectedFaces.GetSize() > 0)
929   {
930     face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(0));
931     pt = &selFace->texdef;
932     if (g_qeglobals.m_bBrushPrimitMode)
933     {
934       // compute a texture matrix related to the default matrix width=2 height=2
935       ConvertTexMatWithQTexture( &selFace->brushprimit_texdef, selFace->d_texture, &local_bp, NULL );
936       bpt = &local_bp;
937     }
938   }
939   else
940   {
941     pt = &g_qeglobals.d_texturewin.texdef;
942     if (g_qeglobals.m_bBrushPrimitMode)
943     {
944       bpt = &g_qeglobals.d_texturewin.brushprimit_texdef;
945     }
946   }
947   // brush primitive mode : compute fake shift scale rot representation
948   if (g_qeglobals.m_bBrushPrimitMode)
949     TexMatToFakeTexCoords( bpt->coords, m_shift, &m_rotate, m_scale );
950
951   g_bListenChanged = false;
952
953   if(strncmp(pt->GetName(), "textures/", 9) != 0)
954     pt->SetName(SHADER_NOT_FOUND);
955   gtk_entry_set_text (GTK_ENTRY (GetDlgWidget ("texture")), pt->GetName()+9);
956
957   GtkSpinButton *spin;
958   spin = GTK_SPIN_BUTTON (GetDlgWidget ("hshift"));
959     gtk_spin_button_set_digits (spin, 2);
960     if (g_qeglobals.m_bBrushPrimitMode)
961       gtk_spin_button_set_value (spin, m_shift[0]);
962     else
963       gtk_spin_button_set_value (spin, pt->shift[0]);
964   GtkAdjustment *adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));
965   adjust->step_increment = l_pIncrement->shift[0];
966   char buf[10]; // got into snprintf paranoia after BoundChecker detected a stack overrun
967 #ifdef _WIN32
968   // TTimo: THIS IS UGLY
969 #define snprintf _snprintf
970 #endif
971   snprintf (buf, 10, "%g", l_pIncrement->shift[0]);
972   gtk_entry_set_text (GTK_ENTRY (GetDlgWidget ("hshift_inc")), buf);
973
974   spin = GTK_SPIN_BUTTON (GetDlgWidget ("vshift"));
975     gtk_spin_button_set_digits (spin, 2);
976     if (g_qeglobals.m_bBrushPrimitMode)
977       gtk_spin_button_set_value (spin, m_shift[1]);
978     else
979       gtk_spin_button_set_value (spin, pt->shift[1]);
980   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));
981   adjust->step_increment = l_pIncrement->shift[1];
982   snprintf (buf, 10, "%g", l_pIncrement->shift[1]);
983   gtk_entry_set_text (GTK_ENTRY (GetDlgWidget ("vshift_inc")), buf);
984
985   spin = GTK_SPIN_BUTTON (GetDlgWidget ("hscale"));
986   gtk_spin_button_set_digits (spin, 5);
987   gtk_spin_button_set_value (spin, g_qeglobals.m_bBrushPrimitMode ? m_scale[0] : pt->scale[0]);
988
989   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));
990   adjust->step_increment = l_pIncrement->scale[0];
991   snprintf (buf, 10, "%g", l_pIncrement->scale[0]);
992   gtk_entry_set_text (GTK_ENTRY (GetDlgWidget ("hscale_inc")), buf);
993
994   spin = GTK_SPIN_BUTTON (GetDlgWidget ("vscale"));
995   gtk_spin_button_set_digits (spin, 5);
996   gtk_spin_button_set_value (spin, g_qeglobals.m_bBrushPrimitMode ? m_scale[1] : pt->scale[1]);
997
998   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));
999   adjust->step_increment = l_pIncrement->scale[1];
1000   snprintf (buf, 10, "%g", l_pIncrement->scale[1]);
1001   gtk_entry_set_text (GTK_ENTRY (GetDlgWidget ("vscale_inc")), buf);
1002
1003   //++timo compute BProtate as int ..
1004   spin = GTK_SPIN_BUTTON (GetDlgWidget ("rotate"));
1005   gtk_spin_button_set_digits (spin, 2);
1006   gtk_spin_button_set_value (spin, g_qeglobals.m_bBrushPrimitMode ? m_rotate : pt->rotate);
1007
1008   adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));
1009   adjust->step_increment = l_pIncrement->rotate;
1010   snprintf (buf, 10, "%g", l_pIncrement->rotate);
1011   gtk_entry_set_text (GTK_ENTRY (GetDlgWidget ("rotate_inc")), buf);
1012
1013   g_bListenChanged = true;
1014
1015   // undo tricks: set the undo id to zero so we don't attempt to undo something that does not belong to us
1016   m_nUndoId = 0;
1017   // store the current texdef as our escape route if user hits OnCancel
1018   g_old_texdef = g_qeglobals.d_texturewin.texdef;
1019   // reset the Enter key behaviour flag
1020   m_bEditingTextureWidget = false;
1021 }
1022
1023 /*
1024 ==============
1025 GetTexMods
1026
1027 Reads the fields to get the current texdef (i.e. widgets -> MAP)
1028 in brush primitive mode, grab the fake shift scale rot and compute a new texture matrix
1029 ===============
1030 */
1031 void SurfaceDlg::GetTexMods()
1032 {
1033   char buffer[1024];
1034   texdef_t *pt;
1035
1036 #ifdef DBG_SI
1037   Sys_Printf("SurfaceDlg::GetTexMods\n");
1038 #endif
1039
1040   if (g_ptrSelectedFaces.GetSize() > 0)
1041   {
1042     //++timo just a test, we disable the undo when working on selected faces
1043     m_nUndoId=0;
1044     face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(0));
1045     g_qeglobals.d_texturewin.texdef = selFace->texdef;
1046 #ifdef DBG_SI
1047     Sys_Printf("g_qeglobals.d_texturewin.texdef = selFace->texdef\n");
1048 #endif
1049   }
1050 //  else
1051 //  {
1052     pt = &g_qeglobals.d_texturewin.texdef;
1053 #ifdef DBG_SI
1054     Sys_Printf("pt = &g_qeglobals.d_texturewin.texdef\n");
1055 #endif
1056 //  }
1057
1058   const char* text = gtk_entry_get_text (GTK_ENTRY (GetDlgWidget ("texture")));
1059
1060 #ifdef DBG_SI
1061   Sys_Printf("pt->SetName(%s)\n", text );
1062 #endif
1063
1064   // TTimo: detect and refuse invalid texture names (at least the ones with spaces)
1065   if (text[0] <= ' ' || strchr(text, ' '))
1066   {
1067     Sys_FPrintf(SYS_WRN, "WARNING: spaces in shader names are not allowed, ignoring '%s'\n", text);
1068     pt->SetName(SHADER_NOT_FOUND);
1069     gtk_entry_set_text (GTK_ENTRY (GetDlgWidget ("texture")), pt->GetName());
1070   }
1071   else
1072   {
1073     strcpy(buffer, "textures/");
1074     strcpy(buffer+9, text);
1075     pt->SetName(buffer);
1076   }
1077
1078
1079   (g_qeglobals.m_bBrushPrimitMode ? m_shift[0] : pt->shift[0]) =
1080     gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (GetDlgWidget ("hshift")));
1081   (g_qeglobals.m_bBrushPrimitMode ? m_shift[1] : pt->shift[1]) =
1082     gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (GetDlgWidget ("vshift")));
1083   (g_qeglobals.m_bBrushPrimitMode ? m_scale[0] : pt->scale[0]) =
1084     gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (GetDlgWidget ("hscale")));
1085   (g_qeglobals.m_bBrushPrimitMode ? m_scale[1] : pt->scale[1]) =
1086     gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (GetDlgWidget ("vscale")));
1087   (g_qeglobals.m_bBrushPrimitMode ? m_rotate : pt->rotate) =
1088     gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (GetDlgWidget ("rotate")));
1089
1090   // a local copy of the texture matrix, given for a qtexture_t with width=2 height=2
1091   brushprimit_texdef_t  local_bp;
1092   brushprimit_texdef_t  *bpt;
1093   if (g_qeglobals.m_bBrushPrimitMode)
1094   {
1095     face_t *selFace = NULL;
1096     if (g_ptrSelectedFaces.GetSize() > 0)
1097     {
1098       selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(0));
1099       bpt = &selFace->brushprimit_texdef;
1100     }
1101     else
1102     {
1103       bpt = &g_qeglobals.d_texturewin.brushprimit_texdef;
1104     }
1105     // compute texture matrix
1106     // the matrix returned must be understood as a qtexture_t with width=2 height=2
1107     FakeTexCoordsToTexMat( m_shift, m_rotate, m_scale, local_bp.coords );
1108     // copy the texture matrix in the global struct
1109     // fit the qtexture if we have a face selected, otherwise g_qeglobals.d_texturewin.brushprimit_texdef uses the basic qtexture_t with width=2 height=2
1110
1111     ConvertTexMatWithQTexture( &local_bp, NULL, bpt, ( (selFace) ? selFace->d_texture : NULL ) );
1112   }
1113   // we are gonna do stuff, if we own the last do we undo it first
1114   if (m_nUndoId != 0)
1115   {
1116     // check the do we're about to undo is the one we pushed earlier
1117                 if (m_nUndoId == Undo_GetUndoId())
1118     {
1119 #ifdef DBG_SI
1120       Sys_Printf("GetTexMods calling Undo_Undo (silent)\n");
1121 #endif
1122       g_bListenUpdate=false;
1123                         Undo_Undo(true);
1124       g_bListenUpdate=true;
1125     }
1126         }
1127   Select_SetTexture(pt,&local_bp);
1128   m_nUndoId = Undo_GetUndoId();
1129 }
1130
1131 void SurfaceDlg::FitAll()
1132 {
1133   OnBtnFaceFit(NULL, NULL);
1134   OnBtnPatchFit(NULL, NULL);
1135 }