X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=radiant%2Ftexwindow.cpp;h=d18a152e8333fdc3efcbe67ef4bcc3bc2c1ba118;hb=f6b9708d076f575f8ecc2baec9d5057824dbfcae;hp=94717d0949bd75a9d9b913c62b72ef40ee42bdc3;hpb=7fc621fc78d0e040dc2c12f38dc53dd9048215dc;p=xonotic%2Fnetradiant.git diff --git a/radiant/texwindow.cpp b/radiant/texwindow.cpp index 94717d09..d18a152e 100644 --- a/radiant/texwindow.cpp +++ b/radiant/texwindow.cpp @@ -132,8 +132,9 @@ typedef ReferenceCaller1 namespace { bool g_TextureBrowser_shaderlistOnly = false; -bool g_TextureBrowser_fixedSize = false; +bool g_TextureBrowser_fixedSize = true; bool g_TextureBrowser_filterNotex = false; +bool g_TextureBrowser_enableAlpha = true; } class DeferredAdjustment @@ -194,6 +195,9 @@ typedef FreeCaller1 void TextureBrowser_showShadersExport( const BoolImportCallback& importer ); typedef FreeCaller1 TextureBrowserShowShadersExport; +void TextureBrowser_showTexturesExport( const BoolImportCallback& importer ); +typedef FreeCaller1 TextureBrowserShowTexturesExport; + void TextureBrowser_showShaderlistOnly( const BoolImportCallback& importer ); typedef FreeCaller1 TextureBrowserShowShaderlistOnlyExport; @@ -203,6 +207,9 @@ typedef FreeCaller1 Texture void TextureBrowser_filterNotex( const BoolImportCallback& importer ); typedef FreeCaller1 TextureBrowserFilterNotexExport; +void TextureBrowser_enableAlpha( const BoolImportCallback& importer ); +typedef FreeCaller1 TextureBrowserEnableAlphaExport; + class TextureBrowser { public: @@ -235,9 +242,11 @@ std::set m_found_shaders; ToggleItem m_hideunused_item; ToggleItem m_showshaders_item; +ToggleItem m_showtextures_item; ToggleItem m_showshaderlistonly_item; ToggleItem m_fixedsize_item; ToggleItem m_filternotex_item; +ToggleItem m_enablealpha_item; guint m_sizeHandler; guint m_exposeHandler; @@ -254,6 +263,7 @@ std::size_t m_mouseWheelScrollIncrement; std::size_t m_textureScale; // make the texture increments match the grid changes bool m_showShaders; +bool m_showTextures; bool m_showTextureScrollbar; StartupShaders m_startupShaders; // if true, the texture window will only display in-use shaders @@ -264,49 +274,87 @@ bool m_searchedTags; bool m_tags; // The uniform size (in pixels) that textures are resized to when m_resizeTextures is true. int m_uniformTextureSize; +int m_uniformTextureMinSize; // Return the display width of a texture in the texture browser -int getTextureWidth( qtexture_t* tex ){ - int width; +/*void getTextureWH( qtexture_t* tex, int *width, int *height ){ if ( !g_TextureBrowser_fixedSize ) { // Don't use uniform size - width = (int)( tex->width * ( (float)m_textureScale / 100 ) ); + *width = (int)( tex->width * ( (float)m_textureScale / 100 ) ); + *height = (int)( tex->height * ( (float)m_textureScale / 100 ) ); + } - else if - ( tex->width >= tex->height ) { + else if ( tex->width >= tex->height ) { // Texture is square, or wider than it is tall - width = m_uniformTextureSize; + if ( tex->width >= m_uniformTextureSize ){ + *width = m_uniformTextureSize; + *height = (int)( m_uniformTextureSize * ( (float)tex->height / tex->width ) ); + } + else if ( tex->width <= m_uniformTextureMinSize ){ + *width = m_uniformTextureMinSize; + *height = (int)( m_uniformTextureMinSize * ( (float)tex->height / tex->width ) ); + } + else { + *width = tex->width; + *height = tex->height; + } } else { - // Otherwise, preserve the texture's aspect ratio - width = (int)( m_uniformTextureSize * ( (float)tex->width / tex->height ) ); + // Texture taller than it is wide + if ( tex->height >= m_uniformTextureSize ){ + *height = m_uniformTextureSize; + *width = (int)( m_uniformTextureSize * ( (float)tex->width / tex->height ) ); + } + else if ( tex->height <= m_uniformTextureMinSize ){ + *height = m_uniformTextureMinSize; + *width = (int)( m_uniformTextureMinSize * ( (float)tex->width / tex->height ) ); + } + else { + *width = tex->width; + *height = tex->height; + } } - return width; } -// Return the display height of a texture in the texture browser -int getTextureHeight( qtexture_t* tex ){ - int height; - if ( !g_TextureBrowser_fixedSize ) { +*/ +void getTextureWH( qtexture_t* tex, int &W, int &H ){ // Don't use uniform size - height = (int)( tex->height * ( (float)m_textureScale / 100 ) ); - } - else if ( tex->height >= tex->width ) { - // Texture is square, or taller than it is wide - height = m_uniformTextureSize; - } - else { - // Otherwise, preserve the texture's aspect ratio - height = (int)( m_uniformTextureSize * ( (float)tex->height / tex->width ) ); + W = (int)( tex->width * ( (float)m_textureScale / 100 ) ); + H = (int)( tex->height * ( (float)m_textureScale / 100 ) ); + + if ( g_TextureBrowser_fixedSize ){ + if ( W >= H ) { + // Texture is square, or wider than it is tall + if ( W >= m_uniformTextureSize ){ + H = m_uniformTextureSize * H / W; + W = m_uniformTextureSize; + } + else if ( W <= m_uniformTextureMinSize ){ + H = m_uniformTextureMinSize * H / W; + W = m_uniformTextureMinSize; + } + } + else { + // Texture taller than it is wide + if ( H >= m_uniformTextureSize ){ + W = m_uniformTextureSize * W / H; + H = m_uniformTextureSize; + } + else if ( H <= m_uniformTextureMinSize ){ + W = m_uniformTextureMinSize * W / H; + H = m_uniformTextureMinSize; + } + } } - return height; } TextureBrowser() : m_texture_scroll( 0 ), m_hideunused_item( TextureBrowserHideUnusedExport() ), m_showshaders_item( TextureBrowserShowShadersExport() ), + m_showtextures_item( TextureBrowserShowTexturesExport() ), m_showshaderlistonly_item( TextureBrowserShowShaderlistOnlyExport() ), m_fixedsize_item( TextureBrowserFixedSizeExport() ), m_filternotex_item( TextureBrowserFilterNotexExport() ), + m_enablealpha_item( TextureBrowserEnableAlphaExport() ), m_heightChanged( true ), m_originInvalid( true ), m_scrollAdjustment( TextureBrowser_scrollChanged, this ), @@ -314,13 +362,15 @@ TextureBrowser() : m_mouseWheelScrollIncrement( 64 ), m_textureScale( 50 ), m_showShaders( true ), + m_showTextures( true ), m_showTextureScrollbar( true ), m_startupShaders( STARTUPSHADERS_NONE ), m_hideUnused( false ), m_rmbSelected( false ), m_searchedTags( false ), m_tags( false ), - m_uniformTextureSize( 128 ){ + m_uniformTextureSize( 160 ), + m_uniformTextureMinSize( 48 ){ } }; @@ -421,8 +471,8 @@ void Texture_StartPos( TextureLayout& layout ){ void Texture_NextPos( TextureBrowser& textureBrowser, TextureLayout& layout, qtexture_t* current_texture, int *x, int *y ){ qtexture_t* q = current_texture; - int nWidth = textureBrowser.getTextureWidth( q ); - int nHeight = textureBrowser.getTextureHeight( q ); + int nWidth, nHeight; + textureBrowser.getTextureWH( q, nWidth, nHeight ); if ( layout.current_x + nWidth > textureBrowser.width - 8 && layout.current_row ) { // go to the next row unless the texture is the first on the row layout.current_x = 8; layout.current_y -= layout.current_row + TextureBrowser_fontHeight( textureBrowser ) + 4; @@ -461,7 +511,7 @@ CopiedString g_notex; CopiedString g_shadernotex; // if texture_showinuse jump over non in-use textures -bool Texture_IsShown( IShader* shader, bool show_shaders, bool hideUnused ){ +bool Texture_IsShown( IShader* shader, bool show_shaders, bool show_textures, bool hideUnused ){ // filter notex / shadernotex images if ( g_TextureBrowser_filterNotex && ( string_equal( g_notex.c_str(), shader->getTexture()->name ) || string_equal( g_shadernotex.c_str(), shader->getTexture()->name ) ) ) { return false; @@ -488,6 +538,10 @@ bool Texture_IsShown( IShader* shader, bool show_shaders, bool hideUnused ){ return false; } + if ( !show_textures && shader->IsDefault() ) { + return false; + } + if ( hideUnused && !shader->IsInUse() ) { return false; } @@ -528,13 +582,15 @@ void TextureBrowser_evaluateHeight( TextureBrowser& textureBrowser ){ { IShader* shader = QERApp_ActiveShaders_IteratorCurrent(); - if ( !Texture_IsShown( shader, textureBrowser.m_showShaders, textureBrowser.m_hideUnused ) ) { + if ( !Texture_IsShown( shader, textureBrowser.m_showShaders, textureBrowser.m_showTextures, textureBrowser.m_hideUnused ) ) { continue; } int x, y; Texture_NextPos( textureBrowser, layout, shader->getTexture(), &x, &y ); - textureBrowser.m_nTotalHeight = std::max( textureBrowser.m_nTotalHeight, abs( layout.current_y ) + TextureBrowser_fontHeight( textureBrowser ) + textureBrowser.getTextureHeight( shader->getTexture() ) + 4 ); + int nWidth, nHeight; + textureBrowser.getTextureWH( shader->getTexture(), nWidth, nHeight ); + textureBrowser.m_nTotalHeight = std::max( textureBrowser.m_nTotalHeight, abs( layout.current_y ) + TextureBrowser_fontHeight( textureBrowser ) + nHeight + 4 ); } } } @@ -581,12 +637,16 @@ void TextureBrowser_addActiveShadersChangedCallback( const SignalHandler& handle g_activeShadersChangedCallbacks.connectLast( handler ); } +void TextureBrowser_constructTreeStore(); + class ShadersObserver : public ModuleObserver { Signal0 m_realiseCallbacks; public: void realise(){ m_realiseCallbacks(); + /* texturebrowser tree update on vfs restart */ +// TextureBrowser_constructTreeStore(); } void unrealise(){ } @@ -813,6 +873,11 @@ void TextureBrowser_showShadersExport( const BoolImportCallback& importer ){ } typedef FreeCaller1 TextureBrowserShowShadersExport; +void TextureBrowser_showTexturesExport( const BoolImportCallback& importer ){ + importer( GlobalTextureBrowser().m_showTextures ); +} +typedef FreeCaller1 TextureBrowserShowTexturesExport; + void TextureBrowser_showShaderlistOnly( const BoolImportCallback& importer ){ importer( g_TextureBrowser_shaderlistOnly ); } @@ -828,6 +893,11 @@ void TextureBrowser_filterNotex( const BoolImportCallback& importer ){ } typedef FreeCaller1 TextureBrowser_filterNotexExport; +void TextureBrowser_enableAlpha( const BoolImportCallback& importer ){ + importer( g_TextureBrowser_enableAlpha ); +} +typedef FreeCaller1 TextureBrowser_enableAlphaExport; + void TextureBrowser_SetHideUnused( TextureBrowser& textureBrowser, bool hideUnused ){ if ( hideUnused ) { textureBrowser.m_hideUnused = true; @@ -863,7 +933,7 @@ void TextureBrowser_Focus( TextureBrowser& textureBrowser, const char* name ){ { IShader* shader = QERApp_ActiveShaders_IteratorCurrent(); - if ( !Texture_IsShown( shader, textureBrowser.m_showShaders, textureBrowser.m_hideUnused ) ) { + if ( !Texture_IsShown( shader, textureBrowser.m_showShaders, textureBrowser.m_showTextures, textureBrowser.m_hideUnused ) ) { continue; } @@ -904,7 +974,7 @@ IShader* Texture_At( TextureBrowser& textureBrowser, int mx, int my ){ { IShader* shader = QERApp_ActiveShaders_IteratorCurrent(); - if ( !Texture_IsShown( shader, textureBrowser.m_showShaders, textureBrowser.m_hideUnused ) ) { + if ( !Texture_IsShown( shader, textureBrowser.m_showShaders, textureBrowser.m_showTextures, textureBrowser.m_hideUnused ) ) { continue; } @@ -915,8 +985,8 @@ IShader* Texture_At( TextureBrowser& textureBrowser, int mx, int my ){ break; } - int nWidth = textureBrowser.getTextureWidth( q ); - int nHeight = textureBrowser.getTextureHeight( q ); + int nWidth, nHeight; + textureBrowser.getTextureWH( q, nWidth, nHeight ); if ( mx > x && mx - x < nWidth && my < y && y - my < nHeight + TextureBrowser_fontHeight( textureBrowser ) ) { return shader; @@ -1021,7 +1091,15 @@ void Texture_Draw( TextureBrowser& textureBrowser ){ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glDisable( GL_DEPTH_TEST ); - glDisable( GL_BLEND ); + //glDisable( GL_BLEND ); + if ( g_TextureBrowser_enableAlpha ) { + glEnable( GL_BLEND ); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + else { + glDisable( GL_BLEND ); + } + glOrtho( 0, textureBrowser.width, originy - textureBrowser.height, originy, -100, 100 ); glEnable( GL_TEXTURE_2D ); @@ -1035,7 +1113,7 @@ void Texture_Draw( TextureBrowser& textureBrowser ){ { IShader* shader = QERApp_ActiveShaders_IteratorCurrent(); - if ( !Texture_IsShown( shader, textureBrowser.m_showShaders, textureBrowser.m_hideUnused ) ) { + if ( !Texture_IsShown( shader, textureBrowser.m_showShaders, textureBrowser.m_showTextures, textureBrowser.m_hideUnused ) ) { continue; } @@ -1046,8 +1124,8 @@ void Texture_Draw( TextureBrowser& textureBrowser ){ break; } - int nWidth = textureBrowser.getTextureWidth( q ); - int nHeight = textureBrowser.getTextureHeight( q ); + int nWidth, nHeight; + textureBrowser.getTextureWH( q, nWidth, nHeight ); if ( y != last_y ) { last_y = y; @@ -1063,8 +1141,41 @@ void Texture_Draw( TextureBrowser& textureBrowser ){ // shaders have a white border, simple textures don't // if !texture_showinuse: (some textures displayed may not be in use) // draw an additional square around with 0.5 1 0.5 color + glLineWidth( 1 ); + // shader border: + if ( !shader->IsDefault() ) { + //real 1px white/black stipple + glColor3f( 0, 0, 0 ); + glDisable( GL_TEXTURE_2D ); + + float xf = (float)x; + float yf = (float)( y - TextureBrowser_fontHeight( textureBrowser ) ); + glBegin( GL_LINE_LOOP ); + glVertex2f( xf - 1.5,yf + 1.5 ); + glVertex2f( xf - 1.5,yf - nHeight - 1.5 ); + glVertex2f( xf + 1.5 + nWidth,yf - nHeight - 1.5 ); + glVertex2f( xf + 1.5 + nWidth,yf + 1.5 ); + + glEnd(); + + glEnable( GL_LINE_STIPPLE ); + glLineStipple( 1, 0x0FFF ); + + glBegin( GL_LINE_LOOP ); + glColor3f( 1, 1, 1 ); + + glVertex2f( xf - 1.5,yf + 1.5 ); + glVertex2f( xf - 1.5,yf - nHeight - 1.5 ); + glVertex2f( xf + 1.5 + nWidth,yf - nHeight - 1.5 ); + glVertex2f( xf + 1.5 + nWidth,yf + 1.5 ); + + glEnd(); + glDisable( GL_LINE_STIPPLE ); + glEnable( GL_TEXTURE_2D ); + + } if ( shader_equal( TextureBrowser_GetSelectedShader( textureBrowser ), shader->getName() ) ) { - glLineWidth( 3 ); + glLineWidth( 2 ); if ( textureBrowser.m_rmbSelected ) { glColor3f( 0,0,1 ); } @@ -1083,35 +1194,44 @@ void Texture_Draw( TextureBrowser& textureBrowser ){ glEnable( GL_TEXTURE_2D ); glLineWidth( 1 ); } - else - { - glLineWidth( 1 ); - // shader border: - if ( !shader->IsDefault() ) { - glColor3f( 1,1,1 ); - glDisable( GL_TEXTURE_2D ); - - glBegin( GL_LINE_LOOP ); - glVertex2i( x - 1,y + 1 - TextureBrowser_fontHeight( textureBrowser ) ); - glVertex2i( x - 1,y - nHeight - 1 - TextureBrowser_fontHeight( textureBrowser ) ); - glVertex2i( x + 1 + nWidth,y - nHeight - 1 - TextureBrowser_fontHeight( textureBrowser ) ); - glVertex2i( x + 1 + nWidth,y + 1 - TextureBrowser_fontHeight( textureBrowser ) ); - glEnd(); - glEnable( GL_TEXTURE_2D ); - } + // highlight in-use textures + else if ( !textureBrowser.m_hideUnused && shader->IsInUse() ) { + //1px with float + float xf = (float)x; + float yf = (float)( y - TextureBrowser_fontHeight( textureBrowser ) ); + glColor3f( 0.5,1,0.5 ); + glDisable( GL_TEXTURE_2D ); + glBegin( GL_LINE_LOOP ); + glVertex2f( xf - 3.5,yf + 3.5 ); + glVertex2f( xf - 3.5,yf - nHeight - 3.5 ); + glVertex2f( xf + 3.5 + nWidth,yf - nHeight - 3.5 ); + glVertex2f( xf + 3.5 + nWidth,yf + 3.5 ); + glEnd(); + glEnable( GL_TEXTURE_2D ); + } - // highlight in-use textures - if ( !textureBrowser.m_hideUnused && shader->IsInUse() ) { - glColor3f( 0.5,1,0.5 ); - glDisable( GL_TEXTURE_2D ); - glBegin( GL_LINE_LOOP ); - glVertex2i( x - 3,y + 3 - TextureBrowser_fontHeight( textureBrowser ) ); - glVertex2i( x - 3,y - nHeight - 3 - TextureBrowser_fontHeight( textureBrowser ) ); - glVertex2i( x + 3 + nWidth,y - nHeight - 3 - TextureBrowser_fontHeight( textureBrowser ) ); - glVertex2i( x + 3 + nWidth,y + 3 - TextureBrowser_fontHeight( textureBrowser ) ); - glEnd(); - glEnable( GL_TEXTURE_2D ); - } + // draw checkerboard for transparent textures + if ( g_TextureBrowser_enableAlpha ) + { + glDisable( GL_TEXTURE_2D ); + glBegin( GL_QUADS ); + int font_height = TextureBrowser_fontHeight( textureBrowser ); + for ( int i = 0; i < nHeight; i += 8 ) + for ( int j = 0; j < nWidth; j += 8 ) + { + unsigned char color = (i + j) / 8 % 2 ? 0x66 : 0x99; + glColor3ub( color, color, color ); + int left = j; + int right = std::min(j+8, nWidth); + int top = i; + int bottom = std::min(i+8, nHeight); + glVertex2i(x + right, y - nHeight - font_height + top); + glVertex2i(x + left, y - nHeight - font_height + top); + glVertex2i(x + left, y - nHeight - font_height + bottom); + glVertex2i(x + right, y - nHeight - font_height + bottom); + } + glEnd(); + glEnable( GL_TEXTURE_2D ); } // Draw the texture @@ -1164,9 +1284,32 @@ void TextureBrowser_queueDraw( TextureBrowser& textureBrowser ){ void TextureBrowser_setScale( TextureBrowser& textureBrowser, std::size_t scale ){ textureBrowser.m_textureScale = scale; + textureBrowser.m_heightChanged = true; + textureBrowser.m_originInvalid = true; + g_activeShadersChangedCallbacks(); + + TextureBrowser_queueDraw( textureBrowser ); +} + +void TextureBrowser_setUniformSize( TextureBrowser& textureBrowser, std::size_t scale ){ + textureBrowser.m_uniformTextureSize = scale; + + textureBrowser.m_heightChanged = true; + textureBrowser.m_originInvalid = true; + g_activeShadersChangedCallbacks(); + TextureBrowser_queueDraw( textureBrowser ); } +void TextureBrowser_setUniformMinSize( TextureBrowser& textureBrowser, std::size_t scale ){ + textureBrowser.m_uniformTextureMinSize = scale; + + textureBrowser.m_heightChanged = true; + textureBrowser.m_originInvalid = true; + g_activeShadersChangedCallbacks(); + + TextureBrowser_queueDraw( textureBrowser ); +} void TextureBrowser_MouseWheel( TextureBrowser& textureBrowser, bool bUp ){ int originy = TextureBrowser_getOriginY( textureBrowser ); @@ -1280,6 +1423,29 @@ gboolean TextureBrowser_button_press( GtkWidget* widget, GdkEventButton* event, } } } + else if ( event->type == GDK_2BUTTON_PRESS && event->button == 1 ) { + CopiedString texName = textureBrowser->shader; + const char* sh = texName.c_str(); + char* dir = strrchr( sh, '/' ); + if( dir != NULL ){ + *(dir + 1) = '\0'; + dir = strchr( sh, '/' ); + if( dir != NULL ){ + dir++; + if( *dir != '\0'){ + ScopeDisableScreenUpdates disableScreenUpdates( dir, "Loading Textures" ); + TextureBrowser_ShowDirectory( *textureBrowser, dir ); + TextureBrowser_Focus( *textureBrowser, textureBrowser->shader.c_str() ); + TextureBrowser_queueDraw( *textureBrowser ); + } + } + } + } + else if ( event->type == GDK_2BUTTON_PRESS && event->button == 3 ) { + ScopeDisableScreenUpdates disableScreenUpdates( TextureBrowser_getComonShadersDir(), "Loading Textures" ); + TextureBrowser_ShowDirectory( *textureBrowser, TextureBrowser_getComonShadersDir() ); + TextureBrowser_queueDraw( *textureBrowser ); + } return FALSE; } @@ -1477,6 +1643,8 @@ void TreeView_onRowActivated( GtkTreeView* treeview, GtkTreePath* path, GtkTreeV ScopeDisableScreenUpdates disableScreenUpdates( dirName, "Loading Textures" ); TextureBrowser_ShowDirectory( GlobalTextureBrowser(), dirName ); TextureBrowser_queueDraw( GlobalTextureBrowser() ); + //deactivate, so SPACE and RETURN wont be broken for 2d + gtk_window_set_focus( GTK_WINDOW( gtk_widget_get_toplevel( GTK_WIDGET( treeview ) ) ), NULL ); } } @@ -1560,12 +1728,9 @@ GtkMenuItem* TextureBrowser_constructViewMenu( GtkMenu* menu ){ } create_check_menu_item_with_mnemonic( menu, "Hide _Unused", "ShowInUse" ); - if ( string_empty( g_pGameDescription->getKeyValue( "show_wads" ) ) ) { - create_check_menu_item_with_mnemonic( menu, "Hide Image Missing", "FilterNotex" ); - } + create_menu_item_with_mnemonic( menu, "Show All", "ShowAllTextures" ); menu_separator( menu ); - create_menu_item_with_mnemonic( menu, "Show All", "ShowAllTextures" ); // we always want to show shaders but don't want a "Show Shaders" menu for doom3 and .wad file games if ( g_pGameDescription->mGameType == "doom3" || !string_empty( g_pGameDescription->getKeyValue( "show_wads" ) ) ) { @@ -1574,16 +1739,23 @@ GtkMenuItem* TextureBrowser_constructViewMenu( GtkMenu* menu ){ else { create_check_menu_item_with_mnemonic( menu, "Show shaders", "ToggleShowShaders" ); + create_check_menu_item_with_mnemonic( menu, "Show textures", "ToggleShowTextures" ); + menu_separator( menu ); } - if ( g_pGameDescription->mGameType != "doom3" && string_empty( g_pGameDescription->getKeyValue( "show_wads" ) ) ) { - create_check_menu_item_with_mnemonic( menu, "Shaders Only", "ToggleShowShaderlistOnly" ); - } if ( g_TextureBrowser.m_tags ) { create_menu_item_with_mnemonic( menu, "Show Untagged", "ShowUntagged" ); } + if ( g_pGameDescription->mGameType != "doom3" && string_empty( g_pGameDescription->getKeyValue( "show_wads" ) ) ) { + create_check_menu_item_with_mnemonic( menu, "ShaderList Only", "ToggleShowShaderlistOnly" ); + } + if ( string_empty( g_pGameDescription->getKeyValue( "show_wads" ) ) ) { + create_check_menu_item_with_mnemonic( menu, "Hide Image Missing", "FilterNotex" ); + menu_separator( menu ); + } create_check_menu_item_with_mnemonic( menu, "Fixed Size", "FixedSize" ); + create_check_menu_item_with_mnemonic( menu, "Transparency", "EnableAlpha" ); if ( string_empty( g_pGameDescription->getKeyValue( "show_wads" ) ) ) { menu_separator( menu ); @@ -1594,6 +1766,10 @@ GtkMenuItem* TextureBrowser_constructViewMenu( GtkMenu* menu ){ return textures_menu_item; } +void Popup_View_Menu( GtkWidget *widget, GtkMenu *menu ){ + gtk_menu_popup( menu, NULL, NULL, NULL, NULL, 1, gtk_get_current_event_time() ); +} + GtkMenuItem* TextureBrowser_constructToolsMenu( GtkMenu* menu ){ GtkMenuItem* textures_menu_item = new_sub_menu_item_with_mnemonic( "_Tools" ); @@ -1877,11 +2053,11 @@ void TextureBrowser_checkTagFile(){ void TextureBrowser_SetNotex(){ StringOutputStream name( 256 ); - name << GlobalRadiant().getAppPath() << "bitmaps/notex.bmp"; + name << GlobalRadiant().getAppPath() << "bitmaps/notex.png"; g_notex = name.c_str(); name = NULL; - name << GlobalRadiant().getAppPath() << "bitmaps/shadernotex.bmp"; + name << GlobalRadiant().getAppPath() << "bitmaps/shadernotex.png"; g_shadernotex = name.c_str(); } @@ -1901,25 +2077,56 @@ GtkWidget* TextureBrowser_constructWindow( GtkWindow* toplevel ){ GtkWidget* table = gtk_table_new( 3, 3, FALSE ); GtkWidget* frame_table = NULL; GtkWidget* vbox = gtk_vbox_new( FALSE, 0 ); - gtk_table_attach( GTK_TABLE( table ), vbox, 0, 1, 1, 3, GTK_FILL, GTK_FILL, 0, 0 ); + gtk_table_attach( GTK_TABLE( table ), vbox, 0, 1, 0, 3, GTK_FILL, GTK_FILL, 0, 0 ); gtk_widget_show( vbox ); - GtkWidget* menu_bar; + //GtkWidget* menu_bar; + GtkToolbar* toolbar; { // menu bar - menu_bar = gtk_menu_bar_new(); + //menu_bar = gtk_menu_bar_new(); GtkWidget* menu_view = gtk_menu_new(); - GtkWidget* view_item = (GtkWidget*)TextureBrowser_constructViewMenu( GTK_MENU( menu_view ) ); - gtk_menu_item_set_submenu( GTK_MENU_ITEM( view_item ), menu_view ); - gtk_menu_bar_append( GTK_MENU_BAR( menu_bar ), view_item ); + //GtkWidget* view_item = (GtkWidget*) + TextureBrowser_constructViewMenu( GTK_MENU( menu_view ) ); + gtk_menu_set_title( GTK_MENU( menu_view ), "View" ); + //gtk_menu_item_set_submenu( GTK_MENU_ITEM( view_item ), menu_view ); + //gtk_menu_bar_append( GTK_MENU_BAR( menu_bar ), view_item ); + + toolbar = GTK_TOOLBAR( gtk_toolbar_new() ); + //gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( toolbar ), 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0 ); + gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( toolbar ), FALSE, FALSE, 0 ); + + //view menu button + GtkButton* button = GTK_BUTTON( gtk_button_new() ); + button_set_icon( button, "texbro_view.png" ); + gtk_widget_show( GTK_WIDGET( button ) ); + gtk_button_set_relief( button, GTK_RELIEF_NONE ); + gtk_widget_set_size_request( GTK_WIDGET( button ), 24, 24 ); + GTK_WIDGET_UNSET_FLAGS( GTK_WIDGET( button ), GTK_CAN_FOCUS ); + GTK_WIDGET_UNSET_FLAGS( GTK_WIDGET( button ), GTK_CAN_DEFAULT ); + gtk_toolbar_append_element( toolbar, GTK_TOOLBAR_CHILD_WIDGET, GTK_WIDGET( button ), "", "View", "", 0, 0, 0 ); + g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( Popup_View_Menu ), menu_view ); + + //to show detached menu over floating tex bro + gtk_menu_attach_to_widget( GTK_MENU( menu_view ), GTK_WIDGET( button ), NULL ); + + button = toolbar_append_button( toolbar, "Find / Replace...", "texbro_gtk-find-and-replace.png", "FindReplaceTextures" ); + gtk_widget_set_size_request( GTK_WIDGET( button ), 22, 22 ); + + + button = toolbar_append_button( toolbar, "Flush & Reload Shaders", "texbro_refresh.png", "RefreshShaders" ); + gtk_widget_set_size_request( GTK_WIDGET( button ), 22, 22 ); + gtk_widget_show( GTK_WIDGET( toolbar ) ); + +/* GtkWidget* menu_tools = gtk_menu_new(); GtkWidget* tools_item = (GtkWidget*)TextureBrowser_constructToolsMenu( GTK_MENU( menu_tools ) ); gtk_menu_item_set_submenu( GTK_MENU_ITEM( tools_item ), menu_tools ); gtk_menu_bar_append( GTK_MENU_BAR( menu_bar ), tools_item ); - - gtk_table_attach( GTK_TABLE( table ), menu_bar, 0, 3, 0, 1, GTK_FILL, GTK_SHRINK, 0, 0 ); - gtk_widget_show( menu_bar ); +*/ + //gtk_table_attach( GTK_TABLE( table ), menu_bar, 0, 3, 0, 1, GTK_FILL, GTK_SHRINK, 0, 0 ); + //gtk_widget_show( menu_bar ); } { // Texture TreeView g_TextureBrowser.m_scr_win_tree = gtk_scrolled_window_new( NULL, NULL ); @@ -1977,9 +2184,24 @@ GtkWidget* TextureBrowser_constructWindow( GtkWindow* toplevel ){ } { // tag menu bar GtkWidget* menu_tags = gtk_menu_new(); - GtkWidget* tags_item = (GtkWidget*)TextureBrowser_constructTagsMenu( GTK_MENU( menu_tags ) ); - gtk_menu_item_set_submenu( GTK_MENU_ITEM( tags_item ), menu_tags ); - gtk_menu_bar_append( GTK_MENU_BAR( menu_bar ), tags_item ); + //GtkWidget* tags_item = (GtkWidget*) + TextureBrowser_constructTagsMenu( GTK_MENU( menu_tags ) ); + //gtk_menu_item_set_submenu( GTK_MENU_ITEM( tags_item ), menu_tags ); + //gtk_menu_bar_append( GTK_MENU_BAR( menu_bar ), tags_item ); + + GtkButton* button = GTK_BUTTON( gtk_button_new() ); + //button_set_icon( button, "texbro_tags.png" ); + GtkWidget *label = gtk_label_new (">t"); + gtk_container_add (GTK_CONTAINER (button), label); + gtk_widget_show (label); + + gtk_widget_show( GTK_WIDGET( button ) ); + gtk_button_set_relief( button, GTK_RELIEF_NONE ); + gtk_widget_set_size_request( GTK_WIDGET( button ), 22, 22 ); + GTK_WIDGET_UNSET_FLAGS( GTK_WIDGET( button ), GTK_CAN_FOCUS ); + GTK_WIDGET_UNSET_FLAGS( GTK_WIDGET( button ), GTK_CAN_DEFAULT ); + gtk_toolbar_append_element( toolbar, GTK_TOOLBAR_CHILD_WIDGET, GTK_WIDGET( button ), "", "Tags", "", 0, 0, 0 ); + g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( Popup_View_Menu ), menu_tags ); } { // Tag TreeView g_TextureBrowser.m_scr_win_tags = gtk_scrolled_window_new( NULL, NULL ); @@ -2307,14 +2529,62 @@ void TextureBrowser_pasteTag(){ } void RefreshShaders(){ - ScopeDisableScreenUpdates disableScreenUpdates( "Processing...", "Loading Shaders" ); - GlobalShaderSystem().refresh(); - UpdateAllWindows(); + + /* When shaders are refreshed, forces reloading the textures as well. + Previously it would at best only display shaders, at worst mess up some textured objects. */ + + GtkTreeSelection* selection = gtk_tree_view_get_selection((GtkTreeView*)GlobalTextureBrowser().m_treeViewTree); + GtkTreeModel* model = NULL; + GtkTreeIter iter; + if ( gtk_tree_selection_get_selected (selection, &model, &iter) ) + { + gchar dirName[1024]; + gchar* buffer; + gtk_tree_model_get( model, &iter, 0, &buffer, -1 ); + strcpy( dirName, buffer ); + g_free( buffer ); + if ( !TextureBrowser_showWads() ) { + strcat( dirName, "/" ); + } + + ScopeDisableScreenUpdates disableScreenUpdates( "Processing...", "Loading Shaders" ); + GlobalShaderSystem().refresh(); + /* texturebrowser tree update on vfs restart */ + TextureBrowser_constructTreeStore(); + UpdateAllWindows(); + + TextureBrowser_ShowDirectory( GlobalTextureBrowser(), dirName ); + TextureBrowser_queueDraw( GlobalTextureBrowser() ); + } + else{ + ScopeDisableScreenUpdates disableScreenUpdates( "Processing...", "Loading Shaders" ); + GlobalShaderSystem().refresh(); + /* texturebrowser tree update on vfs restart */ + TextureBrowser_constructTreeStore(); + UpdateAllWindows(); + } + } void TextureBrowser_ToggleShowShaders(){ g_TextureBrowser.m_showShaders ^= 1; g_TextureBrowser.m_showshaders_item.update(); + + g_TextureBrowser.m_heightChanged = true; + g_TextureBrowser.m_originInvalid = true; + g_activeShadersChangedCallbacks(); + + TextureBrowser_queueDraw( g_TextureBrowser ); +} + +void TextureBrowser_ToggleShowTextures(){ + g_TextureBrowser.m_showTextures ^= 1; + g_TextureBrowser.m_showtextures_item.update(); + + g_TextureBrowser.m_heightChanged = true; + g_TextureBrowser.m_originInvalid = true; + g_activeShadersChangedCallbacks(); + TextureBrowser_queueDraw( g_TextureBrowser ); } @@ -2328,7 +2598,9 @@ void TextureBrowser_ToggleShowShaderListOnly(){ void TextureBrowser_showAll(){ g_TextureBrowser_currentDirectory = ""; g_TextureBrowser.m_searchedTags = false; - TextureBrowser_heightChanged( g_TextureBrowser ); +// TextureBrowser_SetHideUnused( g_TextureBrowser, false ); + TextureBrowser_ToggleHideUnused(); + //TextureBrowser_heightChanged( g_TextureBrowser ); TextureBrowser_updateTitle(); } @@ -2371,6 +2643,12 @@ void TextureBrowser_FilterNotex(){ TextureBrowser_activeShadersChanged( GlobalTextureBrowser() ); } +void TextureBrowser_EnableAlpha(){ + g_TextureBrowser_enableAlpha ^= 1; + GlobalTextureBrowser().m_enablealpha_item.update(); + TextureBrowser_activeShadersChanged( GlobalTextureBrowser() ); +} + void TextureBrowser_exportTitle( const StringImportCallback& importer ){ StringOutputStream buffer( 64 ); buffer << "Textures: "; @@ -2429,6 +2707,18 @@ void TextureScaleExport( TextureBrowser& textureBrowser, const IntImportCallback } typedef ReferenceCaller1 TextureScaleExportCaller; +void UniformTextureSizeImport( TextureBrowser& textureBrowser, int value ){ + if ( value >= 16 ) + TextureBrowser_setUniformSize( textureBrowser, value ); +} +typedef ReferenceCaller1 UniformTextureSizeImportCaller; + +void UniformTextureMinSizeImport( TextureBrowser& textureBrowser, int value ){ + if ( value >= 16 ) + TextureBrowser_setUniformMinSize( textureBrowser, value ); +} +typedef ReferenceCaller1 UniformTextureMinSizeImportCaller; + void TextureBrowser_constructPreferences( PreferencesPage& page ){ page.appendCheckBox( "", "Texture scrollbar", @@ -2444,6 +2734,8 @@ void TextureBrowser_constructPreferences( PreferencesPage& page ){ IntExportCallback( TextureScaleExportCaller( GlobalTextureBrowser() ) ) ); } + page.appendSpinner( "Thumbnails Max Size", GlobalTextureBrowser().m_uniformTextureSize, GlobalTextureBrowser().m_uniformTextureSize, 16, 8192 ); + page.appendSpinner( "Thumbnails Min Size", GlobalTextureBrowser().m_uniformTextureMinSize, GlobalTextureBrowser().m_uniformTextureMinSize, 16, 8192 ); page.appendEntry( "Mousewheel Increment", GlobalTextureBrowser().m_mouseWheelScrollIncrement ); { const char* startup_shaders[] = { "None", TextureBrowser_getComonShadersName() }; @@ -2481,22 +2773,32 @@ void TextureBrowser_Construct(){ GlobalCommands_insert( "ShowAllTextures", FreeCaller(), Accelerator( 'A', (GdkModifierType)GDK_CONTROL_MASK ) ); GlobalCommands_insert( "ToggleTextures", FreeCaller(), Accelerator( 'T' ) ); GlobalToggles_insert( "ToggleShowShaders", FreeCaller(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_showshaders_item ) ); + GlobalToggles_insert( "ToggleShowTextures", FreeCaller(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_showtextures_item ) ); GlobalToggles_insert( "ToggleShowShaderlistOnly", FreeCaller(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_showshaderlistonly_item ) ); GlobalToggles_insert( "FixedSize", FreeCaller(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_fixedsize_item ) ); GlobalToggles_insert( "FilterNotex", FreeCaller(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_filternotex_item ) ); + GlobalToggles_insert( "EnableAlpha", FreeCaller(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_enablealpha_item ) ); GlobalPreferenceSystem().registerPreference( "TextureScale", makeSizeStringImportCallback( TextureBrowserSetScaleCaller( g_TextureBrowser ) ), SizeExportStringCaller( g_TextureBrowser.m_textureScale ) ); + GlobalPreferenceSystem().registerPreference( "UniformTextureSize", + makeIntStringImportCallback(UniformTextureSizeImportCaller(g_TextureBrowser)), + IntExportStringCaller(g_TextureBrowser.m_uniformTextureSize) ); + GlobalPreferenceSystem().registerPreference( "UniformTextureMinSize", + makeIntStringImportCallback(UniformTextureMinSizeImportCaller(g_TextureBrowser)), + IntExportStringCaller(g_TextureBrowser.m_uniformTextureMinSize) ); GlobalPreferenceSystem().registerPreference( "TextureScrollbar", makeBoolStringImportCallback( TextureBrowserImportShowScrollbarCaller( g_TextureBrowser ) ), BoolExportStringCaller( GlobalTextureBrowser().m_showTextureScrollbar ) ); GlobalPreferenceSystem().registerPreference( "ShowShaders", BoolImportStringCaller( GlobalTextureBrowser().m_showShaders ), BoolExportStringCaller( GlobalTextureBrowser().m_showShaders ) ); + GlobalPreferenceSystem().registerPreference( "ShowTextures", BoolImportStringCaller( GlobalTextureBrowser().m_showTextures ), BoolExportStringCaller( GlobalTextureBrowser().m_showTextures ) ); GlobalPreferenceSystem().registerPreference( "ShowShaderlistOnly", BoolImportStringCaller( g_TextureBrowser_shaderlistOnly ), BoolExportStringCaller( g_TextureBrowser_shaderlistOnly ) ); GlobalPreferenceSystem().registerPreference( "FixedSize", BoolImportStringCaller( g_TextureBrowser_fixedSize ), BoolExportStringCaller( g_TextureBrowser_fixedSize ) ); GlobalPreferenceSystem().registerPreference( "FilterNotex", BoolImportStringCaller( g_TextureBrowser_filterNotex ), BoolExportStringCaller( g_TextureBrowser_filterNotex ) ); + GlobalPreferenceSystem().registerPreference( "EnableAlpha", BoolImportStringCaller( g_TextureBrowser_enableAlpha ), BoolExportStringCaller( g_TextureBrowser_enableAlpha ) ); GlobalPreferenceSystem().registerPreference( "LoadShaders", IntImportStringCaller( reinterpret_cast( GlobalTextureBrowser().m_startupShaders ) ), IntExportStringCaller( reinterpret_cast( GlobalTextureBrowser().m_startupShaders ) ) ); GlobalPreferenceSystem().registerPreference( "WheelMouseInc", SizeImportStringCaller( GlobalTextureBrowser().m_mouseWheelScrollIncrement ), SizeExportStringCaller( GlobalTextureBrowser().m_mouseWheelScrollIncrement ) ); GlobalPreferenceSystem().registerPreference( "SI_Colors0", Vector3ImportStringCaller( GlobalTextureBrowser().color_textureback ), Vector3ExportStringCaller( GlobalTextureBrowser().color_textureback ) ); @@ -2516,3 +2818,7 @@ void TextureBrowser_Destroy(){ Textures_setModeChangedNotify( Callback() ); } + +GtkWidget* TextureBrowser_getGLWidget(){ + return GlobalTextureBrowser().m_gl_widget; +}