]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - radiant/select.cpp
Merge branch 'NateEag-master-patch-12920' into 'master'
[xonotic/netradiant.git] / radiant / select.cpp
index 8e749542975c5d62dcab68f6f6784ab4a4dcc0cb..8f25906d83df876c9b02f5ec047680b79015aa25 100644 (file)
@@ -41,6 +41,7 @@
 #include "gtkutil/widget.h"
 #include "brushmanip.h"
 #include "brush.h"
+#include "patch.h"
 #include "patchmanip.h"
 #include "patchdialog.h"
 #include "selection.h"
@@ -277,10 +278,11 @@ void Select_Delete( void ){
 class InvertSelectionWalker : public scene::Graph::Walker
 {
 SelectionSystem::EMode m_mode;
+SelectionSystem::EComponentMode m_compmode;
 mutable Selectable* m_selectable;
 public:
-InvertSelectionWalker( SelectionSystem::EMode mode )
-       : m_mode( mode ), m_selectable( 0 ){
+InvertSelectionWalker( SelectionSystem::EMode mode, SelectionSystem::EComponentMode compmode )
+       : m_mode( mode ), m_compmode( compmode ), m_selectable( 0 ){
 }
 bool pre( const scene::Path& path, scene::Instance& instance ) const {
        if( !path.top().get().visible() ){
@@ -300,6 +302,18 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
                        m_selectable = path.top().get().visible() ? selectable : 0;
                        break;
                case SelectionSystem::eComponent:
+                       BrushInstance* brushinstance = Instance_getBrush( instance );
+                       if( brushinstance != 0 ){
+                               if( brushinstance->isSelected() )
+                                       brushinstance->invertComponentSelection( m_compmode );
+                       }
+                       else{
+                               PatchInstance* patchinstance = Instance_getPatch( instance );
+                               if( patchinstance != 0 && m_compmode == SelectionSystem::eVertex ){
+                                       if( patchinstance->isSelected() )
+                                               patchinstance->invertComponentSelection();
+                               }
+                       }
                        break;
                }
        }
@@ -314,7 +328,7 @@ void post( const scene::Path& path, scene::Instance& instance ) const {
 };
 
 void Scene_Invert_Selection( scene::Graph& graph ){
-       graph.traverse( InvertSelectionWalker( GlobalSelectionSystem().Mode() ) );
+       graph.traverse( InvertSelectionWalker( GlobalSelectionSystem().Mode(), GlobalSelectionSystem().ComponentMode() ) );
 }
 
 void Select_Invert(){
@@ -391,7 +405,7 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
        if ( m_depth == 2 ) { // entity depth
                // traverse and select children if any one is selected
                bool beselected = false;
-               if ( instance.childSelected() ) {
+               if ( instance.childSelected() || instance.isSelected() ) {
                        beselected = true;
                        if( path.top().get() != worldspawn ){
                                Instance_setSelected( instance, true );
@@ -438,9 +452,9 @@ void UpdateWorkzone_ForSelection(){
 
 // update the workzone to the current selection
 void UpdateWorkzone_ForSelectionChanged( const Selectable& selectable ){
-       if ( selectable.isSelected() ) {
+       //if ( selectable.isSelected() ) {
                UpdateWorkzone_ForSelection();
-       }
+       //}
 }
 
 void Select_SetShader( const char* shader ){
@@ -451,6 +465,13 @@ void Select_SetShader( const char* shader ){
        Scene_BrushSetShader_Component_Selected( GlobalSceneGraph(), shader );
 }
 
+void Select_SetShader_Undo( const char* shader ){
+       if ( GlobalSelectionSystem().countSelectedComponents() != 0 || GlobalSelectionSystem().countSelected() != 0 ) {
+               UndoableCommand undo( "textureNameSetSelected" );
+               Select_SetShader( shader );
+       }
+}
+
 void Select_SetTexdef( const TextureProjection& projection ){
        if ( GlobalSelectionSystem().Mode() != SelectionSystem::eComponent ) {
                Scene_BrushSetTexdef_Selected( GlobalSceneGraph(), projection );
@@ -1351,3 +1372,79 @@ void DoScaleDlg(){
 
        g_scale_dialog.window.show();
 }
+
+
+class EntityGetSelectedPropertyValuesWalker_nonEmpty : public scene::Graph::Walker
+{
+PropertyValues& m_propertyvalues;
+const char *m_prop;
+const NodeSmartReference worldspawn;
+public:
+EntityGetSelectedPropertyValuesWalker_nonEmpty( const char *prop, PropertyValues& propertyvalues )
+       : m_propertyvalues( propertyvalues ), m_prop( prop ), worldspawn( Map_FindOrInsertWorldspawn( g_map ) ){
+}
+bool pre( const scene::Path& path, scene::Instance& instance ) const {
+       Entity* entity = Node_getEntity( path.top() );
+       if ( entity != 0 ){
+               if( path.top().get() != worldspawn ){
+                       Selectable* selectable = Instance_getSelectable( instance );
+                       if ( ( selectable != 0 && selectable->isSelected() ) || instance.childSelected() ) {
+                               const char* keyvalue = entity->getKeyValue( m_prop );
+                               if ( !string_empty( keyvalue ) && !propertyvalues_contain( m_propertyvalues, keyvalue ) ) {
+                                       m_propertyvalues.push_back( keyvalue );
+                               }
+                       }
+               }
+               return false;
+       }
+       return true;
+}
+};
+
+void Scene_EntityGetPropertyValues_nonEmpty( scene::Graph& graph, const char *prop, PropertyValues& propertyvalues ){
+       graph.traverse( EntityGetSelectedPropertyValuesWalker_nonEmpty( prop, propertyvalues ) );
+}
+
+#include "preferences.h"
+
+void Select_ConnectedEntities( bool targeting, bool targets, bool focus ){
+       PropertyValues target_propertyvalues;
+       PropertyValues targetname_propertyvalues;
+       const char *target_prop = "target";
+       const char *targetname_prop;
+       if ( g_pGameDescription->mGameType == "doom3" ) {
+               targetname_prop = "name";
+       }
+       else{
+               targetname_prop = "targetname";
+       }
+
+       if( targeting ){
+               Scene_EntityGetPropertyValues_nonEmpty( GlobalSceneGraph(), targetname_prop, targetname_propertyvalues );
+       }
+       if( targets ){
+               Scene_EntityGetPropertyValues_nonEmpty( GlobalSceneGraph(), target_prop, target_propertyvalues );
+       }
+
+       if( target_propertyvalues.empty() && targetname_propertyvalues.empty() ){
+               globalErrorStream() << "SelectConnectedEntities: nothing found\n";
+               return;
+       }
+
+       if( !targeting || !targets ){
+               GlobalSelectionSystem().setSelectedAll( false );
+       }
+       if ( targeting && !targetname_propertyvalues.empty() ) {
+               Scene_EntitySelectByPropertyValues( GlobalSceneGraph(), target_prop, targetname_propertyvalues );
+       }
+       if ( targets && !target_propertyvalues.empty() ) {
+               Scene_EntitySelectByPropertyValues( GlobalSceneGraph(), targetname_prop, target_propertyvalues );
+       }
+       if( focus ){
+               FocusAllViews();
+       }
+}
+
+void SelectConnectedEntities(){
+       Select_ConnectedEntities( true, true, false );
+}