Skip to content

Commit

Permalink
Add ClassType wrapper and Editor SceneTemplates
Browse files Browse the repository at this point in the history
  • Loading branch information
willnationsdev committed Nov 16, 2018
1 parent 89a8f93 commit 862000b
Show file tree
Hide file tree
Showing 19 changed files with 2,008 additions and 85 deletions.
131 changes: 54 additions & 77 deletions editor/create_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@
#include "editor_help.h"
#include "editor_node.h"
#include "editor_settings.h"
#include "modules/class_type/class_type.h"
#include "scene/gui/box_container.h"

void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode) {

type_list.clear();
ClassDB::get_class_list(&type_list);
ScriptServer::get_global_class_list(&type_list);
ClassType::get_class_list(&type_list);
type_list.sort_custom<StringName::AlphCompare>();

recent->clear();
Expand Down Expand Up @@ -131,6 +131,8 @@ void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode) {
set_title(vformat(TTR("Create New %s"), base_type));
get_ok()->set_text(TTR("Create"));
}

_scene_template_cache = "";
}

void CreateDialog::_text_changed(const String &p_newtext) {
Expand All @@ -156,27 +158,18 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p
if (p_types.has(p_type))
return;

bool cpp_type = ClassDB::class_exists(p_type);
EditorData &ed = EditorNode::get_editor_data();
Ref<ClassType> class_type = ClassType::from_name(p_type);

if (p_type == base_type)
return;

if (cpp_type) {
if (!ClassDB::is_parent_class(p_type, base_type))
return;
} else {
if (!ScriptServer::is_global_class(p_type) || !ed.script_class_is_parent(p_type, base_type))
if (!class_type->exists() || !class_type->is_parent_class(base_type))
return;
if (class_type->has_valid_path() && class_type->get_path().find("res://addons/", 0) != -1) {
if (!EditorNode::get_singleton()->is_addon_plugin_enabled(class_type->get_path().get_slicec('/', 3)))
return;

String script_path = ScriptServer::get_global_class_path(p_type);
if (script_path.find("res://addons/", 0) != -1) {
if (!EditorNode::get_singleton()->is_addon_plugin_enabled(script_path.get_slicec('/', 3)))
return;
}
}

String inherits = cpp_type ? ClassDB::get_parent_class(p_type) : ed.script_class_get_base(p_type);
String inherits = class_type->get_parent_class();

TreeItem *parent = p_root;

Expand All @@ -189,35 +182,30 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p

if (p_types.has(inherits))
parent = p_types[inherits];
else if (ScriptServer::is_global_class(inherits))
return;
else {
Ref<ClassType> inherits_type = ClassType::from_name(inherits);
if (inherits_type.is_null() || inherits_type->is_script_class() || inherits_type->is_scene_template())
return;
}
}

bool can_instance = (cpp_type && ClassDB::can_instance(p_type)) || ScriptServer::is_global_class(p_type);
bool can_instance = class_type->can_instance();

TreeItem *item = search_options->create_item(parent);
if (cpp_type) {
item->set_text(0, p_type);
} else {
String name_text = class_type->get_name();
if (class_type->has_valid_path()) {
name_text += " (" + class_type->get_path().get_file() + ")";
item->set_metadata(0, p_type);
item->set_text(0, p_type + " (" + ScriptServer::get_global_class_path(p_type).get_file() + ")");
}
item->set_text(0, name_text);
if (!can_instance) {
item->set_custom_color(0, get_color("disabled_font_color", "Editor"));
item->set_selectable(0, false);
} else {
bool is_search_subsequence = search_box->get_text().is_subsequence_ofi(p_type);
String to_select_type = *to_select ? (*to_select)->get_text(0) : "";
to_select_type = to_select_type.split(" ")[0];
bool current_item_is_preferred;
if (cpp_type) {
String cpp_to_select_type = to_select_type;
if (ScriptServer::is_global_class(to_select_type))
cpp_to_select_type = ScriptServer::get_global_class_base(to_select_type);
current_item_is_preferred = ClassDB::is_parent_class(p_type, preferred_search_result_type) && !ClassDB::is_parent_class(cpp_to_select_type, preferred_search_result_type);
} else {
current_item_is_preferred = ed.script_class_is_parent(p_type, preferred_search_result_type) && !ed.script_class_is_parent(to_select_type, preferred_search_result_type) && search_box->get_text() != to_select_type;
}
Ref<ClassType> to_select_type = ClassType::from_name(*to_select ? _get_name_from_text((*to_select)->get_text(0)) : "");
bool current_item_is_preferred = class_type->is_parent_class(preferred_search_result_type) && !to_select_type->is_parent_class(preferred_search_result_type);

if (*to_select && p_type.length() < (*to_select)->get_text(0).length()) {
current_item_is_preferred = true;
}
Expand Down Expand Up @@ -261,7 +249,6 @@ void CreateDialog::_update_search() {
HashMap<String, TreeItem *> types;

TreeItem *root = search_options->create_item();
EditorData &ed = EditorNode::get_editor_data();

root->set_text(0, base_type);
if (has_icon(base_type, "EditorIcons")) {
Expand All @@ -273,18 +260,21 @@ void CreateDialog::_update_search() {
for (List<StringName>::Element *I = type_list.front(); I; I = I->next()) {

String type = I->get();
bool cpp_type = ClassDB::class_exists(type);

Ref<ClassType> class_type = ClassType::from_name(type);
if (class_type.is_null())
continue;

if (base_type == "Node" && type.begins_with("Editor"))
continue; // do not show editor nodes

if (cpp_type && !ClassDB::can_instance(type))
if (!class_type->can_instance())
continue; // can't create what can't be instanced

bool skip = false;
if (cpp_type) {
if (class_type->is_engine_class()) {
for (Set<StringName>::Element *E = type_blacklist.front(); E && !skip; E = E->next()) {
if (ClassDB::is_parent_class(type, E->get()))
if (class_type->is_parent_class(E->get()))
skip = true;
}
if (skip)
Expand All @@ -296,15 +286,15 @@ void CreateDialog::_update_search() {
} else {

bool found = false;
String type = I->get();
while (type != "" && (cpp_type ? ClassDB::is_parent_class(type, base_type) : ed.script_class_is_parent(type, base_type)) && type != base_type) {
if (search_box->get_text().is_subsequence_ofi(type)) {
Ref<ClassType> match_type = ClassType::from_name(I->get());
while (match_type.is_valid() && match_type->get_name() != "" && match_type->is_parent_class(base_type) && match_type->get_name() != base_type) {
if (search_box->get_text().is_subsequence_ofi(match_type->get_name())) {

found = true;
break;
}

type = cpp_type ? ClassDB::get_parent_class(type) : ed.script_class_get_base(type);
match_type->set_name(match_type->get_parent_class());
}

if (found)
Expand Down Expand Up @@ -453,30 +443,12 @@ String CreateDialog::get_selected_type() {

Object *CreateDialog::instance_selected() {

TreeItem *selected = search_options->get_selected();

if (selected) {

Variant md = selected->get_metadata(0);

String custom;
if (md.get_type() != Variant::NIL)
custom = md;

if (custom != String()) {
if (ScriptServer::is_global_class(custom)) {
Object *obj = EditorNode::get_editor_data().script_class_instance(custom);
Node *n = Object::cast_to<Node>(obj);
if (n)
n->set_name(custom);
return obj;
}
return EditorNode::get_editor_data().instance_custom_type(selected->get_text(0), custom);
} else {
return ClassDB::instance(selected->get_text(0));
}
Ref<ClassType> type = ClassType::from_name(_get_name_from_text(get_selected_type()));
if (type.is_valid() && type->exists()) {
if (!type->is_scene_template())
return type->instance();
_scene_template_cache = type->get_path();
}

return NULL;
}

Expand All @@ -486,10 +458,11 @@ void CreateDialog::_item_selected() {
if (!item)
return;

String name = item->get_text(0);
String text = item->get_text(0);
String name = _get_name_from_text(text);

favorite->set_disabled(false);
favorite->set_pressed(favorite_list.find(name) != -1);
favorite->set_pressed(favorite_list.find(text) != -1);

if (!EditorHelp::get_doc_data()->class_list.has(name))
return;
Expand All @@ -505,13 +478,13 @@ void CreateDialog::_favorite_toggled() {
if (!item)
return;

String name = item->get_text(0);
String text = item->get_text(0);

if (favorite_list.find(name) == -1) {
favorite_list.push_back(name);
if (favorite_list.find(text) == -1) {
favorite_list.push_back(text);
favorite->set_pressed(true);
} else {
favorite_list.erase(name);
favorite_list.erase(text);
favorite->set_pressed(false);
}

Expand All @@ -526,7 +499,7 @@ void CreateDialog::_save_favorite_list() {

for (int i = 0; i < favorite_list.size(); i++) {
String l = favorite_list[i];
String name = l.split(" ")[0];
String name = _get_name_from_text(l);
if (!(ClassDB::class_exists(name) || ScriptServer::is_global_class(name)))
continue;
f->store_line(l);
Expand All @@ -541,7 +514,7 @@ void CreateDialog::_update_favorite_list() {
TreeItem *root = favorites->create_item();
for (int i = 0; i < favorite_list.size(); i++) {
String l = favorite_list[i];
String name = l.split(" ")[0];
String name = _get_name_from_text(l);
if (!(ClassDB::class_exists(name) || ScriptServer::is_global_class(name)))
continue;
TreeItem *ti = favorites->create_item(root);
Expand All @@ -557,7 +530,7 @@ void CreateDialog::_history_selected() {
if (!item)
return;

search_box->set_text(item->get_text(0).get_slicec(' ', 0));
search_box->set_text(_get_name_from_text(item->get_text(0)));
favorites->deselect_all();
_update_search();
}
Expand All @@ -568,7 +541,7 @@ void CreateDialog::_favorite_selected() {
if (!item)
return;

search_box->set_text(item->get_text(0).get_slicec(' ', 0));
search_box->set_text(_get_name_from_text(item->get_text(0)));
recent->deselect_all();
_update_search();
}
Expand Down Expand Up @@ -656,6 +629,10 @@ void CreateDialog::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co
_save_and_update_favorite_list();
}

String CreateDialog::_get_name_from_text(const String &p_text) const {
return p_text.split(" ")[0];
}

void CreateDialog::_save_and_update_favorite_list() {
_save_favorite_list();
_update_favorite_list();
Expand Down
5 changes: 5 additions & 0 deletions editor/create_dialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class CreateDialog : public ConfirmationDialog {
EditorHelpBit *help_bit;
List<StringName> type_list;
Set<StringName> type_blacklist;
String _scene_template_cache;

void _item_selected();

Expand Down Expand Up @@ -86,6 +87,8 @@ class CreateDialog : public ConfirmationDialog {
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);

String _get_name_from_text(const String &p_text) const;

protected:
void _notification(int p_what);
static void _bind_methods();
Expand All @@ -102,6 +105,8 @@ class CreateDialog : public ConfirmationDialog {
void set_preferred_search_result_type(const String &p_preferred_type);
String get_preferred_search_result_type();

String get_scene_template_cache() const { return _scene_template_cache; }

void popup_create(bool p_dont_clear, bool p_replace_mode = false);

CreateDialog();
Expand Down
27 changes: 27 additions & 0 deletions editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3191,6 +3191,33 @@ Ref<Texture> EditorNode::get_class_icon(const String &p_class, const String &p_f
return gui_base->get_icon(p_class, "EditorIcons");
}

EditorSceneTemplateSettings *scene_template_settings = project_settings->get_scene_template_settings();
if (scene_template_settings->scene_template_exists(p_class)) {
String scene_path = scene_template_settings->scene_template_get_path(p_class);
if (scene_path.empty() || !FileAccess::exists(scene_path))
return NULL;
Ref<PackedScene> scene = ResourceLoader::load(scene_path, "PackedScene");
if (scene.is_null())
return NULL;
Ref<SceneState> state = scene->get_state();
if (state.is_null())
return NULL;
for (int i = 0; i < state->get_node_property_count(0); i++) {
String name = state->get_node_property_name(0, i);
if ("script" == name) {
Ref<Script> script = state->get_node_property_value(0, i);
while (script.is_valid()) {
String script_name = script->get_language()->get_global_class_name(script->get_path());
if (ScriptServer::is_global_class(script_name))
return get_class_icon(script_name);
script = script->get_base_script();
}
break;
}
}
return get_class_icon(state->get_node_type(0));
}

if (ScriptServer::is_global_class(p_class)) {
String icon_path = EditorNode::get_editor_data().script_class_get_icon_path(p_class);
RES icon;
Expand Down
10 changes: 10 additions & 0 deletions editor/editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,14 @@ void EditorPlugin::set_force_draw_over_forwarding_enabled() {
always_draw_over_forwarding_list->add_plugin(this);
}

void EditorPlugin::scene_template_add(const String &p_name, const String &p_path) {
EditorNode::get_singleton()->get_project_settings()->get_scene_template_settings()->scene_template_add(p_name, p_path);
}

void EditorPlugin::scene_template_remove(const String &p_name) {
EditorNode::get_singleton()->get_project_settings()->get_scene_template_settings()->scene_template_remove(p_name);
}

void EditorPlugin::notify_scene_changed(const Node *scn_root) {
emit_signal("scene_changed", scn_root);
}
Expand Down Expand Up @@ -757,6 +765,8 @@ void EditorPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove_tool_menu_item", "name"), &EditorPlugin::remove_tool_menu_item);
ClassDB::bind_method(D_METHOD("add_custom_type", "type", "base", "script", "icon"), &EditorPlugin::add_custom_type);
ClassDB::bind_method(D_METHOD("remove_custom_type", "type"), &EditorPlugin::remove_custom_type);
ClassDB::bind_method(D_METHOD("scene_template_add", "name", "path"), &EditorPlugin::scene_template_add);
ClassDB::bind_method(D_METHOD("scene_template_remove", "name"), &EditorPlugin::scene_template_remove);

ClassDB::bind_method(D_METHOD("add_autoload_singleton", "name", "path"), &EditorPlugin::add_autoload_singleton);
ClassDB::bind_method(D_METHOD("remove_autoload_singleton", "name"), &EditorPlugin::remove_autoload_singleton);
Expand Down
3 changes: 3 additions & 0 deletions editor/editor_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@ class EditorPlugin : public Node {
void set_force_draw_over_forwarding_enabled();
bool is_force_draw_over_forwarding_enabled() { return force_draw_over_forwarding_enabled; }

void scene_template_add(const String &p_name, const String &p_path);
void scene_template_remove(const String &p_name);

void notify_main_screen_changed(const String &screen_name);
void notify_scene_changed(const Node *scn_root);
void notify_scene_closed(const String &scene_filepath);
Expand Down
Loading

0 comments on commit 862000b

Please sign in to comment.