]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - radiant/select.cpp
fix invert selection logic
[xonotic/netradiant.git] / radiant / select.cpp
index 14e7fde383d8def98c552306a920dd4c44acab29..f4e8b7f9d6f0af3bcda2389513448424448eea6a 100644 (file)
@@ -47,6 +47,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #include "mainframe.h"
 #include "grid.h"
 #include "map.h"
+#include "entityinspector.h"
 
 
 
@@ -289,13 +290,16 @@ void Select_Delete (void)
 class InvertSelectionWalker : public scene::Graph::Walker
 {
   SelectionSystem::EMode m_mode;
-  mutable Selectable* m_selectable;
 public:
   InvertSelectionWalker(SelectionSystem::EMode mode)
-    : m_mode(mode), m_selectable(0)
+    : m_mode(mode)
   {
   }
   bool pre(const scene::Path& path, scene::Instance& instance) const
+  {
+    return true;
+  }
+  void post(const scene::Path& path, scene::Instance& instance) const
   {
     Selectable* selectable = Instance_getSelectable(instance);
     if(selectable)
@@ -304,26 +308,17 @@ public:
       {
       case SelectionSystem::eEntity:
         if(Node_isEntity(path.top()) != 0)
-        {
-          m_selectable = path.top().get().visible() ? selectable : 0;
-        }
+          if(path.top().get().visible())
+            selectable->setSelected(!selectable->isSelected());
         break;
       case SelectionSystem::ePrimitive:
-        m_selectable = path.top().get().visible() ? selectable : 0;
+        if(path.top().get().visible())
+          selectable->setSelected(!selectable->isSelected());
         break;
       case SelectionSystem::eComponent:
         break;
       }
     }
-    return true;
-  }
-  void post(const scene::Path& path, scene::Instance& instance) const
-  {
-    if(m_selectable != 0)
-    {
-      m_selectable->setSelected(!m_selectable->isSelected());
-      m_selectable = 0;
-    }
   }
 };
 
@@ -340,19 +335,26 @@ void Select_Invert()
 class ExpandSelectionToEntitiesWalker : public scene::Graph::Walker
 {
   mutable std::size_t m_depth;
+  NodeSmartReference worldspawn;
 public:
-  ExpandSelectionToEntitiesWalker() : m_depth(0)
+  ExpandSelectionToEntitiesWalker() : m_depth(0), worldspawn(Map_FindOrInsertWorldspawn(g_map))
   {
   }
   bool pre(const scene::Path& path, scene::Instance& instance) const
   {
     ++m_depth;
+
+    // ignore worldspawn
+    NodeSmartReference me(path.top().get());
+    if(me == worldspawn)
+           return false;
+
     if(m_depth == 2) // entity depth
     {
       // traverse and select children if any one is selected
          if(instance.childSelected())
                Instance_setSelected(instance, true);
-      return Node_getEntity(path.top())->isContainer() && instance.childSelected();
+      return Node_getEntity(path.top())->isContainer() && instance.isSelected();
     }
     else if(m_depth == 3) // primitive depth
     {
@@ -651,13 +653,13 @@ void FindReplaceTextures(const char* pFind, const char* pReplace, bool bSelected
   }
 }
 
-typedef std::vector<const char*> Classnames;
+typedef std::vector<const char*> PropertyValues;
 
-bool classnames_match_entity(const Classnames& classnames, Entity* entity)
+bool propertyvalues_contain(const PropertyValues& propertyvalues, const char *str)
 {
-  for(Classnames::const_iterator i = classnames.begin(); i != classnames.end(); ++i)
+  for(PropertyValues::const_iterator i = propertyvalues.begin(); i != propertyvalues.end(); ++i)
   {
-    if(string_equal(entity->getKeyValue("classname"), *i))
+    if(string_equal(str, *i))
     {
       return true;
     }
@@ -665,19 +667,20 @@ bool classnames_match_entity(const Classnames& classnames, Entity* entity)
   return false;
 }
 
-class EntityFindByClassnameWalker : public scene::Graph::Walker
+class EntityFindByPropertyValueWalker : public scene::Graph::Walker
 {
-  const Classnames& m_classnames;
+  const PropertyValues& m_propertyvalues;
+  const char *m_prop;
 public:
-  EntityFindByClassnameWalker(const Classnames& classnames)
-    : m_classnames(classnames)
+  EntityFindByPropertyValueWalker(const char *prop, const PropertyValues& propertyvalues)
+    : m_propertyvalues(propertyvalues), m_prop(prop)
   {
   }
   bool pre(const scene::Path& path, scene::Instance& instance) const
   {
     Entity* entity = Node_getEntity(path.top());
     if(entity != 0
-      && classnames_match_entity(m_classnames, entity))
+      && propertyvalues_contain(m_propertyvalues, entity->getKeyValue(m_prop)))
     {
       Instance_getSelectable(instance)->setSelected(true);
     }
@@ -685,17 +688,18 @@ public:
   }
 };
 
-void Scene_EntitySelectByClassnames(scene::Graph& graph, const Classnames& classnames)
+void Scene_EntitySelectByPropertyValues(scene::Graph& graph, const char *prop, const PropertyValues& propertyvalues)
 {
-  graph.traverse(EntityFindByClassnameWalker(classnames));
+  graph.traverse(EntityFindByPropertyValueWalker(prop, propertyvalues));
 }
 
-class EntityGetSelectedClassnamesWalker : public scene::Graph::Walker
+class EntityGetSelectedPropertyValuesWalker : public scene::Graph::Walker
 {
-  Classnames& m_classnames;
+  PropertyValues& m_propertyvalues;
+  const char *m_prop;
 public:
-  EntityGetSelectedClassnamesWalker(Classnames& classnames)
-    : m_classnames(classnames)
+  EntityGetSelectedPropertyValuesWalker(const char *prop, PropertyValues& propertyvalues)
+    : m_propertyvalues(propertyvalues), m_prop(prop)
   {
   }
   bool pre(const scene::Path& path, scene::Instance& instance) const
@@ -707,16 +711,17 @@ public:
       Entity* entity = Node_getEntity(path.top());
       if(entity != 0)
       {
-        m_classnames.push_back(entity->getKeyValue("classname"));
+       if(!propertyvalues_contain(m_propertyvalues, entity->getKeyValue(m_prop)))
+          m_propertyvalues.push_back(entity->getKeyValue(m_prop));
       }
     }
     return true;
   }
 };
 
-void Scene_EntityGetClassnames(scene::Graph& graph, Classnames& classnames)
+void Scene_EntityGetPropertyValues(scene::Graph& graph, const char *prop, PropertyValues& propertyvalues)
 {
-  graph.traverse(EntityGetSelectedClassnamesWalker(classnames));
+  graph.traverse(EntityGetSelectedPropertyValuesWalker(prop, propertyvalues));
 }
 
 void Select_AllOfType()
@@ -731,12 +736,15 @@ void Select_AllOfType()
   }
   else
   {
-    Classnames classnames;
-    Scene_EntityGetClassnames(GlobalSceneGraph(), classnames);
+    PropertyValues propertyvalues;
+    const char *prop = EntityInspector_getCurrentKey();
+    if(!prop || !*prop)
+      prop = "classname";
+    Scene_EntityGetPropertyValues(GlobalSceneGraph(), prop, propertyvalues);
     GlobalSelectionSystem().setSelectedAll(false);
-    if(!classnames.empty())
+    if(!propertyvalues.empty())
     {
-      Scene_EntitySelectByClassnames(GlobalSceneGraph(), classnames);
+      Scene_EntitySelectByPropertyValues(GlobalSceneGraph(), prop, propertyvalues);
     }
     else
     {
@@ -1051,7 +1059,7 @@ void DoRotateDlg()
                                                  (GtkAttachOptions) (0), 0, 0);
                          }
                          {
-                                 GtkAdjustment* adj = GTK_ADJUSTMENT(gtk_adjustment_new(0, -359, 359, 1, 10, 10));
+                                 GtkAdjustment* adj = GTK_ADJUSTMENT(gtk_adjustment_new(0, -359, 359, 1, 10, 0));
                                  GtkSpinButton* spin = GTK_SPIN_BUTTON(gtk_spin_button_new(adj, 1, 0));
                                  gtk_widget_show(GTK_WIDGET(spin));
                                  gtk_table_attach(table, GTK_WIDGET(spin), 1, 2, 0, 1,
@@ -1065,7 +1073,7 @@ void DoRotateDlg()
                                  g_rotate_dialog.x = spin;
                          }
                          {
-                                 GtkAdjustment* adj = GTK_ADJUSTMENT(gtk_adjustment_new(0, -359, 359, 1, 10, 10));
+                                 GtkAdjustment* adj = GTK_ADJUSTMENT(gtk_adjustment_new(0, -359, 359, 1, 10, 0));
                                  GtkSpinButton* spin = GTK_SPIN_BUTTON(gtk_spin_button_new(adj, 1, 0));
                                  gtk_widget_show(GTK_WIDGET(spin));
                                  gtk_table_attach(table, GTK_WIDGET(spin), 1, 2, 1, 2,
@@ -1077,7 +1085,7 @@ void DoRotateDlg()
                                  g_rotate_dialog.y = spin;
                          }
                          {
-                                 GtkAdjustment* adj = GTK_ADJUSTMENT(gtk_adjustment_new(0, -359, 359, 1, 10, 10));
+                                 GtkAdjustment* adj = GTK_ADJUSTMENT(gtk_adjustment_new(0, -359, 359, 1, 10, 0));
                                  GtkSpinButton* spin = GTK_SPIN_BUTTON(gtk_spin_button_new(adj, 1, 0));
                                  gtk_widget_show(GTK_WIDGET(spin));
                                  gtk_table_attach(table, GTK_WIDGET(spin), 1, 2, 2, 3,