From 7e95dbb1e040228ee7b2d056b9b14e376c350fad Mon Sep 17 00:00:00 2001 From: Pan7 Date: Tue, 2 May 2017 02:15:35 +0200 Subject: [PATCH] Texture directory list --- radiant/gtkdlgs.cpp | 17 ++-- radiant/mainframe.cpp | 173 +++++++++++++++++++++++++++++++++++++--- radiant/mainframe.h | 2 +- radiant/preferences.cpp | 33 +++++++- radiant/preferences.h | 6 +- radiant/qe3.cpp | 5 +- radiant/qe3.h | 5 +- radiant/textures.h | 1 + radiant/texwindow.cpp | 148 +++++++++++++++++++++++++--------- 9 files changed, 328 insertions(+), 62 deletions(-) diff --git a/radiant/gtkdlgs.cpp b/radiant/gtkdlgs.cpp index 5f18ced8..504f0b19 100644 --- a/radiant/gtkdlgs.cpp +++ b/radiant/gtkdlgs.cpp @@ -2478,18 +2478,15 @@ void DoTextureListDlg(){ { // Initialize dialog - GSList *textures = (GSList*)NULL; - FillTextureMenu( &textures ); - while ( textures != NULL ) + GSList *texdirs = NULL, *dir; + FillTextureList( &texdirs ); + for( dir = texdirs; dir != NULL; dir = g_slist_next( dir ) ) { - { - GtkTreeIter iter; - gtk_list_store_append( store, &iter ); - gtk_list_store_set( store, &iter, 0, (gchar*)textures->data, -1 ); - } - free( textures->data ); - textures = g_slist_remove( textures, textures->data ); + GtkTreeIter iter; + gtk_list_store_append( store, &iter ); + gtk_list_store_set( store, &iter, 0, (gchar*)dir->data, -1 ); } + ClearGSList( texdirs ); } g_object_unref( G_OBJECT( store ) ); diff --git a/radiant/mainframe.cpp b/radiant/mainframe.cpp index 4a1da7be..6e6ccf69 100644 --- a/radiant/mainframe.cpp +++ b/radiant/mainframe.cpp @@ -1407,8 +1407,9 @@ void MainFrame::create_main_menu( GtkWidget *window, GtkWidget *vbox ){ G_CALLBACK( HandleCommand ), ID_TEXTURES_SHADERLISTONLY, FALSE ); g_object_set_data( G_OBJECT( window ), "menu_textures_shaderlistonly", item ); item = menu_separator( menu ); - g_object_set_data( G_OBJECT( window ), "menu_textures_separator", item ); - g_object_set_data( G_OBJECT( window ), "menu_textures", menu ); + + menu_in_menu = create_menu_in_menu_with_mnemonic( menu, _( "Texture Directories" ) ); + g_object_set_data( G_OBJECT( window ), "menu_texture_dirs", menu_in_menu ); // Misc menu menu = create_sub_menu_with_mnemonic( menu_bar, _( "_Misc" ) ); @@ -2395,6 +2396,87 @@ GtkWidget* create_framed_widget( GtkWidget* widget ){ return frame; } +static void textdirlist_activate( GtkTreeView *tree_view ) +{ + GtkTreeSelection* selection; + + GtkTreeModel* model; + GtkTreeIter iter; + + selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( tree_view ) ); + + if ( gtk_tree_selection_get_selected( selection, &model, &iter ) ) { + GtkTreePath* path = gtk_tree_model_get_path( model, &iter ); + if ( gtk_tree_path_get_depth( path ) == 1 ) { + char* p; + gtk_tree_model_get( model, &iter, 0, &p, -1 ); + + Texture_ShowDirectory_by_path( p ); + g_free( p ); + } + gtk_tree_path_free( path ); + } +} + +static void textdirlist_row_activated( GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data ) +{ + textdirlist_activate( tree_view ); +} +static void textdirlist_cursor_changed( GtkTreeView *tree_view, gpointer user_data ) +{ + textdirlist_activate( tree_view ); +} + +GtkWidget* create_texdirlist_widget() +{ + GtkWidget *scr; + GtkWidget* view; + + scr = gtk_scrolled_window_new( (GtkAdjustment*)NULL, (GtkAdjustment*)NULL ); + + gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scr ), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); + gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( scr ), GTK_SHADOW_IN ); + + { + GtkListStore* store = gtk_list_store_new( 1, G_TYPE_STRING ); + + view = gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) ); + gtk_tree_view_set_headers_visible( GTK_TREE_VIEW( view ), FALSE ); + + { + GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); + GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( "Textures", renderer, "text", 0, (char *) NULL ); + gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column ); + } + + gtk_container_add( GTK_CONTAINER( scr ), view ); + + g_object_set_data( G_OBJECT( g_qeglobals_gui.d_main_window ), "dirlist_treeview" , view ); + + GSList *texdirs = NULL; + FillTextureList( &texdirs ); + FillTextureDirListWidget( texdirs ); + ClearGSList( texdirs ); + + g_object_unref( G_OBJECT( store ) ); + + gtk_tree_selection_set_mode( gtk_tree_view_get_selection( GTK_TREE_VIEW( view ) ), GTK_SELECTION_SINGLE ); +#if GTK_CHECK_VERSION( 3,12,0 ) + gtk_tree_view_set_activate_on_single_click( GTK_TREE_VIEW( view ), TRUE ); +#else + g_signal_connect( view, "cursor-changed", G_CALLBACK( textdirlist_cursor_changed ), view ); +#endif + g_signal_connect( view, "row-activated", G_CALLBACK( textdirlist_row_activated ), view ); + + gtk_widget_show( view ); + + } + + gtk_widget_show( scr ); + + return scr; +} + gboolean entry_focus_in( GtkWidget *widget, GdkEventFocus *event, gpointer user_data ){ gtk_window_remove_accel_group( GTK_WINDOW( g_pParentWnd->m_pWidget ), global_accel ); return FALSE; @@ -2662,7 +2744,26 @@ void MainFrame::Create(){ m_pTexWnd = new TexWnd(); { GtkWidget* frame = create_framed_texwnd( m_pTexWnd ); - gtk_paned_add2( GTK_PANED( vsplit2 ), frame ); + if( g_PrefsDlg.m_bShowTexDirList ) { + + GtkWidget* texDirList = create_texdirlist_widget(); + + GtkWidget* texSplit = gtk_hpaned_new(); + m_pSplits[4] = texSplit; + + gtk_paned_pack2( GTK_PANED( vsplit2 ), texSplit, TRUE, FALSE ); + gtk_paned_add1( GTK_PANED( texSplit ), texDirList ); + gtk_paned_add2( GTK_PANED( texSplit ), frame ); + + if( g_PrefsDlg.mWindowInfo.nTextureDirectoryListWidth >= 0 ) { + gtk_paned_set_position( GTK_PANED( texSplit ), g_PrefsDlg.mWindowInfo.nTextureDirectoryListWidth ); + } + + gtk_widget_show( texSplit ); + } else + { + gtk_paned_pack2( GTK_PANED( vsplit2 ), frame, TRUE, TRUE ); + } } // console @@ -2852,9 +2953,28 @@ void MainFrame::Create(){ GtkWidget* frame = create_framed_texwnd( m_pTexWnd ); m_pTexWnd->m_pParent = g_pGroupDlg->m_pWidget; + GtkWidget* w = gtk_label_new( _( "Textures" ) ); + gtk_widget_show( w ); + + if( g_PrefsDlg.m_bShowTexDirList ) + { + GtkWidget* texDirList = create_texdirlist_widget(); + + GtkWidget* texSplit = gtk_hpaned_new(); + m_pSplits[4] = texSplit; + + gtk_paned_add1( GTK_PANED( texSplit ), texDirList ); + gtk_paned_add2( GTK_PANED( texSplit ), frame ); + + if( g_PrefsDlg.mWindowInfo.nTextureDirectoryListWidth >= 0 ) { + gtk_paned_set_position( GTK_PANED( texSplit ), g_PrefsDlg.mWindowInfo.nTextureDirectoryListWidth ); + } + + gtk_widget_show( texSplit ); + + gtk_notebook_insert_page( GTK_NOTEBOOK( g_pGroupDlg->m_pNotebook ), texSplit, w, 1 ); + } else { - GtkWidget* w = gtk_label_new( _( "Textures" ) ); - gtk_widget_show( w ); gtk_notebook_insert_page( GTK_NOTEBOOK( g_pGroupDlg->m_pNotebook ), frame, w, 1 ); } } @@ -2915,9 +3035,28 @@ void MainFrame::Create(){ m_pTexWnd = new TexWnd(); GtkWidget* frame = create_framed_texwnd( m_pTexWnd ); + GtkWidget* w = gtk_label_new( _( "Textures" ) ); + gtk_widget_show( w ); + + if( g_PrefsDlg.m_bShowTexDirList ) + { + GtkWidget* texDirList = create_texdirlist_widget(); + + GtkWidget* texSplit = gtk_hpaned_new(); + m_pSplits[4] = texSplit; + + gtk_paned_add1( GTK_PANED( texSplit ), texDirList ); + gtk_paned_add2( GTK_PANED( texSplit ), frame ); + + if( g_PrefsDlg.mWindowInfo.nTextureDirectoryListWidth >= 0 ) { + gtk_paned_set_position( GTK_PANED( texSplit ), g_PrefsDlg.mWindowInfo.nTextureDirectoryListWidth ); + } + + gtk_widget_show( texSplit ); + + gtk_notebook_insert_page( GTK_NOTEBOOK( g_pGroupDlg->m_pNotebook ), texSplit, w, 1 ); + } else { - GtkWidget* w = gtk_label_new( _( "Textures" ) ); - gtk_widget_show( w ); gtk_notebook_insert_page( GTK_NOTEBOOK( g_pGroupDlg->m_pNotebook ), frame, w, 1 ); } } @@ -3310,6 +3449,9 @@ void MainFrame::OnDelete(){ else{ g_PrefsDlg.mWindowInfo.nZFloatWidth = gtk_paned_get_position( GTK_PANED( m_pSplits[0] ) ); } + if( g_PrefsDlg.m_bShowTexDirList ) { + g_PrefsDlg.mWindowInfo.nTextureDirectoryListWidth = gtk_paned_get_position( GTK_PANED( m_pSplits[4] ) ); + } if ( CurrentStyle() == eFloating ) { save_window_pos( m_pCamWnd->m_pParent, g_PrefsDlg.mWindowInfo.posCamWnd ); @@ -4651,6 +4793,7 @@ void MainFrame::OnPrefs() { bool bPluginToolbar = g_PrefsDlg.m_bPluginToolbar; bool bDetachableMenus = g_PrefsDlg.m_bDetachableMenus; bool bFloatingZ = g_PrefsDlg.m_bFloatingZ; + bool bShowTexDirList = g_PrefsDlg.m_bShowTexDirList; g_PrefsDlg.LoadPrefs(); @@ -4662,7 +4805,8 @@ void MainFrame::OnPrefs() { (g_PrefsDlg.m_bLatchedPluginToolbar != bPluginToolbar ) || (g_PrefsDlg.m_nLatchedShader != nShader ) || (g_PrefsDlg.m_nLatchedTextureQuality != nTextureQuality ) || - (g_PrefsDlg.m_bLatchedFloatingZ != bFloatingZ)) { + (g_PrefsDlg.m_bLatchedFloatingZ != bFloatingZ ) || + (g_PrefsDlg.m_bShowTexDirList != bShowTexDirList)) { gtk_MessageBoxNew(m_pWidget, _( "You must restart Radiant for the " "changes to take effect." ), _( "Restart Radiant" ), MB_OK | MB_ICONINFORMATION); @@ -5812,6 +5956,12 @@ void MainFrame::OnTexturesReloadshaders(){ Texture_SetTexture( &g_qeglobals.d_texturewin.texdef, &g_qeglobals.d_texturewin.brushprimit_texdef, false, NULL, false ); Sys_UpdateWindows( W_ALL ); Sys_EndWait(); + + GSList *texdirs = NULL; + FillTextureList( &texdirs ); + FillTextureMenu( texdirs ); + FillTextureDirListWidget( texdirs ); + ClearGSList( texdirs ); } void MainFrame::OnTexturesShadersShow(){ @@ -5903,7 +6053,12 @@ void MainFrame::OnTexturesShaderlistonly(){ g_bIgnoreCommands++; gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( item ), g_PrefsDlg.m_bTexturesShaderlistOnly ? TRUE : FALSE ); g_bIgnoreCommands--; - FillTextureMenu(); + + GSList *texdirs = NULL; + FillTextureList( &texdirs ); + FillTextureMenu( texdirs ); + FillTextureDirListWidget( texdirs ); + ClearGSList( texdirs ); } void MainFrame::OnTextureWad( unsigned int nID ){ diff --git a/radiant/mainframe.h b/radiant/mainframe.h index c61c78f6..87e5a35c 100644 --- a/radiant/mainframe.h +++ b/radiant/mainframe.h @@ -489,7 +489,7 @@ void create_main_toolbar( GtkWidget *window, GtkWidget *vbox ); void create_plugin_toolbar( GtkWidget *window, GtkWidget *vbox ); void create_main_statusbar( GtkWidget *window, GtkWidget *vbox ); GtkWidget *m_pStatusLabel[6]; -GtkWidget *m_pSplits[4]; +GtkWidget *m_pSplits[5]; XYWnd* m_pXYWnd; XYWnd* m_pYZWnd; XYWnd* m_pXZWnd; diff --git a/radiant/preferences.cpp b/radiant/preferences.cpp index dc78d258..1050f2b8 100644 --- a/radiant/preferences.cpp +++ b/radiant/preferences.cpp @@ -119,6 +119,7 @@ #define SHADERTEST_KEY "ShaderTest" #define GLLIGHTING_KEY "UseGLLighting" #define LOADSHADERS_KEY "LoadShaders" +#define SHOWTEXDIRLIST_KEY "ShowTextureDirectoryList" #define NOSTIPPLE_KEY "NoStipple" #define UNDOLEVELS_KEY "UndoLevels" #define VERTEXMODE_KEY "VertexSplit" @@ -185,6 +186,7 @@ #define CAMHEIGHT_KEY "CamHeight" #define ZFLOATWIDTH_KEY "ZWidthFloating" #define STATE_KEY "State" +#define TEXDIRLISTWIDTH_KEY "TextureDirectoryListWidth" // menu stuff #define COUNT_KEY "Count" @@ -1668,6 +1670,11 @@ void PrefsDlg::BuildDialog(){ gtk_tree_store_append( store, &tab, &group ); gtk_tree_store_set( store, &tab, 0, _( "Texture Settings" ), 1, (gpointer)PTAB_TEXTURE, -1 ); } + { + GtkTreeIter tab; + gtk_tree_store_append( store, &tab, &group ); + gtk_tree_store_set( store, &tab, 0, _( "Texture Directory List" ), 1, (gpointer)PTAB_TEXTURE_DIR, -1 ); + } } { @@ -2106,6 +2113,23 @@ void PrefsDlg::BuildDialog(){ } g_list_free( combo_list ); + /******** Texture dir list group *********/ + preflabel = gtk_label_new( _( "Texture directory list" ) ); + gtk_widget_show( preflabel ); + pageframe = gtk_frame_new( _( "Texture directory list" ) ); + gtk_container_set_border_width( GTK_CONTAINER( pageframe ), 5 ); + gtk_widget_show( pageframe ); + vbox = gtk_vbox_new( FALSE, 5 ); + gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 ); + gtk_container_add( GTK_CONTAINER( pageframe ), vbox ); + gtk_widget_show( vbox ); + + check = gtk_check_button_new_with_label( _( "Show Texture Directory List" ) ); + gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 ); + gtk_widget_show( check ); + AddDialogData( check, &m_bShowTexDirList, DLG_CHECK_BOOL ); + + // Add the page to the notebook gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), pageframe, preflabel ); @@ -3024,6 +3048,8 @@ void PrefsDlg::LoadPrefs(){ mLocalPrefs.GetPref( LOADSHADERS_KEY, &m_nLatchedShader, 0 ); m_nShader = m_nLatchedShader; + mLocalPrefs.GetPref( SHOWTEXDIRLIST_KEY, &m_bShowTexDirList, TRUE ); + mLocalPrefs.GetPref( NOCLAMP_KEY, &m_bNoClamp, FALSE ); mLocalPrefs.GetPref( SNAP_KEY, &m_bSnap, TRUE ); mLocalPrefs.GetPref( USERINI_KEY, &m_strUserPath, "" ); @@ -3106,6 +3132,7 @@ void PrefsDlg::LoadPrefs(){ #ifdef _WIN32 mLocalPrefs.GetPref( STATE_KEY, &mWindowInfo.nState, SW_SHOW ); #endif + mLocalPrefs.GetPref( TEXDIRLISTWIDTH_KEY, &mWindowInfo.nTextureDirectoryListWidth, 50 ); // menu stuff mLocalPrefs.GetPref( COUNT_KEY, &m_nMRUCount, 0 ); @@ -3489,9 +3516,9 @@ void CGameInstall::BuildDialog() { g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( OnBtnBrowseEngine ), this ); gtk_box_pack_start( GTK_BOX( hbox ), button, FALSE, FALSE, 0 ); - m_executablesVBox = gtk_vbox_new( TRUE, 0 ); - gtk_box_pack_start( GTK_BOX( vbox2 ), m_executablesVBox, FALSE, FALSE, 0 ); - gtk_widget_show( m_executablesVBox ); + m_executablesVBox = gtk_vbox_new( TRUE, 0 ); + gtk_box_pack_start( GTK_BOX( vbox2 ), m_executablesVBox, FALSE, FALSE, 0 ); + gtk_widget_show( m_executablesVBox ); text = gtk_label_new( _( "Engine binaries directory:" ) ); gtk_widget_show( text ); diff --git a/radiant/preferences.h b/radiant/preferences.h index 4bc1f831..bbe31ffc 100644 --- a/radiant/preferences.h +++ b/radiant/preferences.h @@ -470,6 +470,8 @@ typedef struct { int nCamHeight; int nZFloatWidth; int nState; + int nTextureDirectoryListWidth; + } windowPosInfo_t; class PrefsDlg : public Dialog @@ -506,7 +508,7 @@ enum {SHADER_NONE = 0, SHADER_COMMON, SHADER_ALL}; // Gef: updated preferences dialog /*! Preference notebook page numbers */ -enum {PTAB_FRONT = 0, PTAB_GAME_SETTINGS, PTAB_2D, PTAB_CAMERA, PTAB_TEXTURE, PTAB_LAYOUT, PTAB_MOUSE, +enum {PTAB_FRONT = 0, PTAB_GAME_SETTINGS, PTAB_2D, PTAB_CAMERA, PTAB_TEXTURE, PTAB_TEXTURE_DIR, PTAB_LAYOUT, PTAB_MOUSE, PTAB_EDITING, PTAB_STARTUP, PTAB_PATHS, PTAB_BRUSH, PTAB_MISC, PTAB_BSPMONITOR} pref_tabs; GtkWidget *notebook; @@ -727,6 +729,8 @@ int m_nLatchedTextureQuality; // texture compression format int m_nTextureCompressionFormat; +bool m_bShowTexDirList; + int m_nLightRadiuses; bool m_bQ3Map2Texturing; diff --git a/radiant/qe3.cpp b/radiant/qe3.cpp index ce78e7ce..349f13d9 100644 --- a/radiant/qe3.cpp +++ b/radiant/qe3.cpp @@ -902,7 +902,10 @@ void QE_Init( void ){ FillClassList(); // list in entity window Map_Init(); - FillTextureMenu(); + GSList *texdirs = NULL; + FillTextureList( &texdirs ); + FillTextureMenu( texdirs ); + ClearGSList( texdirs ); FillBSPMenu(); /* diff --git a/radiant/qe3.h b/radiant/qe3.h index 5a9ec542..e4769cdd 100644 --- a/radiant/qe3.h +++ b/radiant/qe3.h @@ -259,8 +259,11 @@ void MRU_AddFile( const char *str ); void MRU_Activate( int index ); -void FillTextureMenu( GSList** pArray = NULL ); void FillBSPMenu( void ); +void ClearGSList( GSList *lst ); +void FillTextureList( GSList** pArray ); +void FillTextureMenu( GSList *texdirs ); +void FillTextureDirListWidget( GSList *texdirs ); // profile functions - kind of utility lib // they are kind of dumb, they expect to get the path to the .ini file or to the prefs directory when called diff --git a/radiant/textures.h b/radiant/textures.h index 939a65a7..63c02b7b 100644 --- a/radiant/textures.h +++ b/radiant/textures.h @@ -26,6 +26,7 @@ void Texture_Init(); void Texture_ShowDirectory( int menunum ); void Texture_ShowDirectory(); +void Texture_ShowDirectory_by_path( const char* pPath ); void Texture_ShowAll(); void WINAPI Texture_ShowInuse(); extern char texture_directory[]; diff --git a/radiant/texwindow.cpp b/radiant/texwindow.cpp index f2f070df..aef58c42 100644 --- a/radiant/texwindow.cpp +++ b/radiant/texwindow.cpp @@ -545,35 +545,15 @@ void ClearGSList( GSList* lst ){ } } -void FillTextureMenu( GSList** pArray ){ - GtkWidget *menu, *sep, *item; // point to the Textures GtkMenu and to the last separator - GList *children, *seplst, *lst; - GSList *texdirs = NULL; - GSList *texdirs_tmp = NULL; +void FillTextureList( GSList** pArray ) +{ GSList *p; char dirRoot[NAME_MAX]; + int texture_num; + GSList *texdirs = NULL; + GSList *texdirs_tmp = NULL; - // delete everything - menu = GTK_WIDGET( g_object_get_data( G_OBJECT( g_qeglobals_gui.d_main_window ), "menu_textures" ) ); - sep = GTK_WIDGET( g_object_get_data( G_OBJECT( g_qeglobals_gui.d_main_window ), "menu_textures_separator" ) ); - children = gtk_container_get_children( GTK_CONTAINER( menu ) ); - if( children ) { - seplst = g_list_find( children, sep ); - if( seplst ) { - for ( lst = g_list_next( seplst ); lst != NULL; lst = g_list_next( lst ) ) - { - gtk_widget_destroy( GTK_WIDGET( lst->data ) ); - } - } - g_list_free( children ); - } - - texture_nummenus = 0; - - // add everything - if ( !g_qeglobals.d_project_entity ) { - return; - } + texture_num = 0; // scan texture dirs and pak files only if not restricting to shaderlist if ( !g_PrefsDlg.m_bTexturesShaderlistOnly ) { @@ -583,7 +563,7 @@ void FillTextureMenu( GSList** pArray ){ // Hydra: erm, this didn't used to do anything except leak memory... // For Halflife support this is required to work however. // g_slist_append(texdirs, p->data); - texdirs = g_slist_append( texdirs, strdup( (char *)p->data ) ); + texdirs = g_slist_append( texdirs, g_strdup( (char *)p->data ) ); } vfsClearFileDirList( &texdirs_tmp ); } @@ -595,12 +575,20 @@ void FillTextureMenu( GSList** pArray ){ while ( l_shaderfiles != NULL ) { char shaderfile[PATH_MAX]; + char *colon; gboolean found = FALSE; ExtractFileName( (char*)l_shaderfiles->data, shaderfile ); StripExtension( shaderfile ); strlwr( shaderfile ); + //support for shaderlist.txt tags, forward + colon = strstr( (char*)l_shaderfiles->data, ":" ); + if( colon ) + { + strncat( shaderfile, colon, sizeof( shaderfile ) ); + } + for ( GSList *tmp = texdirs; tmp; tmp = g_slist_next( tmp ) ) if ( !strcasecmp( (char*)tmp->data, shaderfile ) ) { found = TRUE; @@ -608,16 +596,79 @@ void FillTextureMenu( GSList** pArray ){ } if ( !found ) { - texdirs = g_slist_prepend( texdirs, strdup( shaderfile ) ); + texdirs = g_slist_prepend( texdirs, g_strdup( shaderfile ) ); } - free( l_shaderfiles->data ); + g_free( l_shaderfiles->data ); l_shaderfiles = g_slist_remove( l_shaderfiles, l_shaderfiles->data ); } // sort the list texdirs = g_slist_sort( texdirs, (GCompareFunc)strcmp ); + GSList *temp = texdirs; + while ( temp ) + { + char* ptr = strchr( (char*)temp->data, '_' ); + + // do we shrink the menus? + if ( ptr != NULL ) { + // extract the root + strcpy( dirRoot, (char*)temp->data ); + dirRoot[ptr - (char*)temp->data + 1] = 0; + + // we shrink only if we have at least two things to shrink :-) + if ( temp->next && ( strstr( (char*)temp->next->data, dirRoot ) == (char*)temp->next->data ) ) { + do + { + if ( pArray ) { + *pArray = g_slist_append( *pArray, g_strdup( (char*)temp->data ) ); + } + if ( ++texture_num == MAX_TEXTUREDIRS ) { + Sys_FPrintf( SYS_WRN, "WARNING: max texture directories count has been reached!\n" ); + ClearGSList( texdirs ); + return; + } + temp = temp->next; + } + while ( temp && ( strstr( (char*)temp->data, dirRoot ) == temp->data ) ); + + ptr = strchr( dirRoot, '_' ); + *ptr = 0; + continue; + } + } + if ( pArray ) { + *pArray = g_slist_append( *pArray, g_strdup( (char*)temp->data ) ); + } + if ( ++texture_num == MAX_TEXTUREDIRS ) { + Sys_FPrintf( SYS_WRN, "WARNING: max texture directories count has been reached!\n" ); + ClearGSList( texdirs ); + return; + } + + temp = temp->next; + } + ClearGSList( texdirs ); +} + +void FillTextureMenu( GSList *texdirs ) +{ + GtkWidget *menu, *item; + GList *children, *lst; + char dirRoot[NAME_MAX]; + + // delete everything + menu = GTK_WIDGET( g_object_get_data( G_OBJECT( g_qeglobals_gui.d_main_window ), "menu_texture_dirs" ) ); + children = gtk_container_get_children( GTK_CONTAINER( menu ) ); + if( children ) { + for ( lst = g_list_first( children ); lst != NULL; lst = g_list_next( lst ) ) + { + gtk_widget_destroy( GTK_WIDGET( lst->data ) ); + } + g_list_free( children ); + } + GSList *temp = texdirs; while ( temp ) { @@ -645,9 +696,7 @@ void FillTextureMenu( GSList** pArray ){ strcpy( texture_menunames[texture_nummenus], (char*)temp->data ); strcat( texture_menunames[texture_nummenus], "/" ); - if ( pArray ) { - *pArray = g_slist_append( *pArray, strdup( (char*)temp->data ) ); - } + if ( ++texture_nummenus == MAX_TEXTUREDIRS ) { Sys_FPrintf( SYS_WRN, "WARNING: max texture directories count has been reached!\n" ); // push submenu and get out @@ -682,9 +731,7 @@ void FillTextureMenu( GSList** pArray ){ strcpy( texture_menunames[texture_nummenus], (char*)temp->data ); strcat( texture_menunames[texture_nummenus], "/" ); - if ( pArray ) { - *pArray = g_slist_append( *pArray, strdup( (char*)temp->data ) ); - } + if ( ++texture_nummenus == MAX_TEXTUREDIRS ) { Sys_FPrintf( SYS_WRN, "WARNING: max texture directories count has been reached!\n" ); ClearGSList( texdirs ); @@ -693,7 +740,36 @@ void FillTextureMenu( GSList** pArray ){ temp = temp->next; } - ClearGSList( texdirs ); +} + +void FillTextureDirListWidget( GSList *texdirs ) +{ + GtkWidget* treeview; + GtkTreeModel* model; + GtkListStore* store; + GtkTreeIter iter; + GSList *dir; + + treeview = GTK_WIDGET( g_object_get_data( G_OBJECT( g_qeglobals_gui.d_main_window ), "dirlist_treeview" ) ); + if( treeview == NULL ) { + return; + } + model = gtk_tree_view_get_model( GTK_TREE_VIEW( treeview ) ); + store = GTK_LIST_STORE( model ); + + gtk_list_store_clear( store ); + + for( dir = texdirs; dir != NULL; dir = g_slist_next( dir ) ) + { + gtk_list_store_append( store, &iter ); + gtk_list_store_set( store, &iter, 0, (gchar*)dir->data, -1 ); + } +} + +void Texture_ShowDirectory_by_path( const char* pPath ) +{ + snprintf( texture_directory, sizeof( texture_directory ), "%s%s", pPath, "/" ); + Texture_ShowDirectory(); } /*