diff --git a/include/iselection.h b/include/iselection.h index 3f98c640..9a9a5880 100644 --- a/include/iselection.h +++ b/include/iselection.h @@ -103,6 +103,7 @@ virtual std::size_t countSelectedComponents() const = 0; virtual void countSelectedStuff( std::size_t& brushes, std::size_t& patches, std::size_t& entities ) const = 0; virtual void onSelectedChanged( scene::Instance& instance, const Selectable& selectable ) = 0; virtual void onComponentSelection( scene::Instance& instance, const Selectable& selectable ) = 0; +virtual scene::Instance& firstSelected() const = 0; virtual scene::Instance& ultimateSelected() const = 0; virtual scene::Instance& penultimateSelected() const = 0; virtual void setSelectedAll( bool selected ) = 0; diff --git a/radiant/entity.cpp b/radiant/entity.cpp index d415115c..0975315a 100644 --- a/radiant/entity.cpp +++ b/radiant/entity.cpp @@ -185,6 +185,10 @@ void Scene_EntitySetClassname_Selected( const char* classname ){ } } +void Entity_ungroup(){ + Scene_EntitySetClassname_Selected( "worldspawn" ); +} + #if 0 void Entity_ungroupSelected(){ if ( GlobalSelectionSystem().countSelected() < 1 ) { @@ -296,14 +300,14 @@ void Entity_moveSelectedPrimitives(){ } } #else -/// moves selected primitives to entity, which is or its primitive is ultimateSelected() -void Entity_moveSelectedPrimitives(){ +/// moves selected primitives to entity, which is or its primitive is ultimateSelected() or firstSelected() +void Entity_moveSelectedPrimitives( bool toLast ){ if ( GlobalSelectionSystem().countSelected() < 2 ) { globalErrorStream() << "Source and target entity primitives should be selected!\n"; return; } - const scene::Path& path = GlobalSelectionSystem().ultimateSelected().path(); + const scene::Path& path = toLast? GlobalSelectionSystem().ultimateSelected().path() : GlobalSelectionSystem().firstSelected().path(); scene::Node& node = ( !Node_isEntity( path.top() ) && path.size() > 1 )? path.parent() : path.top(); if ( Node_isEntity( node ) && node_is_group( node ) ) { @@ -313,6 +317,12 @@ void Entity_moveSelectedPrimitives(){ Scene_parentSelectedBrushesToEntity( GlobalSceneGraph(), node ); } } +void Entity_moveSelectedPrimitivesToLast(){ + Entity_moveSelectedPrimitives( true ); +} +void Entity_moveSelectedPrimitivesToFirst(){ + Entity_moveSelectedPrimitives( false ); +} #endif @@ -495,6 +505,10 @@ void Entity_createFromSelection( const char* name, const Vector3& origin ){ } } +void Entity_ungroupSelectedPrimitives(){ + Entity_createFromSelection( "worldspawn", g_vector3_identity ); +} + /* scale color so that at least one component is at 1.0F */ void NormalizeColor( Vector3& color ){ @@ -688,11 +702,17 @@ void Entity_constructMenu( GtkMenu* menu ){ if ( g_pGameDescription->mGameType == "nexuiz" || g_pGameDescription->mGameType == "q1" ) { create_menu_item_with_mnemonic( menu, "_KillConnect Entities", "EntitiesKillConnect" ); } - create_menu_item_with_mnemonic( menu, "_Move Primitives to Entity", "EntityMovePrimitives" ); + create_menu_item_with_mnemonic( menu, "_Move Primitives to Entity", "EntityMovePrimitivesToLast" ); create_menu_item_with_mnemonic( menu, "_Select Color...", "EntityColorSet" ); create_menu_item_with_mnemonic( menu, "_Normalize Color", "EntityColorNormalize" ); } +void Entity_registerShortcuts(){ + command_connect_accelerator( "EntityMovePrimitivesToFirst" ); + command_connect_accelerator( "EntityUngroup" ); + command_connect_accelerator( "EntityUngroupPrimitives" ); +} + #include "preferencesystem.h" @@ -704,7 +724,10 @@ void Entity_Construct(){ GlobalCommands_insert( "EntitiesConnect", FreeCaller(), Accelerator( 'K', (GdkModifierType)GDK_CONTROL_MASK ) ); if ( g_pGameDescription->mGameType == "nexuiz" || g_pGameDescription->mGameType == "q1" ) GlobalCommands_insert( "EntitiesKillConnect", FreeCaller(), Accelerator( 'K', (GdkModifierType)GDK_SHIFT_MASK ) ); - GlobalCommands_insert( "EntityMovePrimitives", FreeCaller(), Accelerator( 'M', (GdkModifierType)GDK_CONTROL_MASK ) ); + GlobalCommands_insert( "EntityMovePrimitivesToLast", FreeCaller(), Accelerator( 'M', (GdkModifierType)GDK_CONTROL_MASK ) ); + GlobalCommands_insert( "EntityMovePrimitivesToFirst", FreeCaller() ); + GlobalCommands_insert( "EntityUngroup", FreeCaller() ); + GlobalCommands_insert( "EntityUngroupPrimitives", FreeCaller() ); GlobalToggles_insert( "ShowLightRadiuses", FreeCaller(), ToggleItem::AddCallbackCaller( g_show_lightradii_item ) ); diff --git a/radiant/entity.h b/radiant/entity.h index 9096287a..4638d6a7 100644 --- a/radiant/entity.h +++ b/radiant/entity.h @@ -37,6 +37,8 @@ void Entity_setColour(); typedef struct _GtkMenu GtkMenu; void Entity_constructMenu( GtkMenu* menu ); +void Entity_registerShortcuts(); + void Entity_Construct(); void Entity_Destroy(); diff --git a/radiant/mainframe.cpp b/radiant/mainframe.cpp index 4d60ded9..80e608db 100644 --- a/radiant/mainframe.cpp +++ b/radiant/mainframe.cpp @@ -2433,6 +2433,7 @@ void register_shortcuts(){ // SelectByType_registerShortcuts(); TexBro_registerShortcuts(); Misc_registerShortcuts(); + Entity_registerShortcuts(); } void File_constructToolbar( GtkToolbar* toolbar ){ diff --git a/radiant/selection.cpp b/radiant/selection.cpp index 7beba5bf..09c9f873 100644 --- a/radiant/selection.cpp +++ b/radiant/selection.cpp @@ -4425,6 +4425,10 @@ void onComponentSelection( scene::Instance& instance, const Selectable& selectab ASSERT_MESSAGE( m_component_selection.size() == m_count_component.size(), "selection-tracking error" ); } +scene::Instance& firstSelected() const { + ASSERT_MESSAGE( m_selection.size() > 0, "no instance selected" ); + return **m_selection.begin(); +} scene::Instance& ultimateSelected() const { ASSERT_MESSAGE( m_selection.size() > 0, "no instance selected" ); return m_selection.back();