-/*\r
-Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
-For a list of contributors, see the accompanying CONTRIBUTORS file.\r
-\r
-This file is part of GtkRadiant.\r
-\r
-GtkRadiant is free software; you can redistribute it and/or modify\r
-it under the terms of the GNU General Public License as published by\r
-the Free Software Foundation; either version 2 of the License, or\r
-(at your option) any later version.\r
-\r
-GtkRadiant is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
-GNU General Public License for more details.\r
-\r
-You should have received a copy of the GNU General Public License\r
-along with GtkRadiant; if not, write to the Free Software\r
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\r
-*/\r
-\r
-//\r
-// Surface Dialog\r
-//\r
-// Leonardo Zide (leo@lokigames.com)\r
-//\r
-\r
-#include <gdk/gdkkeysyms.h>\r
-#include "stdafx.h"\r
-#include "surfacedialog.h"\r
-\r
-SurfaceDlg g_dlgSurface;\r
-\r
-/////////////////////////////////////////////////////////////////////////////\r
-// surface properties plugin\r
-\r
-/*\r
-===================================================\r
-\r
- SURFACE INSPECTOR\r
-\r
-===================================================\r
-*/\r
-\r
-// the texdef to switch back to when the OnCancel is called\r
-texdef_t g_old_texdef;\r
-// when != NULL, this thing means the surface inspector is currently being displayed\r
-// NOTE a boolean flag would have been more explicit, this is totally so ugly\r
-GtkWidget* g_surfwin = NULL;\r
-// turn on/off processing of the "changed" "value_changed" messages\r
-// (need to turn off when we are feeding data in)\r
-bool g_bListenChanged = true;\r
-// the struct used to store the increments (saved in registry)\r
-texdef_t *l_pIncrement = &g_qeglobals.d_savedinfo.m_SIIncrement;\r
-// turn on/off listening of the update messages\r
-bool g_bListenUpdate = true;\r
-\r
-#ifdef _DEBUG\r
-// experimental stuff, work directly on BP\r
-static void OnTest(GtkWidget *widget, gpointer data) \r
-{\r
- if (!g_qeglobals.m_bBrushPrimitMode)\r
- {\r
- Sys_FPrintf(SYS_WRN, "BP mode required\n");\r
- return;\r
- }\r
- if (g_ptrSelectedFaces.GetSize() != 1)\r
- {\r
- Sys_FPrintf(SYS_WRN, "Expected single face selection\n");\r
- return;\r
- }\r
- brush_t *b = reinterpret_cast<brush_t*>(g_ptrSelectedFaceBrushes.GetAt(0));\r
- face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(0));\r
- // get the ST axis base for the face\r
- vec3_t texS,texT;\r
- ComputeAxisBase(selFace->plane.normal, texS, texT);\r
- // find ST coordinates for the center of the face\r
- float Os=0,Ot=0;\r
- int i;\r
- for (i=0; i<selFace->face_winding->numpoints; i++)\r
- {\r
- Os += DotProduct(selFace->face_winding->points[i],texS);\r
- Ot += DotProduct(selFace->face_winding->points[i],texT);\r
- }\r
- Os /= selFace->face_winding->numpoints;\r
- Ot /= selFace->face_winding->numpoints;\r
- brushprimit_texdef_t *pBP = &selFace->brushprimit_texdef;\r
-\r
- // (FIXME: initial version, before axis base change optimize)\r
-\r
- // we need to compute our BP matrix in this new axis base (O,texS,texT)\r
- // the general case if BPO = M * BP * M^-1\r
- // where BPO is transformation expressed in (O,texS,texT)\r
- // M is the axis base change from (origin,texS,texT) to (O,texS,texT)\r
- // here we have a special case, M is a translation and it's inverse is easy\r
- vec_t BPO[2][3];\r
- vec_t aux[2][3];\r
- vec_t m[2][3];\r
- memset(&m, 0, sizeof(vec_t)*6);\r
- m[0][0] = 1; m[1][1] = 1; m[0][2] = -Os; m[1][2] = -Ot;\r
- BPMatMul(m, pBP->coords, aux);\r
- m[0][2] = Os; m[1][2] = Ot; // now M^-1\r
- BPMatMul(aux, m, BPO); \r
-\r
-#if 0\r
- // apply a scaling\r
- // scale factors against S and T axis, we apply on top of the existing matrix\r
- // <1 will decrease the texel/world resolution, >1 will increase\r
- float sS = 1.025,sT = 1.025;\r
- BPMatScale(BPO,sS,sT);\r
-#endif\r
-#if 0\r
- // apply a rotation\r
- float theta = 5;\r
- BPMatRotate(BPO,theta);\r
-#endif\r
-#if 0\r
- // read the scale\r
- ConvertTexMatWithQTexture(BPO, selFace->d_texture, aux, NULL);\r
- // reset the scale (normalize the matrix)\r
- vec_t v1,v2;\r
- v1 = sqrt(aux[0][0]*aux[0][0]+aux[1][0]*aux[1][0]);\r
- v2 = sqrt(aux[0][1]*aux[0][1]+aux[1][1]*aux[1][1]);\r
- // if reading the scale values, we have them here:\r
- Sys_Printf("Current Scale: S: %g T: %g\n", v1, v2);\r
- return;\r
-#endif\r
-#if 1\r
- // apply a given scale (on S and T)\r
- ConvertTexMatWithQTexture(BPO, selFace->d_texture, aux, NULL);\r
- // reset the scale (normalize the matrix)\r
- vec_t v1,v2;\r
- v1 = sqrt(aux[0][0]*aux[0][0]+aux[1][0]*aux[1][0]);\r
- v2 = sqrt(aux[0][1]*aux[0][1]+aux[1][1]*aux[1][1]);\r
- vec_t sS,sT;\r
- // put the values for scale on S and T here:\r
- sS = 1.2 / v1;\r
- sT = 0.8 / v2;\r
- aux[0][0] *= sS; aux[1][0] *= sS;\r
- aux[0][1] *= sT; aux[1][1] *= sT;\r
- ConvertTexMatWithQTexture(aux, NULL, BPO, selFace->d_texture);\r
-#endif\r
-\r
- // now BPO must be expressed back in (origin,texS,texT) axis base BP = M^-1 * BPO * M\r
- BPMatMul(m, BPO, aux); // m is M^-1\r
- m[0][2] = -Os; m[1][2] = -Ot;\r
- BPMatMul(aux, m, pBP->coords);\r
-\r
- // now emit the coordinates on the winding\r
- EmitBrushPrimitTextureCoordinates(selFace, selFace->face_winding);\r
- Sys_UpdateWindows(W_CAMERA);\r
-}\r
-\r
-/*\r
- FIXME: try again, there must be a silly mistake in the formula expansion\r
- // we need to compute our BP matrix in this new axis base (O,texS,texT)\r
- // the general case is BPO = M * BP * M^-1\r
- // where BPO is transformation expressed in (O,texS,texT)\r
- // M is the axis base change from (origin,texS,texT) to (O,texS,texT)\r
- // here we have a special case, M is a translation and it's inverse is easy\r
- // the M * BP * M^-1 formula can be expanded and simplified\r
- vec_t BPO[2][3];\r
- memcpy(&BPO, &pBP->coords, sizeof(vec_t)*6);\r
- BPO[0][2] = Os*(pBP->coords[0][0]-1.0) + Ot*pBP->coords[0][1] + pBP->coords[0][2];\r
- BPO[1][2] = Os*pBP->coords[1][0] + Ot*(pBP->coords[1][1]-1.0) + Ot*pBP->coords[1][2]; \r
-\r
- // apply a scaling\r
- // scale factors against S and T axis, we apply on top of the existing matrix\r
- // <1 will decrease the texel/world resolution, >1 will increase\r
- float sS = 1.025,sT = 1.025;\r
- BPMatScale(BPO,sS,sT);\r
-\r
- // now BPO must be expressed back in (origin,texS,texT) axis base BP = M^-1 * BPO * M\r
- // same expanded formula as above\r
- memcpy(&pBP->coords, &BPO, sizeof(vec_t)*6);\r
- pBP->coords[0][2] = Os*(1.0-BPO[0][0]) - Ot*BPO[0][1] + BPO[0][2];\r
- pBP->coords[1][2] = -Os*BPO[1][0] + Ot*(1.0-BPO[1][1]) + BPO[1][2];\r
-*/\r
-\r
-/*\r
- // initial version, before axis base change optimize\r
-\r
- // we need to compute our BP matrix in this new axis base (O,texS,texT)\r
- // the general case if BPO = M * BP * M^-1\r
- // where BPO is transformation expressed in (O,texS,texT)\r
- // M is the axis base change from (origin,texS,texT) to (O,texS,texT)\r
- // here we have a special case, M is a translation and it's inverse is easy\r
- vec_t BPO[2][3];\r
- vec_t aux[2][3];\r
- vec_t m[2][3];\r
- memset(&m, 0, sizeof(vec_t)*6);\r
- m[0][0] = 1; m[1][1] = 1; m[0][2] = -Os; m[1][2] = -Ot;\r
- BPMatMul(m, pBP->coords, aux);\r
- m[0][2] = Os; m[1][2] = Ot; // now M^-1\r
- BPMatMul(aux, m, BPO); \r
-\r
- // apply a scaling\r
- // scale factors against S and T axis, we apply on top of the existing matrix\r
- // <1 will decrease the texel/world resolution, >1 will increase\r
- float sS = 1.025,sT = 1.025;\r
- BPMatScale(BPO,sS,sT);\r
-\r
- // now BPO must be expressed back in (origin,texS,texT) axis base BP = M^-1 * BPO * M\r
- BPMatMul(m, BPO, aux); // m is M^-1\r
- m[0][2] = -Os; m[1][2] = -Ot;\r
- BPMatMul(aux, m, pBP->coords);\r
-*/\r
-#endif\r
-\r
-static void OnDone(GtkWidget *widget, gpointer data) \r
-{\r
- g_dlgSurface.GetTexMods();\r
- g_dlgSurface.HideDlg ();\r
- Sys_UpdateWindows(W_ALL);\r
-}\r
-\r
-// OnUpdate is called when something is changed in the dialog\r
-// and must be reflected in the views. But it's not a change\r
-// so important, so the system will try to undo our last do before applying the new changes\r
-static void OnUpdate (GtkWidget *widget, gpointer data)\r
-{\r
- if (!g_bListenChanged)\r
- return;\r
-\r
- if (OnlyPatchesSelected())\r
- {\r
- //++timo possible bug or misfeature in our gtk_MessageBox here..\r
-// gtk_MessageBox("The surface inspector doesn't work for patches, use the patch inspector instead (Shift+S)", "Surface Inspector", MB_OK );\r
- Sys_Printf("The surface inspector doesn't work for patches, use the patch inspector instead (Shift+S)\n");\r
- return;\r
- }\r
-\r
- // avoid long delays on slow computers\r
- while (gtk_events_pending ())\r
- gtk_main_iteration ();\r
-\r
- g_dlgSurface.GetTexMods ();\r
- Sys_UpdateWindows(W_CAMERA);\r
-}\r
-\r
-// reflect the current changes in the views, and make sure\r
-// the changes are stored in the undo.\r
-static void OnApply (GtkWidget *widget, gpointer data) \r
-{\r
- if (!g_bListenChanged)\r
- return;\r
-\r
- g_dlgSurface.GetTexMods ();\r
- g_dlgSurface.m_nUndoId = 0; // that way we are sure we won't call undo\r
- Sys_UpdateWindows(W_CAMERA);\r
-}\r
-\r
-// we use OnTextureKey to detect when the user edits something in the texture widget\r
-// in which case next 'Enter' will be interpreted as a OnApply instead of a OnDone\r
-static gint OnTextureKey (GtkWidget* widget, GdkEventKey* event, gpointer data)\r
-{\r
-#ifdef DBG_SI\r
- Sys_Printf("OnTextureKey\n");\r
-#endif\r
- if (event->keyval != GDK_Return)\r
- g_dlgSurface.m_bEditingTextureWidget = true;\r
- return FALSE;\r
-}\r
-\r
-static void OnCancel(GtkWidget *widget, gpointer data) \r
-{\r
- g_qeglobals.d_texturewin.texdef = g_old_texdef;\r
- // cancel the last do if we own it\r
- if (g_dlgSurface.m_nUndoId == Undo_GetUndoId())\r
- {\r
-#ifdef DBG_SI\r
- Sys_Printf("OnCancel calling Undo_Undo\n");\r
-#endif\r
- g_bListenUpdate = false;\r
- Undo_Undo();\r
- g_bListenUpdate = true;\r
- g_dlgSurface.m_nUndoId = 0;\r
- }\r
- g_dlgSurface.HideDlg ();\r
-}\r
-\r
-static gint OnDialogKey (GtkWidget* widget, GdkEventKey* event, gpointer data)\r
-{\r
- if (g_surfwin)\r
- {\r
- if (event->keyval == GDK_Return)\r
- {\r
- if (g_dlgSurface.m_bEditingTextureWidget)\r
- {\r
- OnApply (NULL, NULL);\r
- g_dlgSurface.m_bEditingTextureWidget = false;\r
- }\r
- else\r
- {\r
- OnDone (NULL, NULL);\r
- }\r
- return TRUE;\r
- }\r
- if (event->keyval == GDK_Escape)\r
- {\r
- OnCancel (NULL, NULL);\r
- return TRUE;\r
- }\r
- }\r
- return FALSE;\r
-}\r
-\r
-// the widget can be one of hshift, vshift, hscale, vscale, rotate\r
-// we use the g_bListenChanged flag to ignore when changing stuff ourselves\r
-static void OnIncrementChanged(GtkWidget *widget, gpointer data)\r
-{\r
- if (!g_bListenChanged)\r
- return;\r
-\r
-#ifdef DBG_SI\r
- Sys_Printf("OnIncrementChanged\n");\r
-#endif\r
-\r
- gfloat val = 0;\r
- sscanf( gtk_entry_get_text (GTK_ENTRY (widget)), "%g", &val);\r
- // now push it into the appropriate spin button\r
- GtkAdjustment * adjust;\r
- if (widget == g_dlgSurface.GetDlgWidget ("hshift_inc"))\r
- {\r
- l_pIncrement->shift[0] = val;\r
- adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (g_dlgSurface.GetDlgWidget ("hshift")));\r
- adjust->step_increment = l_pIncrement->shift[0];\r
- }\r
- else if (widget == g_dlgSurface.GetDlgWidget ("vshift_inc"))\r
- {\r
- l_pIncrement->shift[1] = val;\r
- adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (g_dlgSurface.GetDlgWidget ("vshift")));\r
- adjust->step_increment = l_pIncrement->shift[1];\r
- }\r
- else if (widget == g_dlgSurface.GetDlgWidget ("hscale_inc"))\r
- {\r
- l_pIncrement->scale[0] = val;\r
- adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (g_dlgSurface.GetDlgWidget ("hscale")));\r
- adjust->step_increment = l_pIncrement->scale[0];\r
- }\r
- else if (widget == g_dlgSurface.GetDlgWidget ("vscale_inc"))\r
- {\r
- l_pIncrement->scale[1] = val;\r
- adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (g_dlgSurface.GetDlgWidget ("vscale")));\r
- adjust->step_increment = l_pIncrement->scale[1];\r
- }\r
- else if (widget == g_dlgSurface.GetDlgWidget ("rotate_inc"))\r
- {\r
- l_pIncrement->rotate = val;\r
- adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (g_dlgSurface.GetDlgWidget ("rotate")));\r
- adjust->step_increment = l_pIncrement->rotate;\r
- }\r
-}\r
-\r
-// make the shift increments match the grid settings\r
-// the objective being that the shift+arrows shortcuts move the texture by the corresponding grid size\r
-// this depends on a scale value if you have selected a particular texture on which you want it to work:\r
-// we move the textures in pixels, not world units. (i.e. increment values are in pixel)\r
-// depending on the texture scale it doesn't take the same amount of pixels to move of g_qeglobals.d_gridsize\r
-// increment * scale = gridsize\r
-// hscale and vscale are optional parameters, if they are zero they will be set to the default scale\r
-// NOTE: the default scale depends if you are using BP mode or regular.\r
-// For regular it's 0.5f (128 pixels cover 64 world units), for BP it's simply 1.0f\r
-// see fenris #2810\r
-void DoSnapTToGrid(float hscale, float vscale)\r
-{\r
- if (hscale == 0.0f) \r
- {\r
- (g_qeglobals.m_bBrushPrimitMode) ? hscale = 1.0f : hscale = 0.5f;\r
- }\r
- if (vscale == 0.0f)\r
- {\r
- (g_qeglobals.m_bBrushPrimitMode) ? vscale = 1.0f : vscale = 0.5f;\r
- }\r
-#ifdef _DEBUG\r
- Sys_Printf ("DoSnapTToGrid: hscale %g vscale %g\n", hscale, vscale);\r
-#endif\r
- l_pIncrement->shift[0] = (int) ( (float)g_qeglobals.d_gridsize / hscale );\r
- l_pIncrement->shift[1] = (int) ( (float)g_qeglobals.d_gridsize / vscale );\r
- // now some update work\r
- // FIXME: doesn't look good here, seems to be called several times\r
- g_dlgSurface.SetTexMods();\r
-}\r
-\r
-// make the shift increments match the grid settings\r
-// the objective being that the shift+arrows shortcuts move the texture by the corresponding grid size\r
-// this depends on the current texture scale used?\r
-// we move the textures in pixels, not world units. (i.e. increment values are in pixel)\r
-// depending on the texture scale it doesn't take the same amount of pixels to move of g_qeglobals.d_gridsize\r
-// increment * scale = gridsize\r
-static void OnBtnMatchGrid(GtkWidget *widget, gpointer data)\r
-{\r
- float hscale, vscale;\r
- hscale = gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (g_dlgSurface.GetDlgWidget ("hscale")));\r
- vscale = gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (g_dlgSurface.GetDlgWidget ("vscale")));\r
- if (hscale == 0.0f || vscale == 0.0f)\r
- {\r
- Sys_Printf("ERROR: unexpected scale == 0.0f\n");\r
- return;\r
- }\r
- DoSnapTToGrid (hscale, vscale);\r
-}\r
-\r
-void UpdateSurfaceDialog()\r
-{\r
- if (!g_bListenUpdate)\r
- return;\r
-\r
- g_SurfaceTable.m_pfnUpdateSurfaceDialog();\r
-}\r
-\r
-// DoSurface will always try to show the surface inspector\r
-// or update it because something new has been selected\r
-void DoSurface (void)\r
-{\r
-#ifdef DBG_SI\r
- Sys_Printf("DoSurface\n");\r
-#endif\r
- g_SurfaceTable.m_pfnDoSurface();\r
- return;\r
-}\r
-\r
-void ToggleSurface()\r
-{\r
- g_SurfaceTable.m_pfnToggleSurface();\r
- return;\r
-}\r
-\r
-// NOTE: will raise and show the Surface inspector and exec fit for patches and brushes\r
-void SurfaceDlgFitAll()\r
-{\r
- g_SurfaceTable.m_pfnSurfaceDlgFitAll();\r
- return;\r
-}\r
-\r
-static void OnBtnPatchdetails(GtkWidget *widget, gpointer data) \r
-{\r
- Patch_NaturalizeSelected(true);\r
- Sys_UpdateWindows(W_ALL);\r
-}\r
-\r
-static void OnBtnPatchnatural(GtkWidget *widget, gpointer data) \r
-{\r
- Patch_NaturalizeSelected();\r
- Sys_UpdateWindows(W_ALL);\r
-}\r
-\r
-static void OnBtnPatchreset(GtkWidget *widget, gpointer data) \r
-{\r
- float fx, fy;\r
-\r
- if (DoTextureLayout (&fx, &fy) == IDOK)\r
- Patch_ResetTexturing (fx, fy);\r
- Sys_UpdateWindows(W_ALL);\r
-}\r
-\r
-static void OnBtnPatchFit(GtkWidget *widget, gpointer data) \r
-{\r
- Patch_ResetTexturing(1.0, 1.0);\r
- Sys_UpdateWindows(W_ALL);\r
-}\r
-\r
-static void OnBtnAxial(GtkWidget *widget, gpointer data)\r
-{\r
- Select_SetTexture (&g_qeglobals.d_texturewin.texdef, &g_qeglobals.d_texturewin.brushprimit_texdef, true);\r
- g_dlgSurface.SetTexMods();\r
- Sys_UpdateWindows(W_ALL);\r
-}\r
-\r
-static void OnBtnFaceFit(GtkWidget *widget, gpointer data) \r
-{\r
- g_dlgSurface.UpdateData(TRUE);\r
- if (g_ptrSelectedFaces.GetSize() == 0)\r
- {\r
- brush_t *b;\r
- for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)\r
- {\r
- for (face_t* pFace = b->brush_faces; pFace; pFace = pFace->next)\r
- {\r
- g_ptrSelectedFaces.Add(pFace);\r
- g_ptrSelectedFaceBrushes.Add(b);\r
- }\r
- }\r
- Select_FitTexture(g_dlgSurface.m_nHeight, g_dlgSurface.m_nWidth);\r
- g_dlgSurface.SetTexMods();\r
- g_ptrSelectedFaces.RemoveAll();\r
- }\r
- else\r
- {\r
- Select_FitTexture(g_dlgSurface.m_nHeight, g_dlgSurface.m_nWidth);\r
- g_dlgSurface.SetTexMods();\r
- }\r
- Sys_UpdateWindows(W_ALL);\r
-}\r
-\r
-// =============================================================================\r
-// SurfaceDialog class\r
-\r
-SurfaceDlg::SurfaceDlg ()\r
-{\r
- m_nHeight = 1;\r
- m_nWidth = 1;\r
- m_nUndoId = 0;\r
-}\r
-\r
-void SurfaceDlg::ShowDlg()\r
-{\r
- Dialog::ShowDlg();\r
- if(GetWidget() == NULL)\r
- Create();\r
- g_surfwin = GetWidget ();\r
-}\r
-void SurfaceDlg::HideDlg()\r
-{\r
- g_surfwin = NULL;\r
- Dialog::HideDlg();\r
-}\r
-\r
-GtkWidget* SurfaceDlg::GetWidget()\r
-{\r
- return g_SurfaceTable.m_pfnGet_SI_Module_Widget();\r
-}\r
-\r
-// set default values for increments (shift scale and rot)\r
-// this is called by the prefs code if can't find the values\r
-void SurfaceDlg::InitDefaultIncrement(texdef_t *tex)\r
-{\r
- tex->SetName("foo");\r
- tex->shift[0] = 8;\r
- tex->shift[1] = 8;\r
- tex->scale[0] = 0.25;\r
- tex->scale[1] = 0.25;\r
- tex->rotate = 10; \r
-}\r
-\r
-void SurfaceDlg::BuildDialog ()\r
-{\r
- GtkWidget *dlg, *vbox, *hbox2, *frame, *table, *label;\r
- GtkWidget *button, *entry, *spin;\r
-\r
- dlg = m_pWidget;\r
-\r
- load_window_pos (dlg, g_PrefsDlg.mWindowInfo.posSurfaceWnd);\r
-\r
- gtk_window_set_title (GTK_WINDOW (dlg), "Surface inspector");\r
- //g_signal_connect (G_OBJECT (dlg), "delete_event", G_CALLBACK (OnCancel), NULL);\r
- // we catch 'Enter' and interpret is as OnDone\r
- gtk_signal_connect (GTK_OBJECT (dlg), "key_press_event", GTK_SIGNAL_FUNC (OnDialogKey), NULL);\r
- gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (g_pParentWnd->m_pWidget));\r
-\r
- // replaced by only the vbox:\r
- vbox = gtk_vbox_new (FALSE, 5);\r
- gtk_widget_show (vbox);\r
- gtk_container_add (GTK_CONTAINER (dlg), vbox);\r
- gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);\r
-\r
- hbox2 = gtk_hbox_new (FALSE, 5);\r
- gtk_widget_show (hbox2);\r
- gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, TRUE, 0);\r
-\r
- label = gtk_label_new ("Texture");\r
- gtk_widget_show (label);\r
- gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);\r
-\r
- entry = gtk_entry_new ();\r
- gtk_signal_connect (GTK_OBJECT (entry), "key_press_event", GTK_SIGNAL_FUNC (OnTextureKey), NULL);\r
- gtk_widget_show (entry);\r
- gtk_box_pack_start (GTK_BOX (hbox2), entry, TRUE, TRUE, 0);\r
- g_object_set_data (G_OBJECT (m_pWidget), "texture", entry);\r
-\r
-// table = gtk_table_new (5, 4, FALSE);\r
- table = gtk_table_new (6, 4, FALSE);\r
- gtk_widget_show (table);\r
- gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);\r
- gtk_table_set_row_spacings (GTK_TABLE (table), 5);\r
- gtk_table_set_col_spacings (GTK_TABLE (table), 5);\r
-\r
- label = gtk_label_new ("Horizontal shift");\r
- gtk_widget_show (label);\r
- gtk_misc_set_alignment (GTK_MISC (label), 0, 0);\r
- gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,\r
- (GtkAttachOptions) (GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
-\r
- spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, -8192, 8192, 2, 8, 8)), 0, 0);\r
- g_object_set_data (G_OBJECT (dlg), "hshift", spin);\r
- gtk_signal_connect (GTK_OBJECT (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin))), "value_changed",\r
- GTK_SIGNAL_FUNC (OnUpdate), NULL);\r
- gtk_widget_show (spin);\r
- gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 0, 1,\r
- (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
- gtk_widget_set_usize (spin, 60, -2);\r
-\r
- label = gtk_label_new ("Step");\r
- gtk_widget_show (label);\r
- gtk_misc_set_alignment (GTK_MISC (label), 0, 0);\r
- gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1,\r
- (GtkAttachOptions) (GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
- \r
- entry = gtk_entry_new ();\r
- g_object_set_data (G_OBJECT (dlg), "hshift_inc", entry);\r
- gtk_signal_connect (GTK_OBJECT (entry), "changed",\r
- GTK_SIGNAL_FUNC (OnIncrementChanged), NULL);\r
- gtk_widget_show (entry);\r
- gtk_table_attach (GTK_TABLE (table), entry, 3, 4, 0, 1,\r
- (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
- gtk_widget_set_usize (entry, 50, -2);\r
-\r
- label = gtk_label_new ("Vertical shift");\r
- gtk_widget_show (label);\r
- gtk_misc_set_alignment (GTK_MISC (label), 0, 0);\r
- gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,\r
- (GtkAttachOptions) (GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
-\r
- spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, -8192, 8192, 2, 8, 8)), 0, 0);\r
- g_object_set_data (G_OBJECT (dlg), "vshift", spin);\r
- gtk_signal_connect (GTK_OBJECT (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin))), "value_changed",\r
- GTK_SIGNAL_FUNC (OnUpdate), NULL);\r
- gtk_widget_show (spin);\r
- gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 1, 2,\r
- (GtkAttachOptions) (GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
- gtk_widget_set_usize (spin, 60, -2);\r
- \r
- label = gtk_label_new ("Step");\r
- gtk_widget_show (label);\r
- gtk_misc_set_alignment (GTK_MISC (label), 0, 0);\r
- gtk_table_attach (GTK_TABLE (table), label, 2, 3, 1, 2,\r
- (GtkAttachOptions) (GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
- \r
- entry = gtk_entry_new ();\r
- g_object_set_data (G_OBJECT (dlg), "vshift_inc", entry);\r
- gtk_signal_connect (GTK_OBJECT (entry), "changed",\r
- GTK_SIGNAL_FUNC (OnIncrementChanged), NULL);\r
- gtk_widget_show (entry);\r
- gtk_table_attach (GTK_TABLE (table), entry, 3, 4, 1, 2,\r
- (GtkAttachOptions) (GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
- gtk_widget_set_usize (entry, 50, -2);\r
-\r
- label = gtk_label_new ("Horizontal stretch");\r
- gtk_widget_show (label);\r
- gtk_misc_set_alignment (GTK_MISC (label), 0, 0);\r
- gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,\r
- (GtkAttachOptions) (GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
-\r
- spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, -1000, 1000, 1, 10, 10)), 0, 0);\r
- g_object_set_data (G_OBJECT (dlg), "hscale", spin);\r
- gtk_signal_connect (GTK_OBJECT (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin))), "value_changed",\r
- GTK_SIGNAL_FUNC (OnUpdate), NULL);\r
- gtk_widget_show (spin);\r
- gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 2, 3,\r
- (GtkAttachOptions) (GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
- gtk_widget_set_usize (spin, 60, -2);\r
-\r
- label = gtk_label_new ("Step");\r
- gtk_widget_show (label);\r
- gtk_misc_set_alignment (GTK_MISC (label), 0, 0);\r
- gtk_table_attach (GTK_TABLE (table), label, 2, 3, 2, 3,\r
- (GtkAttachOptions) (GTK_FILL),\r
- (GtkAttachOptions) (0), 2, 3);\r
- \r
- entry = gtk_entry_new ();\r
- g_object_set_data (G_OBJECT (dlg), "hscale_inc", entry);\r
- gtk_signal_connect (GTK_OBJECT (entry), "changed",\r
- GTK_SIGNAL_FUNC (OnIncrementChanged), NULL);\r
- gtk_widget_show (entry);\r
- gtk_table_attach (GTK_TABLE (table), entry, 3, 4, 2, 3,\r
- (GtkAttachOptions) (GTK_FILL),\r
- (GtkAttachOptions) (0), 2, 3);\r
- gtk_widget_set_usize (entry, 50, -2);\r
-\r
- label = gtk_label_new ("Vertical stretch");\r
- gtk_widget_show (label);\r
- gtk_misc_set_alignment (GTK_MISC (label), 0, 0);\r
- gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4,\r
- (GtkAttachOptions) (GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
-\r
- spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, -1000, 1000, 1, 10, 10)), 0, 0);\r
- g_object_set_data (G_OBJECT (dlg), "vscale", spin);\r
- gtk_signal_connect (GTK_OBJECT (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin))), "value_changed",\r
- GTK_SIGNAL_FUNC (OnUpdate), NULL);\r
- gtk_widget_show (spin);\r
- gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 3, 4,\r
- (GtkAttachOptions) (GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
- gtk_widget_set_usize (spin, 60, -2);\r
- \r
- label = gtk_label_new ("Step");\r
- gtk_widget_show (label);\r
- gtk_misc_set_alignment (GTK_MISC (label), 0, 0);\r
- gtk_table_attach (GTK_TABLE (table), label, 2, 3, 3, 4,\r
- (GtkAttachOptions) (GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
- \r
- entry = gtk_entry_new ();\r
- g_object_set_data (G_OBJECT (dlg), "vscale_inc", entry);\r
- gtk_signal_connect (GTK_OBJECT (entry), "changed",\r
- GTK_SIGNAL_FUNC (OnIncrementChanged), NULL);\r
- gtk_widget_show (entry);\r
- gtk_table_attach (GTK_TABLE (table), entry, 3, 4, 3, 4,\r
- (GtkAttachOptions) (GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
- gtk_widget_set_usize (entry, 50, -2);\r
-\r
- label = gtk_label_new ("Rotate");\r
- gtk_widget_show (label);\r
- gtk_misc_set_alignment (GTK_MISC (label), 0, 0);\r
- gtk_table_attach (GTK_TABLE (table), label, 0, 1, 4, 5,\r
- (GtkAttachOptions) (GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
-\r
- spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, -360, 360, 1, 10, 10)), 1, 0);\r
- g_object_set_data (G_OBJECT (dlg), "rotate", spin);\r
- gtk_signal_connect (GTK_OBJECT (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin))), "value_changed",\r
- GTK_SIGNAL_FUNC (OnUpdate), NULL);\r
- gtk_widget_show (spin);\r
- gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 4, 5,\r
- (GtkAttachOptions) (GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
- gtk_widget_set_usize (spin, 60, -2);\r
- gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spin), TRUE);\r
-\r
- label = gtk_label_new ("Step");\r
- gtk_widget_show (label);\r
- gtk_misc_set_alignment (GTK_MISC (label), 0, 0);\r
- gtk_table_attach (GTK_TABLE (table), label, 2, 3, 4, 5,\r
- (GtkAttachOptions) (GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
- \r
- entry = gtk_entry_new ();\r
- g_object_set_data (G_OBJECT (dlg), "rotate_inc", entry);\r
- gtk_signal_connect (GTK_OBJECT (entry), "changed",\r
- GTK_SIGNAL_FUNC (OnIncrementChanged), NULL);\r
- gtk_widget_show (entry);\r
- gtk_table_attach (GTK_TABLE (table), entry, 3, 4, 4, 5,\r
- (GtkAttachOptions) (GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
- gtk_widget_set_usize (entry, 50, -2);\r
-\r
- // match grid button\r
- button = gtk_button_new_with_label ("Match Grid");\r
- gtk_widget_show (button);\r
- gtk_table_attach (GTK_TABLE (table), button, 2, 4, 5, 6,\r
- (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
- gtk_signal_connect (GTK_OBJECT (button), "clicked",\r
- GTK_SIGNAL_FUNC (OnBtnMatchGrid), NULL);\r
-\r
- frame = gtk_frame_new ("Texturing");\r
- gtk_widget_show (frame);\r
- gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);\r
-\r
- table = gtk_table_new (4, 4, FALSE);\r
- gtk_widget_show (table);\r
- gtk_container_add (GTK_CONTAINER (frame), table);\r
- gtk_table_set_row_spacings (GTK_TABLE (table), 5);\r
- gtk_table_set_col_spacings (GTK_TABLE (table), 5);\r
- gtk_container_set_border_width (GTK_CONTAINER (table), 5);\r
-\r
- label = gtk_label_new ("Brush");\r
- gtk_widget_show (label);\r
- gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,\r
- (GtkAttachOptions) (GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
-\r
- label = gtk_label_new ("Patch");\r
- gtk_widget_show (label);\r
- gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,\r
- (GtkAttachOptions) (GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
-\r
- label = gtk_label_new ("Width");\r
- gtk_widget_show (label);\r
- gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1,\r
- (GtkAttachOptions) (GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
-\r
- label = gtk_label_new ("Height");\r
- gtk_widget_show (label);\r
- gtk_table_attach (GTK_TABLE (table), label, 3, 4, 0, 1,\r
- (GtkAttachOptions) (GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
-\r
- button = gtk_button_new_with_label ("Axial");\r
- gtk_widget_show (button);\r
- gtk_table_attach (GTK_TABLE (table), button, 0, 1, 1, 2,\r
- (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
- gtk_signal_connect (GTK_OBJECT (button), "clicked",\r
- GTK_SIGNAL_FUNC (OnBtnAxial), NULL);\r
- gtk_widget_set_usize (button, 60, -2);\r
-\r
- button = gtk_button_new_with_label ("Fit");\r
- gtk_widget_show (button);\r
- gtk_table_attach (GTK_TABLE (table), button, 1, 2, 1, 2,\r
- (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
- gtk_signal_connect (GTK_OBJECT (button), "clicked",\r
- GTK_SIGNAL_FUNC (OnBtnFaceFit), NULL);\r
- gtk_widget_set_usize (button, 60, -2);\r
-\r
- button = gtk_button_new_with_label ("CAP");\r
- gtk_widget_show (button);\r
- gtk_table_attach (GTK_TABLE (table), button, 0, 1, 3, 4,\r
- (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
- gtk_signal_connect (GTK_OBJECT (button), "clicked",\r
- GTK_SIGNAL_FUNC (OnBtnPatchdetails), NULL);\r
- gtk_widget_set_usize (button, 60, -2);\r
-\r
- button = gtk_button_new_with_label ("Set...");\r
- gtk_widget_show (button);\r
- gtk_table_attach (GTK_TABLE (table), button, 1, 2, 3, 4,\r
- (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
- gtk_signal_connect (GTK_OBJECT (button), "clicked",\r
- GTK_SIGNAL_FUNC (OnBtnPatchreset), NULL);\r
- gtk_widget_set_usize (button, 60, -2);\r
-\r
- button = gtk_button_new_with_label ("Natural");\r
- gtk_widget_show (button);\r
- gtk_table_attach (GTK_TABLE (table), button, 2, 3, 3, 4,\r
- (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
- gtk_signal_connect (GTK_OBJECT (button), "clicked",\r
- GTK_SIGNAL_FUNC (OnBtnPatchnatural), NULL);\r
- gtk_widget_set_usize (button, 60, -2);\r
-\r
- button = gtk_button_new_with_label ("Fit");\r
- gtk_widget_show (button);\r
- gtk_table_attach (GTK_TABLE (table), button, 3, 4, 3, 4,\r
- (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
- gtk_signal_connect (GTK_OBJECT (button), "clicked",\r
- GTK_SIGNAL_FUNC (OnBtnPatchFit), NULL);\r
- gtk_widget_set_usize (button, 60, -2);\r
-\r
- spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (1, 1, 32, 1, 10, 10)), 1, 0);\r
- gtk_widget_show (spin);\r
- gtk_table_attach (GTK_TABLE (table), spin, 2, 3, 1, 2,\r
- (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
- gtk_widget_set_usize (spin, 60, -2);\r
- AddDialogData (spin, &m_nWidth, DLG_SPIN_INT);\r
-\r
- spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (1, 1, 32, 1, 10, 10)), 1, 0);\r
- gtk_widget_show (spin);\r
- gtk_table_attach (GTK_TABLE (table), spin, 3, 4, 1, 2,\r
- (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),\r
- (GtkAttachOptions) (0), 0, 0);\r
- gtk_widget_set_usize (spin, 60, -2);\r
- AddDialogData (spin, &m_nHeight, DLG_SPIN_INT);\r
-\r
- hbox2 = gtk_hbox_new (FALSE, 5);\r
- gtk_widget_show (hbox2);\r
- gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, TRUE, 0);\r
-\r
- button = gtk_button_new_with_label ("Done");\r
- gtk_widget_show (button);\r
- gtk_box_pack_start (GTK_BOX (hbox2), button, FALSE, FALSE, 0);\r
- gtk_signal_connect (GTK_OBJECT (button), "clicked",\r
- GTK_SIGNAL_FUNC (OnDone), NULL);\r
- gtk_widget_set_usize (button, 60, -2);\r
-\r
- button = gtk_button_new_with_label ("Apply");\r
- gtk_widget_show (button);\r
- gtk_box_pack_start (GTK_BOX (hbox2), button, FALSE, FALSE, 0);\r
- gtk_signal_connect (GTK_OBJECT (button), "clicked",\r
- GTK_SIGNAL_FUNC (OnApply), NULL);\r
- gtk_widget_set_usize (button, 60, -2);\r
-\r
- button = gtk_button_new_with_label ("Cancel");\r
- gtk_widget_show (button);\r
- gtk_box_pack_start (GTK_BOX (hbox2), button, FALSE, FALSE, 0);\r
- gtk_signal_connect (GTK_OBJECT (button), "clicked",\r
- GTK_SIGNAL_FUNC (OnCancel), NULL);\r
- gtk_widget_set_usize (button, 60, -2);\r
-\r
- // that's a bit of trashy stuff from Textool-v2 branch\r
-#ifdef _DEBUG\r
- // FIXME: testing only, scaling in BP mode\r
- button = gtk_button_new_with_label ("Test");\r
- gtk_widget_show (button);\r
- gtk_box_pack_start (GTK_BOX (hbox2), button, FALSE, FALSE, 0);\r
- gtk_signal_connect (GTK_OBJECT (button), "clicked",\r
- GTK_SIGNAL_FUNC (OnTest), NULL);\r
- gtk_widget_set_usize (button, 60, -2);\r
-#endif\r
-\r
- // Initialize\r
- SetTexMods ();\r
-}\r
-\r
-/*\r
-==============\r
-SetTexMods\r
-\r
-Set the fields to the current texdef (i.e. map/texdef -> dialog widgets)\r
-if faces selected (instead of brushes) -> will read this face texdef, else current texdef\r
-if only patches selected, will read the patch texdef\r
-===============\r
-*/\r
-\r
-void SurfaceDlg::SetTexMods()\r
-{\r
- texdef_t *pt;\r
- brushprimit_texdef_t *bpt;\r
- // local copy if a width=2 height=2 qtetxture_t is needed\r
- brushprimit_texdef_t local_bp;\r
-\r
-#ifdef DBG_SI\r
- Sys_Printf("SurfaceDlg::SetTexMods\n");\r
-#endif\r
-\r
- if (!g_surfwin)\r
- return;\r
- \r
- if (g_ptrSelectedFaces.GetSize() > 0)\r
- {\r
- face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(0));\r
- pt = &selFace->texdef;\r
- if (g_qeglobals.m_bBrushPrimitMode)\r
- {\r
- // compute a texture matrix related to the default matrix width=2 height=2\r
- ConvertTexMatWithQTexture( &selFace->brushprimit_texdef, selFace->d_texture, &local_bp, NULL );\r
- bpt = &local_bp;\r
- }\r
- }\r
- else\r
- {\r
- pt = &g_qeglobals.d_texturewin.texdef;\r
- if (g_qeglobals.m_bBrushPrimitMode)\r
- {\r
- bpt = &g_qeglobals.d_texturewin.brushprimit_texdef;\r
- }\r
- }\r
- // brush primitive mode : compute fake shift scale rot representation\r
- if (g_qeglobals.m_bBrushPrimitMode)\r
- TexMatToFakeTexCoords( bpt->coords, m_shift, &m_rotate, m_scale );\r
- \r
- g_bListenChanged = false;\r
- \r
- if(strncmp(pt->GetName(), "textures/", 9) != 0)\r
- pt->SetName(SHADER_NOT_FOUND);\r
- gtk_entry_set_text (GTK_ENTRY (GetDlgWidget ("texture")), pt->GetName()+9);\r
-\r
- GtkSpinButton *spin;\r
- spin = GTK_SPIN_BUTTON (GetDlgWidget ("hshift"));\r
- gtk_spin_button_set_digits (spin, 2);\r
- if (g_qeglobals.m_bBrushPrimitMode)\r
- gtk_spin_button_set_value (spin, m_shift[0]);\r
- else\r
- gtk_spin_button_set_value (spin, pt->shift[0]);\r
- GtkAdjustment *adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));\r
- adjust->step_increment = l_pIncrement->shift[0];\r
- char buf[10]; // got into snprintf paranoia after BoundChecker detected a stack overrun\r
-#ifdef _WIN32\r
- // TTimo: THIS IS UGLY\r
-#define snprintf _snprintf\r
-#endif\r
- snprintf (buf, 10, "%g", l_pIncrement->shift[0]);\r
- gtk_entry_set_text (GTK_ENTRY (GetDlgWidget ("hshift_inc")), buf);\r
-\r
- spin = GTK_SPIN_BUTTON (GetDlgWidget ("vshift"));\r
- gtk_spin_button_set_digits (spin, 2);\r
- if (g_qeglobals.m_bBrushPrimitMode)\r
- gtk_spin_button_set_value (spin, m_shift[1]);\r
- else\r
- gtk_spin_button_set_value (spin, pt->shift[1]);\r
- adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));\r
- adjust->step_increment = l_pIncrement->shift[1];\r
- snprintf (buf, 10, "%g", l_pIncrement->shift[1]);\r
- gtk_entry_set_text (GTK_ENTRY (GetDlgWidget ("vshift_inc")), buf);\r
-\r
- spin = GTK_SPIN_BUTTON (GetDlgWidget ("hscale"));\r
- gtk_spin_button_set_digits (spin, 5);\r
- gtk_spin_button_set_value (spin, g_qeglobals.m_bBrushPrimitMode ? m_scale[0] : pt->scale[0]);\r
-\r
- adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));\r
- adjust->step_increment = l_pIncrement->scale[0];\r
- snprintf (buf, 10, "%g", l_pIncrement->scale[0]);\r
- gtk_entry_set_text (GTK_ENTRY (GetDlgWidget ("hscale_inc")), buf);\r
-\r
- spin = GTK_SPIN_BUTTON (GetDlgWidget ("vscale"));\r
- gtk_spin_button_set_digits (spin, 5);\r
- gtk_spin_button_set_value (spin, g_qeglobals.m_bBrushPrimitMode ? m_scale[1] : pt->scale[1]);\r
-\r
- adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));\r
- adjust->step_increment = l_pIncrement->scale[1];\r
- snprintf (buf, 10, "%g", l_pIncrement->scale[1]);\r
- gtk_entry_set_text (GTK_ENTRY (GetDlgWidget ("vscale_inc")), buf);\r
-\r
- //++timo compute BProtate as int ..\r
- spin = GTK_SPIN_BUTTON (GetDlgWidget ("rotate"));\r
- gtk_spin_button_set_digits (spin, 2);\r
- gtk_spin_button_set_value (spin, g_qeglobals.m_bBrushPrimitMode ? m_rotate : pt->rotate);\r
-\r
- adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));\r
- adjust->step_increment = l_pIncrement->rotate;\r
- snprintf (buf, 10, "%g", l_pIncrement->rotate);\r
- gtk_entry_set_text (GTK_ENTRY (GetDlgWidget ("rotate_inc")), buf);\r
-\r
- g_bListenChanged = true;\r
- \r
- // undo tricks: set the undo id to zero so we don't attempt to undo something that does not belong to us\r
- m_nUndoId = 0;\r
- // store the current texdef as our escape route if user hits OnCancel\r
- g_old_texdef = g_qeglobals.d_texturewin.texdef;\r
- // reset the Enter key behaviour flag\r
- m_bEditingTextureWidget = false;\r
-}\r
-\r
-/*\r
-==============\r
-GetTexMods\r
-\r
-Reads the fields to get the current texdef (i.e. widgets -> MAP)\r
-in brush primitive mode, grab the fake shift scale rot and compute a new texture matrix\r
-===============\r
-*/\r
-void SurfaceDlg::GetTexMods()\r
-{\r
- char buffer[1024];\r
- texdef_t *pt;\r
-\r
-#ifdef DBG_SI\r
- Sys_Printf("SurfaceDlg::GetTexMods\n");\r
-#endif\r
- \r
- if (g_ptrSelectedFaces.GetSize() > 0)\r
- {\r
- //++timo just a test, we disable the undo when working on selected faces\r
- m_nUndoId=0;\r
- face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(0));\r
- g_qeglobals.d_texturewin.texdef = selFace->texdef;\r
-#ifdef DBG_SI\r
- Sys_Printf("g_qeglobals.d_texturewin.texdef = selFace->texdef\n");\r
-#endif\r
- }\r
-// else\r
-// {\r
- pt = &g_qeglobals.d_texturewin.texdef;\r
-#ifdef DBG_SI\r
- Sys_Printf("pt = &g_qeglobals.d_texturewin.texdef\n");\r
-#endif\r
-// }\r
- \r
- const char* text = gtk_entry_get_text (GTK_ENTRY (GetDlgWidget ("texture")));\r
-\r
-#ifdef DBG_SI\r
- Sys_Printf("pt->SetName(%s)\n", text );\r
-#endif\r
- \r
- // TTimo: detect and refuse invalid texture names (at least the ones with spaces)\r
- if (text[0] <= ' ' || strchr(text, ' '))\r
- {\r
- Sys_FPrintf(SYS_WRN, "WARNING: spaces in shader names are not allowed, ignoring '%s'\n", text);\r
- pt->SetName(SHADER_NOT_FOUND);\r
- gtk_entry_set_text (GTK_ENTRY (GetDlgWidget ("texture")), pt->GetName());\r
- }\r
- else\r
- {\r
- strcpy(buffer, "textures/");\r
- strcpy(buffer+9, text);\r
- pt->SetName(buffer);\r
- }\r
-\r
-\r
- (g_qeglobals.m_bBrushPrimitMode ? m_shift[0] : pt->shift[0]) = \r
- gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (GetDlgWidget ("hshift")));\r
- (g_qeglobals.m_bBrushPrimitMode ? m_shift[1] : pt->shift[1]) =\r
- gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (GetDlgWidget ("vshift")));\r
- (g_qeglobals.m_bBrushPrimitMode ? m_scale[0] : pt->scale[0]) =\r
- gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (GetDlgWidget ("hscale")));\r
- (g_qeglobals.m_bBrushPrimitMode ? m_scale[1] : pt->scale[1]) =\r
- gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (GetDlgWidget ("vscale")));\r
- (g_qeglobals.m_bBrushPrimitMode ? m_rotate : pt->rotate) =\r
- gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (GetDlgWidget ("rotate")));\r
-\r
- // a local copy of the texture matrix, given for a qtexture_t with width=2 height=2\r
- brushprimit_texdef_t local_bp;\r
- brushprimit_texdef_t *bpt;\r
- if (g_qeglobals.m_bBrushPrimitMode)\r
- {\r
- face_t *selFace = NULL;\r
- if (g_ptrSelectedFaces.GetSize() > 0)\r
- {\r
- selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(0));\r
- bpt = &selFace->brushprimit_texdef;\r
- }\r
- else\r
- {\r
- bpt = &g_qeglobals.d_texturewin.brushprimit_texdef;\r
- }\r
- // compute texture matrix\r
- // the matrix returned must be understood as a qtexture_t with width=2 height=2\r
- FakeTexCoordsToTexMat( m_shift, m_rotate, m_scale, local_bp.coords );\r
- // copy the texture matrix in the global struct\r
- // 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\r
-\r
- ConvertTexMatWithQTexture( &local_bp, NULL, bpt, ( (selFace) ? selFace->d_texture : NULL ) );\r
- }\r
- // we are gonna do stuff, if we own the last do we undo it first\r
- if (m_nUndoId != 0)\r
- {\r
- // check the do we're about to undo is the one we pushed earlier\r
- if (m_nUndoId == Undo_GetUndoId())\r
- {\r
-#ifdef DBG_SI\r
- Sys_Printf("GetTexMods calling Undo_Undo (silent)\n");\r
-#endif\r
- g_bListenUpdate=false;\r
- Undo_Undo(true);\r
- g_bListenUpdate=true;\r
- }\r
- }\r
- Select_SetTexture(pt,&local_bp);\r
- m_nUndoId = Undo_GetUndoId();\r
-}\r
-\r
-void SurfaceDlg::FitAll()\r
-{\r
- OnBtnFaceFit(NULL, NULL);\r
- OnBtnPatchFit(NULL, NULL);\r
-}\r
+/*
+Copyright (C) 1999-2007 id Software, Inc. and contributors.
+For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+This file is part of GtkRadiant.
+
+GtkRadiant is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+GtkRadiant is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GtkRadiant; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+//
+// Surface Dialog
+//
+// Leonardo Zide (leo@lokigames.com)
+//
+
+#include <gdk/gdkkeysyms.h>
+#include "stdafx.h"
+#include "surfacedialog.h"
+
+SurfaceDlg g_dlgSurface;
+
+/////////////////////////////////////////////////////////////////////////////
+// surface properties plugin
+
+/*
+===================================================
+
+ SURFACE INSPECTOR
+
+===================================================
+*/
+
+// the texdef to switch back to when the OnCancel is called
+texdef_t g_old_texdef;
+// when != NULL, this thing means the surface inspector is currently being displayed
+// NOTE a boolean flag would have been more explicit, this is totally so ugly
+GtkWidget* g_surfwin = NULL;
+// turn on/off processing of the "changed" "value_changed" messages
+// (need to turn off when we are feeding data in)
+bool g_bListenChanged = true;
+// the struct used to store the increments (saved in registry)
+texdef_t *l_pIncrement = &g_qeglobals.d_savedinfo.m_SIIncrement;
+// turn on/off listening of the update messages
+bool g_bListenUpdate = true;
+
+#ifdef _DEBUG
+// experimental stuff, work directly on BP
+static void OnTest(GtkWidget *widget, gpointer data)
+{
+ if (!g_qeglobals.m_bBrushPrimitMode)
+ {
+ Sys_FPrintf(SYS_WRN, "BP mode required\n");
+ return;
+ }
+ if (g_ptrSelectedFaces.GetSize() != 1)
+ {
+ Sys_FPrintf(SYS_WRN, "Expected single face selection\n");
+ return;
+ }
+ brush_t *b = reinterpret_cast<brush_t*>(g_ptrSelectedFaceBrushes.GetAt(0));
+ face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(0));
+ // get the ST axis base for the face
+ vec3_t texS,texT;
+ ComputeAxisBase(selFace->plane.normal, texS, texT);
+ // find ST coordinates for the center of the face
+ float Os=0,Ot=0;
+ int i;
+ for (i=0; i<selFace->face_winding->numpoints; i++)
+ {
+ Os += DotProduct(selFace->face_winding->points[i],texS);
+ Ot += DotProduct(selFace->face_winding->points[i],texT);
+ }
+ Os /= selFace->face_winding->numpoints;
+ Ot /= selFace->face_winding->numpoints;
+ brushprimit_texdef_t *pBP = &selFace->brushprimit_texdef;
+
+ // (FIXME: initial version, before axis base change optimize)
+
+ // we need to compute our BP matrix in this new axis base (O,texS,texT)
+ // the general case if BPO = M * BP * M^-1
+ // where BPO is transformation expressed in (O,texS,texT)
+ // M is the axis base change from (origin,texS,texT) to (O,texS,texT)
+ // here we have a special case, M is a translation and it's inverse is easy
+ vec_t BPO[2][3];
+ vec_t aux[2][3];
+ vec_t m[2][3];
+ memset(&m, 0, sizeof(vec_t)*6);
+ m[0][0] = 1; m[1][1] = 1; m[0][2] = -Os; m[1][2] = -Ot;
+ BPMatMul(m, pBP->coords, aux);
+ m[0][2] = Os; m[1][2] = Ot; // now M^-1
+ BPMatMul(aux, m, BPO);
+
+#if 0
+ // apply a scaling
+ // scale factors against S and T axis, we apply on top of the existing matrix
+ // <1 will decrease the texel/world resolution, >1 will increase
+ float sS = 1.025,sT = 1.025;
+ BPMatScale(BPO,sS,sT);
+#endif
+#if 0
+ // apply a rotation
+ float theta = 5;
+ BPMatRotate(BPO,theta);
+#endif
+#if 0
+ // read the scale
+ ConvertTexMatWithQTexture(BPO, selFace->d_texture, aux, NULL);
+ // reset the scale (normalize the matrix)
+ vec_t v1,v2;
+ v1 = sqrt(aux[0][0]*aux[0][0]+aux[1][0]*aux[1][0]);
+ v2 = sqrt(aux[0][1]*aux[0][1]+aux[1][1]*aux[1][1]);
+ // if reading the scale values, we have them here:
+ Sys_Printf("Current Scale: S: %g T: %g\n", v1, v2);
+ return;
+#endif
+#if 1
+ // apply a given scale (on S and T)
+ ConvertTexMatWithQTexture(BPO, selFace->d_texture, aux, NULL);
+ // reset the scale (normalize the matrix)
+ vec_t v1,v2;
+ v1 = sqrt(aux[0][0]*aux[0][0]+aux[1][0]*aux[1][0]);
+ v2 = sqrt(aux[0][1]*aux[0][1]+aux[1][1]*aux[1][1]);
+ vec_t sS,sT;
+ // put the values for scale on S and T here:
+ sS = 1.2 / v1;
+ sT = 0.8 / v2;
+ aux[0][0] *= sS; aux[1][0] *= sS;
+ aux[0][1] *= sT; aux[1][1] *= sT;
+ ConvertTexMatWithQTexture(aux, NULL, BPO, selFace->d_texture);
+#endif
+
+ // now BPO must be expressed back in (origin,texS,texT) axis base BP = M^-1 * BPO * M
+ BPMatMul(m, BPO, aux); // m is M^-1
+ m[0][2] = -Os; m[1][2] = -Ot;
+ BPMatMul(aux, m, pBP->coords);
+
+ // now emit the coordinates on the winding
+ EmitBrushPrimitTextureCoordinates(selFace, selFace->face_winding);
+ Sys_UpdateWindows(W_CAMERA);
+}
+
+/*
+ FIXME: try again, there must be a silly mistake in the formula expansion
+ // we need to compute our BP matrix in this new axis base (O,texS,texT)
+ // the general case is BPO = M * BP * M^-1
+ // where BPO is transformation expressed in (O,texS,texT)
+ // M is the axis base change from (origin,texS,texT) to (O,texS,texT)
+ // here we have a special case, M is a translation and it's inverse is easy
+ // the M * BP * M^-1 formula can be expanded and simplified
+ vec_t BPO[2][3];
+ memcpy(&BPO, &pBP->coords, sizeof(vec_t)*6);
+ BPO[0][2] = Os*(pBP->coords[0][0]-1.0) + Ot*pBP->coords[0][1] + pBP->coords[0][2];
+ BPO[1][2] = Os*pBP->coords[1][0] + Ot*(pBP->coords[1][1]-1.0) + Ot*pBP->coords[1][2];
+
+ // apply a scaling
+ // scale factors against S and T axis, we apply on top of the existing matrix
+ // <1 will decrease the texel/world resolution, >1 will increase
+ float sS = 1.025,sT = 1.025;
+ BPMatScale(BPO,sS,sT);
+
+ // now BPO must be expressed back in (origin,texS,texT) axis base BP = M^-1 * BPO * M
+ // same expanded formula as above
+ memcpy(&pBP->coords, &BPO, sizeof(vec_t)*6);
+ pBP->coords[0][2] = Os*(1.0-BPO[0][0]) - Ot*BPO[0][1] + BPO[0][2];
+ pBP->coords[1][2] = -Os*BPO[1][0] + Ot*(1.0-BPO[1][1]) + BPO[1][2];
+*/
+
+/*
+ // initial version, before axis base change optimize
+
+ // we need to compute our BP matrix in this new axis base (O,texS,texT)
+ // the general case if BPO = M * BP * M^-1
+ // where BPO is transformation expressed in (O,texS,texT)
+ // M is the axis base change from (origin,texS,texT) to (O,texS,texT)
+ // here we have a special case, M is a translation and it's inverse is easy
+ vec_t BPO[2][3];
+ vec_t aux[2][3];
+ vec_t m[2][3];
+ memset(&m, 0, sizeof(vec_t)*6);
+ m[0][0] = 1; m[1][1] = 1; m[0][2] = -Os; m[1][2] = -Ot;
+ BPMatMul(m, pBP->coords, aux);
+ m[0][2] = Os; m[1][2] = Ot; // now M^-1
+ BPMatMul(aux, m, BPO);
+
+ // apply a scaling
+ // scale factors against S and T axis, we apply on top of the existing matrix
+ // <1 will decrease the texel/world resolution, >1 will increase
+ float sS = 1.025,sT = 1.025;
+ BPMatScale(BPO,sS,sT);
+
+ // now BPO must be expressed back in (origin,texS,texT) axis base BP = M^-1 * BPO * M
+ BPMatMul(m, BPO, aux); // m is M^-1
+ m[0][2] = -Os; m[1][2] = -Ot;
+ BPMatMul(aux, m, pBP->coords);
+*/
+#endif
+
+static void OnDone(GtkWidget *widget, gpointer data)
+{
+ g_dlgSurface.GetTexMods();
+ g_dlgSurface.HideDlg ();
+ Sys_UpdateWindows(W_ALL);
+}
+
+// OnUpdate is called when something is changed in the dialog
+// and must be reflected in the views. But it's not a change
+// so important, so the system will try to undo our last do before applying the new changes
+static void OnUpdate (GtkWidget *widget, gpointer data)
+{
+ if (!g_bListenChanged)
+ return;
+
+ if (OnlyPatchesSelected())
+ {
+ //++timo possible bug or misfeature in our gtk_MessageBox here..
+// gtk_MessageBox("The surface inspector doesn't work for patches, use the patch inspector instead (Shift+S)", "Surface Inspector", MB_OK );
+ Sys_Printf("The surface inspector doesn't work for patches, use the patch inspector instead (Shift+S)\n");
+ return;
+ }
+
+ // avoid long delays on slow computers
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+
+ g_dlgSurface.GetTexMods ();
+ Sys_UpdateWindows(W_CAMERA);
+}
+
+// reflect the current changes in the views, and make sure
+// the changes are stored in the undo.
+static void OnApply (GtkWidget *widget, gpointer data)
+{
+ if (!g_bListenChanged)
+ return;
+
+ g_dlgSurface.GetTexMods ();
+ g_dlgSurface.m_nUndoId = 0; // that way we are sure we won't call undo
+ Sys_UpdateWindows(W_CAMERA);
+}
+
+// we use OnTextureKey to detect when the user edits something in the texture widget
+// in which case next 'Enter' will be interpreted as a OnApply instead of a OnDone
+static gint OnTextureKey (GtkWidget* widget, GdkEventKey* event, gpointer data)
+{
+#ifdef DBG_SI
+ Sys_Printf("OnTextureKey\n");
+#endif
+ if (event->keyval != GDK_Return)
+ g_dlgSurface.m_bEditingTextureWidget = true;
+ return FALSE;
+}
+
+static void OnCancel(GtkWidget *widget, gpointer data)
+{
+ g_qeglobals.d_texturewin.texdef = g_old_texdef;
+ // cancel the last do if we own it
+ if (g_dlgSurface.m_nUndoId == Undo_GetUndoId())
+ {
+#ifdef DBG_SI
+ Sys_Printf("OnCancel calling Undo_Undo\n");
+#endif
+ g_bListenUpdate = false;
+ Undo_Undo();
+ g_bListenUpdate = true;
+ g_dlgSurface.m_nUndoId = 0;
+ }
+ g_dlgSurface.HideDlg ();
+}
+
+static gint OnDialogKey (GtkWidget* widget, GdkEventKey* event, gpointer data)
+{
+ if (g_surfwin)
+ {
+ if (event->keyval == GDK_Return)
+ {
+ if (g_dlgSurface.m_bEditingTextureWidget)
+ {
+ OnApply (NULL, NULL);
+ g_dlgSurface.m_bEditingTextureWidget = false;
+ }
+ else
+ {
+ OnDone (NULL, NULL);
+ }
+ return TRUE;
+ }
+ if (event->keyval == GDK_Escape)
+ {
+ OnCancel (NULL, NULL);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+// the widget can be one of hshift, vshift, hscale, vscale, rotate
+// we use the g_bListenChanged flag to ignore when changing stuff ourselves
+static void OnIncrementChanged(GtkWidget *widget, gpointer data)
+{
+ if (!g_bListenChanged)
+ return;
+
+#ifdef DBG_SI
+ Sys_Printf("OnIncrementChanged\n");
+#endif
+
+ gfloat val = 0;
+ sscanf( gtk_entry_get_text (GTK_ENTRY (widget)), "%g", &val);
+ // now push it into the appropriate spin button
+ GtkAdjustment * adjust;
+ if (widget == g_dlgSurface.GetDlgWidget ("hshift_inc"))
+ {
+ l_pIncrement->shift[0] = val;
+ adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (g_dlgSurface.GetDlgWidget ("hshift")));
+ adjust->step_increment = l_pIncrement->shift[0];
+ }
+ else if (widget == g_dlgSurface.GetDlgWidget ("vshift_inc"))
+ {
+ l_pIncrement->shift[1] = val;
+ adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (g_dlgSurface.GetDlgWidget ("vshift")));
+ adjust->step_increment = l_pIncrement->shift[1];
+ }
+ else if (widget == g_dlgSurface.GetDlgWidget ("hscale_inc"))
+ {
+ l_pIncrement->scale[0] = val;
+ adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (g_dlgSurface.GetDlgWidget ("hscale")));
+ adjust->step_increment = l_pIncrement->scale[0];
+ }
+ else if (widget == g_dlgSurface.GetDlgWidget ("vscale_inc"))
+ {
+ l_pIncrement->scale[1] = val;
+ adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (g_dlgSurface.GetDlgWidget ("vscale")));
+ adjust->step_increment = l_pIncrement->scale[1];
+ }
+ else if (widget == g_dlgSurface.GetDlgWidget ("rotate_inc"))
+ {
+ l_pIncrement->rotate = val;
+ adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (g_dlgSurface.GetDlgWidget ("rotate")));
+ adjust->step_increment = l_pIncrement->rotate;
+ }
+}
+
+// make the shift increments match the grid settings
+// the objective being that the shift+arrows shortcuts move the texture by the corresponding grid size
+// this depends on a scale value if you have selected a particular texture on which you want it to work:
+// we move the textures in pixels, not world units. (i.e. increment values are in pixel)
+// depending on the texture scale it doesn't take the same amount of pixels to move of g_qeglobals.d_gridsize
+// increment * scale = gridsize
+// hscale and vscale are optional parameters, if they are zero they will be set to the default scale
+// NOTE: the default scale depends if you are using BP mode or regular.
+// For regular it's 0.5f (128 pixels cover 64 world units), for BP it's simply 1.0f
+// see fenris #2810
+void DoSnapTToGrid(float hscale, float vscale)
+{
+ if (hscale == 0.0f)
+ {
+ (g_qeglobals.m_bBrushPrimitMode) ? hscale = 1.0f : hscale = 0.5f;
+ }
+ if (vscale == 0.0f)
+ {
+ (g_qeglobals.m_bBrushPrimitMode) ? vscale = 1.0f : vscale = 0.5f;
+ }
+#ifdef _DEBUG
+ Sys_Printf ("DoSnapTToGrid: hscale %g vscale %g\n", hscale, vscale);
+#endif
+ l_pIncrement->shift[0] = (int) ( (float)g_qeglobals.d_gridsize / hscale );
+ l_pIncrement->shift[1] = (int) ( (float)g_qeglobals.d_gridsize / vscale );
+ // now some update work
+ // FIXME: doesn't look good here, seems to be called several times
+ g_dlgSurface.SetTexMods();
+}
+
+// make the shift increments match the grid settings
+// the objective being that the shift+arrows shortcuts move the texture by the corresponding grid size
+// this depends on the current texture scale used?
+// we move the textures in pixels, not world units. (i.e. increment values are in pixel)
+// depending on the texture scale it doesn't take the same amount of pixels to move of g_qeglobals.d_gridsize
+// increment * scale = gridsize
+static void OnBtnMatchGrid(GtkWidget *widget, gpointer data)
+{
+ float hscale, vscale;
+ hscale = gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (g_dlgSurface.GetDlgWidget ("hscale")));
+ vscale = gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (g_dlgSurface.GetDlgWidget ("vscale")));
+ if (hscale == 0.0f || vscale == 0.0f)
+ {
+ Sys_Printf("ERROR: unexpected scale == 0.0f\n");
+ return;
+ }
+ DoSnapTToGrid (hscale, vscale);
+}
+
+void UpdateSurfaceDialog()
+{
+ if (!g_bListenUpdate)
+ return;
+
+ g_SurfaceTable.m_pfnUpdateSurfaceDialog();
+}
+
+// DoSurface will always try to show the surface inspector
+// or update it because something new has been selected
+void DoSurface (void)
+{
+#ifdef DBG_SI
+ Sys_Printf("DoSurface\n");
+#endif
+ g_SurfaceTable.m_pfnDoSurface();
+ return;
+}
+
+void ToggleSurface()
+{
+ g_SurfaceTable.m_pfnToggleSurface();
+ return;
+}
+
+// NOTE: will raise and show the Surface inspector and exec fit for patches and brushes
+void SurfaceDlgFitAll()
+{
+ g_SurfaceTable.m_pfnSurfaceDlgFitAll();
+ return;
+}
+
+static void OnBtnPatchdetails(GtkWidget *widget, gpointer data)
+{
+ Patch_NaturalizeSelected(true);
+ Sys_UpdateWindows(W_ALL);
+}
+
+static void OnBtnPatchnatural(GtkWidget *widget, gpointer data)
+{
+ Patch_NaturalizeSelected();
+ Sys_UpdateWindows(W_ALL);
+}
+
+static void OnBtnPatchreset(GtkWidget *widget, gpointer data)
+{
+ float fx, fy;
+
+ if (DoTextureLayout (&fx, &fy) == IDOK)
+ Patch_ResetTexturing (fx, fy);
+ Sys_UpdateWindows(W_ALL);
+}
+
+static void OnBtnPatchFit(GtkWidget *widget, gpointer data)
+{
+ Patch_ResetTexturing(1.0, 1.0);
+ Sys_UpdateWindows(W_ALL);
+}
+
+static void OnBtnAxial(GtkWidget *widget, gpointer data)
+{
+ Select_SetTexture (&g_qeglobals.d_texturewin.texdef, &g_qeglobals.d_texturewin.brushprimit_texdef, true);
+ g_dlgSurface.SetTexMods();
+ Sys_UpdateWindows(W_ALL);
+}
+
+static void OnBtnFaceFit(GtkWidget *widget, gpointer data)
+{
+ g_dlgSurface.UpdateData(TRUE);
+ if (g_ptrSelectedFaces.GetSize() == 0)
+ {
+ brush_t *b;
+ for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
+ {
+ for (face_t* pFace = b->brush_faces; pFace; pFace = pFace->next)
+ {
+ g_ptrSelectedFaces.Add(pFace);
+ g_ptrSelectedFaceBrushes.Add(b);
+ }
+ }
+ Select_FitTexture(g_dlgSurface.m_nHeight, g_dlgSurface.m_nWidth);
+ g_dlgSurface.SetTexMods();
+ g_ptrSelectedFaces.RemoveAll();
+ }
+ else
+ {
+ Select_FitTexture(g_dlgSurface.m_nHeight, g_dlgSurface.m_nWidth);
+ g_dlgSurface.SetTexMods();
+ }
+ Sys_UpdateWindows(W_ALL);
+}
+
+// =============================================================================
+// SurfaceDialog class
+
+SurfaceDlg::SurfaceDlg ()
+{
+ m_nHeight = 1;
+ m_nWidth = 1;
+ m_nUndoId = 0;
+}
+
+void SurfaceDlg::ShowDlg()
+{
+ Dialog::ShowDlg();
+ if(GetWidget() == NULL)
+ Create();
+ g_surfwin = GetWidget ();
+}
+void SurfaceDlg::HideDlg()
+{
+ g_surfwin = NULL;
+ Dialog::HideDlg();
+}
+
+GtkWidget* SurfaceDlg::GetWidget()
+{
+ return g_SurfaceTable.m_pfnGet_SI_Module_Widget();
+}
+
+// set default values for increments (shift scale and rot)
+// this is called by the prefs code if can't find the values
+void SurfaceDlg::InitDefaultIncrement(texdef_t *tex)
+{
+ tex->SetName("foo");
+ tex->shift[0] = 8;
+ tex->shift[1] = 8;
+ tex->scale[0] = 0.25;
+ tex->scale[1] = 0.25;
+ tex->rotate = 10;
+}
+
+void SurfaceDlg::BuildDialog ()
+{
+ GtkWidget *dlg, *vbox, *hbox2, *frame, *table, *label;
+ GtkWidget *button, *entry, *spin;
+
+ dlg = m_pWidget;
+
+ load_window_pos (dlg, g_PrefsDlg.mWindowInfo.posSurfaceWnd);
+
+ gtk_window_set_title (GTK_WINDOW (dlg), "Surface inspector");
+ //g_signal_connect (G_OBJECT (dlg), "delete_event", G_CALLBACK (OnCancel), NULL);
+ // we catch 'Enter' and interpret is as OnDone
+ gtk_signal_connect (GTK_OBJECT (dlg), "key_press_event", GTK_SIGNAL_FUNC (OnDialogKey), NULL);
+ gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (g_pParentWnd->m_pWidget));
+
+ // replaced by only the vbox:
+ vbox = gtk_vbox_new (FALSE, 5);
+ gtk_widget_show (vbox);
+ gtk_container_add (GTK_CONTAINER (dlg), vbox);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
+
+ hbox2 = gtk_hbox_new (FALSE, 5);
+ gtk_widget_show (hbox2);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, TRUE, 0);
+
+ label = gtk_label_new ("Texture");
+ gtk_widget_show (label);
+ gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
+
+ entry = gtk_entry_new ();
+ gtk_signal_connect (GTK_OBJECT (entry), "key_press_event", GTK_SIGNAL_FUNC (OnTextureKey), NULL);
+ gtk_widget_show (entry);
+ gtk_box_pack_start (GTK_BOX (hbox2), entry, TRUE, TRUE, 0);
+ g_object_set_data (G_OBJECT (m_pWidget), "texture", entry);
+
+// table = gtk_table_new (5, 4, FALSE);
+ table = gtk_table_new (6, 4, FALSE);
+ gtk_widget_show (table);
+ gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 5);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 5);
+
+ label = gtk_label_new ("Horizontal shift");
+ gtk_widget_show (label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, -8192, 8192, 2, 8, 8)), 0, 0);
+ g_object_set_data (G_OBJECT (dlg), "hshift", spin);
+ gtk_signal_connect (GTK_OBJECT (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin))), "value_changed",
+ GTK_SIGNAL_FUNC (OnUpdate), NULL);
+ gtk_widget_show (spin);
+ gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 0, 1,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_widget_set_usize (spin, 60, -2);
+
+ label = gtk_label_new ("Step");
+ gtk_widget_show (label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
+ gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ entry = gtk_entry_new ();
+ g_object_set_data (G_OBJECT (dlg), "hshift_inc", entry);
+ gtk_signal_connect (GTK_OBJECT (entry), "changed",
+ GTK_SIGNAL_FUNC (OnIncrementChanged), NULL);
+ gtk_widget_show (entry);
+ gtk_table_attach (GTK_TABLE (table), entry, 3, 4, 0, 1,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_widget_set_usize (entry, 50, -2);
+
+ label = gtk_label_new ("Vertical shift");
+ gtk_widget_show (label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, -8192, 8192, 2, 8, 8)), 0, 0);
+ g_object_set_data (G_OBJECT (dlg), "vshift", spin);
+ gtk_signal_connect (GTK_OBJECT (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin))), "value_changed",
+ GTK_SIGNAL_FUNC (OnUpdate), NULL);
+ gtk_widget_show (spin);
+ gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_widget_set_usize (spin, 60, -2);
+
+ label = gtk_label_new ("Step");
+ gtk_widget_show (label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
+ gtk_table_attach (GTK_TABLE (table), label, 2, 3, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ entry = gtk_entry_new ();
+ g_object_set_data (G_OBJECT (dlg), "vshift_inc", entry);
+ gtk_signal_connect (GTK_OBJECT (entry), "changed",
+ GTK_SIGNAL_FUNC (OnIncrementChanged), NULL);
+ gtk_widget_show (entry);
+ gtk_table_attach (GTK_TABLE (table), entry, 3, 4, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_widget_set_usize (entry, 50, -2);
+
+ label = gtk_label_new ("Horizontal stretch");
+ gtk_widget_show (label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, -1000, 1000, 1, 10, 10)), 0, 0);
+ g_object_set_data (G_OBJECT (dlg), "hscale", spin);
+ gtk_signal_connect (GTK_OBJECT (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin))), "value_changed",
+ GTK_SIGNAL_FUNC (OnUpdate), NULL);
+ gtk_widget_show (spin);
+ gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 2, 3,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_widget_set_usize (spin, 60, -2);
+
+ label = gtk_label_new ("Step");
+ gtk_widget_show (label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
+ gtk_table_attach (GTK_TABLE (table), label, 2, 3, 2, 3,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 2, 3);
+
+ entry = gtk_entry_new ();
+ g_object_set_data (G_OBJECT (dlg), "hscale_inc", entry);
+ gtk_signal_connect (GTK_OBJECT (entry), "changed",
+ GTK_SIGNAL_FUNC (OnIncrementChanged), NULL);
+ gtk_widget_show (entry);
+ gtk_table_attach (GTK_TABLE (table), entry, 3, 4, 2, 3,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 2, 3);
+ gtk_widget_set_usize (entry, 50, -2);
+
+ label = gtk_label_new ("Vertical stretch");
+ gtk_widget_show (label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, -1000, 1000, 1, 10, 10)), 0, 0);
+ g_object_set_data (G_OBJECT (dlg), "vscale", spin);
+ gtk_signal_connect (GTK_OBJECT (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin))), "value_changed",
+ GTK_SIGNAL_FUNC (OnUpdate), NULL);
+ gtk_widget_show (spin);
+ gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 3, 4,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_widget_set_usize (spin, 60, -2);
+
+ label = gtk_label_new ("Step");
+ gtk_widget_show (label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
+ gtk_table_attach (GTK_TABLE (table), label, 2, 3, 3, 4,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ entry = gtk_entry_new ();
+ g_object_set_data (G_OBJECT (dlg), "vscale_inc", entry);
+ gtk_signal_connect (GTK_OBJECT (entry), "changed",
+ GTK_SIGNAL_FUNC (OnIncrementChanged), NULL);
+ gtk_widget_show (entry);
+ gtk_table_attach (GTK_TABLE (table), entry, 3, 4, 3, 4,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_widget_set_usize (entry, 50, -2);
+
+ label = gtk_label_new ("Rotate");
+ gtk_widget_show (label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 4, 5,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, -360, 360, 1, 10, 10)), 1, 0);
+ g_object_set_data (G_OBJECT (dlg), "rotate", spin);
+ gtk_signal_connect (GTK_OBJECT (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin))), "value_changed",
+ GTK_SIGNAL_FUNC (OnUpdate), NULL);
+ gtk_widget_show (spin);
+ gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 4, 5,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_widget_set_usize (spin, 60, -2);
+ gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spin), TRUE);
+
+ label = gtk_label_new ("Step");
+ gtk_widget_show (label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
+ gtk_table_attach (GTK_TABLE (table), label, 2, 3, 4, 5,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ entry = gtk_entry_new ();
+ g_object_set_data (G_OBJECT (dlg), "rotate_inc", entry);
+ gtk_signal_connect (GTK_OBJECT (entry), "changed",
+ GTK_SIGNAL_FUNC (OnIncrementChanged), NULL);
+ gtk_widget_show (entry);
+ gtk_table_attach (GTK_TABLE (table), entry, 3, 4, 4, 5,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_widget_set_usize (entry, 50, -2);
+
+ // match grid button
+ button = gtk_button_new_with_label ("Match Grid");
+ gtk_widget_show (button);
+ gtk_table_attach (GTK_TABLE (table), button, 2, 4, 5, 6,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (OnBtnMatchGrid), NULL);
+
+ frame = gtk_frame_new ("Texturing");
+ gtk_widget_show (frame);
+ gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
+
+ table = gtk_table_new (4, 4, FALSE);
+ gtk_widget_show (table);
+ gtk_container_add (GTK_CONTAINER (frame), table);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 5);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 5);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 5);
+
+ label = gtk_label_new ("Brush");
+ gtk_widget_show (label);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ label = gtk_label_new ("Patch");
+ gtk_widget_show (label);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ label = gtk_label_new ("Width");
+ gtk_widget_show (label);
+ gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ label = gtk_label_new ("Height");
+ gtk_widget_show (label);
+ gtk_table_attach (GTK_TABLE (table), label, 3, 4, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ button = gtk_button_new_with_label ("Axial");
+ gtk_widget_show (button);
+ gtk_table_attach (GTK_TABLE (table), button, 0, 1, 1, 2,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (OnBtnAxial), NULL);
+ gtk_widget_set_usize (button, 60, -2);
+
+ button = gtk_button_new_with_label ("Fit");
+ gtk_widget_show (button);
+ gtk_table_attach (GTK_TABLE (table), button, 1, 2, 1, 2,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (OnBtnFaceFit), NULL);
+ gtk_widget_set_usize (button, 60, -2);
+
+ button = gtk_button_new_with_label ("CAP");
+ gtk_widget_show (button);
+ gtk_table_attach (GTK_TABLE (table), button, 0, 1, 3, 4,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (OnBtnPatchdetails), NULL);
+ gtk_widget_set_usize (button, 60, -2);
+
+ button = gtk_button_new_with_label ("Set...");
+ gtk_widget_show (button);
+ gtk_table_attach (GTK_TABLE (table), button, 1, 2, 3, 4,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (OnBtnPatchreset), NULL);
+ gtk_widget_set_usize (button, 60, -2);
+
+ button = gtk_button_new_with_label ("Natural");
+ gtk_widget_show (button);
+ gtk_table_attach (GTK_TABLE (table), button, 2, 3, 3, 4,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (OnBtnPatchnatural), NULL);
+ gtk_widget_set_usize (button, 60, -2);
+
+ button = gtk_button_new_with_label ("Fit");
+ gtk_widget_show (button);
+ gtk_table_attach (GTK_TABLE (table), button, 3, 4, 3, 4,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (OnBtnPatchFit), NULL);
+ gtk_widget_set_usize (button, 60, -2);
+
+ spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (1, 1, 32, 1, 10, 10)), 1, 0);
+ gtk_widget_show (spin);
+ gtk_table_attach (GTK_TABLE (table), spin, 2, 3, 1, 2,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_widget_set_usize (spin, 60, -2);
+ AddDialogData (spin, &m_nWidth, DLG_SPIN_INT);
+
+ spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (1, 1, 32, 1, 10, 10)), 1, 0);
+ gtk_widget_show (spin);
+ gtk_table_attach (GTK_TABLE (table), spin, 3, 4, 1, 2,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_widget_set_usize (spin, 60, -2);
+ AddDialogData (spin, &m_nHeight, DLG_SPIN_INT);
+
+ hbox2 = gtk_hbox_new (FALSE, 5);
+ gtk_widget_show (hbox2);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, TRUE, 0);
+
+ button = gtk_button_new_with_label ("Done");
+ gtk_widget_show (button);
+ gtk_box_pack_start (GTK_BOX (hbox2), button, FALSE, FALSE, 0);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (OnDone), NULL);
+ gtk_widget_set_usize (button, 60, -2);
+
+ button = gtk_button_new_with_label ("Apply");
+ gtk_widget_show (button);
+ gtk_box_pack_start (GTK_BOX (hbox2), button, FALSE, FALSE, 0);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (OnApply), NULL);
+ gtk_widget_set_usize (button, 60, -2);
+
+ button = gtk_button_new_with_label ("Cancel");
+ gtk_widget_show (button);
+ gtk_box_pack_start (GTK_BOX (hbox2), button, FALSE, FALSE, 0);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (OnCancel), NULL);
+ gtk_widget_set_usize (button, 60, -2);
+
+ // that's a bit of trashy stuff from Textool-v2 branch
+#ifdef _DEBUG
+ // FIXME: testing only, scaling in BP mode
+ button = gtk_button_new_with_label ("Test");
+ gtk_widget_show (button);
+ gtk_box_pack_start (GTK_BOX (hbox2), button, FALSE, FALSE, 0);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (OnTest), NULL);
+ gtk_widget_set_usize (button, 60, -2);
+#endif
+
+ // Initialize
+ SetTexMods ();
+}
+
+/*
+==============
+SetTexMods
+
+Set the fields to the current texdef (i.e. map/texdef -> dialog widgets)
+if faces selected (instead of brushes) -> will read this face texdef, else current texdef
+if only patches selected, will read the patch texdef
+===============
+*/
+
+void SurfaceDlg::SetTexMods()
+{
+ texdef_t *pt;
+ brushprimit_texdef_t *bpt;
+ // local copy if a width=2 height=2 qtetxture_t is needed
+ brushprimit_texdef_t local_bp;
+
+#ifdef DBG_SI
+ Sys_Printf("SurfaceDlg::SetTexMods\n");
+#endif
+
+ if (!g_surfwin)
+ return;
+
+ if (g_ptrSelectedFaces.GetSize() > 0)
+ {
+ face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(0));
+ pt = &selFace->texdef;
+ if (g_qeglobals.m_bBrushPrimitMode)
+ {
+ // compute a texture matrix related to the default matrix width=2 height=2
+ ConvertTexMatWithQTexture( &selFace->brushprimit_texdef, selFace->d_texture, &local_bp, NULL );
+ bpt = &local_bp;
+ }
+ }
+ else
+ {
+ pt = &g_qeglobals.d_texturewin.texdef;
+ if (g_qeglobals.m_bBrushPrimitMode)
+ {
+ bpt = &g_qeglobals.d_texturewin.brushprimit_texdef;
+ }
+ }
+ // brush primitive mode : compute fake shift scale rot representation
+ if (g_qeglobals.m_bBrushPrimitMode)
+ TexMatToFakeTexCoords( bpt->coords, m_shift, &m_rotate, m_scale );
+
+ g_bListenChanged = false;
+
+ if(strncmp(pt->GetName(), "textures/", 9) != 0)
+ pt->SetName(SHADER_NOT_FOUND);
+ gtk_entry_set_text (GTK_ENTRY (GetDlgWidget ("texture")), pt->GetName()+9);
+
+ GtkSpinButton *spin;
+ spin = GTK_SPIN_BUTTON (GetDlgWidget ("hshift"));
+ gtk_spin_button_set_digits (spin, 2);
+ if (g_qeglobals.m_bBrushPrimitMode)
+ gtk_spin_button_set_value (spin, m_shift[0]);
+ else
+ gtk_spin_button_set_value (spin, pt->shift[0]);
+ GtkAdjustment *adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));
+ adjust->step_increment = l_pIncrement->shift[0];
+ char buf[10]; // got into snprintf paranoia after BoundChecker detected a stack overrun
+#ifdef _WIN32
+ // TTimo: THIS IS UGLY
+#define snprintf _snprintf
+#endif
+ snprintf (buf, 10, "%g", l_pIncrement->shift[0]);
+ gtk_entry_set_text (GTK_ENTRY (GetDlgWidget ("hshift_inc")), buf);
+
+ spin = GTK_SPIN_BUTTON (GetDlgWidget ("vshift"));
+ gtk_spin_button_set_digits (spin, 2);
+ if (g_qeglobals.m_bBrushPrimitMode)
+ gtk_spin_button_set_value (spin, m_shift[1]);
+ else
+ gtk_spin_button_set_value (spin, pt->shift[1]);
+ adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));
+ adjust->step_increment = l_pIncrement->shift[1];
+ snprintf (buf, 10, "%g", l_pIncrement->shift[1]);
+ gtk_entry_set_text (GTK_ENTRY (GetDlgWidget ("vshift_inc")), buf);
+
+ spin = GTK_SPIN_BUTTON (GetDlgWidget ("hscale"));
+ gtk_spin_button_set_digits (spin, 5);
+ gtk_spin_button_set_value (spin, g_qeglobals.m_bBrushPrimitMode ? m_scale[0] : pt->scale[0]);
+
+ adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));
+ adjust->step_increment = l_pIncrement->scale[0];
+ snprintf (buf, 10, "%g", l_pIncrement->scale[0]);
+ gtk_entry_set_text (GTK_ENTRY (GetDlgWidget ("hscale_inc")), buf);
+
+ spin = GTK_SPIN_BUTTON (GetDlgWidget ("vscale"));
+ gtk_spin_button_set_digits (spin, 5);
+ gtk_spin_button_set_value (spin, g_qeglobals.m_bBrushPrimitMode ? m_scale[1] : pt->scale[1]);
+
+ adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));
+ adjust->step_increment = l_pIncrement->scale[1];
+ snprintf (buf, 10, "%g", l_pIncrement->scale[1]);
+ gtk_entry_set_text (GTK_ENTRY (GetDlgWidget ("vscale_inc")), buf);
+
+ //++timo compute BProtate as int ..
+ spin = GTK_SPIN_BUTTON (GetDlgWidget ("rotate"));
+ gtk_spin_button_set_digits (spin, 2);
+ gtk_spin_button_set_value (spin, g_qeglobals.m_bBrushPrimitMode ? m_rotate : pt->rotate);
+
+ adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));
+ adjust->step_increment = l_pIncrement->rotate;
+ snprintf (buf, 10, "%g", l_pIncrement->rotate);
+ gtk_entry_set_text (GTK_ENTRY (GetDlgWidget ("rotate_inc")), buf);
+
+ g_bListenChanged = true;
+
+ // undo tricks: set the undo id to zero so we don't attempt to undo something that does not belong to us
+ m_nUndoId = 0;
+ // store the current texdef as our escape route if user hits OnCancel
+ g_old_texdef = g_qeglobals.d_texturewin.texdef;
+ // reset the Enter key behaviour flag
+ m_bEditingTextureWidget = false;
+}
+
+/*
+==============
+GetTexMods
+
+Reads the fields to get the current texdef (i.e. widgets -> MAP)
+in brush primitive mode, grab the fake shift scale rot and compute a new texture matrix
+===============
+*/
+void SurfaceDlg::GetTexMods()
+{
+ char buffer[1024];
+ texdef_t *pt;
+
+#ifdef DBG_SI
+ Sys_Printf("SurfaceDlg::GetTexMods\n");
+#endif
+
+ if (g_ptrSelectedFaces.GetSize() > 0)
+ {
+ //++timo just a test, we disable the undo when working on selected faces
+ m_nUndoId=0;
+ face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(0));
+ g_qeglobals.d_texturewin.texdef = selFace->texdef;
+#ifdef DBG_SI
+ Sys_Printf("g_qeglobals.d_texturewin.texdef = selFace->texdef\n");
+#endif
+ }
+// else
+// {
+ pt = &g_qeglobals.d_texturewin.texdef;
+#ifdef DBG_SI
+ Sys_Printf("pt = &g_qeglobals.d_texturewin.texdef\n");
+#endif
+// }
+
+ const char* text = gtk_entry_get_text (GTK_ENTRY (GetDlgWidget ("texture")));
+
+#ifdef DBG_SI
+ Sys_Printf("pt->SetName(%s)\n", text );
+#endif
+
+ // TTimo: detect and refuse invalid texture names (at least the ones with spaces)
+ if (text[0] <= ' ' || strchr(text, ' '))
+ {
+ Sys_FPrintf(SYS_WRN, "WARNING: spaces in shader names are not allowed, ignoring '%s'\n", text);
+ pt->SetName(SHADER_NOT_FOUND);
+ gtk_entry_set_text (GTK_ENTRY (GetDlgWidget ("texture")), pt->GetName());
+ }
+ else
+ {
+ strcpy(buffer, "textures/");
+ strcpy(buffer+9, text);
+ pt->SetName(buffer);
+ }
+
+
+ (g_qeglobals.m_bBrushPrimitMode ? m_shift[0] : pt->shift[0]) =
+ gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (GetDlgWidget ("hshift")));
+ (g_qeglobals.m_bBrushPrimitMode ? m_shift[1] : pt->shift[1]) =
+ gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (GetDlgWidget ("vshift")));
+ (g_qeglobals.m_bBrushPrimitMode ? m_scale[0] : pt->scale[0]) =
+ gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (GetDlgWidget ("hscale")));
+ (g_qeglobals.m_bBrushPrimitMode ? m_scale[1] : pt->scale[1]) =
+ gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (GetDlgWidget ("vscale")));
+ (g_qeglobals.m_bBrushPrimitMode ? m_rotate : pt->rotate) =
+ gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (GetDlgWidget ("rotate")));
+
+ // a local copy of the texture matrix, given for a qtexture_t with width=2 height=2
+ brushprimit_texdef_t local_bp;
+ brushprimit_texdef_t *bpt;
+ if (g_qeglobals.m_bBrushPrimitMode)
+ {
+ face_t *selFace = NULL;
+ if (g_ptrSelectedFaces.GetSize() > 0)
+ {
+ selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(0));
+ bpt = &selFace->brushprimit_texdef;
+ }
+ else
+ {
+ bpt = &g_qeglobals.d_texturewin.brushprimit_texdef;
+ }
+ // compute texture matrix
+ // the matrix returned must be understood as a qtexture_t with width=2 height=2
+ FakeTexCoordsToTexMat( m_shift, m_rotate, m_scale, local_bp.coords );
+ // copy the texture matrix in the global struct
+ // 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
+
+ ConvertTexMatWithQTexture( &local_bp, NULL, bpt, ( (selFace) ? selFace->d_texture : NULL ) );
+ }
+ // we are gonna do stuff, if we own the last do we undo it first
+ if (m_nUndoId != 0)
+ {
+ // check the do we're about to undo is the one we pushed earlier
+ if (m_nUndoId == Undo_GetUndoId())
+ {
+#ifdef DBG_SI
+ Sys_Printf("GetTexMods calling Undo_Undo (silent)\n");
+#endif
+ g_bListenUpdate=false;
+ Undo_Undo(true);
+ g_bListenUpdate=true;
+ }
+ }
+ Select_SetTexture(pt,&local_bp);
+ m_nUndoId = Undo_GetUndoId();
+}
+
+void SurfaceDlg::FitAll()
+{
+ OnBtnFaceFit(NULL, NULL);
+ OnBtnPatchFit(NULL, NULL);
+}