]> git.xonotic.org Git - xonotic/netradiant.git/commitdiff
Merge branch 'master' into divVerent/cutAtDash divVerent/cutAtDash
authorRudolf Polzer <divverent@xonotic.org>
Tue, 15 May 2012 09:52:19 +0000 (11:52 +0200)
committerRudolf Polzer <divverent@xonotic.org>
Tue, 15 May 2012 09:52:31 +0000 (11:52 +0200)
Conflicts:
radiant/texwindow.cpp

radiant/texwindow.cpp

index 94717d0949bd75a9d9b913c62b72ef40ee42bdc3..98f8ac27c562848b1c5f04ee126ed9db85827424 100644 (file)
@@ -113,19 +113,120 @@ void TextureGroups_addWad( TextureGroups& groups, const char* archive ){
 }
 typedef ReferenceCaller1<TextureGroups, const char*, TextureGroups_addWad> TextureGroupsAddWadCaller;
 
+namespace
+{
+bool softGroups();
+
+CopiedString Texture_getCategoryByName( const char *tex ){
+       char *n = string_clone( tex );
+       int l = string_length( n );
+       char *s = strrchr( n, '/' );
+       char *p = strchr( s ? ( s + 1 ) : n, '-' );
+       if ( softGroups() ) {
+               if ( s ? ( p >= s ) : ( p != NULL ) ) {
+                       p[1] = 0;
+               }
+               else if ( s ) {
+                       s[1] = 0;
+               }
+               else{
+                       n[0] = 0;
+               }
+       }
+       else
+       {
+               if ( s ) {
+                       s[0] = 0;
+               }
+               else{
+                       n[0] = 0;
+               }
+       }
+       CopiedString cs( n );
+       string_release( n, l );
+       return cs;
+}
+CopiedString Texture_getCategoryDirectory( const char *cat ){
+       if ( !softGroups() ) {
+               StringOutputStream o( 64 );
+               if ( string_length( cat ) ) {
+                       o << cat << "/";
+               }
+               return o.c_str();
+       }
+       char *n = string_clone( cat );
+       int l = string_length( n );
+       if ( l == 0 ) {
+               string_release( n, l );
+               return "";
+       }
+       CopiedString cs;
+       char *p = strrchr( n, '/' );
+       if ( p ) {
+               cs = StringRange( n, p + 1 );
+       }
+       else{
+               cs = "";
+       }
+       string_release( n, l );
+       return cs;
+}
+bool Texture_matchCategory( const char *matchcat, const char *texcat ){
+       int l = string_length( matchcat );
+       if ( softGroups() ) {
+               if ( l > 0 && matchcat[l - 1] == '*' ) {
+                       return string_equal_n( texcat, matchcat, l - 1 );
+               }
+       }
+       return string_equal( texcat, matchcat );
+}
+};
+
+
 void TextureGroups_addShader( TextureGroups& groups, const char* shaderName ){
        const char* texture = path_make_relative( shaderName, "textures/" );
+       globalErrorStream() << texture << "\n";
        if ( texture != shaderName ) {
-               const char* last = path_remove_directory( texture );
-               if ( !string_empty( last ) ) {
-                       groups.insert( CopiedString( StringRange( texture, --last ) ) );
+               CopiedString n = Texture_getCategoryByName( texture );
+               if ( !string_empty( n.c_str() ) ) {
+                       groups.insert( n );
                }
        }
 }
 typedef ReferenceCaller1<TextureGroups, const char*, TextureGroups_addShader> TextureGroupsAddShaderCaller;
 
+
+
+class FindTexturesByTypeVisitor : public ImageModules::Visitor
+{
+TextureGroups& m_groups;
+const char* m_dirstring;
+void visitFile( const char *name ) const {
+       StringOutputStream dirstring( 64 );
+       dirstring << m_dirstring << name;
+       TextureGroups_addShader( m_groups, dirstring.c_str() );
+}
+typedef ConstMemberCaller1<FindTexturesByTypeVisitor, const char *, &FindTexturesByTypeVisitor::visitFile> VisitFileMemberCaller;
+public:
+FindTexturesByTypeVisitor( TextureGroups& groups, const char* dirstring )
+       : m_groups( groups ), m_dirstring( dirstring ){
+}
+void visit( const char* minor, const _QERPlugImageTable& table ) const {
+       GlobalFileSystem().forEachFile( m_dirstring, minor, VisitFileMemberCaller( *this ) );
+}
+};
+
 void TextureGroups_addDirectory( TextureGroups& groups, const char* directory ){
-       groups.insert( directory );
+       if ( softGroups() ) {
+               // enumerate all files, find dashes
+               StringOutputStream dirstring( 64 );
+               dirstring << "textures/" << directory << "/";
+               Radiant_getImageModules().foreachModule( FindTexturesByTypeVisitor( groups, dirstring.c_str() ) );
+       }
+       else
+       {
+               groups.insert( directory );
+       }
 }
 typedef ReferenceCaller1<TextureGroups, const char*, TextureGroups_addDirectory> TextureGroupsAddDirectoryCaller;
 
@@ -194,6 +295,9 @@ typedef FreeCaller1<const BoolImportCallback&, TextureBrowser_hideUnusedExport>
 void TextureBrowser_showShadersExport( const BoolImportCallback& importer );
 typedef FreeCaller1<const BoolImportCallback&, TextureBrowser_showShadersExport> TextureBrowserShowShadersExport;
 
+void TextureBrowser_softGroupsExport( const BoolImportCallback& importer );
+typedef FreeCaller1<const BoolImportCallback&, TextureBrowser_softGroupsExport> TextureBrowserSoftGroupsExport;
+
 void TextureBrowser_showShaderlistOnly( const BoolImportCallback& importer );
 typedef FreeCaller1<const BoolImportCallback&, TextureBrowser_showShaderlistOnly> TextureBrowserShowShaderlistOnlyExport;
 
@@ -236,6 +340,7 @@ std::set<CopiedString> m_found_shaders;
 ToggleItem m_hideunused_item;
 ToggleItem m_showshaders_item;
 ToggleItem m_showshaderlistonly_item;
+ToggleItem m_softgroups_item;
 ToggleItem m_fixedsize_item;
 ToggleItem m_filternotex_item;
 
@@ -254,6 +359,7 @@ std::size_t m_mouseWheelScrollIncrement;
 std::size_t m_textureScale;
 // make the texture increments match the grid changes
 bool m_showShaders;
+bool m_softGroups;
 bool m_showTextureScrollbar;
 StartupShaders m_startupShaders;
 // if true, the texture window will only display in-use shaders
@@ -305,6 +411,7 @@ TextureBrowser() :
        m_hideunused_item( TextureBrowserHideUnusedExport() ),
        m_showshaders_item( TextureBrowserShowShadersExport() ),
        m_showshaderlistonly_item( TextureBrowserShowShaderlistOnlyExport() ),
+       m_softgroups_item( TextureBrowserSoftGroupsExport() ),
        m_fixedsize_item( TextureBrowserFixedSizeExport() ),
        m_filternotex_item( TextureBrowserFilterNotexExport() ),
        m_heightChanged( true ),
@@ -323,6 +430,13 @@ TextureBrowser() :
        m_uniformTextureSize( 128 ){
 }
 };
+namespace
+{
+bool softGroups(){
+       return GlobalTextureBrowser().m_softGroups;
+}
+};
+
 
 void ( *TextureBrowser_textureSelected )( const char* shader );
 
@@ -501,7 +615,7 @@ bool Texture_IsShown( IShader* shader, bool show_shaders, bool hideUnused ){
                }
        }
        else {
-               if ( !shader_equal_prefix( shader_get_textureName( shader->getName() ), g_TextureBrowser_currentDirectory.c_str() ) ) {
+               if ( !Texture_matchCategory( g_TextureBrowser_currentDirectory.c_str(), Texture_getCategoryByName( shader_get_textureName( shader->getName() ) ).c_str() ) ) {
                        return false;
                }
        }
@@ -703,20 +817,25 @@ TextureCategoryLoadShader( const char* directory, std::size_t& count )
        m_count = 0;
 }
 void operator()( const char* name ) const {
-       if ( shader_equal_prefix( name, "textures/" )
-                && shader_equal_prefix( name + string_length( "textures/" ), m_directory ) ) {
-               ++m_count;
-               // request the shader, this will load the texture if needed
-               // this Shader_ForName call is a kind of hack
-               IShader *pFoo = QERApp_Shader_ForName( name );
-               pFoo->DecRef();
+       if ( !shader_equal_prefix( name, "textures/" ) ) {
+               return;
+       }
+       if ( !Texture_matchCategory( m_directory, Texture_getCategoryByName( name + string_length( "textures/" ) ).c_str() ) ) {
+               return;
        }
+
+       ++m_count;
+       // request the shader, this will load the texture if needed
+       // this Shader_ForName call is a kind of hack
+       IShader *pFoo = QERApp_Shader_ForName( name );
+       pFoo->DecRef();
 }
 };
 
-void TextureDirectory_loadTexture( const char* directory, const char* texture ){
+void TextureDirectory_loadTexture( const char* category, const char* texture ){
+       CopiedString directory = Texture_getCategoryDirectory( category );
        StringOutputStream name( 256 );
-       name << directory << StringRange( texture, path_get_filename_base_end( texture ) );
+       name << "textures/" << directory.c_str() << StringRange( texture, path_get_filename_base_end( texture ) );
 
        if ( texture_name_ignore( name.c_str() ) ) {
                return;
@@ -727,6 +846,13 @@ void TextureDirectory_loadTexture( const char* directory, const char* texture ){
                return;
        }
 
+       if ( !shader_equal_prefix( name.c_str(), "textures/" ) ) { // can't happen
+               return;
+       }
+       if ( !Texture_matchCategory( category, Texture_getCategoryByName( name.c_str() + string_length( "textures/" ) ).c_str() ) ) {
+               return;
+       }
+
        // if a texture is already in use to represent a shader, ignore it
        IShader* shader = QERApp_Shader_ForName( name.c_str() );
        shader->DecRef();
@@ -735,13 +861,15 @@ typedef ConstPointerCaller1<char, const char*, TextureDirectory_loadTexture> Tex
 
 class LoadTexturesByTypeVisitor : public ImageModules::Visitor
 {
-const char* m_dirstring;
+const char* m_catstring;
 public:
-LoadTexturesByTypeVisitor( const char* dirstring )
-       : m_dirstring( dirstring ){
+LoadTexturesByTypeVisitor( const char* catstring )
+       : m_catstring( catstring ){
 }
 void visit( const char* minor, const _QERPlugImageTable& table ) const {
-       GlobalFileSystem().forEachFile( m_dirstring, minor, TextureDirectoryLoadTextureCaller( m_dirstring ) );
+       StringOutputStream dirstring( 64 );
+       dirstring << "textures/" << Texture_getCategoryDirectory( m_catstring ).c_str();
+       GlobalFileSystem().forEachFile( dirstring.c_str(), minor, TextureDirectoryLoadTextureCaller( m_catstring ) );
 }
 };
 
@@ -763,11 +891,7 @@ void TextureBrowser_ShowDirectory( TextureBrowser& textureBrowser, const char* d
 
                if ( g_pGameDescription->mGameType != "doom3" ) {
                        // load remaining texture files
-
-                       StringOutputStream dirstring( 64 );
-                       dirstring << "textures/" << directory;
-
-                       Radiant_getImageModules().foreachModule( LoadTexturesByTypeVisitor( dirstring.c_str() ) );
+                       Radiant_getImageModules().foreachModule( LoadTexturesByTypeVisitor( directory ) );
                }
        }
 
@@ -813,6 +937,11 @@ void TextureBrowser_showShadersExport( const BoolImportCallback& importer ){
 }
 typedef FreeCaller1<const BoolImportCallback&, TextureBrowser_showShadersExport> TextureBrowserShowShadersExport;
 
+void TextureBrowser_softGroupsExport( const BoolImportCallback& importer ){
+       importer( GlobalTextureBrowser().m_softGroups );
+}
+typedef FreeCaller1<const BoolImportCallback&, TextureBrowser_softGroupsExport> TextureBrowserSoftGroupsExport;
+
 void TextureBrowser_showShaderlistOnly( const BoolImportCallback& importer ){
        importer( g_TextureBrowser_shaderlistOnly );
 }
@@ -1386,6 +1515,10 @@ void TextureGroups_constructTreeModel( TextureGroups groups, GtkTreeStore* store
        {
                const char* dirName = ( *i ).c_str();
                const char* firstUnderscore = strchr( dirName, '_' );
+               const char* firstSlash = strchr( dirName, '/' );
+               if ( firstSlash && ( !firstUnderscore || firstSlash < firstUnderscore ) ) {
+                       firstUnderscore = firstSlash;
+               }
                StringRange dirRoot( dirName, ( firstUnderscore == 0 ) ? dirName : firstUnderscore + 1 );
 
                TextureGroups::const_iterator next = i;
@@ -1394,7 +1527,12 @@ void TextureGroups_constructTreeModel( TextureGroups groups, GtkTreeStore* store
                         && next != groups.end()
                         && string_equal_start( ( *next ).c_str(), dirRoot ) ) {
                        gtk_tree_store_append( store, &iter, NULL );
-                       gtk_tree_store_set( store, &iter, 0, CopiedString( StringRange( dirName, firstUnderscore ) ).c_str(), -1 );
+                       StringOutputStream ost( 64 );
+                       ost << CopiedString( StringRange( dirName, firstUnderscore ) ).c_str();
+                       if ( *firstUnderscore == '/' ) {
+                               ost << "/*";
+                       }
+                       gtk_tree_store_set( store, &iter, 0, ost.c_str(), -1 );
 
                        // keep going...
                        while ( i != groups.end() && string_equal_start( ( *i ).c_str(), dirRoot ) )
@@ -1470,10 +1608,6 @@ void TreeView_onRowActivated( GtkTreeView* treeview, GtkTreePath* path, GtkTreeV
 
                g_TextureBrowser.m_searchedTags = false;
 
-               if ( !TextureBrowser_showWads() ) {
-                       strcat( dirName, "/" );
-               }
-
                ScopeDisableScreenUpdates disableScreenUpdates( dirName, "Loading Textures" );
                TextureBrowser_ShowDirectory( GlobalTextureBrowser(), dirName );
                TextureBrowser_queueDraw( GlobalTextureBrowser() );
@@ -1583,6 +1717,8 @@ GtkMenuItem* TextureBrowser_constructViewMenu( GtkMenu* menu ){
                create_menu_item_with_mnemonic( menu, "Show Untagged", "ShowUntagged" );
        }
 
+       create_check_menu_item_with_mnemonic( menu, "Use soft groups", "ToggleSoftGroups" );
+
        create_check_menu_item_with_mnemonic( menu, "Fixed Size", "FixedSize" );
 
        if ( string_empty( g_pGameDescription->getKeyValue( "show_wads" ) ) ) {
@@ -2318,6 +2454,15 @@ void TextureBrowser_ToggleShowShaders(){
        TextureBrowser_queueDraw( g_TextureBrowser );
 }
 
+void TextureBrowser_constructTreeStore();
+void TextureBrowser_ToggleSoftGroups(){
+       g_TextureBrowser.m_softGroups ^= 1;
+       g_TextureBrowser.m_softgroups_item.update();
+       TextureBrowser_constructTreeStore();
+       GlobalShaderSystem().refresh();
+       UpdateAllWindows();
+}
+
 void TextureBrowser_ToggleShowShaderListOnly(){
        g_TextureBrowser_shaderlistOnly ^= 1;
        g_TextureBrowser.m_showshaderlistonly_item.update();
@@ -2482,6 +2627,7 @@ void TextureBrowser_Construct(){
        GlobalCommands_insert( "ToggleTextures", FreeCaller<TextureBrowser_toggleShow>(), Accelerator( 'T' ) );
        GlobalToggles_insert( "ToggleShowShaders", FreeCaller<TextureBrowser_ToggleShowShaders>(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_showshaders_item ) );
        GlobalToggles_insert( "ToggleShowShaderlistOnly", FreeCaller<TextureBrowser_ToggleShowShaderListOnly>(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_showshaderlistonly_item ) );
+       GlobalToggles_insert( "ToggleSoftGroups",  FreeCaller<TextureBrowser_ToggleSoftGroups>(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_softgroups_item ) );
        GlobalToggles_insert( "FixedSize", FreeCaller<TextureBrowser_FixedSize>(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_fixedsize_item ) );
        GlobalToggles_insert( "FilterNotex", FreeCaller<TextureBrowser_FilterNotex>(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_filternotex_item ) );
 
@@ -2495,6 +2641,7 @@ void TextureBrowser_Construct(){
                                                                                                 );
        GlobalPreferenceSystem().registerPreference( "ShowShaders", BoolImportStringCaller( GlobalTextureBrowser().m_showShaders ), BoolExportStringCaller( GlobalTextureBrowser().m_showShaders ) );
        GlobalPreferenceSystem().registerPreference( "ShowShaderlistOnly", BoolImportStringCaller( g_TextureBrowser_shaderlistOnly ), BoolExportStringCaller( g_TextureBrowser_shaderlistOnly ) );
+       GlobalPreferenceSystem().registerPreference( "SoftGroups", BoolImportStringCaller( GlobalTextureBrowser().m_softGroups ), BoolExportStringCaller( GlobalTextureBrowser().m_softGroups ) );
        GlobalPreferenceSystem().registerPreference( "FixedSize", BoolImportStringCaller( g_TextureBrowser_fixedSize ), BoolExportStringCaller( g_TextureBrowser_fixedSize ) );
        GlobalPreferenceSystem().registerPreference( "FilterNotex", BoolImportStringCaller( g_TextureBrowser_filterNotex ), BoolExportStringCaller( g_TextureBrowser_filterNotex ) );
        GlobalPreferenceSystem().registerPreference( "LoadShaders", IntImportStringCaller( reinterpret_cast<int&>( GlobalTextureBrowser().m_startupShaders ) ), IntExportStringCaller( reinterpret_cast<int&>( GlobalTextureBrowser().m_startupShaders ) ) );