diff options
Diffstat (limited to 'editor/editor_resource_picker.cpp')
-rw-r--r-- | editor/editor_resource_picker.cpp | 218 |
1 files changed, 159 insertions, 59 deletions
diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp index c72d240962..d1a0bfeded 100644 --- a/editor/editor_resource_picker.cpp +++ b/editor/editor_resource_picker.cpp @@ -144,54 +144,7 @@ void EditorResourcePicker::_update_menu_items() { edit_menu->clear(); // Add options for creating specific subtypes of the base resource type. - if (base_type != "") { - int idx = 0; - - Set<String> allowed_types; - _get_allowed_types(false, &allowed_types); - - Vector<EditorData::CustomType> custom_resources; - if (EditorNode::get_editor_data().get_custom_types().has("Resource")) { - custom_resources = EditorNode::get_editor_data().get_custom_types()["Resource"]; - } - - for (Set<String>::Element *E = allowed_types.front(); E; E = E->next()) { - const String &t = E->get(); - - bool is_custom_resource = false; - Ref<Texture2D> icon; - if (!custom_resources.is_empty()) { - for (int j = 0; j < custom_resources.size(); j++) { - if (custom_resources[j].name == t) { - is_custom_resource = true; - if (custom_resources[j].icon.is_valid()) { - icon = custom_resources[j].icon; - } - break; - } - } - } - - if (!is_custom_resource && !(ScriptServer::is_global_class(t) || ClassDB::can_instance(t))) { - continue; - } - - inheritors_array.push_back(t); - - if (!icon.is_valid()) { - icon = get_theme_icon(has_theme_icon(t, "EditorIcons") ? t : "Object", "EditorIcons"); - } - - int id = TYPE_BASE_ID + idx; - edit_menu->add_icon_item(icon, vformat(TTR("New %s"), t), id); - - idx++; - } - - if (edit_menu->get_item_count()) { - edit_menu->add_separator(); - } - } + set_create_options(edit_menu); // Add an option to load a resource from a file. edit_menu->add_icon_item(get_theme_icon("Load", "EditorIcons"), TTR("Load"), OBJ_MENU_LOAD); @@ -271,6 +224,13 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { valid_extensions.insert(E->get()); } + if (!file_dialog) { + file_dialog = memnew(EditorFileDialog); + file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); + add_child(file_dialog); + file_dialog->connect("file_selected", callable_mp(this, &EditorResourcePicker::_file_selected)); + } + file_dialog->clear_filters(); for (Set<String>::Element *E = valid_extensions.front(); E; E = E->next()) { file_dialog->add_filter("*." + E->get() + " ; " + E->get().to_upper()); @@ -352,6 +312,11 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { } break; default: { + // Allow subclasses to handle their own options first, only then fallback on the default branch logic. + if (handle_menu_selected(p_which)) { + break; + } + if (p_which >= CONVERT_BASE_ID) { int to_type = p_which - CONVERT_BASE_ID; Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(edited_resource); @@ -394,6 +359,72 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { } } +void EditorResourcePicker::set_create_options(Object *p_menu_node) { + // If a subclass implements this method, use it to replace all create items. + if (get_script_instance() && get_script_instance()->has_method("set_create_options")) { + get_script_instance()->call("set_create_options", p_menu_node); + return; + } + + // By default provide generic "New ..." options. + if (base_type != "") { + int idx = 0; + + Set<String> allowed_types; + _get_allowed_types(false, &allowed_types); + + Vector<EditorData::CustomType> custom_resources; + if (EditorNode::get_editor_data().get_custom_types().has("Resource")) { + custom_resources = EditorNode::get_editor_data().get_custom_types()["Resource"]; + } + + for (Set<String>::Element *E = allowed_types.front(); E; E = E->next()) { + const String &t = E->get(); + + bool is_custom_resource = false; + Ref<Texture2D> icon; + if (!custom_resources.is_empty()) { + for (int j = 0; j < custom_resources.size(); j++) { + if (custom_resources[j].name == t) { + is_custom_resource = true; + if (custom_resources[j].icon.is_valid()) { + icon = custom_resources[j].icon; + } + break; + } + } + } + + if (!is_custom_resource && !(ScriptServer::is_global_class(t) || ClassDB::can_instance(t))) { + continue; + } + + inheritors_array.push_back(t); + + if (!icon.is_valid()) { + icon = get_theme_icon(has_theme_icon(t, "EditorIcons") ? t : "Object", "EditorIcons"); + } + + int id = TYPE_BASE_ID + idx; + edit_menu->add_icon_item(icon, vformat(TTR("New %s"), t), id); + + idx++; + } + + if (edit_menu->get_item_count()) { + edit_menu->add_separator(); + } + } +} + +bool EditorResourcePicker::handle_menu_selected(int p_which) { + if (get_script_instance() && get_script_instance()->has_method("handle_menu_selected")) { + return get_script_instance()->call("handle_menu_selected", p_which); + } + + return false; +} + void EditorResourcePicker::_button_draw() { if (dropping) { Color color = get_theme_color("accent_color", "Editor"); @@ -603,12 +634,19 @@ void EditorResourcePicker::_bind_methods() { ClassDB::bind_method(D_METHOD("get_allowed_types"), &EditorResourcePicker::get_allowed_types); ClassDB::bind_method(D_METHOD("set_edited_resource", "resource"), &EditorResourcePicker::set_edited_resource); ClassDB::bind_method(D_METHOD("get_edited_resource"), &EditorResourcePicker::get_edited_resource); + ClassDB::bind_method(D_METHOD("set_toggle_mode", "enable"), &EditorResourcePicker::set_toggle_mode); + ClassDB::bind_method(D_METHOD("is_toggle_mode"), &EditorResourcePicker::is_toggle_mode); + ClassDB::bind_method(D_METHOD("set_toggle_pressed", "pressed"), &EditorResourcePicker::set_toggle_pressed); ClassDB::bind_method(D_METHOD("set_editable", "enable"), &EditorResourcePicker::set_editable); ClassDB::bind_method(D_METHOD("is_editable"), &EditorResourcePicker::is_editable); + ClassDB::add_virtual_method(get_class_static(), MethodInfo("set_create_options", PropertyInfo(Variant::OBJECT, "menu_node"))); + ClassDB::add_virtual_method(get_class_static(), MethodInfo("handle_menu_selected", PropertyInfo(Variant::INT, "id"))); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_type"), "set_base_type", "get_base_type"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "edited_resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource", 0), "set_edited_resource", "get_edited_resource"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "toggle_mode"), "set_toggle_mode", "is_toggle_mode"); ADD_SIGNAL(MethodInfo("resource_selected", PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource"))); ADD_SIGNAL(MethodInfo("resource_changed", PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource"))); @@ -689,6 +727,8 @@ Vector<String> EditorResourcePicker::get_allowed_types() const { void EditorResourcePicker::set_edited_resource(RES p_resource) { if (!p_resource.is_valid()) { + edited_resource = RES(); + _update_resource(); return; } @@ -717,6 +757,22 @@ RES EditorResourcePicker::get_edited_resource() { return edited_resource; } +void EditorResourcePicker::set_toggle_mode(bool p_enable) { + assign_button->set_toggle_mode(p_enable); +} + +bool EditorResourcePicker::is_toggle_mode() const { + return assign_button->is_toggle_mode(); +} + +void EditorResourcePicker::set_toggle_pressed(bool p_pressed) { + if (!is_toggle_mode()) { + return; + } + + assign_button->set_pressed(p_pressed); +} + void EditorResourcePicker::set_editable(bool p_editable) { editable = p_editable; assign_button->set_disabled(!editable); @@ -732,10 +788,11 @@ EditorResourcePicker::EditorResourcePicker() { assign_button->set_flat(true); assign_button->set_h_size_flags(SIZE_EXPAND_FILL); assign_button->set_clip_text(true); - assign_button->connect("pressed", callable_mp(this, &EditorResourcePicker::_resource_selected)); assign_button->set_drag_forwarding(this); - assign_button->connect("draw", callable_mp(this, &EditorResourcePicker::_button_draw)); add_child(assign_button); + assign_button->connect("pressed", callable_mp(this, &EditorResourcePicker::_resource_selected)); + assign_button->connect("draw", callable_mp(this, &EditorResourcePicker::_button_draw)); + assign_button->connect("gui_input", callable_mp(this, &EditorResourcePicker::_button_input)); preview_rect = memnew(TextureRect); preview_rect->set_expand(true); @@ -744,21 +801,64 @@ EditorResourcePicker::EditorResourcePicker() { preview_rect->set_offset(SIDE_BOTTOM, -1); preview_rect->set_offset(SIDE_RIGHT, -1); assign_button->add_child(preview_rect); - assign_button->connect("gui_input", callable_mp(this, &EditorResourcePicker::_button_input)); - edit_menu = memnew(PopupMenu); - add_child(edit_menu); edit_button = memnew(Button); edit_button->set_flat(true); edit_button->set_toggle_mode(true); - edit_menu->connect("id_pressed", callable_mp(this, &EditorResourcePicker::_edit_menu_cbk)); - edit_menu->connect("popup_hide", callable_mp((BaseButton *)edit_button, &BaseButton::set_pressed), varray(false)); edit_button->connect("pressed", callable_mp(this, &EditorResourcePicker::_update_menu)); add_child(edit_button); edit_button->connect("gui_input", callable_mp(this, &EditorResourcePicker::_button_input)); + edit_menu = memnew(PopupMenu); + add_child(edit_menu); + edit_menu->connect("id_pressed", callable_mp(this, &EditorResourcePicker::_edit_menu_cbk)); + edit_menu->connect("popup_hide", callable_mp((BaseButton *)edit_button, &BaseButton::set_pressed), varray(false)); +} + +void EditorScriptPicker::set_create_options(Object *p_menu_node) { + PopupMenu *menu_node = Object::cast_to<PopupMenu>(p_menu_node); + if (!menu_node) { + return; + } + + menu_node->add_icon_item(get_theme_icon("ScriptCreate", "EditorIcons"), TTR("New Script"), OBJ_MENU_NEW_SCRIPT); + menu_node->add_icon_item(get_theme_icon("ScriptExtend", "EditorIcons"), TTR("Extend Script"), OBJ_MENU_EXTEND_SCRIPT); + menu_node->add_separator(); +} + +bool EditorScriptPicker::handle_menu_selected(int p_which) { + switch (p_which) { + case OBJ_MENU_NEW_SCRIPT: { + if (script_owner) { + EditorNode::get_singleton()->get_scene_tree_dock()->open_script_dialog(script_owner, false); + } + return true; + } + + case OBJ_MENU_EXTEND_SCRIPT: { + if (script_owner) { + EditorNode::get_singleton()->get_scene_tree_dock()->open_script_dialog(script_owner, true); + } + return true; + } + } + + return false; +} + +void EditorScriptPicker::set_script_owner(Node *p_owner) { + script_owner = p_owner; +} + +Node *EditorScriptPicker::get_script_owner() const { + return script_owner; +} + +void EditorScriptPicker::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_script_owner", "owner_node"), &EditorScriptPicker::set_script_owner); + ClassDB::bind_method(D_METHOD("get_script_owner"), &EditorScriptPicker::get_script_owner); + + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "script_owner", PROPERTY_HINT_RESOURCE_TYPE, "Node", 0), "set_script_owner", "get_script_owner"); +} - file_dialog = memnew(EditorFileDialog); - file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); - add_child(file_dialog); - file_dialog->connect("file_selected", callable_mp(this, &EditorResourcePicker::_file_selected)); +EditorScriptPicker::EditorScriptPicker() { } |