소스 검색

Merge pull request #77632 from Wiwip/inline-edit-fix

Inline edit for FileSystem dock in SPLIT_MODE
Rémi Verschelde 2 년 전
부모
커밋
e3681eb05f
2개의 변경된 파일134개의 추가작업 그리고 18개의 파일을 삭제
  1. 116 17
      editor/filesystem_dock.cpp
  2. 18 1
      editor/filesystem_dock.h

+ 116 - 17
editor/filesystem_dock.cpp

@@ -76,6 +76,94 @@ Control *FileSystemList::make_custom_tooltip(const String &p_text) const {
 	return FileSystemDock::get_singleton()->create_tooltip_for_path(get_item_metadata(idx));
 }
 
+void FileSystemList::_line_editor_submit(String p_text) {
+	popup_editor->hide();
+
+	emit_signal(SNAME("item_edited"));
+	queue_redraw();
+}
+
+bool FileSystemList::edit_selected() {
+	ERR_FAIL_COND_V_MSG(!is_anything_selected(), false, "No item selected.");
+	int s = get_current();
+	ensure_current_is_visible();
+
+	Rect2 rect;
+	Rect2 popup_rect;
+	Vector2 ofs;
+
+	Vector2 icon_size = get_item_icon(s)->get_size();
+
+	// Handles the different icon modes (TOP/LEFT).
+	switch (get_icon_mode()) {
+		case ItemList::ICON_MODE_LEFT:
+			rect = get_item_rect(s, true);
+			ofs = Vector2(0, Math::floor((MAX(line_editor->get_minimum_size().height, rect.size.height) - rect.size.height) / 2));
+			popup_rect.position = get_screen_position() + rect.position - ofs;
+			popup_rect.size = rect.size;
+
+			// Adjust for icon position and size.
+			popup_rect.size.x -= icon_size.x;
+			popup_rect.position.x += icon_size.x;
+			break;
+		case ItemList::ICON_MODE_TOP:
+			rect = get_item_rect(s, false);
+			popup_rect.position = get_screen_position() + rect.position;
+			popup_rect.size = rect.size;
+
+			// Adjust for icon position and size.
+			popup_rect.size.y -= icon_size.y;
+			popup_rect.position.y += icon_size.y;
+			break;
+	}
+
+	popup_editor->set_position(popup_rect.position);
+	popup_editor->set_size(popup_rect.size);
+
+	String name = get_item_text(s);
+	line_editor->set_text(name);
+	line_editor->select(0, name.rfind("."));
+
+	popup_editor->popup();
+	popup_editor->child_controls_changed();
+	line_editor->grab_focus();
+	return true;
+}
+
+String FileSystemList::get_edit_text() {
+	return line_editor->get_text();
+}
+
+void FileSystemList::_text_editor_popup_modal_close() {
+	if (Input::get_singleton()->is_key_pressed(Key::ESCAPE) ||
+			Input::get_singleton()->is_key_pressed(Key::KP_ENTER) ||
+			Input::get_singleton()->is_key_pressed(Key::ENTER)) {
+		return;
+	}
+
+	_line_editor_submit(line_editor->get_text());
+}
+
+void FileSystemList::_bind_methods() {
+	ADD_SIGNAL(MethodInfo("item_edited"));
+}
+
+FileSystemList::FileSystemList() {
+	popup_editor = memnew(Popup);
+	add_child(popup_editor);
+
+	popup_editor_vb = memnew(VBoxContainer);
+	popup_editor_vb->add_theme_constant_override("separation", 0);
+	popup_editor_vb->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
+	popup_editor->add_child(popup_editor_vb);
+
+	line_editor = memnew(LineEdit);
+	line_editor->set_v_size_flags(SIZE_EXPAND_FILL);
+	popup_editor_vb->add_child(line_editor);
+	line_editor->connect("text_submitted", callable_mp(this, &FileSystemList::_line_editor_submit));
+	popup_editor->connect("popup_hide", callable_mp(this, &FileSystemList::_text_editor_popup_modal_close));
+}
+
 FileSystemDock *FileSystemDock::singleton = nullptr;
 
 Ref<Texture2D> FileSystemDock::_get_tree_item_icon(bool p_is_valid, String p_file_type) {
@@ -1581,13 +1669,15 @@ void FileSystemDock::_folder_removed(String p_folder) {
 }
 
 void FileSystemDock::_rename_operation_confirm() {
-	if (!tree->is_anything_selected()) {
-		return;
-	}
+	String new_name;
 	TreeItem *s = tree->get_selected();
 	int col_index = tree->get_selected_column();
-	String new_name = s->get_text(col_index);
-	new_name = new_name.strip_edges();
+
+	if (tree->has_focus()) {
+		new_name = s->get_text(col_index).strip_edges();
+	} else if (files->has_focus()) {
+		new_name = files->get_edit_text().strip_edges();
+	}
 	String old_name = to_rename.is_file ? to_rename.path.get_file() : to_rename.path.left(-1).get_file();
 
 	bool rename_error = false;
@@ -1607,10 +1697,12 @@ void FileSystemDock::_rename_operation_confirm() {
 		}
 	}
 
-	// Restores Tree to restore original names.
-	if (rename_error) {
+	// Restore original name.
+	if (rename_error && tree->has_focus()) {
 		s->set_text(col_index, old_name);
 		return;
+	} else if (rename_error && files->has_focus()) {
+		return;
 	}
 
 	String old_path = to_rename.path.ends_with("/") ? to_rename.path.left(-1) : to_rename.path;
@@ -2032,21 +2124,27 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
 		} break;
 
 		case FILE_RENAME: {
-			if (tree->is_anything_selected() && !p_selected.is_empty()) {
+			if (!p_selected.is_empty()) {
 				// Set to_rename variable for callback execution.
 				to_rename.path = p_selected[0];
 				to_rename.is_file = !to_rename.path.ends_with("/");
+				if (to_rename.path == "res://") {
+					break;
+				}
 
-				// Edit node in Tree.
-				tree->grab_focus();
-				tree->edit_selected(true);
+				if (tree->has_focus()) {
+					// Edit node in Tree.
+					tree->edit_selected(true);
 
-				if (to_rename.is_file) {
-					String name = to_rename.path.get_file();
-					tree->set_editor_selection(0, name.rfind("."));
-				} else {
-					String name = to_rename.path.left(-1).get_file(); // Removes the "/" suffix for folders.
-					tree->set_editor_selection(0, name.length());
+					if (to_rename.is_file) {
+						String name = to_rename.path.get_file();
+						tree->set_editor_selection(0, name.rfind("."));
+					} else {
+						String name = to_rename.path.left(-1).get_file(); // Removes the "/" suffix for folders.
+						tree->set_editor_selection(0, name.length());
+					}
+				} else if (files->has_focus()) {
+					files->edit_selected();
 				}
 			}
 		} break;
@@ -3329,6 +3427,7 @@ FileSystemDock::FileSystemDock() {
 	files->connect("gui_input", callable_mp(this, &FileSystemDock::_file_list_gui_input));
 	files->connect("multi_selected", callable_mp(this, &FileSystemDock::_file_multi_selected));
 	files->connect("empty_clicked", callable_mp(this, &FileSystemDock::_file_list_empty_clicked));
+	files->connect("item_edited", callable_mp(this, &FileSystemDock::_rename_operation_confirm));
 	files->set_custom_minimum_size(Size2(0, 15 * EDSCALE));
 	files->set_allow_rmb_select(true);
 	file_list_vb->add_child(files);

+ 18 - 1
editor/filesystem_dock.h

@@ -57,7 +57,24 @@ class FileSystemTree : public Tree {
 };
 
 class FileSystemList : public ItemList {
-	virtual Control *make_custom_tooltip(const String &p_text) const;
+	GDCLASS(FileSystemList, ItemList);
+
+	VBoxContainer *popup_editor_vb = nullptr;
+	Popup *popup_editor = nullptr;
+	LineEdit *line_editor = nullptr;
+
+	virtual Control *make_custom_tooltip(const String &p_text) const override;
+	void _line_editor_submit(String p_text);
+	void _text_editor_popup_modal_close();
+
+protected:
+	static void _bind_methods();
+
+public:
+	bool edit_selected();
+	String get_edit_text();
+
+	FileSystemList();
 };
 
 class FileSystemDock : public VBoxContainer {