From b14dcffd7d378b5930b5ce080b035fd5a5769d89 Mon Sep 17 00:00:00 2001 From: Garux Date: Mon, 3 Mar 2025 21:40:14 +0500 Subject: [PATCH] * hide group entity node when all its children get hidden --- docs/changelog-custom.txt | 1 + libs/scenelib.h | 4 ++-- radiant/map.cpp | 4 ++-- radiant/select.cpp | 33 +++++++++++++++++++++++++++++++-- 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/docs/changelog-custom.txt b/docs/changelog-custom.txt index 157b4172..471f3be1 100644 --- a/docs/changelog-custom.txt +++ b/docs/changelog-custom.txt @@ -1114,6 +1114,7 @@ misc... * add prefs->Build->Region Box Shader (shader to use on the box generated around region) * add bobToolz.explodeEntity: create group entity from each primitive of existing group entity * improve CSG Subtract results via more defined splits order + * hide group entity node when all its children get hidden diff --git a/libs/scenelib.h b/libs/scenelib.h index d5a19eb5..33e25937 100644 --- a/libs/scenelib.h +++ b/libs/scenelib.h @@ -217,10 +217,10 @@ public: void disable( unsigned int state ){ m_state &= ~state; } - bool visible(){ + bool visible() const { return m_state == eVisible; } - bool excluded(){ + bool excluded() const { return ( m_state & eExcluded ) != 0; } bool operator<( const scene::Node& other ){ diff --git a/radiant/map.cpp b/radiant/map.cpp index 6a723311..cd9c0cde 100644 --- a/radiant/map.cpp +++ b/radiant/map.cpp @@ -1415,7 +1415,7 @@ void Map_ApplyRegion(){ g_region_item.update(); Scene_Exclude_Region( false ); - /* newly created brushes have to be visible! */ + /* not hiding worldspawn node so that newly created brushes are visible */ if( scene::Node* w = Map_FindWorldspawn( g_map ) ) exclude_node( *w, false ); } @@ -1436,7 +1436,7 @@ void Map_RegionSelectedBrushes(){ Select_GetBounds( g_region_mins, g_region_maxs ); Scene_Exclude_Selected( false ); - /* newly created brushes have to be visible! */ + /* not hiding worldspawn node so that newly created brushes are visible */ if( scene::Node* w = Map_FindWorldspawn( g_map ) ) exclude_node( *w, false ); diff --git a/radiant/select.cpp b/radiant/select.cpp index dbc83849..c436a989 100644 --- a/radiant/select.cpp +++ b/radiant/select.cpp @@ -941,6 +941,26 @@ void Select_FitTexture( float horizontal, float vertical, bool only_dimension ){ #include "commands.h" #include "dialog.h" +template +bool Traversable_all_of_children( scene::Traversable* traversable, const Check&& check ){ + class Check_all : public scene::Traversable::Walker + { + const Check m_check; + public: + mutable bool m_all = true; // true for empty container + Check_all( Check check ) : m_check( check ){ + } + bool pre( scene::Node& node ) const override { + if( !m_check( node ) ) + m_all = false; + return m_all; + } + } check_all( check ); + + traversable->traverse( check_all ); + return check_all.m_all; +} + inline void hide_node( scene::Node& node, bool hide ){ hide ? node.enable( scene::Node::eHidden ) @@ -953,18 +973,24 @@ ToggleItem g_hidden_item{ BoolExportCaller( g_nodes_be_hidden ) }; class HideSelectedWalker : public scene::Graph::Walker { - bool m_hide; + const bool m_hide; public: HideSelectedWalker( bool hide ) : m_hide( hide ){ } - bool pre( const scene::Path& path, scene::Instance& instance ) const { + bool pre( const scene::Path& path, scene::Instance& instance ) const override { if ( Instance_isSelected( instance ) ) { g_nodes_be_hidden = m_hide; hide_node( path.top(), m_hide ); } return true; } + void post( const scene::Path& path, scene::Instance& instance ) const override { + if( m_hide && Node_isEntity( path.top().get() ) ) // hide group entity labels, when their content is entirely hidden + if( scene::Traversable* traversable = Node_getTraversable( path.top().get() ) ) + if( Traversable_all_of_children( traversable, []( const scene::Node& node ){ return !node.visible(); } ) ) + hide_node( path.top(), true ); + } }; void Scene_Hide_Selected( bool hide ){ @@ -973,6 +999,9 @@ void Scene_Hide_Selected( bool hide ){ void Select_Hide(){ Scene_Hide_Selected( true ); + /* not hiding worldspawn node so that newly created brushes are visible */ + if( scene::Node* w = Map_FindWorldspawn( g_map ) ) + hide_node( *w, false ); SceneChangeNotify(); }