From bf3f194cffb4df4d9d38eec4b81a77f9c6ddf678 Mon Sep 17 00:00:00 2001 From: Garux Date: Wed, 24 Nov 2021 23:49:46 +0300 Subject: [PATCH] * cloneSelected, cloneSelectedMakeUnique: select cloned stuff (was preserving original selected) important for cloneSelectedMakeUnique usability and when objects order in .map matters --- libs/scenelib.h | 2 +- radiant/mainframe.cpp | 42 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/libs/scenelib.h b/libs/scenelib.h index b02e7c81..e34ca6fc 100644 --- a/libs/scenelib.h +++ b/libs/scenelib.h @@ -823,7 +823,7 @@ inline void Scene_forEachChildSelectable( const Functor& functor, const scene::P class SelectableSetSelected { - bool m_selected; + const bool m_selected; public: SelectableSetSelected( bool selected ) : m_selected( selected ){ } diff --git a/radiant/mainframe.cpp b/radiant/mainframe.cpp index 450a4949..f974e9e4 100644 --- a/radiant/mainframe.cpp +++ b/radiant/mainframe.cpp @@ -1263,6 +1263,7 @@ class CloneSelected : public scene::Graph::Walker const bool m_makeUnique; const scene::Node* m_world; public: + mutable std::vector m_cloned; CloneSelected( bool makeUnique ) : m_makeUnique( makeUnique ), m_world( Map_FindWorldspawn( g_map ) ){ } bool pre( const scene::Path& path, scene::Instance& instance ) const { @@ -1278,10 +1279,7 @@ public: if ( Instance_isSelected( instance ) ) { return false; } - if( m_makeUnique && instance.childSelected() ){ /* clone group entity primitives to new group entity */ - NodeSmartReference clone( Node_Clone_Selected( path.top() ) ); - Map_gatherNamespaced( clone ); - Node_getTraversable( path.parent().get() )->insert( clone ); + if( m_makeUnique && instance.childSelected() ){ /* clone selected group entity primitives to new group entity */ return false; } } @@ -1302,15 +1300,49 @@ public: NodeSmartReference clone( Node_Clone( path.top() ) ); Map_gatherNamespaced( clone ); Node_getTraversable( path.parent().get() )->insert( clone ); + m_cloned.push_back( clone.get_pointer() ); + } + else if( m_makeUnique && instance.childSelected() ){ /* clone selected group entity primitives to new group entity */ + NodeSmartReference clone( Node_Clone_Selected( path.top() ) ); + Map_gatherNamespaced( clone ); + Node_getTraversable( path.parent().get() )->insert( clone ); + m_cloned.push_back( clone.get_pointer() ); } } } }; void Scene_Clone_Selected( scene::Graph& graph, bool makeUnique ){ - graph.traverse( CloneSelected( makeUnique ) ); + CloneSelected cloneSelected( makeUnique ); + graph.traverse( cloneSelected ); Map_mergeClonedNames( makeUnique ); + + /* deselect originals */ + GlobalSelectionSystem().setSelectedAll( false ); + /* select cloned */ + for( scene::Node *node : cloneSelected.m_cloned ) + { + class walker : public scene::Traversable::Walker + { + public: + bool pre( scene::Node& node ) const override { + if( scene::Instantiable *instantiable = Node_getInstantiable( node ) ){ + class visitor : public scene::Instantiable::Visitor + { + public: + void visit( scene::Instance& instance ) const override { + Instance_setSelected( instance, true ); + } + }; + + instantiable->forEachInstance( visitor() ); + } + return true; + } + }; + Node_traverseSubgraph( *node, walker() ); + } } enum ENudgeDirection