Jelajahi Sumber

Improve multiple-selection support

Daniele Bartolini 9 tahun lalu
induk
melakukan
0b44e0a7e7

+ 8 - 7
samples/core/editors/level_editor/level_editor.lua

@@ -166,6 +166,14 @@ function Selection:remove(id)
 	end
 end
 
+function Selection:set(ids)
+	self:clear()
+	for k, v in pairs(ids) do
+		LevelEditor._objects[v]:on_selected(true)
+	end
+	self._ids = ids
+end
+
 function Selection:last_selected_object()
 	local last = self._ids[#self._ids]
 	return last and LevelEditor._objects[last] or nil
@@ -1505,13 +1513,6 @@ function LevelEditor:set_placeable(placeable_type, name)
 	self.place_tool:set_placeable(placeable_type, name)
 end
 
-function LevelEditor:set_selected_unit(id)
-	local unit_box = self._objects[id]
-
-	self._selection:clear()
-	self._selection:add(unit_box:id())
-end
-
 function LevelEditor:destroy(id)
 	self._objects[id]:destroy()
 	self._objects[id] = nil

+ 8 - 3
tools/api/level_editor_api.vala

@@ -178,9 +178,14 @@ namespace Crown
 			return "LevelEditor:set_placeable(\"%s\", \"%s\")".printf((type == PlaceableType.UNIT ? "unit" : "sound"), name);
 		}
 
-		public string set_selected_unit(Guid id)
-		{
-			return @"LevelEditor:set_selected_unit(\"%s\")".printf(id.to_string());
+		public string selection_set(Guid[] ids)
+		{
+			StringBuilder sb = new StringBuilder();
+			sb.append("LevelEditor._selection:set({");
+			for (int i = 0; i < ids.length; ++i)
+				sb.append("\"%s\",".printf(ids[i].to_string()));
+			sb.append("})");
+			return sb.str;
 		}
 
 		public string destroy(Guid id)

+ 13 - 12
tools/level_editor/level.vala

@@ -56,15 +56,6 @@ namespace Crown
 			_client.send_script(LevelEditorApi.reset());
 		}
 
-		public void selection(Guid[] ids)
-		{
-			_selection.clear();
-			foreach (Guid id in ids)
-				_selection.add(id);
-
-			selection_changed(_selection);
-		}
-
 		public void new_level()
 		{
 			load(_toolchain_dir + "core/editors/levels/empty.level");
@@ -457,6 +448,15 @@ namespace Crown
 			_db.add_to_set(GUID_ZERO, "sounds", id);
 		}
 
+		public void on_selection(Guid[] ids)
+		{
+			_selection.clear();
+			foreach (Guid id in ids)
+				_selection.add(id);
+
+			selection_changed(_selection);
+		}
+
 		public void destroy_objects(Guid[] ids)
 		{
 			foreach (Guid id in ids)
@@ -478,11 +478,12 @@ namespace Crown
 			do_destroy_objects(ids);
 		}
 
-		public void set_selected_unit(Guid id)
+		public void selection_set(Guid[] ids)
 		{
-			_client.send_script(LevelEditorApi.set_selected_unit(id));
 			_selection.clear();
-			_selection.add(id);
+			for (int i = 0; i < ids.length; ++i)
+				_selection.add(ids[i]);
+			_client.send_script(LevelEditorApi.selection_set(ids));
 
 			selection_changed(_selection);
 		}

+ 1 - 1
tools/level_editor/level_editor.vala

@@ -478,7 +478,7 @@ namespace Crown
 						ids[i] = Guid.parse((string)objects[k]);
 					}
 
-					_level.selection(ids);
+					_level.on_selection(ids);
 				}
 			}
 			catch (Error e)

+ 39 - 23
tools/level_editor/level_tree_view.vala

@@ -27,6 +27,7 @@ namespace Crown
 		private Gtk.TreeStore _tree_store;
 		private Gtk.TreeModelFilter _tree_filter;
 		private Gtk.TreeView _tree_view;
+		private Gtk.TreeSelection _tree_selection;
 		private Gtk.ScrolledWindow _scrolled_window;
 		private Gtk.Box _vbox;
 
@@ -34,6 +35,7 @@ namespace Crown
 		{
 			// Data
 			_level = level;
+			_level.selection_changed.connect(on_level_selection_changed);
 
 			_db = db;
 			_db.key_changed.connect(on_database_key_changed);
@@ -55,6 +57,10 @@ namespace Crown
 			_tree_view.model = _tree_filter;
 			_tree_view.button_press_event.connect(on_button_pressed);
 
+			_tree_selection = _tree_view.get_selection();
+			_tree_selection.set_mode(Gtk.SelectionMode.MULTIPLE);
+			_tree_selection.changed.connect(on_tree_selection_changed);
+
 			_scrolled_window = new Gtk.ScrolledWindow(null, null);
 			_scrolled_window.add(_tree_view);
 
@@ -72,29 +78,7 @@ namespace Crown
 		{
 			uint button = ev.button;
 
-			if (button == 1)
-			{
-				Gtk.TreePath path;
-				int cell_x;
-				int cell_y;
-				if (_tree_view.get_path_at_pos((int)ev.x, (int)ev.y, out path, null, out cell_x, out cell_y))
-				{
-					Gtk.TreePath child_path = _tree_filter.convert_path_to_child_path(path);
-					Gtk.TreeIter iter;
-					if (_tree_store.get_iter(out iter, child_path))
-					{
-						Value type;
-						_tree_store.get_value(iter, 1, out type);
-						if ((int)type == ItemType.FOLDER)
-							return false;
-
-						Value id;
-						_tree_store.get_value(iter, 0, out id);
-						_level.set_selected_unit(Guid.parse((string)id));
-					}
-				}
-			}
-			else if (button == 3)
+			if (button == 3) // Right
 			{
 				Gtk.TreePath path;
 				int cell_x;
@@ -155,6 +139,33 @@ namespace Crown
 			return false;
 		}
 
+		private void on_tree_selection_changed()
+		{
+			_level.selection_changed.disconnect(on_level_selection_changed);
+
+			Guid[] ids = {};
+			_tree_selection.selected_foreach((model, path, iter) => {
+				Value type;
+				model.get_value(iter, 1, out type);
+				if ((int)type == ItemType.FOLDER)
+					return;
+
+				Value id;
+				model.get_value(iter, 0, out id);
+				ids += Guid.parse((string)id);
+			});
+
+			_level.selection_set(ids);
+			_level.selection_changed.connect(on_level_selection_changed);
+		}
+
+		private void on_level_selection_changed(Gee.ArrayList<Guid?> selection)
+		{
+			_tree_selection.changed.disconnect(on_tree_selection_changed);
+			// FIXME
+			_tree_selection.changed.connect(on_tree_selection_changed);
+		}
+
 		private void on_database_key_changed(Guid id, string key)
 		{
 			if (id != GUID_ZERO)
@@ -163,6 +174,7 @@ namespace Crown
 			if (key != "units" && key != "sounds")
 				return;
 
+			_tree_selection.changed.disconnect(on_tree_selection_changed);
 			_tree_view.model = null;
 			_tree_store.clear();
 
@@ -197,11 +209,15 @@ namespace Crown
 
 			_tree_view.model = _tree_filter;
 			_tree_view.expand_all();
+
+			_tree_selection.changed.connect(on_tree_selection_changed);
 		}
 
 		private void on_filter_entry_text_changed()
 		{
+			_tree_selection.changed.disconnect(on_tree_selection_changed);
 			_tree_filter.refilter();
+			_tree_selection.changed.connect(on_tree_selection_changed);
 		}
 	}
 }