Path: blob/master/editor/gui/editor_object_selector.cpp
9903 views
/**************************************************************************/1/* editor_object_selector.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#include "editor_object_selector.h"3132#include "editor/editor_data.h"33#include "editor/editor_node.h"34#include "editor/editor_string_names.h"35#include "editor/themes/editor_scale.h"36#include "scene/gui/margin_container.h"3738Size2 EditorObjectSelector::get_minimum_size() const {39Ref<Font> font = get_theme_font(SceneStringName(font));40int font_size = get_theme_font_size(SceneStringName(font_size));41return Button::get_minimum_size() + Size2(0, font->get_height(font_size));42}4344void EditorObjectSelector::_add_children_to_popup(Object *p_obj, int p_depth) {45if (p_depth > 8) {46return;47}4849List<PropertyInfo> pinfo;50p_obj->get_property_list(&pinfo);51for (const PropertyInfo &E : pinfo) {52if (!(E.usage & PROPERTY_USAGE_EDITOR)) {53continue;54}55if (E.hint != PROPERTY_HINT_RESOURCE_TYPE) {56continue;57}5859Variant value = p_obj->get(E.name);60if (value.get_type() != Variant::OBJECT) {61continue;62}63Object *obj = value;64if (!obj) {65continue;66}6768Ref<Texture2D> obj_icon = EditorNode::get_singleton()->get_object_icon(obj);6970String proper_name = "";71Vector<String> name_parts = E.name.split("/");7273for (int i = 0; i < name_parts.size(); i++) {74if (i > 0) {75proper_name += " > ";76}77proper_name += name_parts[i].capitalize();78}7980int index = sub_objects_menu->get_item_count();81sub_objects_menu->add_icon_item(obj_icon, proper_name, objects.size());82sub_objects_menu->set_item_indent(index, p_depth);83objects.push_back(obj->get_instance_id());8485_add_children_to_popup(obj, p_depth + 1);86}87}8889void EditorObjectSelector::_show_popup() {90if (sub_objects_menu->is_visible()) {91sub_objects_menu->hide();92return;93}9495sub_objects_menu->clear();9697Size2 size = get_size();98Point2 gp = get_screen_position();99gp.y += size.y;100101sub_objects_menu->popup(Rect2(gp, Size2(size.width, 0)));102}103104void EditorObjectSelector::_about_to_show() {105Object *obj = ObjectDB::get_instance(history->get_path_object(history->get_path_size() - 1));106if (!obj) {107return;108}109110objects.clear();111112_add_children_to_popup(obj);113if (sub_objects_menu->get_item_count() == 0) {114sub_objects_menu->add_item(TTR("No sub-resources found."));115sub_objects_menu->set_item_disabled(0, true);116}117}118119void EditorObjectSelector::update_path() {120for (int i = 0; i < history->get_path_size(); i++) {121Object *obj = ObjectDB::get_instance(history->get_path_object(i));122if (!obj) {123continue;124}125126Ref<Texture2D> obj_icon = EditorNode::get_singleton()->get_object_icon(obj);127if (obj_icon.is_valid()) {128current_object_icon->set_texture(obj_icon);129}130131if (i == history->get_path_size() - 1) {132String name;133if (obj->has_method("_get_editor_name")) {134name = obj->call("_get_editor_name");135} else if (Object::cast_to<Resource>(obj)) {136Resource *r = Object::cast_to<Resource>(obj);137if (r->get_path().is_resource_file()) {138name = r->get_path().get_file();139} else {140name = r->get_name();141}142143if (name.is_empty()) {144name = r->get_class();145}146} else if (obj->is_class("EditorDebuggerRemoteObjects")) {147name = obj->call("get_title");148} else if (Object::cast_to<Node>(obj)) {149name = Object::cast_to<Node>(obj)->get_name();150} else if (Object::cast_to<Resource>(obj) && !Object::cast_to<Resource>(obj)->get_name().is_empty()) {151name = Object::cast_to<Resource>(obj)->get_name();152} else {153name = obj->get_class();154}155156current_object_label->set_text(name);157set_tooltip_text(obj->get_class());158}159}160}161162void EditorObjectSelector::clear_path() {163set_disabled(true);164set_tooltip_text("");165166current_object_label->set_text("");167current_object_icon->set_texture(nullptr);168sub_objects_icon->hide();169}170171void EditorObjectSelector::enable_path() {172set_disabled(false);173sub_objects_icon->show();174}175176void EditorObjectSelector::_id_pressed(int p_idx) {177ERR_FAIL_INDEX(p_idx, objects.size());178179Object *obj = ObjectDB::get_instance(objects[p_idx]);180if (!obj) {181return;182}183184EditorNode::get_singleton()->push_item(obj);185}186187void EditorObjectSelector::_notification(int p_what) {188switch (p_what) {189case NOTIFICATION_THEME_CHANGED: {190update_path();191192int icon_size = get_theme_constant(SNAME("class_icon_size"), EditorStringName(Editor));193194current_object_icon->set_custom_minimum_size(Size2(icon_size, icon_size));195current_object_label->add_theme_font_override(SceneStringName(font), get_theme_font(SNAME("main"), EditorStringName(EditorFonts)));196sub_objects_icon->set_texture(get_theme_icon(SNAME("arrow"), SNAME("OptionButton")));197sub_objects_menu->add_theme_constant_override("icon_max_width", icon_size);198} break;199200case NOTIFICATION_READY: {201connect(SceneStringName(pressed), callable_mp(this, &EditorObjectSelector::_show_popup));202} break;203}204}205206EditorObjectSelector::EditorObjectSelector(EditorSelectionHistory *p_history) {207history = p_history;208209MarginContainer *main_mc = memnew(MarginContainer);210main_mc->set_anchors_and_offsets_preset(PRESET_FULL_RECT);211main_mc->add_theme_constant_override("margin_left", 4 * EDSCALE);212main_mc->add_theme_constant_override("margin_right", 6 * EDSCALE);213add_child(main_mc);214215HBoxContainer *main_hb = memnew(HBoxContainer);216main_mc->add_child(main_hb);217218current_object_icon = memnew(TextureRect);219current_object_icon->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED);220current_object_icon->set_expand_mode(TextureRect::EXPAND_IGNORE_SIZE);221main_hb->add_child(current_object_icon);222223current_object_label = memnew(Label);224current_object_label->set_focus_mode(FOCUS_ACCESSIBILITY);225current_object_label->set_text_overrun_behavior(TextServer::OVERRUN_TRIM_ELLIPSIS);226current_object_label->set_h_size_flags(SIZE_EXPAND_FILL);227current_object_label->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);228current_object_label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);229main_hb->add_child(current_object_label);230231sub_objects_icon = memnew(TextureRect);232sub_objects_icon->hide();233sub_objects_icon->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED);234main_hb->add_child(sub_objects_icon);235236sub_objects_menu = memnew(PopupMenu);237sub_objects_menu->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);238add_child(sub_objects_menu);239sub_objects_menu->connect("about_to_popup", callable_mp(this, &EditorObjectSelector::_about_to_show));240sub_objects_menu->connect(SceneStringName(id_pressed), callable_mp(this, &EditorObjectSelector::_id_pressed));241242set_tooltip_text(TTR("Open a list of sub-resources."));243}244245246