瀏覽代碼

Merge pull request #99649 from ckaiser/run-instances-data

Improve run instances UX: avoid removing data and add a clear popup.
Rémi Verschelde 8 月之前
父節點
當前提交
45d8c217b9
共有 2 個文件被更改,包括 63 次插入5 次删除
  1. 53 5
      editor/run_instances_dialog.cpp
  2. 10 0
      editor/run_instances_dialog.h

+ 53 - 5
editor/run_instances_dialog.cpp

@@ -37,6 +37,7 @@
 #include "scene/gui/grid_container.h"
 #include "scene/gui/label.h"
 #include "scene/gui/line_edit.h"
+#include "scene/gui/popup_menu.h"
 #include "scene/gui/separator.h"
 #include "scene/gui/spin_box.h"
 #include "scene/gui/tree.h"
@@ -63,8 +64,8 @@ void RunInstancesDialog::_refresh_argument_count() {
 	while (instance_count->get_value() > stored_data.size()) {
 		stored_data.append(Dictionary());
 	}
-	stored_data.resize(instance_count->get_value());
-	instances_data.resize(stored_data.size());
+
+	instances_data.resize(instance_count->get_value());
 	InstanceData *instances_write = instances_data.ptrw();
 
 	for (int i = 0; i < instances_data.size(); i++) {
@@ -105,8 +106,6 @@ void RunInstancesDialog::_save_main_args() {
 }
 
 void RunInstancesDialog::_save_arguments() {
-	stored_data.resize(instances_data.size());
-
 	for (int i = 0; i < instances_data.size(); i++) {
 		const InstanceData &instance = instances_data[i];
 		Dictionary dict;
@@ -117,6 +116,7 @@ void RunInstancesDialog::_save_arguments() {
 		stored_data[i] = dict;
 	}
 	EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_instances_config", stored_data);
+	EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_instance_count", instance_count->get_value());
 }
 
 Vector<String> RunInstancesDialog::_split_cmdline_args(const String &p_arg_string) const {
@@ -155,6 +155,45 @@ Vector<String> RunInstancesDialog::_split_cmdline_args(const String &p_arg_strin
 	return split_args;
 }
 
+void RunInstancesDialog::_instance_menu_id_pressed(int p_option) {
+	switch (p_option) {
+		case CLEAR_ITEM: {
+			int item_to_clear = popup_menu->get_item_metadata(0);
+			if (item_to_clear >= 0 && item_to_clear < stored_data.size()) {
+				stored_data[item_to_clear] = Dictionary();
+			}
+		} break;
+		case CLEAR_ALL: {
+			stored_data.clear();
+			stored_data.resize(instance_count->get_value());
+		} break;
+	}
+
+	_start_instance_timer();
+	_refresh_argument_count();
+}
+
+void RunInstancesDialog::_instance_tree_rmb(const Vector2 &p_pos, MouseButton p_button) {
+	if (p_button != MouseButton::RIGHT) {
+		return;
+	}
+
+	popup_menu->clear();
+	popup_menu->add_item(TTR("Clear"), CLEAR_ITEM);
+
+	TreeItem *item = instance_tree->get_item_at_position(p_pos);
+	if (item) {
+		popup_menu->set_item_metadata(0, item->get_index());
+	} else {
+		popup_menu->set_item_disabled(0, true);
+	}
+
+	popup_menu->add_item(TTR("Clear All"), CLEAR_ALL);
+	popup_menu->set_position(instance_tree->get_screen_position() + p_pos);
+	popup_menu->reset_size();
+	popup_menu->popup();
+}
+
 void RunInstancesDialog::popup_dialog() {
 	popup_centered(Vector2(1200, 600) * EDSCALE);
 }
@@ -300,7 +339,8 @@ RunInstancesDialog::RunInstancesDialog() {
 	instance_count = memnew(SpinBox);
 	instance_count->set_min(1);
 	instance_count->set_max(20);
-	instance_count->set_value(stored_data.size());
+	instance_count->set_value(EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_instance_count", stored_data.size()));
+
 	args_gc->add_child(instance_count);
 	instance_count->connect(SceneStringName(value_changed), callable_mp(this, &RunInstancesDialog::_start_instance_timer).unbind(1));
 	instance_count->connect(SceneStringName(value_changed), callable_mp(this, &RunInstancesDialog::_refresh_argument_count).unbind(1));
@@ -342,6 +382,14 @@ RunInstancesDialog::RunInstancesDialog() {
 	instance_tree->set_column_expand(COLUMN_OVERRIDE_FEATURES, false);
 	instance_tree->set_column_title(COLUMN_FEATURE_TAGS, TTR("Feature Tags"));
 	instance_tree->set_hide_root(true);
+	instance_tree->set_allow_rmb_select(true);
+
+	popup_menu = memnew(PopupMenu);
+	popup_menu->connect(SceneStringName(id_pressed), callable_mp(this, &RunInstancesDialog::_instance_menu_id_pressed));
+	instance_tree->add_child(popup_menu);
+
+	instance_tree->connect("item_mouse_selected", callable_mp(this, &RunInstancesDialog::_instance_tree_rmb));
+	instance_tree->connect("empty_clicked", callable_mp(this, &RunInstancesDialog::_instance_tree_rmb));
 	main_vb->add_child(instance_tree);
 
 	_refresh_argument_count();

+ 10 - 0
editor/run_instances_dialog.h

@@ -39,6 +39,7 @@ class SpinBox;
 class Timer;
 class Tree;
 class TreeItem;
+class PopupMenu;
 
 class RunInstancesDialog : public AcceptDialog {
 	GDCLASS(RunInstancesDialog, AcceptDialog);
@@ -59,6 +60,12 @@ class RunInstancesDialog : public AcceptDialog {
 		String get_feature_tags() const;
 	};
 
+	// Right-click popup menu.
+	enum {
+		CLEAR_ITEM,
+		CLEAR_ALL,
+	};
+
 	inline static RunInstancesDialog *singleton = nullptr;
 
 	TypedArray<Dictionary> stored_data;
@@ -72,6 +79,7 @@ class RunInstancesDialog : public AcceptDialog {
 	SpinBox *instance_count = nullptr;
 	CheckBox *enable_multiple_instances_checkbox = nullptr;
 	Tree *instance_tree = nullptr;
+	PopupMenu *popup_menu = nullptr;
 
 	void _fetch_main_args();
 	// These 2 methods are necessary due to callable_mp() not supporting default arguments.
@@ -84,6 +92,8 @@ class RunInstancesDialog : public AcceptDialog {
 	void _save_arguments();
 	// Separates command line arguments without splitting up quoted strings.
 	Vector<String> _split_cmdline_args(const String &p_arg_string) const;
+	void _instance_menu_id_pressed(int p_option);
+	void _instance_tree_rmb(const Vector2 &p_pos, MouseButton p_button);
 
 public:
 	void popup_dialog();