Prechádzať zdrojové kódy

Merge pull request #14699 from GodotExplorer/gdnlib_editor

Add plugin to edit GDNativeLibrary
Thomas Herzog 7 rokov pred
rodič
commit
8d13753e91

+ 2 - 2
modules/gdnative/SCsub

@@ -3,12 +3,12 @@
 Import('env')
 Import('env')
 
 
 gdn_env = env.Clone()
 gdn_env = env.Clone()
-
-gdn_env.add_source_files(env.modules_sources, "gd_native_library_editor.cpp")
 gdn_env.add_source_files(env.modules_sources, "gdnative.cpp")
 gdn_env.add_source_files(env.modules_sources, "gdnative.cpp")
 gdn_env.add_source_files(env.modules_sources, "register_types.cpp")
 gdn_env.add_source_files(env.modules_sources, "register_types.cpp")
 gdn_env.add_source_files(env.modules_sources, "gdnative/*.cpp")
 gdn_env.add_source_files(env.modules_sources, "gdnative/*.cpp")
 gdn_env.add_source_files(env.modules_sources, "nativescript/*.cpp")
 gdn_env.add_source_files(env.modules_sources, "nativescript/*.cpp")
+gdn_env.add_source_files(env.modules_sources, "gdnative_library_singleton_editor.cpp")
+gdn_env.add_source_files(env.modules_sources, "gdnative_library_editor_plugin.cpp")
 
 
 gdn_env.Append(CPPPATH=['#modules/gdnative/include/'])
 gdn_env.Append(CPPPATH=['#modules/gdnative/include/'])
 
 

+ 423 - 0
modules/gdnative/gdnative_library_editor_plugin.cpp

@@ -0,0 +1,423 @@
+/*************************************************************************/
+/*  gdnative_library_editor_plugin.cpp                                   */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)    */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#ifdef TOOLS_ENABLED
+#include "gdnative_library_editor_plugin.h"
+#include "gdnative.h"
+
+void GDNativeLibraryEditor::edit(Ref<GDNativeLibrary> p_library) {
+	library = p_library;
+	Ref<ConfigFile> config = p_library->get_config_file();
+
+	for (Map<String, NativePlatformConfig>::Element *E = platforms.front(); E; E = E->next()) {
+		for (List<String>::Element *it = E->value().entries.front(); it; it = it->next()) {
+
+			String target = E->key() + "." + it->get();
+			TargetConfig ecfg;
+			ecfg.library = config->get_value("entry", target, "");
+			ecfg.dependencies = config->get_value("dependencies", target, Array());
+			entry_configs[target] = ecfg;
+		}
+	}
+
+	_update_tree();
+}
+
+void GDNativeLibraryEditor::_bind_methods() {
+
+	ClassDB::bind_method("_on_item_button", &GDNativeLibraryEditor::_on_item_button);
+	ClassDB::bind_method("_on_library_selected", &GDNativeLibraryEditor::_on_library_selected);
+	ClassDB::bind_method("_on_dependencies_selected", &GDNativeLibraryEditor::_on_dependencies_selected);
+	ClassDB::bind_method("_on_filter_selected", &GDNativeLibraryEditor::_on_filter_selected);
+	ClassDB::bind_method("_on_item_collapsed", &GDNativeLibraryEditor::_on_item_collapsed);
+	ClassDB::bind_method("_on_item_activated", &GDNativeLibraryEditor::_on_item_activated);
+	ClassDB::bind_method("_on_create_new_entry", &GDNativeLibraryEditor::_on_create_new_entry);
+}
+
+void GDNativeLibraryEditor::_update_tree() {
+
+	tree->clear();
+	TreeItem *root = tree->create_item();
+
+	for (Map<String, NativePlatformConfig>::Element *E = platforms.front(); E; E = E->next()) {
+
+		if (showing_platform != E->key() && showing_platform != "All")
+			continue;
+
+		TreeItem *platform = tree->create_item(root);
+		platform->set_text(0, E->get().name);
+		platform->set_metadata(0, E->get().library_extension);
+
+		platform->set_custom_bg_color(0, get_color("prop_category", "Editor"));
+		platform->set_custom_bg_color(1, get_color("prop_category", "Editor"));
+		platform->set_custom_bg_color(2, get_color("prop_category", "Editor"));
+		platform->set_selectable(0, false);
+		platform->set_expand_right(0, true);
+
+		for (List<String>::Element *it = E->value().entries.front(); it; it = it->next()) {
+
+			String target = E->key() + "." + it->get();
+			TreeItem *bit = tree->create_item(platform);
+
+			bit->set_text(0, it->get());
+			bit->set_metadata(0, target);
+			bit->set_selectable(0, false);
+			bit->set_custom_bg_color(0, get_color("prop_subsection", "Editor"));
+
+			bit->add_button(1, get_icon("Folder", "EditorIcons"), BUTTON_SELECT_LIBRARY, false, TTR("Select the dynamic library for this entry"));
+			String file = entry_configs[target].library;
+			if (!file.empty()) {
+				bit->add_button(1, get_icon("Clear", "EditorIcons"), BUTTON_CLEAR_LIBRARY, false, TTR("Clear"));
+			}
+			bit->set_text(1, file);
+
+			bit->add_button(2, get_icon("Folder", "EditorIcons"), BUTTON_SELECT_DEPENDENCES, false, TTR("Select dependencies of the library for this entry"));
+			Array files = entry_configs[target].dependencies;
+			if (files.size()) {
+				bit->add_button(2, get_icon("Clear", "EditorIcons"), BUTTON_CLEAR_DEPENDENCES, false, TTR("Clear"));
+			}
+			bit->set_text(2, Variant(files));
+
+			bit->add_button(3, get_icon("MoveUp", "EditorIcons"), BUTTON_MOVE_UP, false, TTR("Move Up"));
+			bit->add_button(3, get_icon("MoveDown", "EditorIcons"), BUTTON_MOVE_DOWN, false, TTR("Move Down"));
+			bit->add_button(3, get_icon("Remove", "EditorIcons"), BUTTON_ERASE_ENTRY, false, TTR("Remove current entry"));
+		}
+
+		TreeItem *new_arch = tree->create_item(platform);
+		new_arch->set_text(0, TTR("Double click to create a new entry"));
+		new_arch->set_text_align(0, TreeItem::ALIGN_CENTER);
+		new_arch->set_custom_color(0, get_color("accent_color", "Editor"));
+		new_arch->set_expand_right(0, true);
+		new_arch->set_metadata(1, E->key());
+
+		platform->set_collapsed(collapsed_items.find(E->get().name) != NULL);
+	}
+}
+
+void GDNativeLibraryEditor::_on_item_button(Object *item, int column, int id) {
+
+	String target = Object::cast_to<TreeItem>(item)->get_metadata(0);
+	String platform = target.substr(0, target.find("."));
+	String entry = target.substr(platform.length() + 1, target.length());
+	String section = (id == BUTTON_SELECT_DEPENDENCES || id == BUTTON_CLEAR_DEPENDENCES) ? "dependencies" : "entry";
+
+	if (id == BUTTON_SELECT_LIBRARY || id == BUTTON_SELECT_DEPENDENCES) {
+
+		EditorFileDialog::Mode mode = EditorFileDialog::MODE_OPEN_FILE;
+		if (id == BUTTON_SELECT_DEPENDENCES)
+			mode = EditorFileDialog::MODE_OPEN_FILES;
+
+		file_dialog->set_meta("target", target);
+		file_dialog->set_meta("section", section);
+		file_dialog->clear_filters();
+		file_dialog->add_filter(Object::cast_to<TreeItem>(item)->get_parent()->get_metadata(0));
+		file_dialog->set_mode(mode);
+		file_dialog->popup_centered_ratio();
+
+	} else if (id == BUTTON_CLEAR_LIBRARY) {
+		_set_target_value(section, target, "");
+	} else if (id == BUTTON_CLEAR_DEPENDENCES) {
+		_set_target_value(section, target, Array());
+	} else if (id == BUTTON_ERASE_ENTRY) {
+		_erase_entry(platform, entry);
+	} else if (id == BUTTON_MOVE_UP || id == BUTTON_MOVE_DOWN) {
+		_move_entry(platform, entry, id);
+	}
+}
+
+void GDNativeLibraryEditor::_on_library_selected(const String &file) {
+
+	_set_target_value(file_dialog->get_meta("section"), file_dialog->get_meta("target"), file);
+}
+
+void GDNativeLibraryEditor::_on_dependencies_selected(const PoolStringArray &files) {
+
+	_set_target_value(file_dialog->get_meta("section"), file_dialog->get_meta("target"), files);
+}
+
+void GDNativeLibraryEditor::_on_filter_selected(int id) {
+
+	showing_platform = filter->get_item_metadata(id);
+	_update_tree();
+}
+
+void GDNativeLibraryEditor::_on_item_collapsed(Object *p_item) {
+
+	TreeItem *item = Object::cast_to<TreeItem>(p_item);
+	String name = item->get_text(0);
+
+	if (item->is_collapsed()) {
+		collapsed_items.insert(name);
+	} else if (Set<String>::Element *e = collapsed_items.find(name)) {
+		collapsed_items.erase(e);
+	}
+}
+
+void GDNativeLibraryEditor::_on_item_activated() {
+
+	TreeItem *item = tree->get_selected();
+	if (item && tree->get_selected_column() == 0 && item->get_metadata(0).get_type() == Variant::NIL) {
+		new_architecture_dialog->set_meta("platform", item->get_metadata(1));
+		new_architecture_dialog->popup_centered();
+	}
+}
+
+void GDNativeLibraryEditor::_on_create_new_entry() {
+
+	String platform = new_architecture_dialog->get_meta("platform");
+	String entry = new_architecture_input->get_text().strip_edges();
+	if (!entry.empty()) {
+		platforms[platform].entries.push_back(entry);
+		_update_tree();
+	}
+}
+
+void GDNativeLibraryEditor::_set_target_value(const String &section, const String &target, Variant file) {
+	if (section == "entry")
+		entry_configs[target].library = file;
+	else if (section == "dependencies")
+		entry_configs[target].dependencies = file;
+	_translate_to_config_file();
+	_update_tree();
+}
+
+void GDNativeLibraryEditor::_erase_entry(const String &platform, const String &entry) {
+
+	if (platforms.has(platform)) {
+		if (List<String>::Element *E = platforms[platform].entries.find(entry)) {
+
+			String target = platform + "." + entry;
+			Ref<ConfigFile> config = library->get_config_file();
+
+			platforms[platform].entries.erase(E);
+			_set_target_value("entry", target, "");
+			_set_target_value("dependencies", target, Array());
+			_translate_to_config_file();
+			_update_tree();
+		}
+	}
+}
+
+void GDNativeLibraryEditor::_move_entry(const String &platform, const String &entry, int dir) {
+	if (List<String>::Element *E = platforms[platform].entries.find(entry)) {
+		if (E->prev() && dir == BUTTON_MOVE_UP) {
+			platforms[platform].entries.insert_before(E->prev(), E->get());
+			platforms[platform].entries.erase(E);
+		} else if (E->next() && dir == BUTTON_MOVE_DOWN) {
+			platforms[platform].entries.insert_after(E->next(), E->get());
+			platforms[platform].entries.erase(E);
+		}
+		_translate_to_config_file();
+		_update_tree();
+	}
+}
+
+void GDNativeLibraryEditor::_translate_to_config_file() {
+
+	if (!library.is_null()) {
+
+		Ref<ConfigFile> config = library->get_config_file();
+		config->erase_section("entry");
+		config->erase_section("dependencies");
+
+		for (Map<String, NativePlatformConfig>::Element *E = platforms.front(); E; E = E->next()) {
+			for (List<String>::Element *it = E->value().entries.front(); it; it = it->next()) {
+
+				String target = E->key() + "." + it->get();
+				if (entry_configs[target].library.empty() && entry_configs[target].dependencies.empty())
+					continue;
+
+				config->set_value("entry", target, entry_configs[target].library);
+				config->set_value("dependencies", target, entry_configs[target].dependencies);
+			}
+		}
+
+		library->_change_notify();
+	}
+}
+
+GDNativeLibraryEditor::GDNativeLibraryEditor() {
+
+	showing_platform = "All";
+
+	{ // Define platforms
+		NativePlatformConfig platform_windows;
+		platform_windows.name = "Windows";
+		platform_windows.entries.push_back("64");
+		platform_windows.entries.push_back("32");
+		platform_windows.library_extension = "*.dll";
+		platforms["Windows"] = platform_windows;
+
+		NativePlatformConfig platform_linux;
+		platform_linux.name = "Linux/X11";
+		platform_linux.entries.push_back("64");
+		platform_linux.entries.push_back("32");
+		platform_linux.library_extension = "*.so";
+		platforms["X11"] = platform_linux;
+
+		NativePlatformConfig platform_osx;
+		platform_osx.name = "Mac OSX";
+		platform_osx.entries.push_back("64");
+		platform_osx.entries.push_back("32");
+		platform_osx.library_extension = "*.dylib";
+		platforms["OSX"] = platform_osx;
+
+		NativePlatformConfig platform_haiku;
+		platform_haiku.name = "Haiku";
+		platform_haiku.entries.push_back("64");
+		platform_haiku.entries.push_back("32");
+		platform_haiku.library_extension = "*.so";
+		platforms["Haiku"] = platform_haiku;
+
+		NativePlatformConfig platform_uwp;
+		platform_uwp.name = "Windows Universal";
+		platform_uwp.entries.push_back("arm");
+		platform_uwp.entries.push_back("x86");
+		platform_uwp.entries.push_back("x64");
+		platform_uwp.library_extension = "*.dll";
+		platforms["UWP"] = platform_uwp;
+
+		NativePlatformConfig platform_android;
+		platform_android.name = "Android";
+		platform_android.entries.push_back("armeabi-v7a");
+		platform_android.entries.push_back("arm64-v8a");
+		platform_android.entries.push_back("x86");
+		platform_android.entries.push_back("x86_64");
+		platform_android.library_extension = "*.so";
+		platforms["Android"] = platform_android;
+
+		//		TODO: Javascript platform is not supported yet
+		//		NativePlatformConfig platform_html5;
+		//		platform_html5.name = "HTML5";
+		//		platform_html5.library_extension = "*.wasm";
+		//		platforms["Javascript"] = platform_html5;
+
+		NativePlatformConfig platform_ios;
+		platform_ios.name = "iOS";
+		platform_ios.entries.push_back("armv7");
+		platform_ios.entries.push_back("arm64");
+		platform_ios.library_extension = "*.dylib";
+		platforms["iOS"] = platform_ios;
+	}
+
+	VBoxContainer *container = memnew(VBoxContainer);
+	add_child(container);
+	container->set_anchors_and_margins_preset(PRESET_WIDE);
+
+	HBoxContainer *hbox = memnew(HBoxContainer);
+	container->add_child(hbox);
+	Label *label = memnew(Label);
+	label->set_text(TTR("Platform:"));
+	hbox->add_child(label);
+	filter = memnew(OptionButton);
+	hbox->add_child(filter);
+	filter->set_h_size_flags(SIZE_EXPAND_FILL);
+
+	int idx = 0;
+	filter->add_item(TTR("All"), idx);
+	filter->set_item_metadata(idx, "All");
+	idx += 1;
+	for (Map<String, NativePlatformConfig>::Element *E = platforms.front(); E; E = E->next()) {
+		filter->add_item(E->get().name, idx);
+		filter->set_item_metadata(idx, E->key());
+		idx += 1;
+	}
+	filter->connect("item_selected", this, "_on_filter_selected");
+
+	tree = memnew(Tree);
+	container->add_child(tree);
+	tree->set_v_size_flags(SIZE_EXPAND_FILL);
+	tree->set_hide_root(true);
+	tree->set_column_titles_visible(true);
+	tree->set_columns(4);
+	tree->set_column_expand(0, false);
+	tree->set_column_min_width(0, int(200 * EDSCALE));
+	tree->set_column_title(0, TTR("Platform"));
+	tree->set_column_title(1, TTR("Dynamic Library"));
+	tree->set_column_title(2, TTR("Dependencies"));
+	tree->set_column_expand(3, false);
+	tree->set_column_min_width(3, int(110 * EDSCALE));
+	tree->connect("button_pressed", this, "_on_item_button");
+	tree->connect("item_collapsed", this, "_on_item_collapsed");
+	tree->connect("item_activated", this, "_on_item_activated");
+
+	file_dialog = memnew(EditorFileDialog);
+	file_dialog->set_access(EditorFileDialog::ACCESS_RESOURCES);
+	file_dialog->set_resizable(true);
+	add_child(file_dialog);
+	file_dialog->connect("file_selected", this, "_on_library_selected");
+	file_dialog->connect("files_selected", this, "_on_dependencies_selected");
+
+	new_architecture_dialog = memnew(ConfirmationDialog);
+	add_child(new_architecture_dialog);
+	new_architecture_dialog->set_title(TTR("Add an architecture entry"));
+	new_architecture_input = memnew(LineEdit);
+	new_architecture_dialog->add_child(new_architecture_input);
+	new_architecture_dialog->set_custom_minimum_size(Vector2(300, 80) * EDSCALE);
+	new_architecture_input->set_anchors_and_margins_preset(PRESET_HCENTER_WIDE, PRESET_MODE_MINSIZE, 5 * EDSCALE);
+	new_architecture_dialog->get_ok()->connect("pressed", this, "_on_create_new_entry");
+}
+
+void GDNativeLibraryEditorPlugin::edit(Object *p_node) {
+
+	if (Object::cast_to<GDNativeLibrary>(p_node)) {
+		library_editor->edit(Object::cast_to<GDNativeLibrary>(p_node));
+		library_editor->show();
+	} else
+		library_editor->hide();
+}
+
+bool GDNativeLibraryEditorPlugin::handles(Object *p_node) const {
+
+	return p_node->is_class("GDNativeLibrary");
+}
+
+void GDNativeLibraryEditorPlugin::make_visible(bool p_visible) {
+
+	if (p_visible) {
+		button->show();
+		EditorNode::get_singleton()->make_bottom_panel_item_visible(library_editor);
+
+	} else {
+		if (library_editor->is_visible_in_tree())
+			EditorNode::get_singleton()->hide_bottom_panel();
+		button->hide();
+	}
+}
+
+GDNativeLibraryEditorPlugin::GDNativeLibraryEditorPlugin(EditorNode *p_node) {
+
+	library_editor = memnew(GDNativeLibraryEditor);
+	library_editor->set_custom_minimum_size(Size2(0, 250 * EDSCALE));
+	button = p_node->add_bottom_panel_item(TTR("GDNativeLibrary"), library_editor);
+	button->hide();
+}
+
+#endif

+ 113 - 0
modules/gdnative/gdnative_library_editor_plugin.h

@@ -0,0 +1,113 @@
+/*************************************************************************/
+/*  gdnative_library_editor_plugin.h                                     */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)    */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+#ifndef GDNATIVE_LIBRARY_EDITOR_PLUGIN_H
+#define GDNATIVE_LIBRARY_EDITOR_PLUGIN_H
+
+#ifdef TOOLS_ENABLED
+#include "editor/editor_node.h"
+#include "gdnative.h"
+
+class GDNativeLibraryEditor : public Control {
+
+	GDCLASS(GDNativeLibraryEditor, Control);
+
+	struct NativePlatformConfig {
+		String name;
+		String library_extension;
+		List<String> entries;
+	};
+
+	struct TargetConfig {
+		String library;
+		Array dependencies;
+	};
+
+	enum ItemButton {
+		BUTTON_SELECT_LIBRARY,
+		BUTTON_CLEAR_LIBRARY,
+		BUTTON_SELECT_DEPENDENCES,
+		BUTTON_CLEAR_DEPENDENCES,
+		BUTTON_ERASE_ENTRY,
+		BUTTON_MOVE_UP,
+		BUTTON_MOVE_DOWN,
+	};
+
+	Tree *tree;
+	OptionButton *filter;
+	EditorFileDialog *file_dialog;
+	ConfirmationDialog *new_architecture_dialog;
+	LineEdit *new_architecture_input;
+	Set<String> collapsed_items;
+
+	String showing_platform;
+	Ref<GDNativeLibrary> library;
+	Map<String, NativePlatformConfig> platforms;
+	Map<String, TargetConfig> entry_configs;
+
+protected:
+	static void _bind_methods();
+	void _update_tree();
+	void _on_item_button(Object *item, int column, int id);
+	void _on_library_selected(const String &file);
+	void _on_dependencies_selected(const PoolStringArray &files);
+	void _on_filter_selected(int id);
+	void _on_item_collapsed(Object *item);
+	void _on_item_activated();
+	void _on_create_new_entry();
+	void _set_target_value(const String &section, const String &target, Variant file);
+	void _erase_entry(const String &platform, const String &entry);
+	void _move_entry(const String &platform, const String &entry, int dir);
+	void _translate_to_config_file();
+
+public:
+	void edit(Ref<GDNativeLibrary> p_library);
+
+	GDNativeLibraryEditor();
+};
+
+class GDNativeLibraryEditorPlugin : public EditorPlugin {
+
+	GDCLASS(GDNativeLibraryEditorPlugin, EditorPlugin);
+
+	GDNativeLibraryEditor *library_editor;
+	EditorNode *editor;
+	Button *button;
+
+public:
+	virtual String get_name() const { return "GDNativeLibrary"; }
+	bool has_main_screen() const { return false; }
+	virtual void edit(Object *p_node);
+	virtual bool handles(Object *p_node) const;
+	virtual void make_visible(bool p_visible);
+
+	GDNativeLibraryEditorPlugin(EditorNode *p_node);
+};
+#endif
+#endif // GDNATIVE_LIBRARY_EDITOR_PLUGIN_H

+ 9 - 10
modules/gdnative/gd_native_library_editor.cpp → modules/gdnative/gdnative_library_singleton_editor.cpp

@@ -1,5 +1,5 @@
 /*************************************************************************/
 /*************************************************************************/
-/*  gd_native_library_editor.cpp                                         */
+/*  gdnative_library_singleton_editor.cpp                               */
 /*************************************************************************/
 /*************************************************************************/
 /*                       This file is part of:                           */
 /*                       This file is part of:                           */
 /*                           GODOT ENGINE                                */
 /*                           GODOT ENGINE                                */
@@ -28,11 +28,10 @@
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
 /*************************************************************************/
 #ifdef TOOLS_ENABLED
 #ifdef TOOLS_ENABLED
-#include "gd_native_library_editor.h"
-
+#include "gdnative_library_singleton_editor.h"
 #include "gdnative.h"
 #include "gdnative.h"
 
 
-void GDNativeLibraryEditor::_find_gdnative_singletons(EditorFileSystemDirectory *p_dir, const Set<String> &enabled_list) {
+void GDNativeLibrarySingletonEditor::_find_gdnative_singletons(EditorFileSystemDirectory *p_dir, const Set<String> &enabled_list) {
 
 
 	// check children
 	// check children
 
 
@@ -65,7 +64,7 @@ void GDNativeLibraryEditor::_find_gdnative_singletons(EditorFileSystemDirectory
 	}
 	}
 }
 }
 
 
-void GDNativeLibraryEditor::_update_libraries() {
+void GDNativeLibrarySingletonEditor::_update_libraries() {
 
 
 	updating = true;
 	updating = true;
 	libraries->clear();
 	libraries->clear();
@@ -88,7 +87,7 @@ void GDNativeLibraryEditor::_update_libraries() {
 	updating = false;
 	updating = false;
 }
 }
 
 
-void GDNativeLibraryEditor::_item_edited() {
+void GDNativeLibrarySingletonEditor::_item_edited() {
 	if (updating)
 	if (updating)
 		return;
 		return;
 
 
@@ -119,7 +118,7 @@ void GDNativeLibraryEditor::_item_edited() {
 	}
 	}
 }
 }
 
 
-void GDNativeLibraryEditor::_notification(int p_what) {
+void GDNativeLibrarySingletonEditor::_notification(int p_what) {
 
 
 	if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
 	if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
 		if (is_visible_in_tree()) {
 		if (is_visible_in_tree()) {
@@ -128,12 +127,12 @@ void GDNativeLibraryEditor::_notification(int p_what) {
 	}
 	}
 }
 }
 
 
-void GDNativeLibraryEditor::_bind_methods() {
+void GDNativeLibrarySingletonEditor::_bind_methods() {
 
 
-	ClassDB::bind_method(D_METHOD("_item_edited"), &GDNativeLibraryEditor::_item_edited);
+	ClassDB::bind_method(D_METHOD("_item_edited"), &GDNativeLibrarySingletonEditor::_item_edited);
 }
 }
 
 
-GDNativeLibraryEditor::GDNativeLibraryEditor() {
+GDNativeLibrarySingletonEditor::GDNativeLibrarySingletonEditor() {
 	libraries = memnew(Tree);
 	libraries = memnew(Tree);
 	libraries->set_columns(2);
 	libraries->set_columns(2);
 	libraries->set_column_titles_visible(true);
 	libraries->set_column_titles_visible(true);

+ 3 - 3
modules/gdnative/gd_native_library_editor.h → modules/gdnative/gdnative_library_singleton_editor.h

@@ -1,5 +1,5 @@
 /*************************************************************************/
 /*************************************************************************/
-/*  gd_native_library_editor.h                                           */
+/*  gdnative_library_singleton_editor.h                                 */
 /*************************************************************************/
 /*************************************************************************/
 /*                       This file is part of:                           */
 /*                       This file is part of:                           */
 /*                           GODOT ENGINE                                */
 /*                           GODOT ENGINE                                */
@@ -34,7 +34,7 @@
 #include "editor/editor_file_system.h"
 #include "editor/editor_file_system.h"
 #include "editor/project_settings_editor.h"
 #include "editor/project_settings_editor.h"
 
 
-class GDNativeLibraryEditor : public VBoxContainer {
+class GDNativeLibrarySingletonEditor : public VBoxContainer {
 	Tree *libraries;
 	Tree *libraries;
 
 
 	bool updating;
 	bool updating;
@@ -48,7 +48,7 @@ protected:
 	static void _bind_methods();
 	static void _bind_methods();
 
 
 public:
 public:
-	GDNativeLibraryEditor();
+	GDNativeLibrarySingletonEditor();
 };
 };
 
 
 #endif
 #endif

+ 5 - 2
modules/gdnative/register_types.cpp

@@ -45,7 +45,8 @@
 
 
 #ifdef TOOLS_ENABLED
 #ifdef TOOLS_ENABLED
 #include "editor/editor_node.h"
 #include "editor/editor_node.h"
-#include "gd_native_library_editor.h"
+#include "gdnative_library_editor_plugin.h"
+#include "gdnative_library_singleton_editor.h"
 // Class used to discover singleton gdnative files
 // Class used to discover singleton gdnative files
 
 
 static void actual_discoverer_handler();
 static void actual_discoverer_handler();
@@ -267,7 +268,7 @@ void GDNativeExportPlugin::_export_file(const String &p_path, const String &p_ty
 
 
 static void editor_init_callback() {
 static void editor_init_callback() {
 
 
-	GDNativeLibraryEditor *library_editor = memnew(GDNativeLibraryEditor);
+	GDNativeLibrarySingletonEditor *library_editor = memnew(GDNativeLibrarySingletonEditor);
 	library_editor->set_name(TTR("GDNative"));
 	library_editor->set_name(TTR("GDNative"));
 	ProjectSettingsEditor::get_singleton()->get_tabs()->add_child(library_editor);
 	ProjectSettingsEditor::get_singleton()->get_tabs()->add_child(library_editor);
 
 
@@ -278,6 +279,8 @@ static void editor_init_callback() {
 	export_plugin.instance();
 	export_plugin.instance();
 
 
 	EditorExport::get_singleton()->add_export_plugin(export_plugin);
 	EditorExport::get_singleton()->add_export_plugin(export_plugin);
+
+	EditorNode::get_singleton()->add_editor_plugin(memnew(GDNativeLibraryEditorPlugin(EditorNode::get_singleton())));
 }
 }
 
 
 #endif
 #endif