X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fnetradiant.git;a=blobdiff_plain;f=plugins%2Ftextool%2FTexTool.cpp;h=818d8d2f44cada980429349a3f38924406012b66;hp=9ba7b01bffd66abe8f7eaf8d0939f9b88ff884ed;hb=fd6b262a39ceeda3f991fc6bd8f767353d149374;hpb=bfc8a12a6b315ae261101a34db8ba1b682c67bb7 diff --git a/plugins/textool/TexTool.cpp b/plugins/textool/TexTool.cpp index 9ba7b01b..818d8d2f 100644 --- a/plugins/textool/TexTool.cpp +++ b/plugins/textool/TexTool.cpp @@ -1,23 +1,23 @@ /* -Copyright (C) 1999-2006 Id Software, Inc. and contributors. -For a list of contributors, see the accompanying CONTRIBUTORS file. + Copyright (C) 1999-2006 Id Software, Inc. and contributors. + For a list of contributors, see the accompanying CONTRIBUTORS file. -This file is part of GtkRadiant. + 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 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. + 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 -*/ + 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 + */ //----------------------------------------------------------------------------- // @@ -28,142 +28,136 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "StdAfx.h" -static void dialog_button_callback (GtkWidget *widget, gpointer data) -{ - GtkWidget *parent; - int *loop, *ret; - - parent = gtk_widget_get_toplevel (widget); - loop = (int*)g_object_get_data (G_OBJECT (parent), "loop"); - ret = (int*)g_object_get_data (G_OBJECT (parent), "ret"); - - *loop = 0; - *ret = gpointer_to_int (data); -} - -static gint dialog_delete_callback (GtkWidget *widget, GdkEvent* event, gpointer data) -{ - int *loop; - - gtk_widget_hide (widget); - loop = (int*)g_object_get_data (G_OBJECT (widget), "loop"); - *loop = 0; - - return TRUE; -} - -int DoMessageBox (const char* lpText, const char* lpCaption, guint32 uType) -{ - GtkWidget *window, *w, *vbox, *hbox; - int mode = (uType & MB_TYPEMASK), ret, loop = 1; - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_signal_connect (GTK_OBJECT (window), "delete_event", - GTK_SIGNAL_FUNC (dialog_delete_callback), NULL); - gtk_signal_connect (GTK_OBJECT (window), "destroy", - GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL); - gtk_window_set_title (GTK_WINDOW (window), lpCaption); - gtk_container_border_width (GTK_CONTAINER (window), 10); - g_object_set_data (G_OBJECT (window), "loop", &loop); - g_object_set_data (G_OBJECT (window), "ret", &ret); - gtk_widget_realize (window); - - vbox = gtk_vbox_new (FALSE, 10); - gtk_container_add (GTK_CONTAINER (window), vbox); - gtk_widget_show (vbox); - - w = gtk_label_new (lpText); - gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 2); - gtk_label_set_justify (GTK_LABEL (w), GTK_JUSTIFY_LEFT); - gtk_widget_show (w); - - w = gtk_hseparator_new (); - gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 2); - gtk_widget_show (w); - - hbox = gtk_hbox_new (FALSE, 10); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 2); - gtk_widget_show (hbox); - - if (mode == MB_OK) - { - w = gtk_button_new_with_label ("Ok"); - gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, TRUE, 0); - gtk_signal_connect (GTK_OBJECT (w), "clicked", - GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK)); - GTK_WIDGET_SET_FLAGS (w, GTK_CAN_DEFAULT); - gtk_widget_grab_default (w); - gtk_widget_show (w); - ret = IDOK; - } - else if (mode == MB_OKCANCEL) - { - w = gtk_button_new_with_label ("Ok"); - gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, TRUE, 0); - gtk_signal_connect (GTK_OBJECT (w), "clicked", - GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK)); - GTK_WIDGET_SET_FLAGS (w, GTK_CAN_DEFAULT); - gtk_widget_grab_default (w); - gtk_widget_show (w); - - w = gtk_button_new_with_label ("Cancel"); - gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, TRUE, 0); - gtk_signal_connect (GTK_OBJECT (w), "clicked", - GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDCANCEL)); - gtk_widget_show (w); - ret = IDCANCEL; - } - else if (mode == MB_YESNOCANCEL) - { - w = gtk_button_new_with_label ("Yes"); - gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, TRUE, 0); - gtk_signal_connect (GTK_OBJECT (w), "clicked", - GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDYES)); - GTK_WIDGET_SET_FLAGS (w, GTK_CAN_DEFAULT); - gtk_widget_grab_default (w); - gtk_widget_show (w); - - w = gtk_button_new_with_label ("No"); - gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, TRUE, 0); - gtk_signal_connect (GTK_OBJECT (w), "clicked", - GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDNO)); - gtk_widget_show (w); - - w = gtk_button_new_with_label ("Cancel"); - gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, TRUE, 0); - gtk_signal_connect (GTK_OBJECT (w), "clicked", - GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDCANCEL)); - gtk_widget_show (w); - ret = IDCANCEL; - } - else /* if (mode == MB_YESNO) */ - { - w = gtk_button_new_with_label ("Yes"); - gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, TRUE, 0); - gtk_signal_connect (GTK_OBJECT (w), "clicked", - GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDYES)); - GTK_WIDGET_SET_FLAGS (w, GTK_CAN_DEFAULT); - gtk_widget_grab_default (w); - gtk_widget_show (w); - - w = gtk_button_new_with_label ("No"); - gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, TRUE, 0); - gtk_signal_connect (GTK_OBJECT (w), "clicked", - GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDNO)); - gtk_widget_show (w); - ret = IDNO; - } - - gtk_widget_show (window); - gtk_grab_add (window); - - while (loop) - gtk_main_iteration (); - - gtk_grab_remove (window); - gtk_widget_destroy (window); - - return ret; +static void dialog_button_callback( GtkWidget *widget, gpointer data ){ + GtkWidget *parent; + int *loop, *ret; + + parent = gtk_widget_get_toplevel( widget ); + loop = (int*)g_object_get_data( G_OBJECT( parent ), "loop" ); + ret = (int*)g_object_get_data( G_OBJECT( parent ), "ret" ); + + *loop = 0; + *ret = gpointer_to_int( data ); +} + +static gint dialog_delete_callback( GtkWidget *widget, GdkEvent* event, gpointer data ){ + int *loop; + + gtk_widget_hide( widget ); + loop = (int*)g_object_get_data( G_OBJECT( widget ), "loop" ); + *loop = 0; + + return TRUE; +} + +int DoMessageBox( const char* lpText, const char* lpCaption, guint32 uType ){ + GtkWidget *w, *vbox, *hbox; + int mode = ( uType & MB_TYPEMASK ), ret, loop = 1; + + auto window = ui::Window( ui::window_type::TOP ); + window.connect( "delete_event", + G_CALLBACK( dialog_delete_callback ), NULL ); + window.connect( "destroy", + G_CALLBACK( gtk_widget_destroy ), NULL ); + gtk_window_set_title( GTK_WINDOW( window ), lpCaption ); + gtk_container_set_border_width( GTK_CONTAINER( window ), 10 ); + g_object_set_data( G_OBJECT( window ), "loop", &loop ); + g_object_set_data( G_OBJECT( window ), "ret", &ret ); + gtk_widget_realize( window ); + + vbox = ui::VBox( FALSE, 10 ); + window.add(vbox); + vbox.show(); + + w = ui::Label( lpText ); + vbox.pack_start( w, FALSE, FALSE, 2 ); + gtk_label_set_justify( GTK_LABEL( w ), GTK_JUSTIFY_LEFT ); + w.show(); + + w = gtk_hseparator_new(); + vbox.pack_start( w, FALSE, FALSE, 2 ); + w.show(); + + hbox = ui::HBox( FALSE, 10 ); + vbox.pack_start( hbox, FALSE, FALSE, 2 ); + hbox.show(); + + if ( mode == MB_OK ) { + w = ui::Button( "Ok" ); + hbox.pack_start( w, TRUE, TRUE, 0 ); + w.connect( "clicked", + G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDOK ) ); + gtk_widget_set_can_default( w, true ); + gtk_widget_grab_default( w ); + w.show(); + ret = IDOK; + } + else if ( mode == MB_OKCANCEL ) { + w = ui::Button( "Ok" ); + hbox.pack_start( w, TRUE, TRUE, 0 ); + w.connect( "clicked", + G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDOK ) ); + gtk_widget_set_can_default( w, true ); + gtk_widget_grab_default( w ); + w.show(); + + w = ui::Button( "Cancel" ); + hbox.pack_start( w, TRUE, TRUE, 0 ); + w.connect( "clicked", + G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) ); + w.show(); + ret = IDCANCEL; + } + else if ( mode == MB_YESNOCANCEL ) { + w = ui::Button( "Yes" ); + hbox.pack_start( w, TRUE, TRUE, 0 ); + w.connect( "clicked", + G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDYES ) ); + gtk_widget_set_can_default( w, true ); + gtk_widget_grab_default( w ); + w.show(); + + w = ui::Button( "No" ); + hbox.pack_start( w, TRUE, TRUE, 0 ); + w.connect( "clicked", + G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDNO ) ); + w.show(); + + w = ui::Button( "Cancel" ); + hbox.pack_start( w, TRUE, TRUE, 0 ); + w.connect( "clicked", + G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) ); + w.show(); + ret = IDCANCEL; + } + else /* if (mode == MB_YESNO) */ + { + w = ui::Button( "Yes" ); + hbox.pack_start( w, TRUE, TRUE, 0 ); + w.connect( "clicked", + G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDYES ) ); + gtk_widget_set_can_default( w, true ); + gtk_widget_grab_default( w ); + w.show(); + + w = ui::Button( "No" ); + hbox.pack_start( w, TRUE, TRUE, 0 ); + w.connect( "clicked", + G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDNO ) ); + w.show(); + ret = IDNO; + } + + window.show(); + gtk_grab_add( window ); + + while ( loop ) + gtk_main_iteration(); + + gtk_grab_remove( window ); + gtk_widget_destroy( window ); + + return ret; } // Radiant function table @@ -181,736 +175,685 @@ IWindow *g_pToolWnd = NULL; // handle to the window CWindowListener g_Listen; // plugin interfaces --------------------------- -bool g_bQglInitDone = false; -OpenGLBinding g_QglTable; -bool g_bSelectedFaceInitDone = false; -_QERSelectedFaceTable g_SelectedFaceTable; -bool g_bUITable = false; -_QERUITable g_UITable; +bool g_bQglInitDone = false; +OpenGLBinding g_QglTable; +bool g_bSelectedFaceInitDone = false; +_QERSelectedFaceTable g_SelectedFaceTable; +bool g_bUITable = false; +_QERUITable g_UITable; // selected face ------------------------------- // we use this one to commit / read with Radiant -_QERFaceData g_SelectedFaceData; +_QERFaceData g_SelectedFaceData; // g_pSelectedFaceWindings gets allocated with MAX_POINTS_ON_WINDING at plugin startup ( QERPlug_Init ) -winding_t *g_pSelectedFaceWinding = NULL; -const float g_ViewportRatio = 1.2f; +winding_t *g_pSelectedFaceWinding = NULL; +const float g_ViewportRatio = 1.2f; // usefull class to manage the 2D view -C2DView g_2DView; +C2DView g_2DView; // control points to move the polygon -CControlPointsManagerBFace g_ControlPointsBFace; +CControlPointsManagerBFace g_ControlPointsBFace; // tells if a face is selected and we have something to render in the TexWindow -bool g_bTexViewReady = false; +bool g_bTexViewReady = false; // data for texture work -int g_NumPoints; -CtrlPts_t g_WorkWinding; +int g_NumPoints; +CtrlPts_t g_WorkWinding; // reference _QERFaceData we use on Cancel, and for Commit -_QERFaceData g_CancelFaceData; +_QERFaceData g_CancelFaceData; // patches ------------------------------------- -bool g_bPatch = false; +bool g_bPatch = false; //++timo we use this one to grab selected patchMesh_t // FIXME: update when there's a real interface to read/write patches -bool g_bSurfaceTableInitDone = false; -_QERAppSurfaceTable g_SurfaceTable; -CControlPointsManagerPatch g_ControlPointsPatch; +bool g_bSurfaceTableInitDone = false; +_QERAppSurfaceTable g_SurfaceTable; +CControlPointsManagerPatch g_ControlPointsPatch; // data for texture work -patchMesh_t* g_pPatch; +patchMesh_t* g_pPatch; // we only use ctrl[][].st in this one -patchMesh_t g_WorkPatch; +patchMesh_t g_WorkPatch; // copy of initial g_pPatch for Cancel situation -patchMesh_t g_CancelPatch; +patchMesh_t g_CancelPatch; // --------------------------------------------- // holds the manager we are currently using -CControlPointsManager *g_pManager = NULL; +CControlPointsManager *g_pManager = NULL; // --------------------------------------------- // globals flags for user preferences //++timo TODO: this should be retrieved from the Editor's .INI prefs in a dedicated interface // update camera view during manipulation ? -bool g_bPrefsUpdateCameraView = true; +bool g_bPrefsUpdateCameraView = true; // misc ---------------------------------------- -bool g_bHelp = false; +bool g_bHelp = false; //++timo FIXME: used to close the plugin window if InitTexView fails // it's dirty, only use is to prevent infinite loop in DialogProc -bool g_bClosing = false; +bool g_bClosing = false; const char *PLUGIN_ABOUT = "Texture Tools for Radiant\n\n" - "Gtk port by Leonardo Zide (leo@lokigames.com)\n" - "Original version by Timothee \"TTimo\" Besset (timo@qeradiant.com)"; + "Gtk port by Leonardo Zide (leo@lokigames.com)\n" + "Original version by Timothee \"TTimo\" Besset (timo@qeradiant.com)"; -extern "C" void* WINAPI QERPlug_GetFuncTable () -{ - return &g_FuncTable; +extern "C" void* WINAPI QERPlug_GetFuncTable(){ + return &g_FuncTable; } -const char* QERPlug_Init (void* hApp, void *pWidget) -{ - int size; - GtkWidget* pMainWidget = static_cast(pWidget); +const char* QERPlug_Init( void* hApp, void *pWidget ){ + int size; + GtkWidget* pMainWidget = static_cast( pWidget ); - g_pMainWnd = pMainWidget; - memset(&g_FuncTable, 0, sizeof(_QERFuncTable_1)); - g_FuncTable.m_nSize = sizeof(_QERFuncTable_1); - size = (int)((winding_t *)0)->points[MAX_POINTS_ON_WINDING]; - g_pSelectedFaceWinding = (winding_t *)malloc( size ); - memset( g_pSelectedFaceWinding, 0, size ); - return "Texture tools for Radiant"; + g_pMainWnd = pMainWidget; + memset( &g_FuncTable, 0, sizeof( _QERFuncTable_1 ) ); + g_FuncTable.m_nSize = sizeof( _QERFuncTable_1 ); + size = (int)( (winding_t *)0 )->points[MAX_POINTS_ON_WINDING]; + g_pSelectedFaceWinding = (winding_t *)malloc( size ); + memset( g_pSelectedFaceWinding, 0, size ); + return "Texture tools for Radiant"; } -const char* QERPlug_GetName() -{ - return (char*)PLUGIN_NAME; +const char* QERPlug_GetName(){ + return (char*)PLUGIN_NAME; } -const char* QERPlug_GetCommandList() -{ - return PLUGIN_COMMANDS; +const char* QERPlug_GetCommandList(){ + return PLUGIN_COMMANDS; } -char *TranslateString (char *buf) -{ - static char buf2[32768]; - int i, l; - char *out; +char *TranslateString( char *buf ){ + static char buf2[32768]; + int i, l; + char *out; - l = strlen(buf); - out = buf2; - for (i=0 ; igetHeight(); - g_2DView.m_rect.right = hwndDlg->getWidth(); - - // we need to draw this area, now compute a bigger area so the texture scale is the same along X and Y - // compute box shape in XY space, let's say X <-> S we'll get a ratio for Y: - if (!g_bPatch) - { - g_SelectedFaceTable.m_pfnGetTextureSize( 0, TexSize ); - } - else - { - TexSize[0] = g_pPatch->d_texture->width; - TexSize[1] = g_pPatch->d_texture->height; - } - // we want a texture with the same X / Y ratio - // compute XY space / window size ratio - float SSize = (float)fabs( g_2DView.m_Maxs[0] - g_2DView.m_Mins[0] ); - float TSize = (float)fabs( g_2DView.m_Maxs[1] - g_2DView.m_Mins[1] ); - float XSize = TexSize[0] * SSize; - float YSize = TexSize[1] * TSize; - float RatioX = XSize / (float)abs( g_2DView.m_rect.left - g_2DView.m_rect.right ); - float RatioY = YSize / (float)abs( g_2DView.m_rect.top - g_2DView.m_rect.bottom ); - if ( RatioX > RatioY ) - { - YSize = (float)abs( g_2DView.m_rect.top - g_2DView.m_rect.bottom ) * RatioX; - TSize = YSize / (float)TexSize[1]; - } - else - { - XSize = (float)abs( g_2DView.m_rect.left - g_2DView.m_rect.right ) * RatioY; - SSize = XSize / (float)TexSize[0]; - } - g_2DView.m_Mins[0] = g_2DView.m_Center[0] - 0.5f * SSize; - g_2DView.m_Maxs[0] = g_2DView.m_Center[0] + 0.5f * SSize; - g_2DView.m_Mins[1] = g_2DView.m_Center[1] - 0.5f * TSize; - g_2DView.m_Maxs[1] = g_2DView.m_Center[1] + 0.5f * TSize; +void FitView( IWindow* hwndDlg, int TexSize[2] ){ + // apply a ratio to get the area we'll draw + g_2DView.m_Center[0] = 0.5f * ( g_2DView.m_Mins[0] + g_2DView.m_Maxs[0] ); + g_2DView.m_Center[1] = 0.5f * ( g_2DView.m_Mins[1] + g_2DView.m_Maxs[1] ); + g_2DView.m_Mins[0] = g_2DView.m_Center[0] + g_ViewportRatio * ( g_2DView.m_Mins[0] - g_2DView.m_Center[0] ); + g_2DView.m_Mins[1] = g_2DView.m_Center[1] + g_ViewportRatio * ( g_2DView.m_Mins[1] - g_2DView.m_Center[1] ); + g_2DView.m_Maxs[0] = g_2DView.m_Center[0] + g_ViewportRatio * ( g_2DView.m_Maxs[0] - g_2DView.m_Center[0] ); + g_2DView.m_Maxs[1] = g_2DView.m_Center[1] + g_ViewportRatio * ( g_2DView.m_Maxs[1] - g_2DView.m_Center[1] ); + + g_2DView.m_rect.left = 0; + g_2DView.m_rect.top = 0; + g_2DView.m_rect.bottom = hwndDlg->getHeight(); + g_2DView.m_rect.right = hwndDlg->getWidth(); + + // we need to draw this area, now compute a bigger area so the texture scale is the same along X and Y + // compute box shape in XY space, let's say X <-> S we'll get a ratio for Y: + if ( !g_bPatch ) { + g_SelectedFaceTable.m_pfnGetTextureSize( 0, TexSize ); + } + else + { + TexSize[0] = g_pPatch->d_texture->width; + TexSize[1] = g_pPatch->d_texture->height; + } + // we want a texture with the same X / Y ratio + // compute XY space / window size ratio + float SSize = (float)fabs( g_2DView.m_Maxs[0] - g_2DView.m_Mins[0] ); + float TSize = (float)fabs( g_2DView.m_Maxs[1] - g_2DView.m_Mins[1] ); + float XSize = TexSize[0] * SSize; + float YSize = TexSize[1] * TSize; + float RatioX = XSize / (float)abs( g_2DView.m_rect.left - g_2DView.m_rect.right ); + float RatioY = YSize / (float)abs( g_2DView.m_rect.top - g_2DView.m_rect.bottom ); + if ( RatioX > RatioY ) { + YSize = (float)abs( g_2DView.m_rect.top - g_2DView.m_rect.bottom ) * RatioX; + TSize = YSize / (float)TexSize[1]; + } + else + { + XSize = (float)abs( g_2DView.m_rect.left - g_2DView.m_rect.right ) * RatioY; + SSize = XSize / (float)TexSize[0]; + } + g_2DView.m_Mins[0] = g_2DView.m_Center[0] - 0.5f * SSize; + g_2DView.m_Maxs[0] = g_2DView.m_Center[0] + 0.5f * SSize; + g_2DView.m_Mins[1] = g_2DView.m_Center[1] - 0.5f * TSize; + g_2DView.m_Maxs[1] = g_2DView.m_Center[1] + 0.5f * TSize; } // call this one each time we need to re-init //++timo TODO: re-init objects state, g_2DView and g_ControlPointsManager -void InitTexView( IWindow* hwndDlg ) -{ - // size of the texture we are working on - int TexSize[2]; - g_bTexViewReady = false; - if (g_SelectedFaceTable.m_pfnGetSelectedFaceCount() != 0) - { - g_SelectedFaceTable.m_pfnGetFaceInfo( 0, &g_SelectedFaceData, g_pSelectedFaceWinding ); - g_bPatch = false; - int i; - // we have something selected - // setup: compute BBox for the winding ( in ST space ) - //++timo FIXME: move this in a C2DView member ? used as well for patches - g_2DView.m_Mins[0] = +9999.0f; g_2DView.m_Mins[1] = +9999.0f; - g_2DView.m_Maxs[0] = -9999.0f; g_2DView.m_Maxs[1] = -9999.0f; - for ( i=0; inumpoints; i++ ) - { - if ( g_pSelectedFaceWinding->points[i][3] < g_2DView.m_Mins[0] ) - g_2DView.m_Mins[0] = g_pSelectedFaceWinding->points[i][3]; - if ( g_pSelectedFaceWinding->points[i][3] > g_2DView.m_Maxs[0] ) - g_2DView.m_Maxs[0] = g_pSelectedFaceWinding->points[i][3]; - if ( g_pSelectedFaceWinding->points[i][4] < g_2DView.m_Mins[1] ) - g_2DView.m_Mins[1] = g_pSelectedFaceWinding->points[i][4]; - if ( g_pSelectedFaceWinding->points[i][4] > g_2DView.m_Maxs[1] ) - g_2DView.m_Maxs[1] = g_pSelectedFaceWinding->points[i][4]; - } - // NOTE: FitView will read and init TexSize - FitView( hwndDlg, TexSize ); - // now init the work tables - g_NumPoints = g_pSelectedFaceWinding->numpoints; - for ( i=0; ipoints[i][3]; - g_WorkWinding.data[i][1] = g_pSelectedFaceWinding->points[i][4]; - } - g_ControlPointsBFace.Init( g_NumPoints, &g_WorkWinding, &g_2DView, TexSize, &g_SelectedFaceData, &g_QglTable ); - // init snap-to-grid - float fTexStep[2]; - fTexStep[0] = 1.0f / float(TexSize[0]); - fTexStep[1] = 1.0f / float(TexSize[1]); - g_2DView.SetGrid( fTexStep[0], fTexStep[1] ); - g_pManager = &g_ControlPointsBFace; - // prepare the "Cancel" data - memcpy( &g_CancelFaceData, &g_SelectedFaceData, sizeof(_QERFaceData) ); - // we are done - g_bTexViewReady = true; - } - else if ( g_SurfaceTable.m_pfnAnyPatchesSelected()) - { - g_pPatch = g_SurfaceTable.m_pfnGetSelectedPatch(); - g_bPatch = true; - int i,j; - // compute BBox for all patch points - g_2DView.m_Mins[0] = +9999.0f; g_2DView.m_Mins[1] = +9999.0f; - g_2DView.m_Maxs[0] = -9999.0f; g_2DView.m_Maxs[1] = -9999.0f; - for ( i=0; iwidth; i++ ) - { - for ( j=0; jheight; j++ ) - { - if ( g_pPatch->ctrl[i][j].st[0] < g_2DView.m_Mins[0] ) - g_2DView.m_Mins[0] = g_pPatch->ctrl[i][j].st[0]; - if ( g_pPatch->ctrl[i][j].st[0] > g_2DView.m_Maxs[0] ) - g_2DView.m_Maxs[0] = g_pPatch->ctrl[i][j].st[0]; - if ( g_pPatch->ctrl[i][j].st[1] < g_2DView.m_Mins[1] ) - g_2DView.m_Mins[1] = g_pPatch->ctrl[i][j].st[1]; - if ( g_pPatch->ctrl[i][j].st[1] > g_2DView.m_Maxs[1] ) - g_2DView.m_Maxs[1] = g_pPatch->ctrl[i][j].st[1]; - } - } - FitView( hwndDlg, TexSize); - // init the work tables - g_WorkPatch = *g_pPatch; - g_ControlPointsPatch.Init( &g_WorkPatch, &g_2DView, &g_QglTable, g_pPatch ); - // init snap-to-grid - float fTexStep[2]; - fTexStep[0] = 1.0f / float(TexSize[0]); - fTexStep[1] = 1.0f / float(TexSize[1]); - g_2DView.SetGrid( fTexStep[0], fTexStep[1] ); - g_pManager = &g_ControlPointsPatch; - // prepare the "cancel" data - g_CancelPatch = *g_pPatch; - // we are done - g_bTexViewReady = true; - } -} - -void Textool_Validate() -{ - // validate current situation into the main view - g_pManager->Commit( ); - // for a brush face we have an aditionnal step - if (!g_bPatch) - { - // tell Radiant to update (will also send update windows messages ) - g_SelectedFaceTable.m_pfnSetFaceInfo( 0, &g_SelectedFaceData ); - } - else - { - // ask to rebuild the patch display data - g_pPatch->bDirty = true; - // send a repaint to the camera window as well - g_FuncTable.m_pfnSysUpdateWindows( W_CAMERA ); - } - // we'll need to update after that as well: - g_bTexViewReady = false; - // send a repaint message - g_pToolWnd->Redraw (); -} - -void Textool_Cancel() -{ - if (!g_bPatch) - { - // tell Radiant to update (will also send update windows messages ) - g_SelectedFaceTable.m_pfnSetFaceInfo( 0, &g_CancelFaceData ); - } - else - { - *g_pPatch = g_CancelPatch; - g_pPatch->bDirty = true; - g_FuncTable.m_pfnSysUpdateWindows( W_CAMERA ); - } - // do not call destroy, decref it - g_pToolWnd->DecRef(); - g_pToolWnd = NULL; -} - -static void DoExpose () -{ - int i,j; - - g_2DView.PreparePaint(); - g_QglTable.m_pfn_qglColor3f(1, 1, 1); - // draw the texture background - g_QglTable.m_pfn_qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - if (!g_bPatch) - { - g_QglTable.m_pfn_qglBindTexture( GL_TEXTURE_2D, g_SelectedFaceTable.m_pfnGetTextureNumber(0) ); - } - else - { - g_QglTable.m_pfn_qglBindTexture( GL_TEXTURE_2D, g_pPatch->d_texture->texture_number ); - } - - g_QglTable.m_pfn_qglEnable( GL_TEXTURE_2D ); - g_QglTable.m_pfn_qglBegin( GL_QUADS ); - g_QglTable.m_pfn_qglTexCoord2f( g_2DView.m_Mins[0], g_2DView.m_Mins[1] ); - g_QglTable.m_pfn_qglVertex2f( g_2DView.m_Mins[0], g_2DView.m_Mins[1] ); - g_QglTable.m_pfn_qglTexCoord2f( g_2DView.m_Maxs[0], g_2DView.m_Mins[1] ); - g_QglTable.m_pfn_qglVertex2f( g_2DView.m_Maxs[0], g_2DView.m_Mins[1] ); - g_QglTable.m_pfn_qglTexCoord2f( g_2DView.m_Maxs[0], g_2DView.m_Maxs[1] ); - g_QglTable.m_pfn_qglVertex2f( g_2DView.m_Maxs[0], g_2DView.m_Maxs[1] ); - g_QglTable.m_pfn_qglTexCoord2f( g_2DView.m_Mins[0], g_2DView.m_Maxs[1] ); - g_QglTable.m_pfn_qglVertex2f( g_2DView.m_Mins[0], g_2DView.m_Maxs[1] ); - g_QglTable.m_pfn_qglEnd(); - g_QglTable.m_pfn_qglDisable( GL_TEXTURE_2D ); - - if (!g_bPatch) - { - g_QglTable.m_pfn_qglBegin( GL_LINE_LOOP ); - for ( i=0; iwidth; i++ ) - for ( j=0; jheight; j++ ) - { - if ( i < g_pPatch->width-1 ) +void InitTexView( IWindow* hwndDlg ){ + // size of the texture we are working on + int TexSize[2]; + g_bTexViewReady = false; + if ( g_SelectedFaceTable.m_pfnGetSelectedFaceCount() != 0 ) { + g_SelectedFaceTable.m_pfnGetFaceInfo( 0, &g_SelectedFaceData, g_pSelectedFaceWinding ); + g_bPatch = false; + int i; + // we have something selected + // setup: compute BBox for the winding ( in ST space ) + //++timo FIXME: move this in a C2DView member ? used as well for patches + g_2DView.m_Mins[0] = +9999.0f; g_2DView.m_Mins[1] = +9999.0f; + g_2DView.m_Maxs[0] = -9999.0f; g_2DView.m_Maxs[1] = -9999.0f; + for ( i = 0; i < g_pSelectedFaceWinding->numpoints; i++ ) + { + if ( g_pSelectedFaceWinding->points[i][3] < g_2DView.m_Mins[0] ) { + g_2DView.m_Mins[0] = g_pSelectedFaceWinding->points[i][3]; + } + if ( g_pSelectedFaceWinding->points[i][3] > g_2DView.m_Maxs[0] ) { + g_2DView.m_Maxs[0] = g_pSelectedFaceWinding->points[i][3]; + } + if ( g_pSelectedFaceWinding->points[i][4] < g_2DView.m_Mins[1] ) { + g_2DView.m_Mins[1] = g_pSelectedFaceWinding->points[i][4]; + } + if ( g_pSelectedFaceWinding->points[i][4] > g_2DView.m_Maxs[1] ) { + g_2DView.m_Maxs[1] = g_pSelectedFaceWinding->points[i][4]; + } + } + // NOTE: FitView will read and init TexSize + FitView( hwndDlg, TexSize ); + // now init the work tables + g_NumPoints = g_pSelectedFaceWinding->numpoints; + for ( i = 0; i < g_NumPoints; i++ ) + { + g_WorkWinding.data[i][0] = g_pSelectedFaceWinding->points[i][3]; + g_WorkWinding.data[i][1] = g_pSelectedFaceWinding->points[i][4]; + } + g_ControlPointsBFace.Init( g_NumPoints, &g_WorkWinding, &g_2DView, TexSize, &g_SelectedFaceData, &g_QglTable ); + // init snap-to-grid + float fTexStep[2]; + fTexStep[0] = 1.0f / float(TexSize[0]); + fTexStep[1] = 1.0f / float(TexSize[1]); + g_2DView.SetGrid( fTexStep[0], fTexStep[1] ); + g_pManager = &g_ControlPointsBFace; + // prepare the "Cancel" data + memcpy( &g_CancelFaceData, &g_SelectedFaceData, sizeof( _QERFaceData ) ); + // we are done + g_bTexViewReady = true; + } + else if ( g_SurfaceTable.m_pfnAnyPatchesSelected() ) { + g_pPatch = g_SurfaceTable.m_pfnGetSelectedPatch(); + g_bPatch = true; + int i,j; + // compute BBox for all patch points + g_2DView.m_Mins[0] = +9999.0f; g_2DView.m_Mins[1] = +9999.0f; + g_2DView.m_Maxs[0] = -9999.0f; g_2DView.m_Maxs[1] = -9999.0f; + for ( i = 0; i < g_pPatch->width; i++ ) + { + for ( j = 0; j < g_pPatch->height; j++ ) + { + if ( g_pPatch->ctrl[i][j].st[0] < g_2DView.m_Mins[0] ) { + g_2DView.m_Mins[0] = g_pPatch->ctrl[i][j].st[0]; + } + if ( g_pPatch->ctrl[i][j].st[0] > g_2DView.m_Maxs[0] ) { + g_2DView.m_Maxs[0] = g_pPatch->ctrl[i][j].st[0]; + } + if ( g_pPatch->ctrl[i][j].st[1] < g_2DView.m_Mins[1] ) { + g_2DView.m_Mins[1] = g_pPatch->ctrl[i][j].st[1]; + } + if ( g_pPatch->ctrl[i][j].st[1] > g_2DView.m_Maxs[1] ) { + g_2DView.m_Maxs[1] = g_pPatch->ctrl[i][j].st[1]; + } + } + } + FitView( hwndDlg, TexSize ); + // init the work tables + g_WorkPatch = *g_pPatch; + g_ControlPointsPatch.Init( &g_WorkPatch, &g_2DView, &g_QglTable, g_pPatch ); + // init snap-to-grid + float fTexStep[2]; + fTexStep[0] = 1.0f / float(TexSize[0]); + fTexStep[1] = 1.0f / float(TexSize[1]); + g_2DView.SetGrid( fTexStep[0], fTexStep[1] ); + g_pManager = &g_ControlPointsPatch; + // prepare the "cancel" data + g_CancelPatch = *g_pPatch; + // we are done + g_bTexViewReady = true; + } +} + +void Textool_Validate(){ + // validate current situation into the main view + g_pManager->Commit(); + // for a brush face we have an aditionnal step + if ( !g_bPatch ) { + // tell Radiant to update (will also send update windows messages ) + g_SelectedFaceTable.m_pfnSetFaceInfo( 0, &g_SelectedFaceData ); + } + else { - g_QglTable.m_pfn_qglVertex2f( g_WorkPatch.ctrl[i][j].st[0], g_WorkPatch.ctrl[i][j].st[1] ); - g_QglTable.m_pfn_qglVertex2f( g_WorkPatch.ctrl[i+1][j].st[0], g_WorkPatch.ctrl[i+1][j].st[1] ); + // ask to rebuild the patch display data + g_pPatch->bDirty = true; + // send a repaint to the camera window as well + g_FuncTable.m_pfnSysUpdateWindows( W_CAMERA ); } + // we'll need to update after that as well: + g_bTexViewReady = false; + // send a repaint message + g_pToolWnd->Redraw(); +} - if ( j < g_pPatch->height-1 ) +void Textool_Cancel(){ + if ( !g_bPatch ) { + // tell Radiant to update (will also send update windows messages ) + g_SelectedFaceTable.m_pfnSetFaceInfo( 0, &g_CancelFaceData ); + } + else { - g_QglTable.m_pfn_qglVertex2f( g_WorkPatch.ctrl[i][j].st[0], g_WorkPatch.ctrl[i][j].st[1] ); - g_QglTable.m_pfn_qglVertex2f( g_WorkPatch.ctrl[i][j+1].st[0], g_WorkPatch.ctrl[i][j+1].st[1] ); - } - } - g_QglTable.m_pfn_qglEnd(); - } - - // let the control points manager render - g_pManager->render( ); -} - -static bool CanProcess () -{ - if (!g_bTexViewReady && !g_bClosing) - { - InitTexView (g_pToolWnd); - - if (!g_bTexViewReady) - { - g_bClosing = true; - DoMessageBox ("You must have brush primitives activated in your project settings and\n" - "have a patch or a single face selected to use the TexTool plugin.\n" - "See plugins/TexToolHelp for documentation.", "TexTool plugin", MB_ICONERROR | MB_OK); - // decref, this will destroy - g_pToolWnd->DecRef(); - g_pToolWnd = NULL; - return 0; - } - else - g_bClosing = false; - } - else if (!g_bTexViewReady && g_bClosing) - { - return 0; - } - - return 1; + *g_pPatch = g_CancelPatch; + g_pPatch->bDirty = true; + g_FuncTable.m_pfnSysUpdateWindows( W_CAMERA ); + } + // do not call destroy, decref it + g_pToolWnd->DecRef(); + g_pToolWnd = NULL; +} + +static void DoExpose(){ + int i,j; + + g_2DView.PreparePaint(); + g_QglTable.m_pfn_qglColor3f( 1, 1, 1 ); + // draw the texture background + g_QglTable.m_pfn_qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + if ( !g_bPatch ) { + g_QglTable.m_pfn_qglBindTexture( GL_TEXTURE_2D, g_SelectedFaceTable.m_pfnGetTextureNumber( 0 ) ); + } + else + { + g_QglTable.m_pfn_qglBindTexture( GL_TEXTURE_2D, g_pPatch->d_texture->texture_number ); + } + + g_QglTable.m_pfn_qglEnable( GL_TEXTURE_2D ); + g_QglTable.m_pfn_qglBegin( GL_QUADS ); + g_QglTable.m_pfn_qglTexCoord2f( g_2DView.m_Mins[0], g_2DView.m_Mins[1] ); + g_QglTable.m_pfn_qglVertex2f( g_2DView.m_Mins[0], g_2DView.m_Mins[1] ); + g_QglTable.m_pfn_qglTexCoord2f( g_2DView.m_Maxs[0], g_2DView.m_Mins[1] ); + g_QglTable.m_pfn_qglVertex2f( g_2DView.m_Maxs[0], g_2DView.m_Mins[1] ); + g_QglTable.m_pfn_qglTexCoord2f( g_2DView.m_Maxs[0], g_2DView.m_Maxs[1] ); + g_QglTable.m_pfn_qglVertex2f( g_2DView.m_Maxs[0], g_2DView.m_Maxs[1] ); + g_QglTable.m_pfn_qglTexCoord2f( g_2DView.m_Mins[0], g_2DView.m_Maxs[1] ); + g_QglTable.m_pfn_qglVertex2f( g_2DView.m_Mins[0], g_2DView.m_Maxs[1] ); + g_QglTable.m_pfn_qglEnd(); + g_QglTable.m_pfn_qglDisable( GL_TEXTURE_2D ); + + if ( !g_bPatch ) { + g_QglTable.m_pfn_qglBegin( GL_LINE_LOOP ); + for ( i = 0; i < g_NumPoints; i++ ) + { + g_QglTable.m_pfn_qglVertex2f( g_WorkWinding.data[i][0], g_WorkWinding.data[i][1] ); + } + g_QglTable.m_pfn_qglEnd(); + } + else + { + g_QglTable.m_pfn_qglBegin( GL_LINES ); + for ( i = 0; i < g_pPatch->width; i++ ) + for ( j = 0; j < g_pPatch->height; j++ ) + { + if ( i < g_pPatch->width - 1 ) { + g_QglTable.m_pfn_qglVertex2f( g_WorkPatch.ctrl[i][j].st[0], g_WorkPatch.ctrl[i][j].st[1] ); + g_QglTable.m_pfn_qglVertex2f( g_WorkPatch.ctrl[i + 1][j].st[0], g_WorkPatch.ctrl[i + 1][j].st[1] ); + } + + if ( j < g_pPatch->height - 1 ) { + g_QglTable.m_pfn_qglVertex2f( g_WorkPatch.ctrl[i][j].st[0], g_WorkPatch.ctrl[i][j].st[1] ); + g_QglTable.m_pfn_qglVertex2f( g_WorkPatch.ctrl[i][j + 1].st[0], g_WorkPatch.ctrl[i][j + 1].st[1] ); + } + } + g_QglTable.m_pfn_qglEnd(); + } + + // let the control points manager render + g_pManager->render(); +} + +static bool CanProcess(){ + if ( !g_bTexViewReady && !g_bClosing ) { + InitTexView( g_pToolWnd ); + + if ( !g_bTexViewReady ) { + g_bClosing = true; + DoMessageBox( "You must have brush primitives activated in your project settings and\n" + "have a patch or a single face selected to use the TexTool plugin.\n" + "See plugins/TexToolHelp for documentation.", "TexTool plugin", MB_ICONERROR | MB_OK ); + // decref, this will destroy + g_pToolWnd->DecRef(); + g_pToolWnd = NULL; + return 0; + } + else{ + g_bClosing = false; + } + } + else if ( !g_bTexViewReady && g_bClosing ) { + return 0; + } + + return 1; } #if 0 -static void button_press (GtkWidget *widget, GdkEventButton *event, gpointer data) -{ - if (CanProcess ()) - { - switch (event->button) - { - case 1: - g_pManager->OnLButtonDown (event->x, event->y); break; - case 3: - g_2DView.OnRButtonDown (event->x, event->y); break; - } - } -} - -static void button_release (GtkWidget *widget, GdkEventButton *event, gpointer data) -{ - if (CanProcess ()) - { - switch (event->button) - { - case 1: - g_pManager->OnLButtonUp (event->x, event->y); break; - case 3: - g_2DView.OnRButtonUp (event->x, event->y); break; - } - } -} - -static void motion (GtkWidget *widget, GdkEventMotion *event, gpointer data) -{ - if (CanProcess ()) - { - if (g_2DView.OnMouseMove (event->x, event->y)) - return; - - if (g_pManager->OnMouseMove (event->x, event->y)) - return; - } -} - -static gint expose (GtkWidget *widget, GdkEventExpose *event, gpointer data) -{ - if (event->count > 0) - return TRUE; - - if (!CanProcess ()) - return TRUE; - - if (g_bTexViewReady) - { - g_2DView.m_rect.bottom = widget->allocation.height; - g_2DView.m_rect.right = widget->allocation.width; - - if (!g_QglTable.m_pfn_glwidget_make_current (g_pToolWidget)) - { - Sys_Printf("TexTool: glMakeCurrent failed\n"); - return TRUE; - } - - DoExpose (); - - g_QglTable.m_pfn_glwidget_swap_buffers (g_pToolWidget); - } - - return TRUE; -} - -static gint keypress (GtkWidget* widget, GdkEventKey* event, gpointer data) -{ - unsigned int code = gdk_keyval_to_upper(event->keyval); - - if (code == GDK_Escape) - { - gtk_widget_destroy (g_pToolWnd); - g_pToolWnd = NULL; - return TRUE; - } - - if (CanProcess ()) - { - if (g_2DView.OnKeyDown (code)) - return FALSE; - - if (code == GDK_Return) - { - Textool_Validate(); - return FALSE; - } - } - - return TRUE; -} - -static gint close (GtkWidget *widget, GdkEvent* event, gpointer data) -{ - gtk_widget_destroy (widget); - g_pToolWnd = NULL; - - return TRUE; -} - -static GtkWidget* CreateOpenGLWidget () -{ - g_pToolWidget = g_QglTable.m_pfn_glwidget_new (FALSE, g_QglTable.m_pfn_GetQeglobalsGLWidget ()); +static void button_press( GtkWidget *widget, GdkEventButton *event, gpointer data ){ + if ( CanProcess() ) { + switch ( event->button ) + { + case 1: + g_pManager->OnLButtonDown( event->x, event->y ); break; + case 3: + g_2DView.OnRButtonDown( event->x, event->y ); break; + } + } +} + +static void button_release( GtkWidget *widget, GdkEventButton *event, gpointer data ){ + if ( CanProcess() ) { + switch ( event->button ) + { + case 1: + g_pManager->OnLButtonUp( event->x, event->y ); break; + case 3: + g_2DView.OnRButtonUp( event->x, event->y ); break; + } + } +} + +static void motion( GtkWidget *widget, GdkEventMotion *event, gpointer data ){ + if ( CanProcess() ) { + if ( g_2DView.OnMouseMove( event->x, event->y ) ) { + return; + } + + if ( g_pManager->OnMouseMove( event->x, event->y ) ) { + return; + } + } +} + +static gint expose( GtkWidget *widget, GdkEventExpose *event, gpointer data ){ + if ( event->count > 0 ) { + return TRUE; + } + + if ( !CanProcess() ) { + return TRUE; + } + + if ( g_bTexViewReady ) { + g_2DView.m_rect.bottom = widget->allocation.height; + g_2DView.m_rect.right = widget->allocation.width; - gtk_widget_set_events (g_pToolWidget, GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_KEY_PRESS_MASK | - GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK); + if ( !g_QglTable.m_pfn_glwidget_make_current( g_pToolWidget ) ) { + Sys_Printf( "TexTool: glMakeCurrent failed\n" ); + return TRUE; + } - // Connect signal handlers - gtk_signal_connect (GTK_OBJECT (g_pToolWidget), "expose_event", GTK_SIGNAL_FUNC (expose), NULL); - gtk_signal_connect (GTK_OBJECT (g_pToolWidget), "motion_notify_event", - GTK_SIGNAL_FUNC (motion), NULL); - gtk_signal_connect (GTK_OBJECT (g_pToolWidget), "button_press_event", - GTK_SIGNAL_FUNC (button_press), NULL); - gtk_signal_connect (GTK_OBJECT (g_pToolWidget), "button_release_event", - GTK_SIGNAL_FUNC (button_release), NULL); + DoExpose(); - gtk_signal_connect (GTK_OBJECT (g_pToolWnd), "delete_event", GTK_SIGNAL_FUNC (close), NULL); - gtk_signal_connect (GTK_OBJECT (g_pToolWnd), "key_press_event", - GTK_SIGNAL_FUNC (keypress), NULL); + g_QglTable.m_pfn_glwidget_swap_buffers( g_pToolWidget ); + } + + return TRUE; +} + +static gint keypress( GtkWidget* widget, GdkEventKey* event, gpointer data ){ + unsigned int code = gdk_keyval_to_upper( event->keyval ); + + if ( code == GDK_Escape ) { + gtk_widget_destroy( g_pToolWnd ); + g_pToolWnd = NULL; + return TRUE; + } + + if ( CanProcess() ) { + if ( g_2DView.OnKeyDown( code ) ) { + return FALSE; + } - return g_pToolWidget; + if ( code == GDK_Return ) { + Textool_Validate(); + return FALSE; + } + } + + return TRUE; +} + +static gint close( GtkWidget *widget, GdkEvent* event, gpointer data ){ + gtk_widget_destroy( widget ); + g_pToolWnd = NULL; + + return TRUE; +} + +static GtkWidget* CreateOpenGLWidget(){ + g_pToolWidget = g_QglTable.m_pfn_glwidget_new( FALSE, g_QglTable.m_pfn_GetQeglobalsGLWidget() ); + + gtk_widget_set_events( g_pToolWidget, GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_KEY_PRESS_MASK | + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK ); + + // Connect signal handlers + g_pToolWidget.connect( "expose_event", G_CALLBACK( expose ), NULL ); + g_pToolWidget.connect( "motion_notify_event", + G_CALLBACK( motion ), NULL ); + g_pToolWidget.connect( "button_press_event", + G_CALLBACK( button_press ), NULL ); + g_pToolWidget.connect( "button_release_event", + G_CALLBACK( button_release ), NULL ); + + g_pToolWnd.connect( "delete_event", G_CALLBACK( close ), NULL ); + g_pToolWnd.connect( "key_press_event", + G_CALLBACK( keypress ), NULL ); + + return g_pToolWidget; } #endif #if 0 -static void DoPaint () -{ - if (!CanProcess ()) - return; - - if (g_bTexViewReady) - { - g_2DView.m_rect.bottom = g_pToolWnd->getHeight(); - g_2DView.m_rect.right = g_pToolWnd->getWidth(); - - // set GL_PROJECTION - g_2DView.PreparePaint(); - // render the objects - // the master is not rendered the same way, draw over a unified texture background - g_2DView.TextureBackground(g_DrawObjects[0].pObject->getTextureNumber()); - if (g_nDrawObjects >= 1) - { - int i; - for (i=1;iPrepareModelView(g_DrawObjects[i].pTopo); - g_DrawObjects[i].pObject->RenderAuxiliary(); - } - } - // draw the polygon outline and control points - g_DrawObjects[0].pObject->PrepareModelView(NULL); - g_DrawObjects[0].pObject->RenderUI(); - } +static void DoPaint(){ + if ( !CanProcess() ) { + return; + } + + if ( g_bTexViewReady ) { + g_2DView.m_rect.bottom = g_pToolWnd->getHeight(); + g_2DView.m_rect.right = g_pToolWnd->getWidth(); + + // set GL_PROJECTION + g_2DView.PreparePaint(); + // render the objects + // the master is not rendered the same way, draw over a unified texture background + g_2DView.TextureBackground( g_DrawObjects[0].pObject->getTextureNumber() ); + if ( g_nDrawObjects >= 1 ) { + int i; + for ( i = 1; i < g_nDrawObjects; i++ ) + { + // we use a first step to the GL_MODELVIEW for the master object + // GL_MODELVIEW will be altered in RenderAuxiliary too + g_DrawObjects[0].pObject->PrepareModelView( g_DrawObjects[i].pTopo ); + g_DrawObjects[i].pObject->RenderAuxiliary(); + } + } + // draw the polygon outline and control points + g_DrawObjects[0].pObject->PrepareModelView( NULL ); + g_DrawObjects[0].pObject->RenderUI(); + } } #endif -bool CWindowListener::OnLButtonDown(guint32 nFlags, double x, double y) -{ - if (CanProcess()) - { - g_pManager->OnLButtonDown((int)x, (int)y); - return true; - } - return false; -} - -bool CWindowListener::OnRButtonDown(guint32 nFlags, double x, double y) -{ - if (CanProcess()) - { - g_2DView.OnRButtonDown ((int)x, (int)y); - return true; - } - return false; -} - -bool CWindowListener::OnLButtonUp(guint32 nFlags, double x, double y) -{ - if (CanProcess()) - { - g_pManager->OnLButtonUp((int)x, (int)y); - return true; - } - return false; -} - -bool CWindowListener::OnRButtonUp(guint32 nFlags, double x, double y) -{ - if (CanProcess()) - { - g_2DView.OnRButtonUp ((int)x, (int)y); - return true; - } - return false; -} - -bool CWindowListener::OnMouseMove(guint32 nFlags, double x, double y) -{ - if (CanProcess ()) - { - if (g_2DView.OnMouseMove ((int)x, (int)y)) - return true; - - g_pManager->OnMouseMove((int)x, (int)y); - return true; - } - return false; +bool CWindowListener::OnLButtonDown( guint32 nFlags, double x, double y ){ + if ( CanProcess() ) { + g_pManager->OnLButtonDown( (int)x, (int)y ); + return true; + } + return false; } -// the widget is closing -void CWindowListener::Close() -{ - g_pToolWnd = NULL; +bool CWindowListener::OnRButtonDown( guint32 nFlags, double x, double y ){ + if ( CanProcess() ) { + g_2DView.OnRButtonDown( (int)x, (int)y ); + return true; + } + return false; } -bool CWindowListener::Paint() -{ - if (!CanProcess ()) - return false; +bool CWindowListener::OnLButtonUp( guint32 nFlags, double x, double y ){ + if ( CanProcess() ) { + g_pManager->OnLButtonUp( (int)x, (int)y ); + return true; + } + return false; +} - if (g_bTexViewReady) - DoExpose(); +bool CWindowListener::OnRButtonUp( guint32 nFlags, double x, double y ){ + if ( CanProcess() ) { + g_2DView.OnRButtonUp( (int)x, (int)y ); + return true; + } + return false; +} + +bool CWindowListener::OnMouseMove( guint32 nFlags, double x, double y ){ + if ( CanProcess() ) { + if ( g_2DView.OnMouseMove( (int)x, (int)y ) ) { + return true; + } - return true; + g_pManager->OnMouseMove( (int)x, (int)y ); + return true; + } + return false; } -bool CWindowListener::OnKeyPressed(char *s) -{ - if (!strcmp(s,"Escape")) - { - Textool_Cancel(); - return TRUE; - } - if (CanProcess ()) - { - if (g_2DView.OnKeyDown (s)) - return TRUE; +// the widget is closing +void CWindowListener::Close(){ + g_pToolWnd = NULL; +} + +bool CWindowListener::Paint(){ + if ( !CanProcess() ) { + return false; + } - if (!strcmp(s,"Return")) - { - Textool_Validate(); - return TRUE; - } - } - return FALSE; + if ( g_bTexViewReady ) { + DoExpose(); + } + + return true; +} + +bool CWindowListener::OnKeyPressed( char *s ){ + if ( !strcmp( s,"Escape" ) ) { + Textool_Cancel(); + return TRUE; + } + if ( CanProcess() ) { + if ( g_2DView.OnKeyDown( s ) ) { + return TRUE; + } + + if ( !strcmp( s,"Return" ) ) { + Textool_Validate(); + return TRUE; + } + } + return FALSE; } -extern "C" void QERPlug_Dispatch(const char* p, vec3_t vMin, vec3_t vMax, bool bSingleBrush) -{ +extern "C" void QERPlug_Dispatch( const char* p, vec3_t vMin, vec3_t vMax, bool bSingleBrush ){ #if 0 - // if it's the first call, perhaps we need some additional init steps - if (!g_bQglInitDone) - { - g_QglTable.m_nSize = sizeof(OpenGLBinding); - if ( g_FuncTable.m_pfnRequestInterface( QERQglTable_GUID, static_cast(&g_QglTable) ) ) - { - g_bQglInitDone = true; - } - else - { - Sys_Printf("TexTool plugin: OpenGLBinding interface request failed\n"); - return; - } - } - - if (!g_bSelectedFaceInitDone) - { - g_SelectedFaceTable.m_nSize = sizeof(_QERSelectedFaceTable); - if (g_FuncTable.m_pfnRequestInterface (QERSelectedFaceTable_GUID, - static_cast(&g_SelectedFaceTable))) - { - g_bSelectedFaceInitDone = true; - } - else - { - Sys_Printf("TexTool plugin: _QERSelectedFaceTable interface request failed\n"); - return; - } - } - - if (!g_bSurfaceTableInitDone) - { - g_SurfaceTable.m_nSize = sizeof(_QERAppSurfaceTable); - if ( g_FuncTable.m_pfnRequestInterface( QERAppSurfaceTable_GUID, static_cast(&g_SurfaceTable) ) ) - { - g_bSurfaceTableInitDone = true; - } - else - { - Sys_Printf("TexTool plugin: _QERAppSurfaceTable interface request failed\n"); - return; - } - } - - if (!g_bUITable) - { - g_UITable.m_nSize = sizeof(_QERUITable); - if ( g_FuncTable.m_pfnRequestInterface( QERUI_GUID, static_cast(&g_UITable) ) ) - { - g_bUITable = true; - } - else - { - Sys_Printf("TexTool plugin: _QERUITable interface request failed\n"); - return; - } - } + // if it's the first call, perhaps we need some additional init steps + if ( !g_bQglInitDone ) { + g_QglTable.m_nSize = sizeof( OpenGLBinding ); + if ( g_FuncTable.m_pfnRequestInterface( QERQglTable_GUID, static_cast( &g_QglTable ) ) ) { + g_bQglInitDone = true; + } + else + { + Sys_Printf( "TexTool plugin: OpenGLBinding interface request failed\n" ); + return; + } + } + + if ( !g_bSelectedFaceInitDone ) { + g_SelectedFaceTable.m_nSize = sizeof( _QERSelectedFaceTable ); + if ( g_FuncTable.m_pfnRequestInterface( QERSelectedFaceTable_GUID, + static_cast( &g_SelectedFaceTable ) ) ) { + g_bSelectedFaceInitDone = true; + } + else + { + Sys_Printf( "TexTool plugin: _QERSelectedFaceTable interface request failed\n" ); + return; + } + } + + if ( !g_bSurfaceTableInitDone ) { + g_SurfaceTable.m_nSize = sizeof( _QERAppSurfaceTable ); + if ( g_FuncTable.m_pfnRequestInterface( QERAppSurfaceTable_GUID, static_cast( &g_SurfaceTable ) ) ) { + g_bSurfaceTableInitDone = true; + } + else + { + Sys_Printf( "TexTool plugin: _QERAppSurfaceTable interface request failed\n" ); + return; + } + } + + if ( !g_bUITable ) { + g_UITable.m_nSize = sizeof( _QERUITable ); + if ( g_FuncTable.m_pfnRequestInterface( QERUI_GUID, static_cast( &g_UITable ) ) ) { + g_bUITable = true; + } + else + { + Sys_Printf( "TexTool plugin: _QERUITable interface request failed\n" ); + return; + } + } #endif - if (!strcmp(p, "About...")) - { - DoMessageBox (PLUGIN_ABOUT, "About ...", MB_OK ); - } - else if (!strcmp(p, "Go...")) - { - if (!g_pToolWnd) - { - g_pToolWnd = g_UITable.m_pfnCreateGLWindow(); - g_pToolWnd->setSizeParm(300,300); - g_pToolWnd->setName("TexTool"); - // g_Listener is a static class, we need to bump the refCount to avoid premature release problems - g_Listen.IncRef(); - // setListener will incRef on the listener too - g_pToolWnd->setListener(&g_Listen); - if (!g_pToolWnd->Show()) - { - DoMessageBox ("Error creating texture tools window!", "TexTool plugin", MB_ICONERROR | MB_OK); - return; - } - } - - g_bTexViewReady = false; - g_bClosing = false; - } - else if (!strcmp(p, "Help...")) - { - if (!g_bHelp) - DoMessageBox ("Select a brush face (ctrl+shift+left mouse) or a patch, and hit Go...\n" - "See tutorials for more", "TexTool plugin", MB_OK ); - else - DoMessageBox ("Are you kidding me ?", "TexTool plugin", MB_OK ); - g_bHelp = true; - } + if ( !strcmp( p, "About..." ) ) { + DoMessageBox( PLUGIN_ABOUT, "About ...", MB_OK ); + } + else if ( !strcmp( p, "Go..." ) ) { + if ( !g_pToolWnd ) { + g_pToolWnd = g_UITable.m_pfnCreateGLWindow(); + g_pToolWnd->setSizeParm( 300,300 ); + g_pToolWnd->setName( "TexTool" ); + // g_Listener is a static class, we need to bump the refCount to avoid premature release problems + g_Listen.IncRef(); + // setListener will incRef on the listener too + g_pToolWnd->setListener( &g_Listen ); + if ( !g_pToolWnd->Show() ) { + DoMessageBox( "Error creating texture tools window!", "TexTool plugin", MB_ICONERROR | MB_OK ); + return; + } + } + + g_bTexViewReady = false; + g_bClosing = false; + } + else if ( !strcmp( p, "Help..." ) ) { + if ( !g_bHelp ) { + DoMessageBox( "Select a brush face (ctrl+shift+left mouse) or a patch, and hit Go...\n" + "See tutorials for more", "TexTool plugin", MB_OK ); + } + else{ + DoMessageBox( "Are you kidding me ?", "TexTool plugin", MB_OK ); + } + g_bHelp = true; + } } // ============================================================================= @@ -919,44 +862,39 @@ extern "C" void QERPlug_Dispatch(const char* p, vec3_t vMin, vec3_t vMax, bool b CSynapseServer* g_pSynapseServer = NULL; CSynapseClientTexTool g_SynapseClient; -extern "C" CSynapseClient* SYNAPSE_DLL_EXPORT Synapse_EnumerateInterfaces (const char *version, CSynapseServer *pServer) -{ - if (strcmp(version, SYNAPSE_VERSION)) - { - Syn_Printf("ERROR: synapse API version mismatch: should be '" SYNAPSE_VERSION "', got '%s'\n", version); - return NULL; - } - g_pSynapseServer = pServer; - g_pSynapseServer->IncRef(); - Set_Syn_Printf(g_pSynapseServer->Get_Syn_Printf()); - - g_SynapseClient.AddAPI(PLUGIN_MAJOR, "textool", sizeof(_QERPluginTable)); - g_SynapseClient.AddAPI(RADIANT_MAJOR, NULL, sizeof(g_FuncTable), SYN_REQUIRE, &g_FuncTable); - g_SynapseClient.AddAPI(QGL_MAJOR, NULL, sizeof(g_QglTable), SYN_REQUIRE, &g_QglTable); - g_SynapseClient.AddAPI(SELECTEDFACE_MAJOR, NULL, sizeof(g_SelectedFaceTable), SYN_REQUIRE, &g_SelectedFaceTable); - - return &g_SynapseClient; -} - -bool CSynapseClientTexTool::RequestAPI(APIDescriptor_t *pAPI) -{ - if (!strcmp(pAPI->major_name, PLUGIN_MAJOR)) - { - _QERPluginTable *pTable = static_cast<_QERPluginTable*>(pAPI->mpTable); - pTable->m_pfnQERPlug_Init = QERPlug_Init; - pTable->m_pfnQERPlug_GetName = QERPlug_GetName; - pTable->m_pfnQERPlug_GetCommandList = QERPlug_GetCommandList; - pTable->m_pfnQERPlug_Dispatch = QERPlug_Dispatch; - return true; - } - - Syn_Printf("ERROR: RequestAPI( '%s' ) not found in '%s'\n", pAPI->major_name, GetInfo()); - return false; +extern "C" CSynapseClient * SYNAPSE_DLL_EXPORT Synapse_EnumerateInterfaces( const char *version, CSynapseServer *pServer ){ + if ( strcmp( version, SYNAPSE_VERSION ) ) { + Syn_Printf( "ERROR: synapse API version mismatch: should be '" SYNAPSE_VERSION "', got '%s'\n", version ); + return NULL; + } + g_pSynapseServer = pServer; + g_pSynapseServer->IncRef(); + Set_Syn_Printf( g_pSynapseServer->Get_Syn_Printf() ); + + g_SynapseClient.AddAPI( PLUGIN_MAJOR, "textool", sizeof( _QERPluginTable ) ); + g_SynapseClient.AddAPI( RADIANT_MAJOR, NULL, sizeof( g_FuncTable ), SYN_REQUIRE, &g_FuncTable ); + g_SynapseClient.AddAPI( QGL_MAJOR, NULL, sizeof( g_QglTable ), SYN_REQUIRE, &g_QglTable ); + g_SynapseClient.AddAPI( SELECTEDFACE_MAJOR, NULL, sizeof( g_SelectedFaceTable ), SYN_REQUIRE, &g_SelectedFaceTable ); + + return &g_SynapseClient; +} + +bool CSynapseClientTexTool::RequestAPI( APIDescriptor_t *pAPI ){ + if ( !strcmp( pAPI->major_name, PLUGIN_MAJOR ) ) { + _QERPluginTable *pTable = static_cast<_QERPluginTable*>( pAPI->mpTable ); + pTable->m_pfnQERPlug_Init = QERPlug_Init; + pTable->m_pfnQERPlug_GetName = QERPlug_GetName; + pTable->m_pfnQERPlug_GetCommandList = QERPlug_GetCommandList; + pTable->m_pfnQERPlug_Dispatch = QERPlug_Dispatch; + return true; + } + + Syn_Printf( "ERROR: RequestAPI( '%s' ) not found in '%s'\n", pAPI->major_name, GetInfo() ); + return false; } #include "version.h" -const char* CSynapseClientTexTool::GetInfo() -{ - return "Texture Tools plugin built " __DATE__ " " RADIANT_VERSION; +const char* CSynapseClientTexTool::GetInfo(){ + return "Texture Tools plugin built " __DATE__ " " RADIANT_VERSION; }