diff options
Diffstat (limited to 'editor')
-rw-r--r-- | editor/code_editor.cpp | 2 | ||||
-rw-r--r-- | editor/editor_inspector.cpp | 273 | ||||
-rw-r--r-- | editor/editor_inspector.h | 12 | ||||
-rw-r--r-- | editor/editor_node.cpp | 11 | ||||
-rw-r--r-- | editor/editor_property_name_processor.cpp | 1 | ||||
-rw-r--r-- | editor/editor_themes.cpp | 7 | ||||
-rw-r--r-- | editor/plugins/canvas_item_editor_plugin.cpp | 4 | ||||
-rw-r--r-- | editor/plugins/node_3d_editor_plugin.cpp | 4 | ||||
-rw-r--r-- | editor/plugins/visual_shader_editor_plugin.cpp | 107 | ||||
-rw-r--r-- | editor/plugins/visual_shader_editor_plugin.h | 42 | ||||
-rw-r--r-- | editor/project_converter_3_to_4.cpp | 8 | ||||
-rw-r--r-- | editor/property_editor.cpp | 1866 | ||||
-rw-r--r-- | editor/property_editor.h | 168 | ||||
-rw-r--r-- | editor/scene_tree_editor.cpp | 4 |
14 files changed, 358 insertions, 2151 deletions
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 99ca82b311..b0eb384efc 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -1045,6 +1045,8 @@ void CodeTextEditor::update_editor_settings() { guideline_cols.append(EditorSettings::get_singleton()->get("text_editor/appearance/guidelines/line_length_guideline_soft_column")); } text_editor->set_line_length_guidelines(guideline_cols); + } else { + text_editor->set_line_length_guidelines(TypedArray<int>()); } } diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index e06e3cbc5f..9f047c775e 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -1677,7 +1677,7 @@ void EditorInspectorArray::_panel_gui_input(Ref<InputEvent> p_event, int p_index Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid()) { - if (mb->get_button_index() == MouseButton::RIGHT) { + if (movable && mb->get_button_index() == MouseButton::RIGHT) { popup_array_index_pressed = begin_array_index + p_index; rmb_popup->set_item_disabled(OPTION_MOVE_UP, popup_array_index_pressed == 0); rmb_popup->set_item_disabled(OPTION_MOVE_DOWN, popup_array_index_pressed == count - 1); @@ -1712,43 +1712,112 @@ void EditorInspectorArray::_move_element(int p_element_index, int p_to_pos) { } } else if (mode == MODE_USE_COUNT_PROPERTY) { ERR_FAIL_COND(p_to_pos < -1 || p_to_pos > count); - List<PropertyInfo> object_property_list; - object->get_property_list(&object_property_list); - Array properties_as_array = _extract_properties_as_array(object_property_list); - properties_as_array.resize(count); + if (!swap_method.is_empty()) { + ERR_FAIL_COND(!object->has_method(swap_method)); - // For undoing things - undo_redo->add_undo_property(object, count_property, properties_as_array.size()); - for (int i = 0; i < (int)properties_as_array.size(); i++) { - Dictionary d = Dictionary(properties_as_array[i]); - Array keys = d.keys(); - for (int j = 0; j < keys.size(); j++) { - String key = keys[j]; - undo_redo->add_undo_property(object, vformat(key, i), d[key]); - } - } + // Swap method was provided, use it. + if (p_element_index < 0) { + // Add an element at position + undo_redo->add_do_property(object, count_property, count + 1); + if (p_to_pos >= 0) { + for (int i = count; i > p_to_pos; i--) { + undo_redo->add_do_method(object, swap_method, i, i - 1); + } + for (int i = p_to_pos; i < count; i++) { + undo_redo->add_undo_method(object, swap_method, i, i + 1); + } + } + undo_redo->add_undo_property(object, count_property, count); + + } else if (p_to_pos < 0) { + if (count > 0) { + // Remove element at position + undo_redo->add_undo_property(object, count_property, count); + + List<PropertyInfo> object_property_list; + object->get_property_list(&object_property_list); + + for (int i = p_element_index; i < count - 1; i++) { + undo_redo->add_do_method(object, swap_method, i, i + 1); + } + + for (int i = count; i > p_element_index; i--) { + undo_redo->add_undo_method(object, swap_method, i, i - 1); + } + + String erase_prefix = String(array_element_prefix) + itos(p_element_index); + + for (const PropertyInfo &E : object_property_list) { + if (E.name.begins_with(erase_prefix)) { + undo_redo->add_undo_property(object, E.name, object->get(E.name)); + } + } - if (p_element_index < 0) { - // Add an element. - properties_as_array.insert(p_to_pos < 0 ? properties_as_array.size() : p_to_pos, Dictionary()); - } else if (p_to_pos < 0) { - // Delete the element. - properties_as_array.remove_at(p_element_index); + undo_redo->add_do_property(object, count_property, count - 1); + } + } else { + if (p_to_pos > p_element_index) { + p_to_pos--; + } + + if (p_to_pos < p_element_index) { + for (int i = p_element_index; i > p_to_pos; i--) { + undo_redo->add_do_method(object, swap_method, i, i - 1); + } + for (int i = p_to_pos; i < p_element_index; i++) { + undo_redo->add_undo_method(object, swap_method, i, i + 1); + } + } else if (p_to_pos > p_element_index) { + for (int i = p_element_index; i < p_to_pos; i++) { + undo_redo->add_do_method(object, swap_method, i, i + 1); + } + + for (int i = p_to_pos; i > p_element_index; i--) { + undo_redo->add_undo_method(object, swap_method, i, i - 1); + } + } + } } else { - // Move the element. - properties_as_array.insert(p_to_pos, properties_as_array[p_element_index].duplicate()); - properties_as_array.remove_at(p_to_pos < p_element_index ? p_element_index + 1 : p_element_index); - } + // Use standard properties. + List<PropertyInfo> object_property_list; + object->get_property_list(&object_property_list); - // Change the array size then set the properties. - undo_redo->add_do_property(object, count_property, properties_as_array.size()); - for (int i = 0; i < (int)properties_as_array.size(); i++) { - Dictionary d = properties_as_array[i]; - Array keys = d.keys(); - for (int j = 0; j < keys.size(); j++) { - String key = keys[j]; - undo_redo->add_do_property(object, vformat(key, i), d[key]); + Array properties_as_array = _extract_properties_as_array(object_property_list); + properties_as_array.resize(count); + + // For undoing things + undo_redo->add_undo_property(object, count_property, properties_as_array.size()); + for (int i = 0; i < (int)properties_as_array.size(); i++) { + Dictionary d = Dictionary(properties_as_array[i]); + Array keys = d.keys(); + for (int j = 0; j < keys.size(); j++) { + String key = keys[j]; + undo_redo->add_undo_property(object, vformat(key, i), d[key]); + } + } + + if (p_element_index < 0) { + // Add an element. + properties_as_array.insert(p_to_pos < 0 ? properties_as_array.size() : p_to_pos, Dictionary()); + } else if (p_to_pos < 0) { + // Delete the element. + properties_as_array.remove_at(p_element_index); + } else { + // Move the element. + properties_as_array.insert(p_to_pos, properties_as_array[p_element_index].duplicate()); + properties_as_array.remove_at(p_to_pos < p_element_index ? p_element_index + 1 : p_element_index); + } + + // Change the array size then set the properties. + undo_redo->add_do_property(object, count_property, properties_as_array.size()); + for (int i = 0; i < (int)properties_as_array.size(); i++) { + Dictionary d = properties_as_array[i]; + Array keys = d.keys(); + for (int j = 0; j < keys.size(); j++) { + String key = keys[j]; + undo_redo->add_do_property(object, vformat(key, i), d[key]); + } } } } @@ -1988,6 +2057,20 @@ void EditorInspectorArray::_setup() { page = CLAMP(page, 0, max_page); } + Ref<Font> numbers_font; + int numbers_min_w = 0; + + if (numbered) { + numbers_font = get_theme_font(SNAME("bold"), SNAME("EditorFonts")); + int digits_found = count; + String test; + while (digits_found) { + test += "8"; + digits_found /= 10; + } + numbers_min_w = numbers_font->get_string_size(test).width; + } + for (int i = 0; i < (int)array_elements.size(); i++) { ArrayElement &ae = array_elements[i]; @@ -2022,19 +2105,38 @@ void EditorInspectorArray::_setup() { ae.margin->add_child(ae.hbox); // Move button. - ae.move_texture_rect = memnew(TextureRect); - ae.move_texture_rect->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); - ae.move_texture_rect->set_default_cursor_shape(Control::CURSOR_MOVE); - if (is_inside_tree()) { - ae.move_texture_rect->set_texture(get_theme_icon(SNAME("TripleBar"), SNAME("EditorIcons"))); + if (movable) { + ae.move_texture_rect = memnew(TextureRect); + ae.move_texture_rect->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); + ae.move_texture_rect->set_default_cursor_shape(Control::CURSOR_MOVE); + + if (is_inside_tree()) { + ae.move_texture_rect->set_texture(get_theme_icon(SNAME("TripleBar"), SNAME("EditorIcons"))); + } + ae.hbox->add_child(ae.move_texture_rect); + } + + if (numbered) { + ae.number = memnew(Label); + ae.number->add_theme_font_override("font", numbers_font); + ae.number->set_custom_minimum_size(Size2(numbers_min_w, 0)); + ae.number->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT); + ae.number->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER); + ae.number->set_text(itos(begin_array_index + i)); + ae.hbox->add_child(ae.number); } - ae.hbox->add_child(ae.move_texture_rect); // Right vbox. ae.vbox = memnew(VBoxContainer); ae.vbox->set_h_size_flags(SIZE_EXPAND_FILL); ae.vbox->set_v_size_flags(SIZE_EXPAND_FILL); ae.hbox->add_child(ae.vbox); + + ae.erase = memnew(Button); + ae.erase->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); + ae.erase->set_v_size_flags(SIZE_SHRINK_CENTER); + ae.erase->connect("pressed", callable_mp(this, &EditorInspectorArray::_remove_item).bind(begin_array_index + i)); + ae.hbox->add_child(ae.erase); } // Hide/show the add button. @@ -2049,7 +2151,14 @@ void EditorInspectorArray::_setup() { } } +void EditorInspectorArray::_remove_item(int p_index) { + _move_element(p_index, -1); +} + Variant EditorInspectorArray::get_drag_data_fw(const Point2 &p_point, Control *p_from) { + if (!movable) { + return Variant(); + } int index = p_from->get_meta("index"); Dictionary dict; dict["type"] = "property_array_element"; @@ -2071,6 +2180,9 @@ void EditorInspectorArray::drop_data_fw(const Point2 &p_point, const Variant &p_ } bool EditorInspectorArray::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const { + if (!movable) { + return false; + } // First, update drawing. control_dropping->update(); @@ -2100,13 +2212,19 @@ void EditorInspectorArray::_notification(int p_what) { for (int i = 0; i < (int)array_elements.size(); i++) { ArrayElement &ae = array_elements[i]; - ae.move_texture_rect->set_texture(get_theme_icon(SNAME("TripleBar"), SNAME("EditorIcons"))); + if (ae.move_texture_rect) { + ae.move_texture_rect->set_texture(get_theme_icon(SNAME("TripleBar"), SNAME("EditorIcons"))); + } Size2 min_size = get_theme_stylebox(SNAME("Focus"), SNAME("EditorStyles"))->get_minimum_size(); ae.margin->add_theme_constant_override("margin_left", min_size.x / 2); ae.margin->add_theme_constant_override("margin_top", min_size.y / 2); ae.margin->add_theme_constant_override("margin_right", min_size.x / 2); ae.margin->add_theme_constant_override("margin_bottom", min_size.y / 2); + + if (ae.erase) { + ae.erase->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); + } } add_button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); @@ -2142,23 +2260,31 @@ void EditorInspectorArray::set_undo_redo(UndoRedo *p_undo_redo) { undo_redo = p_undo_redo; } -void EditorInspectorArray::setup_with_move_element_function(Object *p_object, String p_label, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable) { +void EditorInspectorArray::setup_with_move_element_function(Object *p_object, String p_label, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable, bool p_movable, bool p_numbered, int p_page_length, const String &p_add_item_text) { count_property = ""; mode = MODE_USE_MOVE_ARRAY_ELEMENT_FUNCTION; array_element_prefix = p_array_element_prefix; page = p_page; + movable = p_movable; + page_length = p_page_length; + numbered = p_numbered; EditorInspectorSection::setup(String(p_array_element_prefix) + "_array", p_label, p_object, p_bg_color, p_foldable, 0); _setup(); } -void EditorInspectorArray::setup_with_count_property(Object *p_object, String p_label, const StringName &p_count_property, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable) { +void EditorInspectorArray::setup_with_count_property(Object *p_object, String p_label, const StringName &p_count_property, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable, bool p_movable, bool p_numbered, int p_page_length, const String &p_add_item_text, const String &p_swap_method) { count_property = p_count_property; mode = MODE_USE_COUNT_PROPERTY; array_element_prefix = p_array_element_prefix; page = p_page; + movable = p_movable; + page_length = p_page_length; + numbered = p_numbered; + swap_method = p_swap_method; + add_button->set_text(p_add_item_text); EditorInspectorSection::setup(String(count_property) + "_array", p_label, p_object, p_bg_color, p_foldable, 0); _setup(); @@ -2887,9 +3013,35 @@ void EditorInspector::update_tree() { StringName array_element_prefix; Color c = sscolor; c.a /= level; + + Vector<String> class_name_components = String(p.class_name).split(","); + + array_element_prefix = class_name_components[1]; + int page_size = 5; + bool movable = true; + bool numbered = false; + bool foldable = use_folding; + String add_button_text; + String swap_method; + for (int i = (p.type == Variant::NIL ? 1 : 2); i < class_name_components.size(); i++) { + if (class_name_components[i].begins_with("page_size") && class_name_components[i].get_slice_count("=") == 2) { + page_size = class_name_components[i].get_slice("=", 1).to_int(); + } else if (class_name_components[i].begins_with("add_button_text") && class_name_components[i].get_slice_count("=") == 2) { + add_button_text = class_name_components[i].get_slice("=", 1).strip_edges(); + } else if (class_name_components[i] == "static") { + movable = false; + } else if (class_name_components[i] == "numbered") { + numbered = true; + } else if (class_name_components[i] == "unfoldable") { + foldable = false; + } else if (class_name_components[i].begins_with("swap_method") && class_name_components[i].get_slice_count("=") == 2) { + swap_method = class_name_components[i].get_slice("=", 1).strip_edges(); + } + } + if (p.type == Variant::NIL) { // Setup the array to use a method to create/move/delete elements. - array_element_prefix = p.class_name; + array_element_prefix = class_name_components[0]; editor_inspector_array = memnew(EditorInspectorArray); String array_label = path.contains("/") ? path.substr(path.rfind("/") + 1) : path; @@ -2900,13 +3052,14 @@ void EditorInspector::update_tree() { editor_inspector_array->set_undo_redo(undo_redo); } else if (p.type == Variant::INT) { // Setup the array to use the count property and built-in functions to create/move/delete elements. - Vector<String> class_name_components = String(p.class_name).split(","); - if (class_name_components.size() == 2) { - array_element_prefix = class_name_components[1]; + + if (class_name_components.size() > 2) { editor_inspector_array = memnew(EditorInspectorArray); int page = per_array_page.has(array_element_prefix) ? per_array_page[array_element_prefix] : 0; - editor_inspector_array->setup_with_count_property(object, class_name_components[0], p.name, array_element_prefix, page, c, use_folding); + + editor_inspector_array->setup_with_count_property(object, class_name_components[0], p.name, array_element_prefix, page, c, foldable, movable, numbered, page_size, add_button_text, swap_method); editor_inspector_array->connect("page_change_request", callable_mp(this, &EditorInspector::_page_change_request).bind(array_element_prefix)); + editor_inspector_array->set_undo_redo(undo_redo); } } @@ -2915,6 +3068,7 @@ void EditorInspector::update_tree() { current_vbox->add_child(editor_inspector_array); editor_inspector_array_per_prefix[array_element_prefix] = editor_inspector_array; } + continue; } @@ -3396,14 +3550,23 @@ void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bo undo_redo->add_undo_property(object, p_name, value); } - PropertyInfo prop_info; - if (ClassDB::get_property_info(object->get_class_name(), p_name, &prop_info)) { - for (const String &linked_prop : prop_info.linked_properties) { - valid = false; - value = object->get(linked_prop, &valid); - if (valid) { - undo_redo->add_undo_property(object, linked_prop, value); - } + List<StringName> linked_properties; + ClassDB::get_linked_properties_info(object->get_class_name(), p_name, &linked_properties); + + for (const StringName &linked_prop : linked_properties) { + valid = false; + Variant undo_value = object->get(linked_prop, &valid); + if (valid) { + undo_redo->add_undo_property(object, linked_prop, undo_value); + } + } + + PackedStringArray linked_properties_dynamic = object->call("_get_linked_undo_properties", p_name, p_value); + for (int i = 0; i < linked_properties_dynamic.size(); i++) { + valid = false; + Variant undo_value = object->get(linked_properties_dynamic[i], &valid); + if (valid) { + undo_redo->add_undo_property(object, linked_properties_dynamic[i], undo_value); } } diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index 54533de960..9b5e295854 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -321,6 +321,7 @@ class EditorInspectorArray : public EditorInspectorSection { } mode; StringName count_property; StringName array_element_prefix; + String swap_method; int count = 0; @@ -342,6 +343,9 @@ class EditorInspectorArray : public EditorInspectorSection { int begin_array_index = 0; int end_array_index = 0; + bool movable = true; + bool numbered = false; + enum MenuOptions { OPTION_MOVE_UP = 0, OPTION_MOVE_DOWN, @@ -359,7 +363,9 @@ class EditorInspectorArray : public EditorInspectorSection { MarginContainer *margin = nullptr; HBoxContainer *hbox = nullptr; TextureRect *move_texture_rect = nullptr; + Label *number = nullptr; VBoxContainer *vbox = nullptr; + Button *erase = nullptr; }; LocalVector<ArrayElement> array_elements; @@ -395,6 +401,8 @@ class EditorInspectorArray : public EditorInspectorSection { void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; + void _remove_item(int p_index); + protected: void _notification(int p_what); static void _bind_methods(); @@ -402,8 +410,8 @@ protected: public: void set_undo_redo(UndoRedo *p_undo_redo); - void setup_with_move_element_function(Object *p_object, String p_label, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable); - void setup_with_count_property(Object *p_object, String p_label, const StringName &p_count_property, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable); + void setup_with_move_element_function(Object *p_object, String p_label, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable, bool p_movable = true, bool p_numbered = false, int p_page_length = 5, const String &p_add_item_text = ""); + void setup_with_count_property(Object *p_object, String p_label, const StringName &p_count_property, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable, bool p_movable = true, bool p_numbered = false, int p_page_length = 5, const String &p_add_item_text = "", const String &p_swap_method = ""); VBoxContainer *get_vbox(int p_index); EditorInspectorArray(); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index e9aceb684f..5e00304122 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -2202,9 +2202,10 @@ void EditorNode::_edit_current(bool p_skip_foreign) { Object *prev_inspected_object = InspectorDock::get_inspector_singleton()->get_edited_object(); bool disable_folding = bool(EDITOR_GET("interface/inspector/disable_folding")); - bool stay_in_script_editor_on_node_selected = bool(EDITOR_GET("text_editor/behavior/navigation/stay_in_script_editor_on_node_selected")); bool is_resource = current_obj->is_class("Resource"); bool is_node = current_obj->is_class("Node"); + bool stay_in_script_editor_on_node_selected = bool(EDITOR_GET("text_editor/behavior/navigation/stay_in_script_editor_on_node_selected")); + bool skip_main_plugin = false; String editable_warning; // None by default. @@ -2241,8 +2242,8 @@ void EditorNode::_edit_current(bool p_skip_foreign) { NodeDock::get_singleton()->set_node(current_node); SceneTreeDock::get_singleton()->set_selected(current_node); InspectorDock::get_singleton()->update(current_node); - if (!inspector_only) { - inspector_only = stay_in_script_editor_on_node_selected && ScriptEditor::get_singleton()->is_visible_in_tree(); + if (!inspector_only && !skip_main_plugin) { + skip_main_plugin = stay_in_script_editor_on_node_selected && ScriptEditor::get_singleton()->is_visible_in_tree(); } } else { NodeDock::get_singleton()->set_node(nullptr); @@ -2318,7 +2319,7 @@ void EditorNode::_edit_current(bool p_skip_foreign) { } } - if (main_plugin) { + if (main_plugin && !skip_main_plugin) { // Special case if use of external editor is true. Resource *current_res = Object::cast_to<Resource>(current_obj); if (main_plugin->get_name() == "Script" && !current_obj->is_class("VisualScript") && current_res && !current_res->is_built_in() && (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor")) || overrides_external_editor(current_obj))) { @@ -6156,8 +6157,6 @@ EditorNode::EditorNode() { register_exporters(); - ClassDB::set_class_enabled("RootMotionView", true); - EDITOR_DEF("interface/editor/save_on_focus_loss", false); EDITOR_DEF("interface/editor/show_update_spinner", false); EDITOR_DEF("interface/editor/update_continuously", false); diff --git a/editor/editor_property_name_processor.cpp b/editor/editor_property_name_processor.cpp index 09d2992e07..6c713de94a 100644 --- a/editor/editor_property_name_processor.cpp +++ b/editor/editor_property_name_processor.cpp @@ -114,6 +114,7 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() { capitalize_string_remaps["bidi"] = "BiDi"; capitalize_string_remaps["bp"] = "BP"; capitalize_string_remaps["bpc"] = "BPC"; + capitalize_string_remaps["bpm"] = "BPM"; capitalize_string_remaps["bptc"] = "BPTC"; capitalize_string_remaps["bvh"] = "BVH"; capitalize_string_remaps["ca"] = "CA"; diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index da7105c94c..fb92a9e898 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -641,6 +641,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // Add a highlight line at the top of the selected tab. style_tab_selected->set_border_width_all(0); + style_tab_selected->set_default_margin(SIDE_LEFT, widget_default_margin.x - border_width); style_tab_selected->set_border_width(SIDE_TOP, Math::round(2 * EDSCALE)); // Make the highlight line prominent, but not too prominent as to not be distracting. Color tab_highlight = dark_color_2.lerp(accent_color, 0.75); @@ -653,6 +654,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // We can't prevent them with both rounded corners and non-zero border width, though style_tab_selected->set_expand_margin_size(SIDE_BOTTOM, corner_width > 0 ? corner_width : border_width); + // When using a border width greater than 0, visually line up the left of the selected tab with the underlying panel. + style_tab_selected->set_expand_margin_size(SIDE_LEFT, -border_width); + style_tab_selected->set_default_margin(SIDE_LEFT, widget_default_margin.x + 2 * EDSCALE); style_tab_selected->set_default_margin(SIDE_RIGHT, widget_default_margin.x + 2 * EDSCALE); style_tab_selected->set_default_margin(SIDE_BOTTOM, widget_default_margin.y); @@ -1660,6 +1664,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_dictionary_add_item->set_expand_margin_size(SIDE_RIGHT, 4 * EDSCALE); theme->set_stylebox("DictionaryAddItem", "EditorStyles", style_dictionary_add_item); + Ref<StyleBoxEmpty> vshader_label_style = make_empty_stylebox(2, 1, 2, 1); + theme->set_stylebox("label_style", "VShaderEditor", vshader_label_style); + // adaptive script theme constants // for comments and elements with lower relevance const Color dim_color = Color(font_color.r, font_color.g, font_color.b, 0.5); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 8de1ba326d..6f8d33532f 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -5216,7 +5216,7 @@ CanvasItemEditor::CanvasItemEditor() { group_button->set_flat(true); main_menu_hbox->add_child(group_button); group_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback).bind(GROUP_SELECTED)); - group_button->set_tooltip(TTR("Makes sure the object's children are not selectable.")); + group_button->set_tooltip(TTR("Make selected node's children not selectable.")); // Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused. group_button->set_shortcut(ED_SHORTCUT("editor/group_selected_nodes", TTR("Group Selected Node(s)"), KeyModifierMask::CMD | Key::G)); @@ -5224,7 +5224,7 @@ CanvasItemEditor::CanvasItemEditor() { ungroup_button->set_flat(true); main_menu_hbox->add_child(ungroup_button); ungroup_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback).bind(UNGROUP_SELECTED)); - ungroup_button->set_tooltip(TTR("Restores the object's children's ability to be selected.")); + ungroup_button->set_tooltip(TTR("Make selected node's children selectable.")); // Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused. ungroup_button->set_shortcut(ED_SHORTCUT("editor/ungroup_selected_nodes", TTR("Ungroup Selected Node(s)"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::G)); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 7628a95310..ba505a9abb 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -7796,7 +7796,7 @@ Node3DEditor::Node3DEditor() { main_menu_hbox->add_child(tool_button[TOOL_GROUP_SELECTED]); tool_button[TOOL_GROUP_SELECTED]->set_flat(true); tool_button[TOOL_GROUP_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed).bind(MENU_GROUP_SELECTED)); - tool_button[TOOL_GROUP_SELECTED]->set_tooltip(TTR("Makes sure the object's children are not selectable.")); + tool_button[TOOL_GROUP_SELECTED]->set_tooltip(TTR("Make selected node's children not selectable.")); // Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused. tool_button[TOOL_GROUP_SELECTED]->set_shortcut(ED_SHORTCUT("editor/group_selected_nodes", TTR("Group Selected Node(s)"), KeyModifierMask::CMD | Key::G)); @@ -7804,7 +7804,7 @@ Node3DEditor::Node3DEditor() { main_menu_hbox->add_child(tool_button[TOOL_UNGROUP_SELECTED]); tool_button[TOOL_UNGROUP_SELECTED]->set_flat(true); tool_button[TOOL_UNGROUP_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed).bind(MENU_UNGROUP_SELECTED)); - tool_button[TOOL_UNGROUP_SELECTED]->set_tooltip(TTR("Restores the object's children's ability to be selected.")); + tool_button[TOOL_UNGROUP_SELECTED]->set_tooltip(TTR("Make selected node's children selectable.")); // Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused. tool_button[TOOL_UNGROUP_SELECTED]->set_shortcut(ED_SHORTCUT("editor/ungroup_selected_nodes", TTR("Ungroup Selected Node(s)"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::G)); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 626071aa72..65d684c2a1 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -40,10 +40,17 @@ #include "editor/editor_node.h" #include "editor/editor_properties.h" #include "editor/editor_scale.h" +#include "editor/plugins/curve_editor_plugin.h" #include "editor/plugins/shader_editor_plugin.h" #include "scene/animation/animation_player.h" +#include "scene/gui/button.h" +#include "scene/gui/code_edit.h" +#include "scene/gui/graph_edit.h" #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" +#include "scene/gui/popup.h" +#include "scene/gui/rich_text_label.h" +#include "scene/gui/tree.h" #include "scene/gui/view_panner.h" #include "scene/main/window.h" #include "scene/resources/visual_shader_nodes.h" @@ -91,17 +98,6 @@ void VisualShaderNodePlugin::_bind_methods() { /////////////////// -static Ref<StyleBoxEmpty> make_empty_stylebox(float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1) { - Ref<StyleBoxEmpty> style(memnew(StyleBoxEmpty)); - style->set_default_margin(SIDE_LEFT, p_margin_left * EDSCALE); - style->set_default_margin(SIDE_RIGHT, p_margin_right * EDSCALE); - style->set_default_margin(SIDE_BOTTOM, p_margin_bottom * EDSCALE); - style->set_default_margin(SIDE_TOP, p_margin_top * EDSCALE); - return style; -} - -/////////////////// - VisualShaderGraphPlugin::VisualShaderGraphPlugin() { } @@ -364,8 +360,6 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { Control *offset; - static Ref<StyleBoxEmpty> label_style = make_empty_stylebox(2, 1, 2, 1); - static const Color type_color[] = { Color(0.38, 0.85, 0.96), // scalar (float) Color(0.49, 0.78, 0.94), // scalar (int) @@ -765,14 +759,14 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { } else { Label *label = memnew(Label); label->set_text(name_left); - label->add_theme_style_override("normal", label_style); //more compact + label->add_theme_style_override("normal", editor->get_theme_stylebox(SNAME("label_style"), SNAME("VShaderEditor"))); //more compact hb->add_child(label); if (vsnode->is_input_port_default(i, mode) && !port_left_used) { Label *hint_label = memnew(Label); hint_label->set_text(TTR("[default]")); hint_label->add_theme_color_override("font_color", editor->get_theme_color(SNAME("font_readonly_color"), SNAME("TextEdit"))); - hint_label->add_theme_style_override("normal", label_style); + hint_label->add_theme_style_override("normal", editor->get_theme_stylebox(SNAME("label_style"), SNAME("VShaderEditor"))); hb->add_child(hint_label); } } @@ -813,7 +807,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { } else { Label *label = memnew(Label); label->set_text(name_right); - label->add_theme_style_override("normal", label_style); //more compact + label->add_theme_style_override("normal", editor->get_theme_stylebox(SNAME("label_style"), SNAME("VShaderEditor"))); //more compact hb->add_child(label); } } @@ -1080,6 +1074,23 @@ VisualShaderGraphPlugin::~VisualShaderGraphPlugin() { ///////////////// +void VisualShaderEditedProperty::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_edited_property", "value"), &VisualShaderEditedProperty::set_edited_property); + ClassDB::bind_method(D_METHOD("get_edited_property"), &VisualShaderEditedProperty::get_edited_property); + + ADD_PROPERTY(PropertyInfo(Variant::NIL, "edited_property", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "set_edited_property", "get_edited_property"); +} + +void VisualShaderEditedProperty::set_edited_property(Variant p_variant) { + edited_property = p_variant; +} + +Variant VisualShaderEditedProperty::get_edited_property() const { + return edited_property; +} + +///////////////// + Vector2 VisualShaderEditor::selection_center; List<VisualShaderEditor::CopyItem> VisualShaderEditor::copy_items_buffer; List<VisualShader::Connection> VisualShaderEditor::copy_connections_buffer; @@ -2287,10 +2298,8 @@ void VisualShaderEditor::_port_name_focus_out(Object *line_edit, int p_node_id, } } -void VisualShaderEditor::_port_edited() { +void VisualShaderEditor::_port_edited(const StringName &p_property, const Variant &p_value, const String &p_field, bool p_changing) { VisualShader::Type type = get_current_shader_type(); - - Variant value = property_editor->get_variant(); Ref<VisualShaderNode> vsn = visual_shader->get_node(type, editing_node); ERR_FAIL_COND(!vsn.is_valid()); @@ -2298,30 +2307,51 @@ void VisualShaderEditor::_port_edited() { Ref<VisualShaderNodeCustom> custom = Object::cast_to<VisualShaderNodeCustom>(vsn.ptr()); if (custom.is_valid()) { - undo_redo->add_do_method(custom.ptr(), "_set_input_port_default_value", editing_port, value); + undo_redo->add_do_method(custom.ptr(), "_set_input_port_default_value", editing_port, p_value); undo_redo->add_undo_method(custom.ptr(), "_set_input_port_default_value", editing_port, vsn->get_input_port_default_value(editing_port)); } else { - undo_redo->add_do_method(vsn.ptr(), "set_input_port_default_value", editing_port, value); + undo_redo->add_do_method(vsn.ptr(), "set_input_port_default_value", editing_port, p_value); undo_redo->add_undo_method(vsn.ptr(), "set_input_port_default_value", editing_port, vsn->get_input_port_default_value(editing_port)); } - undo_redo->add_do_method(graph_plugin.ptr(), "set_input_port_default_value", type, editing_node, editing_port, value); + undo_redo->add_do_method(graph_plugin.ptr(), "set_input_port_default_value", type, editing_node, editing_port, p_value); undo_redo->add_undo_method(graph_plugin.ptr(), "set_input_port_default_value", type, editing_node, editing_port, vsn->get_input_port_default_value(editing_port)); undo_redo->commit_action(); - - property_editor->hide(); } void VisualShaderEditor::_edit_port_default_input(Object *p_button, int p_node, int p_port) { VisualShader::Type type = get_current_shader_type(); + Ref<VisualShaderNode> vs_node = visual_shader->get_node(type, p_node); + Variant value = vs_node->get_input_port_default_value(p_port); + + edited_property_holder->set_edited_property(value); + + if (property_editor) { + property_editor->disconnect("property_changed", callable_mp(this, &VisualShaderEditor::_port_edited)); + property_editor_popup->remove_child(property_editor); + } - Ref<VisualShaderNode> vsn = visual_shader->get_node(type, p_node); + // TODO: Define these properties with actual PropertyInfo and feed it to the property editor widget. + property_editor = EditorInspector::instantiate_property_editor(edited_property_holder.ptr(), value.get_type(), "edited_property", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE); + if (property_editor) { + property_editor->set_object_and_property(edited_property_holder.ptr(), "edited_property"); + property_editor->update_property(); + property_editor->set_name_split_ratio(0); + property_editor_popup->add_child(property_editor); + + property_editor->connect("property_changed", callable_mp(this, &VisualShaderEditor::_port_edited)); + + Button *button = Object::cast_to<Button>(p_button); + if (button) { + property_editor_popup->set_position(button->get_screen_position() + Vector2(0, button->get_size().height) * graph->get_zoom()); + } + property_editor_popup->reset_size(); + if (button) { + property_editor_popup->popup(); + } else { + property_editor_popup->popup_centered_ratio(); + } + } - Button *button = Object::cast_to<Button>(p_button); - ERR_FAIL_COND(!button); - Variant value = vsn->get_input_port_default_value(p_port); - property_editor->set_position(button->get_screen_position() + Vector2(0, button->get_size().height)); - property_editor->edit(nullptr, "", value.get_type(), value, 0, ""); - property_editor->popup(); editing_node = p_node; editing_port = p_port; } @@ -5147,6 +5177,10 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("ViewIndex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "view_index", "VIEW_INDEX"), { "view_index" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("ViewMonoLeft", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "view_mono_left", "VIEW_MONO_LEFT"), { "view_mono_left" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("ViewRight", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "view_right", "VIEW_RIGHT"), { "view_right" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("NodePositionWorld", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "node_position_world", "NODE_POSITION_WORLD"), { "node_position_world" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("CameraPositionWorld", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "camera_position_world", "CAMERA_POSITION_WORLD"), { "camera_position_world" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("CameraDirectionWorld", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "camera_direction_world", "CAMERA_DIRECTION_WORLD"), { "camera_direction_world" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("NodePositionView", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "node_position_view", "NODE_POSITION_VIEW"), { "node_position_view" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("Binormal", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal", "BINORMAL"), { "binormal" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("Color", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "color", "COLOR"), { "color" }, VisualShaderNode::PORT_TYPE_VECTOR_4D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); @@ -5162,6 +5196,10 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("ViewIndex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "view_index", "VIEW_INDEX"), { "view_index" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("ViewMonoLeft", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "view_mono_left", "VIEW_MONO_LEFT"), { "view_mono_left" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("ViewRight", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "view_right", "VIEW_RIGHT"), { "view_right" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("NodePositionWorld", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "node_position_world", "NODE_POSITION_WORLD"), { "node_position_world" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("CameraPositionWorld", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "camera_position_world", "CAMERA_POSITION_WORLD"), { "camera_position_world" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("CameraDirectionWorld", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "camera_direction_world", "CAMERA_DIRECTION_WORLD"), { "camera_direction_world" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("NodePositionView", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "node_position_view", "NODE_POSITION_VIEW"), { "node_position_view" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("Albedo", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "albedo", "ALBEDO"), { "albedo" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("Attenuation", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "attenuation", "ATTENUATION"), { "attenuation" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); @@ -5636,10 +5674,11 @@ VisualShaderEditor::VisualShaderEditor() { graph_plugin.instantiate(); graph_plugin->set_editor(this); - property_editor = memnew(CustomPropertyEditor); - add_child(property_editor); + property_editor_popup = memnew(PopupPanel); + property_editor_popup->set_min_size(Size2i(180, 0) * EDSCALE); + add_child(property_editor_popup); - property_editor->connect("variant_changed", callable_mp(this, &VisualShaderEditor::_port_edited)); + edited_property_holder.instantiate(); } class VisualShaderNodePluginInputEditor : public OptionButton { diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index ecaad1e540..b846c34f9e 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -32,17 +32,21 @@ #define VISUAL_SHADER_EDITOR_PLUGIN_H #include "editor/editor_plugin.h" -#include "editor/plugins/curve_editor_plugin.h" #include "editor/plugins/editor_resource_conversion_plugin.h" -#include "editor/property_editor.h" -#include "scene/gui/button.h" -#include "scene/gui/code_edit.h" -#include "scene/gui/graph_edit.h" -#include "scene/gui/popup.h" -#include "scene/gui/rich_text_label.h" -#include "scene/gui/tree.h" #include "scene/resources/visual_shader.h" +class Button; +class CodeEdit; +class CodeHighlighter; +class CurveEditor; +class GraphEdit; +class GraphNode; +class PopupMenu; +class PopupPanel; +class RichTextLabel; +class TextEdit; +class Tree; + class VisualShaderEditor; class VisualShaderNodePlugin : public RefCounted { @@ -138,13 +142,31 @@ public: ~VisualShaderGraphPlugin(); }; +class VisualShaderEditedProperty : public RefCounted { + GDCLASS(VisualShaderEditedProperty, RefCounted); + +private: + Variant edited_property; + +protected: + static void _bind_methods(); + +public: + void set_edited_property(Variant p_variant); + Variant get_edited_property() const; + + VisualShaderEditedProperty() {} +}; + class VisualShaderEditor : public VBoxContainer { GDCLASS(VisualShaderEditor, VBoxContainer); friend class VisualShaderGraphPlugin; - CustomPropertyEditor *property_editor = nullptr; + PopupPanel *property_editor_popup = nullptr; + EditorProperty *property_editor = nullptr; int editing_node = -1; int editing_port = -1; + Ref<VisualShaderEditedProperty> edited_property_holder; Ref<VisualShader> visual_shader; GraphEdit *graph = nullptr; @@ -359,7 +381,7 @@ class VisualShaderEditor : public VBoxContainer { void _node_changed(int p_id); void _edit_port_default_input(Object *p_button, int p_node, int p_port); - void _port_edited(); + void _port_edited(const StringName &p_property, const Variant &p_value, const String &p_field, bool p_changing); int to_node = -1; int to_slot = -1; diff --git a/editor/project_converter_3_to_4.cpp b/editor/project_converter_3_to_4.cpp index 658258d98b..b564195911 100644 --- a/editor/project_converter_3_to_4.cpp +++ b/editor/project_converter_3_to_4.cpp @@ -2519,7 +2519,7 @@ Vector<String> ProjectConverter3To4::check_for_rename_enums(Vector<String> &file int current_line = 1; for (String &line : file_content) { - Array reg_match = reg.search_all(line); + TypedArray<RegExMatch> reg_match = reg.search_all(line); if (reg_match.size() > 0) { found_things.append(line_formatter(current_line, colors_renames[current_index][0], colors_renames[current_index][1], line)); } @@ -2596,7 +2596,7 @@ Vector<String> ProjectConverter3To4::check_for_rename_classes(Vector<String> &fi line = reg_before.sub(line, "TEMP_RENAMED_CLASS.tscn", true); line = reg_before2.sub(line, "TEMP_RENAMED_CLASS.gd", true); - Array reg_match = reg.search_all(line); + TypedArray<RegExMatch> reg_match = reg.search_all(line); if (reg_match.size() > 0) { found_things.append(line_formatter(current_line, class_renames[current_index][0], class_renames[current_index][1], line)); } @@ -3810,7 +3810,7 @@ Vector<String> ProjectConverter3To4::check_for_custom_rename(Vector<String> &fil int current_line = 1; for (String &line : file_content) { - Array reg_match = reg.search_all(line); + TypedArray<RegExMatch> reg_match = reg.search_all(line); if (reg_match.size() > 0) { found_things.append(line_formatter(current_line, from.replace("\\.", "."), to, line)); // Without replacing it will print "\.shader" instead ".shader" } @@ -3841,7 +3841,7 @@ Vector<String> ProjectConverter3To4::check_for_rename_common(const char *array[] int current_line = 1; for (String &line : file_content) { - Array reg_match = reg.search_all(line); + TypedArray<RegExMatch> reg_match = reg.search_all(line); if (reg_match.size() > 0) { found_things.append(line_formatter(current_line, array[current_index][0], array[current_index][1], line)); } diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp deleted file mode 100644 index 3906827027..0000000000 --- a/editor/property_editor.cpp +++ /dev/null @@ -1,1866 +0,0 @@ -/*************************************************************************/ -/* property_editor.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 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. */ -/*************************************************************************/ - -#include "property_editor.h" - -#include "core/config/project_settings.h" -#include "core/input/input.h" -#include "core/io/image_loader.h" -#include "core/io/marshalls.h" -#include "core/io/resource_loader.h" -#include "core/math/expression.h" -#include "core/object/class_db.h" -#include "core/os/keyboard.h" -#include "core/string/print_string.h" -#include "core/templates/pair.h" -#include "editor/array_property_edit.h" -#include "editor/create_dialog.h" -#include "editor/dictionary_property_edit.h" -#include "editor/editor_file_dialog.h" -#include "editor/editor_file_system.h" -#include "editor/editor_help.h" -#include "editor/editor_node.h" -#include "editor/editor_scale.h" -#include "editor/editor_settings.h" -#include "editor/filesystem_dock.h" -#include "editor/multi_node_edit.h" -#include "editor/plugins/editor_resource_conversion_plugin.h" -#include "editor/property_selector.h" -#include "editor/scene_tree_dock.h" -#include "scene/gui/label.h" -#include "scene/main/window.h" -#include "scene/resources/font.h" -#include "scene/resources/packed_scene.h" -#include "scene/scene_string_names.h" - -void CustomPropertyEditor::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_WM_CLOSE_REQUEST: { - hide(); - } break; - } -} - -void CustomPropertyEditor::_menu_option(int p_which) { - switch (type) { - case Variant::INT: { - if (hint == PROPERTY_HINT_FLAGS) { - int idx = menu->get_item_index(p_which); - uint32_t item_value = menu->get_item_metadata(idx); - uint32_t value = v; - // If the item wasn't previously checked it means it was pressed, - // otherwise it was unpressed. - if (!menu->is_item_checked(idx)) { - v = value | item_value; - } else { - v = value & ~item_value; - } - emit_signal(SNAME("variant_changed")); - } else if (hint == PROPERTY_HINT_ENUM) { - v = menu->get_item_metadata(p_which); - emit_signal(SNAME("variant_changed")); - } - } break; - case Variant::STRING: { - if (hint == PROPERTY_HINT_ENUM) { - v = hint_text.get_slice(",", p_which); - emit_signal(SNAME("variant_changed")); - } - } break; - case Variant::OBJECT: { - switch (p_which) { - case OBJ_MENU_LOAD: { - file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); - String type = (hint == PROPERTY_HINT_RESOURCE_TYPE) ? hint_text : String(); - - List<String> extensions; - for (int i = 0; i < type.get_slice_count(","); i++) { - ResourceLoader::get_recognized_extensions_for_type(type.get_slice(",", i), &extensions); - } - - HashSet<String> valid_extensions; - for (const String &E : extensions) { - valid_extensions.insert(E); - } - - file->clear_filters(); - for (const String &E : valid_extensions) { - file->add_filter("*." + E, E.to_upper()); - } - - file->popup_file_dialog(); - } break; - - case OBJ_MENU_EDIT: { - Ref<RefCounted> r = v; - - if (!r.is_null()) { - emit_signal(SNAME("resource_edit_request")); - hide(); - } - } break; - case OBJ_MENU_CLEAR: { - v = Variant(); - emit_signal(SNAME("variant_changed")); - hide(); - } break; - - case OBJ_MENU_MAKE_UNIQUE: { - Ref<Resource> res_orig = v; - if (res_orig.is_null()) { - return; - } - - List<PropertyInfo> property_list; - res_orig->get_property_list(&property_list); - List<Pair<String, Variant>> propvalues; - - for (const PropertyInfo &pi : property_list) { - Pair<String, Variant> p; - if (pi.usage & PROPERTY_USAGE_STORAGE) { - p.first = pi.name; - p.second = res_orig->get(pi.name); - } - - propvalues.push_back(p); - } - - String orig_type = res_orig->get_class(); - - Object *inst = ClassDB::instantiate(orig_type); - - Ref<Resource> res = Ref<Resource>(Object::cast_to<Resource>(inst)); - - ERR_FAIL_COND(res.is_null()); - - for (const Pair<String, Variant> &p : propvalues) { - res->set(p.first, p.second); - } - - v = res; - emit_signal(SNAME("variant_changed")); - hide(); - } break; - - case OBJ_MENU_COPY: { - EditorSettings::get_singleton()->set_resource_clipboard(v); - - } break; - case OBJ_MENU_PASTE: { - v = EditorSettings::get_singleton()->get_resource_clipboard(); - emit_signal(SNAME("variant_changed")); - - } break; - case OBJ_MENU_NEW_SCRIPT: { - if (Object::cast_to<Node>(owner)) { - SceneTreeDock::get_singleton()->open_script_dialog(Object::cast_to<Node>(owner), false); - } - - } break; - case OBJ_MENU_EXTEND_SCRIPT: { - if (Object::cast_to<Node>(owner)) { - SceneTreeDock::get_singleton()->open_script_dialog(Object::cast_to<Node>(owner), true); - } - - } break; - case OBJ_MENU_SHOW_IN_FILE_SYSTEM: { - Ref<Resource> r = v; - FileSystemDock *file_system_dock = FileSystemDock::get_singleton(); - file_system_dock->navigate_to_path(r->get_path()); - // Ensure that the FileSystem dock is visible. - TabContainer *tab_container = (TabContainer *)file_system_dock->get_parent_control(); - tab_container->set_current_tab(tab_container->get_tab_idx_from_control(file_system_dock)); - } break; - default: { - 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(Ref<Resource>(v)); - - ERR_FAIL_INDEX(to_type, conversions.size()); - - Ref<Resource> new_res = conversions[to_type]->convert(v); - - v = new_res; - emit_signal(SNAME("variant_changed")); - break; - } - ERR_FAIL_COND(inheritors_array.is_empty()); - - String intype = inheritors_array[p_which - TYPE_BASE_ID]; - - if (intype == "ViewportTexture") { - scene_tree->set_title(TTR("Pick a Viewport")); - scene_tree->popup_scenetree_dialog(); - picking_viewport = true; - return; - } - - Variant obj = ClassDB::instantiate(intype); - - if (!obj) { - if (ScriptServer::is_global_class(intype)) { - obj = EditorNode::get_editor_data().script_class_instance(intype); - } else { - obj = EditorNode::get_editor_data().instance_custom_type(intype, "Resource"); - } - } - - ERR_BREAK(!obj); - Resource *res = Object::cast_to<Resource>(obj); - ERR_BREAK(!res); - if (owner && hint == PROPERTY_HINT_RESOURCE_TYPE && hint_text == "Script") { - //make visual script the right type - res->call("set_instance_base_type", owner->get_class()); - } - - EditorNode::get_editor_data().instantiate_object_properties(obj); - v = obj; - - emit_signal(SNAME("variant_changed")); - - } break; - } - - } break; - default: { - } - } -} - -void CustomPropertyEditor::hide_menu() { - menu->hide(); -} - -Variant CustomPropertyEditor::get_variant() const { - return v; -} - -String CustomPropertyEditor::get_name() const { - return name; -} - -bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::Type p_type, const Variant &p_variant, int p_hint, String p_hint_text) { - owner = p_owner; - updating = true; - name = p_name; - v = p_variant; - field_names.clear(); - hint = p_hint; - hint_text = p_hint_text; - type_button->hide(); - if (color_picker) { - color_picker->hide(); - } - texture_preview->hide(); - inheritors_array.clear(); - text_edit->hide(); - easing_draw->hide(); - spinbox->hide(); - slider->hide(); - menu->clear(); - menu->reset_size(); - - for (int i = 0; i < MAX_VALUE_EDITORS; i++) { - if (i < MAX_VALUE_EDITORS / 4) { - value_hboxes[i]->hide(); - } - value_editor[i]->hide(); - value_label[i]->hide(); - if (i < 4) { - scroll[i]->hide(); - } - } - - for (int i = 0; i < MAX_ACTION_BUTTONS; i++) { - action_buttons[i]->hide(); - } - - checks20gc->hide(); - for (int i = 0; i < 20; i++) { - checks20[i]->hide(); - } - - type = (p_variant.get_type() != Variant::NIL && p_variant.get_type() != Variant::RID && p_type != Variant::OBJECT) ? p_variant.get_type() : p_type; - - switch (type) { - case Variant::BOOL: { - checks20gc->show(); - - CheckBox *c = checks20[0]; - c->set_text("True"); - checks20gc->set_position(Vector2(4, 4) * EDSCALE); - c->set_pressed(v); - c->show(); - - checks20gc->set_size(checks20gc->get_minimum_size()); - set_size(checks20gc->get_position() + checks20gc->get_size() + c->get_size() + Vector2(4, 4) * EDSCALE); - - } break; - case Variant::INT: - case Variant::FLOAT: { - if (hint == PROPERTY_HINT_RANGE) { - int c = hint_text.get_slice_count(","); - float min = 0, max = 100, step = type == Variant::FLOAT ? .01 : 1; - if (c >= 1) { - if (!hint_text.get_slice(",", 0).is_empty()) { - min = hint_text.get_slice(",", 0).to_float(); - } - } - if (c >= 2) { - if (!hint_text.get_slice(",", 1).is_empty()) { - max = hint_text.get_slice(",", 1).to_float(); - } - } - - if (c >= 3) { - if (!hint_text.get_slice(",", 2).is_empty()) { - step = hint_text.get_slice(",", 2).to_float(); - } - } - - if (c >= 4 && hint_text.get_slice(",", 3) == "slider") { - slider->set_min(min); - slider->set_max(max); - slider->set_step(step); - slider->set_value(v); - slider->show(); - set_size(Size2(110, 30) * EDSCALE); - } else { - spinbox->set_min(min); - spinbox->set_max(max); - spinbox->set_step(step); - spinbox->set_value(v); - spinbox->show(); - set_size(Size2(70, 35) * EDSCALE); - } - - } else if (hint == PROPERTY_HINT_ENUM) { - Vector<String> options = hint_text.split(","); - int current_val = 0; - for (int i = 0; i < options.size(); i++) { - Vector<String> text_split = options[i].split(":"); - if (text_split.size() != 1) { - current_val = text_split[1].to_int(); - } - menu->add_item(text_split[0]); - menu->set_item_metadata(i, current_val); - current_val += 1; - } - menu->set_position(get_position()); - menu->popup(); - hide(); - updating = false; - return false; - - } else if (hint == PROPERTY_HINT_LAYERS_2D_PHYSICS || - hint == PROPERTY_HINT_LAYERS_2D_RENDER || - hint == PROPERTY_HINT_LAYERS_2D_NAVIGATION || - hint == PROPERTY_HINT_LAYERS_3D_PHYSICS || - hint == PROPERTY_HINT_LAYERS_3D_RENDER || - hint == PROPERTY_HINT_LAYERS_3D_NAVIGATION) { - String basename; - switch (hint) { - case PROPERTY_HINT_LAYERS_2D_RENDER: - basename = "layer_names/2d_render"; - break; - case PROPERTY_HINT_LAYERS_2D_PHYSICS: - basename = "layer_names/2d_physics"; - break; - case PROPERTY_HINT_LAYERS_2D_NAVIGATION: - basename = "layer_names/2d_navigation"; - break; - case PROPERTY_HINT_LAYERS_3D_RENDER: - basename = "layer_names/3d_render"; - break; - case PROPERTY_HINT_LAYERS_3D_PHYSICS: - basename = "layer_names/3d_physics"; - break; - case PROPERTY_HINT_LAYERS_3D_NAVIGATION: - basename = "layer_names/3d_navigation"; - break; - } - - checks20gc->show(); - uint32_t flgs = v; - for (int i = 0; i < 2; i++) { - Point2 ofs(4, 4); - ofs.y += 22 * i; - for (int j = 0; j < 10; j++) { - int idx = i * 10 + j; - CheckBox *c = checks20[idx]; - c->set_text(ProjectSettings::get_singleton()->get(basename + "/layer_" + itos(idx + 1))); - c->set_pressed(flgs & (1 << (i * 10 + j))); - c->show(); - } - } - - show(); - - checks20gc->set_position(Vector2(4, 4) * EDSCALE); - checks20gc->set_size(checks20gc->get_minimum_size()); - - set_size(Vector2(4, 4) * EDSCALE + checks20gc->get_position() + checks20gc->get_size()); - - } else if (hint == PROPERTY_HINT_EXP_EASING) { - easing_draw->set_anchor_and_offset(SIDE_LEFT, Control::ANCHOR_BEGIN, 5 * EDSCALE); - easing_draw->set_anchor_and_offset(SIDE_RIGHT, Control::ANCHOR_END, -5 * EDSCALE); - easing_draw->set_anchor_and_offset(SIDE_TOP, Control::ANCHOR_BEGIN, 5 * EDSCALE); - easing_draw->set_anchor_and_offset(SIDE_BOTTOM, Control::ANCHOR_END, -30 * EDSCALE); - type_button->set_anchor_and_offset(SIDE_LEFT, Control::ANCHOR_BEGIN, 3 * EDSCALE); - type_button->set_anchor_and_offset(SIDE_RIGHT, Control::ANCHOR_END, -3 * EDSCALE); - type_button->set_anchor_and_offset(SIDE_TOP, Control::ANCHOR_END, -25 * EDSCALE); - type_button->set_anchor_and_offset(SIDE_BOTTOM, Control::ANCHOR_END, -7 * EDSCALE); - type_button->set_text(TTR("Preset...")); - type_button->get_popup()->clear(); - type_button->get_popup()->add_item(TTR("Linear"), EASING_LINEAR); - type_button->get_popup()->add_item(TTR("Ease In"), EASING_EASE_IN); - type_button->get_popup()->add_item(TTR("Ease Out"), EASING_EASE_OUT); - if (hint_text != "attenuation") { - type_button->get_popup()->add_item(TTR("Zero"), EASING_ZERO); - type_button->get_popup()->add_item(TTR("Ease In-Out"), EASING_IN_OUT); - type_button->get_popup()->add_item(TTR("Ease Out-In"), EASING_OUT_IN); - } - - type_button->show(); - easing_draw->show(); - set_size(Size2(200, 150) * EDSCALE); - } else if (hint == PROPERTY_HINT_FLAGS) { - Vector<String> flags = hint_text.split(","); - uint32_t value = v; - for (int i = 0; i < flags.size(); i++) { - uint32_t current_val; - Vector<String> text_split = flags[i].split(":"); - if (text_split.size() != 1) { - current_val = text_split[1].to_int(); - } else { - current_val = 1 << i; - } - menu->add_check_item(text_split[0], current_val); - menu->set_item_metadata(i, current_val); - if ((value & current_val) == current_val) { - menu->set_item_checked(menu->get_item_index(current_val), true); - } - } - menu->set_position(get_position()); - menu->popup(); - hide(); - updating = false; - return false; - - } else { - List<String> names; - names.push_back("value:"); - config_value_editors(1, 1, 50, names); - value_editor[0]->set_text(TS->format_number(String::num(v))); - } - - } break; - case Variant::STRING: { - if (hint == PROPERTY_HINT_LOCALE_ID) { - List<String> names; - names.push_back(TTR("Locale...")); - names.push_back(TTR("Clear")); - config_action_buttons(names); - } else if (hint == PROPERTY_HINT_FILE || hint == PROPERTY_HINT_GLOBAL_FILE) { - List<String> names; - names.push_back(TTR("File...")); - names.push_back(TTR("Clear")); - config_action_buttons(names); - } else if (hint == PROPERTY_HINT_DIR || hint == PROPERTY_HINT_GLOBAL_DIR) { - List<String> names; - names.push_back(TTR("Dir...")); - names.push_back(TTR("Clear")); - config_action_buttons(names); - } else if (hint == PROPERTY_HINT_ENUM) { - Vector<String> options = hint_text.split(","); - for (int i = 0; i < options.size(); i++) { - menu->add_item(options[i], i); - } - menu->set_position(get_position()); - menu->popup(); - hide(); - updating = false; - return false; - - } else if (hint == PROPERTY_HINT_MULTILINE_TEXT) { - text_edit->show(); - text_edit->set_text(v); - text_edit->deselect(); - - int button_margin = text_edit->get_theme_constant(SNAME("button_margin"), SNAME("Dialogs")); - int margin = text_edit->get_theme_constant(SNAME("margin"), SNAME("Dialogs")); - - action_buttons[0]->set_anchor(SIDE_LEFT, Control::ANCHOR_END); - action_buttons[0]->set_anchor(SIDE_TOP, Control::ANCHOR_END); - action_buttons[0]->set_anchor(SIDE_RIGHT, Control::ANCHOR_END); - action_buttons[0]->set_anchor(SIDE_BOTTOM, Control::ANCHOR_END); - action_buttons[0]->set_begin(Point2(-70 * EDSCALE, -button_margin + 5 * EDSCALE)); - action_buttons[0]->set_end(Point2(-margin, -margin)); - action_buttons[0]->set_text(TTR("Close")); - action_buttons[0]->show(); - - } else if (hint == PROPERTY_HINT_TYPE_STRING) { - if (!create_dialog) { - create_dialog = memnew(CreateDialog); - create_dialog->connect("create", callable_mp(this, &CustomPropertyEditor::_create_dialog_callback)); - add_child(create_dialog); - } - - if (!hint_text.is_empty()) { - create_dialog->set_base_type(hint_text); - } else { - create_dialog->set_base_type("Object"); - } - - create_dialog->popup_create(false); - hide(); - updating = false; - return false; - - } else if (hint == PROPERTY_HINT_METHOD_OF_VARIANT_TYPE) { -#define MAKE_PROPSELECT \ - if (!property_select) { \ - property_select = memnew(PropertySelector); \ - property_select->connect("selected", callable_mp(this, &CustomPropertyEditor::_create_selected_property)); \ - add_child(property_select); \ - } \ - hide(); - - MAKE_PROPSELECT; - - Variant::Type type = Variant::NIL; - for (int i = 0; i < Variant::VARIANT_MAX; i++) { - if (hint_text == Variant::get_type_name(Variant::Type(i))) { - type = Variant::Type(i); - } - } - if (type != Variant::NIL) { - property_select->select_method_from_basic_type(type, v); - } - updating = false; - return false; - - } else if (hint == PROPERTY_HINT_METHOD_OF_BASE_TYPE) { - MAKE_PROPSELECT - - property_select->select_method_from_base_type(hint_text, v); - - updating = false; - return false; - - } else if (hint == PROPERTY_HINT_METHOD_OF_INSTANCE) { - MAKE_PROPSELECT - - Object *instance = ObjectDB::get_instance(ObjectID(hint_text.to_int())); - if (instance) { - property_select->select_method_from_instance(instance, v); - } - updating = false; - return false; - - } else if (hint == PROPERTY_HINT_METHOD_OF_SCRIPT) { - MAKE_PROPSELECT - - Object *obj = ObjectDB::get_instance(ObjectID(hint_text.to_int())); - if (Object::cast_to<Script>(obj)) { - property_select->select_method_from_script(Object::cast_to<Script>(obj), v); - } - - updating = false; - return false; - - } else if (hint == PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE) { - MAKE_PROPSELECT - Variant::Type type = Variant::NIL; - String tname = hint_text; - if (tname.contains(".")) { - tname = tname.get_slice(".", 0); - } - for (int i = 0; i < Variant::VARIANT_MAX; i++) { - if (tname == Variant::get_type_name(Variant::Type(i))) { - type = Variant::Type(Variant::Type(i)); - } - } - - if (type != Variant::NIL) { - property_select->select_property_from_basic_type(type, v); - } - - updating = false; - return false; - - } else if (hint == PROPERTY_HINT_PROPERTY_OF_BASE_TYPE) { - MAKE_PROPSELECT - - property_select->select_property_from_base_type(hint_text, v); - - updating = false; - return false; - - } else if (hint == PROPERTY_HINT_PROPERTY_OF_INSTANCE) { - MAKE_PROPSELECT - - Object *instance = ObjectDB::get_instance(ObjectID(hint_text.to_int())); - if (instance) { - property_select->select_property_from_instance(instance, v); - } - - updating = false; - return false; - - } else if (hint == PROPERTY_HINT_PROPERTY_OF_SCRIPT) { - MAKE_PROPSELECT - - Object *obj = ObjectDB::get_instance(ObjectID(hint_text.to_int())); - if (Object::cast_to<Script>(obj)) { - property_select->select_property_from_script(Object::cast_to<Script>(obj), v); - } - - updating = false; - return false; - - } else { - List<String> names; - names.push_back("string:"); - config_value_editors(1, 1, 50, names); - value_editor[0]->set_text(v); - } - - } break; - case Variant::VECTOR2: { - field_names.push_back("x"); - field_names.push_back("y"); - config_value_editors(2, 2, 10, field_names); - Vector2 vec = v; - value_editor[0]->set_text(String::num(vec.x)); - value_editor[1]->set_text(String::num(vec.y)); - } break; - case Variant::RECT2: { - field_names.push_back("x"); - field_names.push_back("y"); - field_names.push_back("w"); - field_names.push_back("h"); - config_value_editors(4, 4, 10, field_names); - Rect2 r = v; - value_editor[0]->set_text(String::num(r.position.x)); - value_editor[1]->set_text(String::num(r.position.y)); - value_editor[2]->set_text(String::num(r.size.x)); - value_editor[3]->set_text(String::num(r.size.y)); - } break; - case Variant::VECTOR3: { - field_names.push_back("x"); - field_names.push_back("y"); - field_names.push_back("z"); - config_value_editors(3, 3, 10, field_names); - Vector3 vec = v; - value_editor[0]->set_text(String::num(vec.x)); - value_editor[1]->set_text(String::num(vec.y)); - value_editor[2]->set_text(String::num(vec.z)); - } break; - case Variant::PLANE: { - field_names.push_back("x"); - field_names.push_back("y"); - field_names.push_back("z"); - field_names.push_back("d"); - config_value_editors(4, 4, 10, field_names); - Plane plane = v; - value_editor[0]->set_text(String::num(plane.normal.x)); - value_editor[1]->set_text(String::num(plane.normal.y)); - value_editor[2]->set_text(String::num(plane.normal.z)); - value_editor[3]->set_text(String::num(plane.d)); - - } break; - case Variant::QUATERNION: { - field_names.push_back("x"); - field_names.push_back("y"); - field_names.push_back("z"); - field_names.push_back("w"); - config_value_editors(4, 4, 10, field_names); - Quaternion q = v; - value_editor[0]->set_text(String::num(q.x)); - value_editor[1]->set_text(String::num(q.y)); - value_editor[2]->set_text(String::num(q.z)); - value_editor[3]->set_text(String::num(q.w)); - - } break; - case Variant::AABB: { - field_names.push_back("px"); - field_names.push_back("py"); - field_names.push_back("pz"); - field_names.push_back("sx"); - field_names.push_back("sy"); - field_names.push_back("sz"); - config_value_editors(6, 3, 16, field_names); - - AABB aabb = v; - value_editor[0]->set_text(String::num(aabb.position.x)); - value_editor[1]->set_text(String::num(aabb.position.y)); - value_editor[2]->set_text(String::num(aabb.position.z)); - value_editor[3]->set_text(String::num(aabb.size.x)); - value_editor[4]->set_text(String::num(aabb.size.y)); - value_editor[5]->set_text(String::num(aabb.size.z)); - - } break; - case Variant::TRANSFORM2D: { - field_names.push_back("xx"); - field_names.push_back("xy"); - field_names.push_back("yx"); - field_names.push_back("yy"); - field_names.push_back("ox"); - field_names.push_back("oy"); - config_value_editors(6, 2, 16, field_names); - - Transform2D basis = v; - for (int i = 0; i < 6; i++) { - value_editor[i]->set_text(String::num(basis.columns[i / 2][i % 2])); - } - - } break; - case Variant::BASIS: { - field_names.push_back("xx"); - field_names.push_back("xy"); - field_names.push_back("xz"); - field_names.push_back("yx"); - field_names.push_back("yy"); - field_names.push_back("yz"); - field_names.push_back("zx"); - field_names.push_back("zy"); - field_names.push_back("zz"); - config_value_editors(9, 3, 16, field_names); - - Basis basis = v; - for (int i = 0; i < 9; i++) { - value_editor[i]->set_text(String::num(basis.rows[i / 3][i % 3])); - } - - } break; - case Variant::TRANSFORM3D: { - field_names.push_back("xx"); - field_names.push_back("xy"); - field_names.push_back("xz"); - field_names.push_back("xo"); - field_names.push_back("yx"); - field_names.push_back("yy"); - field_names.push_back("yz"); - field_names.push_back("yo"); - field_names.push_back("zx"); - field_names.push_back("zy"); - field_names.push_back("zz"); - field_names.push_back("zo"); - config_value_editors(12, 4, 16, field_names); - - Transform3D tr = v; - for (int i = 0; i < 9; i++) { - value_editor[(i / 3) * 4 + i % 3]->set_text(String::num(tr.basis.rows[i / 3][i % 3])); - } - - value_editor[3]->set_text(String::num(tr.origin.x)); - value_editor[7]->set_text(String::num(tr.origin.y)); - value_editor[11]->set_text(String::num(tr.origin.z)); - - } break; - case Variant::COLOR: { - if (!color_picker) { - //late init for performance - color_picker = memnew(ColorPicker); - color_picker->set_deferred_mode(true); - value_vbox->add_child(color_picker); - color_picker->hide(); - color_picker->connect("color_changed", callable_mp(this, &CustomPropertyEditor::_color_changed)); - color_picker->connect("show", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker).bind(color_picker)); - } - - color_picker->show(); - color_picker->set_edit_alpha(hint != PROPERTY_HINT_COLOR_NO_ALPHA); - color_picker->set_pick_color(v); - color_picker->set_focus_on_line_edit(); - - } break; - - case Variant::NODE_PATH: { - List<String> names; - names.push_back(TTR("Assign")); - names.push_back(TTR("Clear")); - - if (owner && owner->is_class("Node") && (v.get_type() == Variant::NODE_PATH) && Object::cast_to<Node>(owner)->has_node(v)) { - names.push_back(TTR("Select Node")); - } - - config_action_buttons(names); - - } break; - case Variant::OBJECT: { - if (hint != PROPERTY_HINT_RESOURCE_TYPE) { - break; - } - - if (p_name == "script" && hint_text == "Script" && Object::cast_to<Node>(owner)) { - menu->add_item(TTR("New Script"), OBJ_MENU_NEW_SCRIPT); - menu->add_separator(); - } else if (!hint_text.is_empty()) { - int idx = 0; - - 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 (int i = 0; i < hint_text.get_slice_count(","); i++) { - String base = hint_text.get_slice(",", i); - - HashSet<String> valid_inheritors; - valid_inheritors.insert(base); - List<StringName> inheritors; - ClassDB::get_inheriters_from_class(base.strip_edges(), &inheritors); - - for (int j = 0; j < custom_resources.size(); j++) { - inheritors.push_back(custom_resources[j].name); - } - - List<StringName>::Element *E = inheritors.front(); - while (E) { - valid_inheritors.insert(E->get()); - E = E->next(); - } - - for (const String &j : valid_inheritors) { - const String &t = j; - - bool is_custom_resource = false; - Ref<Texture2D> icon; - if (!custom_resources.is_empty()) { - for (int k = 0; k < custom_resources.size(); k++) { - if (custom_resources[k].name == t) { - is_custom_resource = true; - if (custom_resources[k].icon.is_valid()) { - icon = custom_resources[k].icon; - } - break; - } - } - } - - if (!is_custom_resource && (!ClassDB::can_instantiate(t) || ClassDB::is_virtual(t))) { - continue; - } - - inheritors_array.push_back(t); - - int id = TYPE_BASE_ID + idx; - - menu->add_item(vformat(TTR("New %s"), t), id); - - idx++; - } - } - - if (menu->get_item_count()) { - menu->add_separator(); - } - } - - menu->add_item(TTR("Load"), OBJ_MENU_LOAD); - - if (!Ref<Resource>(v).is_null()) { - menu->add_item(TTR("Edit"), OBJ_MENU_EDIT); - menu->add_item(TTR("Clear"), OBJ_MENU_CLEAR); - menu->add_item(TTR("Make Unique"), OBJ_MENU_MAKE_UNIQUE); - - Ref<Resource> r = v; - if (r.is_valid() && r->get_path().is_resource_file()) { - menu->add_separator(); - menu->add_item(TTR("Show in FileSystem"), OBJ_MENU_SHOW_IN_FILE_SYSTEM); - } - } - - Ref<Resource> cb = EditorSettings::get_singleton()->get_resource_clipboard(); - bool paste_valid = false; - if (cb.is_valid()) { - if (hint_text.is_empty()) { - paste_valid = true; - } else { - for (int i = 0; i < hint_text.get_slice_count(","); i++) { - if (ClassDB::is_parent_class(cb->get_class(), hint_text.get_slice(",", i))) { - paste_valid = true; - break; - } - } - } - } - - if (!Ref<Resource>(v).is_null() || paste_valid) { - menu->add_separator(); - - if (!Ref<Resource>(v).is_null()) { - menu->add_item(TTR("Copy"), OBJ_MENU_COPY); - } - - if (paste_valid) { - menu->add_item(TTR("Paste"), OBJ_MENU_PASTE); - } - } - - if (!Ref<Resource>(v).is_null()) { - Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(Ref<Resource>(v)); - if (conversions.size()) { - menu->add_separator(); - } - for (int i = 0; i < conversions.size(); i++) { - String what = conversions[i]->converts_to(); - menu->add_item(vformat(TTR("Convert to %s"), what), CONVERT_BASE_ID + i); - } - } - - menu->set_position(get_position()); - menu->popup(); - hide(); - updating = false; - return false; - } break; - case Variant::DICTIONARY: { - } break; - case Variant::PACKED_BYTE_ARRAY: { - } break; - case Variant::PACKED_INT32_ARRAY: { - } break; - case Variant::PACKED_FLOAT32_ARRAY: { - } break; - case Variant::PACKED_INT64_ARRAY: { - } break; - case Variant::PACKED_FLOAT64_ARRAY: { - } break; - case Variant::PACKED_STRING_ARRAY: { - } break; - case Variant::PACKED_VECTOR3_ARRAY: { - } break; - case Variant::PACKED_COLOR_ARRAY: { - } break; - default: { - } - } - - updating = false; - return true; -} - -void CustomPropertyEditor::_file_selected(String p_file) { - switch (type) { - case Variant::STRING: { - if (hint == PROPERTY_HINT_FILE || hint == PROPERTY_HINT_DIR) { - v = ProjectSettings::get_singleton()->localize_path(p_file); - emit_signal(SNAME("variant_changed")); - hide(); - } - - if (hint == PROPERTY_HINT_GLOBAL_FILE || hint == PROPERTY_HINT_GLOBAL_DIR) { - v = p_file; - emit_signal(SNAME("variant_changed")); - hide(); - } - - } break; - case Variant::OBJECT: { - String type = (hint == PROPERTY_HINT_RESOURCE_TYPE) ? hint_text : String(); - - Ref<Resource> res = ResourceLoader::load(p_file, type); - if (res.is_null()) { - error->set_text(TTR("Error loading file: Not a resource!")); - error->popup_centered(); - break; - } - v = res; - emit_signal(SNAME("variant_changed")); - hide(); - } break; - default: { - } - } -} - -void CustomPropertyEditor::_locale_selected(String p_locale) { - if (type == Variant::STRING && hint == PROPERTY_HINT_LOCALE_ID) { - v = p_locale; - emit_signal(SNAME("variant_changed")); - hide(); - } -} - -void CustomPropertyEditor::_type_create_selected(int p_idx) { - if (type == Variant::INT || type == Variant::FLOAT) { - float newval = 0; - switch (p_idx) { - case EASING_LINEAR: { - newval = 1; - } break; - case EASING_EASE_IN: { - newval = 2.0; - } break; - case EASING_EASE_OUT: { - newval = 0.5; - } break; - case EASING_ZERO: { - newval = 0; - } break; - case EASING_IN_OUT: { - newval = -0.5; - } break; - case EASING_OUT_IN: { - newval = -2.0; - } break; - } - - v = newval; - emit_signal(SNAME("variant_changed")); - easing_draw->update(); - - } else if (type == Variant::OBJECT) { - ERR_FAIL_INDEX(p_idx, inheritors_array.size()); - - String intype = inheritors_array[p_idx]; - - Variant obj = ClassDB::instantiate(intype); - - if (!obj) { - if (ScriptServer::is_global_class(intype)) { - obj = EditorNode::get_editor_data().script_class_instance(intype); - } else { - obj = EditorNode::get_editor_data().instance_custom_type(intype, "Resource"); - } - } - - ERR_FAIL_COND(!obj); - ERR_FAIL_COND(!Object::cast_to<Resource>(obj)); - - EditorNode::get_editor_data().instantiate_object_properties(obj); - v = obj; - - emit_signal(SNAME("variant_changed")); - hide(); - } -} - -void CustomPropertyEditor::_color_changed(const Color &p_color) { - v = p_color; - emit_signal(SNAME("variant_changed")); -} - -void CustomPropertyEditor::_node_path_selected(NodePath p_path) { - if (picking_viewport) { - Node *to_node = get_node(p_path); - if (!Object::cast_to<Viewport>(to_node)) { - EditorNode::get_singleton()->show_warning(TTR("Selected node is not a Viewport!")); - return; - } - - Ref<ViewportTexture> vt; - vt.instantiate(); - vt->set_viewport_path_in_scene(get_tree()->get_edited_scene_root()->get_path_to(to_node)); - vt->setup_local_to_scene(); - v = vt; - emit_signal(SNAME("variant_changed")); - return; - } - - if (hint == PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE && !hint_text.is_empty()) { - Node *node = get_node(hint_text); - if (node) { - Node *tonode = node->get_node(p_path); - if (tonode) { - p_path = node->get_path_to(tonode); - } - } - - } else if (owner) { - Node *node = nullptr; - - if (owner->is_class("Node")) { - node = Object::cast_to<Node>(owner); - } else if (owner->is_class("ArrayPropertyEdit")) { - node = Object::cast_to<ArrayPropertyEdit>(owner)->get_node(); - } else if (owner->is_class("DictionaryPropertyEdit")) { - node = Object::cast_to<DictionaryPropertyEdit>(owner)->get_node(); - } - if (!node) { - v = p_path; - emit_signal(SNAME("variant_changed")); - call_deferred(SNAME("hide")); //to not mess with dialogs - return; - } - - Node *tonode = node->get_node(p_path); - if (tonode) { - p_path = node->get_path_to(tonode); - } - } - - v = p_path; - emit_signal(SNAME("variant_changed")); - call_deferred(SNAME("hide")); //to not mess with dialogs -} - -void CustomPropertyEditor::_action_pressed(int p_which) { - if (updating) { - return; - } - - switch (type) { - case Variant::BOOL: { - v = checks20[0]->is_pressed(); - emit_signal(SNAME("variant_changed")); - } break; - case Variant::INT: { - if (hint == PROPERTY_HINT_LAYERS_2D_PHYSICS || - hint == PROPERTY_HINT_LAYERS_2D_RENDER || - hint == PROPERTY_HINT_LAYERS_2D_NAVIGATION || - hint == PROPERTY_HINT_LAYERS_3D_PHYSICS || - hint == PROPERTY_HINT_LAYERS_3D_RENDER || - hint == PROPERTY_HINT_LAYERS_3D_NAVIGATION) { - uint32_t f = v; - if (checks20[p_which]->is_pressed()) { - f |= (1 << p_which); - } else { - f &= ~(1 << p_which); - } - - v = f; - emit_signal(SNAME("variant_changed")); - } - - } break; - case Variant::STRING: { - if (hint == PROPERTY_HINT_MULTILINE_TEXT) { - hide(); - } else if (hint == PROPERTY_HINT_LOCALE_ID) { - locale->popup_locale_dialog(); - } else if (hint == PROPERTY_HINT_FILE || hint == PROPERTY_HINT_GLOBAL_FILE) { - if (p_which == 0) { - if (hint == PROPERTY_HINT_FILE) { - file->set_access(EditorFileDialog::ACCESS_RESOURCES); - } else { - file->set_access(EditorFileDialog::ACCESS_FILESYSTEM); - } - - file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); - file->clear_filters(); - - file->clear_filters(); - - if (!hint_text.is_empty()) { - Vector<String> extensions = hint_text.split(","); - for (int i = 0; i < extensions.size(); i++) { - String filter = extensions[i]; - if (filter.begins_with(".")) { - filter = "*" + extensions[i]; - } else if (!filter.begins_with("*")) { - filter = "*." + extensions[i]; - } - - file->add_filter(filter, extensions[i].to_upper()); - } - } - file->popup_file_dialog(); - } else { - v = ""; - emit_signal(SNAME("variant_changed")); - hide(); - } - - } else if (hint == PROPERTY_HINT_DIR || hint == PROPERTY_HINT_GLOBAL_DIR) { - if (p_which == 0) { - if (hint == PROPERTY_HINT_DIR) { - file->set_access(EditorFileDialog::ACCESS_RESOURCES); - } else { - file->set_access(EditorFileDialog::ACCESS_FILESYSTEM); - } - file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_DIR); - file->clear_filters(); - file->popup_file_dialog(); - } else { - v = ""; - emit_signal(SNAME("variant_changed")); - hide(); - } - } - - } break; - case Variant::NODE_PATH: { - if (p_which == 0) { - picking_viewport = false; - scene_tree->set_title(TTR("Pick a Node")); - scene_tree->popup_scenetree_dialog(); - - } else if (p_which == 1) { - v = NodePath(); - emit_signal(SNAME("variant_changed")); - hide(); - } else if (p_which == 2) { - if (owner->is_class("Node") && (v.get_type() == Variant::NODE_PATH) && Object::cast_to<Node>(owner)->has_node(v)) { - Node *target_node = Object::cast_to<Node>(owner)->get_node(v); - EditorNode::get_singleton()->get_editor_selection()->clear(); - SceneTreeDock::get_singleton()->set_selected(target_node); - } - - hide(); - } - - } break; - case Variant::OBJECT: { - if (p_which == 0) { - ERR_FAIL_COND(inheritors_array.is_empty()); - - String intype = inheritors_array[0]; - - if (hint == PROPERTY_HINT_RESOURCE_TYPE) { - Variant obj = ClassDB::instantiate(intype); - - if (!obj) { - if (ScriptServer::is_global_class(intype)) { - obj = EditorNode::get_editor_data().script_class_instance(intype); - } else { - obj = EditorNode::get_editor_data().instance_custom_type(intype, "Resource"); - } - } - - ERR_BREAK(!obj); - ERR_BREAK(!Object::cast_to<Resource>(obj)); - - EditorNode::get_editor_data().instantiate_object_properties(obj); - v = obj; - - emit_signal(SNAME("variant_changed")); - hide(); - } - } else if (p_which == 1) { - file->set_access(EditorFileDialog::ACCESS_RESOURCES); - file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); - List<String> extensions; - String type = (hint == PROPERTY_HINT_RESOURCE_TYPE) ? hint_text : String(); - - ResourceLoader::get_recognized_extensions_for_type(type, &extensions); - file->clear_filters(); - for (const String &E : extensions) { - file->add_filter("*." + E, E.to_upper()); - } - - file->popup_file_dialog(); - - } else if (p_which == 2) { - Ref<Resource> r = v; - - if (!r.is_null()) { - emit_signal(SNAME("resource_edit_request")); - hide(); - } - - } else if (p_which == 3) { - v = Variant(); - emit_signal(SNAME("variant_changed")); - hide(); - } else if (p_which == 4) { - Ref<Resource> res_orig = v; - if (res_orig.is_null()) { - return; - } - - List<PropertyInfo> property_list; - res_orig->get_property_list(&property_list); - List<Pair<String, Variant>> propvalues; - - for (const PropertyInfo &pi : property_list) { - Pair<String, Variant> p; - if (pi.usage & PROPERTY_USAGE_STORAGE) { - p.first = pi.name; - p.second = res_orig->get(pi.name); - } - - propvalues.push_back(p); - } - - Ref<Resource> res = Ref<Resource>(ClassDB::instantiate(res_orig->get_class())); - - ERR_FAIL_COND(res.is_null()); - - for (const Pair<String, Variant> &p : propvalues) { - res->set(p.first, p.second); - } - - v = res; - emit_signal(SNAME("variant_changed")); - hide(); - } - - } break; - - default: { - }; - } -} - -void CustomPropertyEditor::_drag_easing(const Ref<InputEvent> &p_ev) { - Ref<InputEventMouseMotion> mm = p_ev; - - if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { - float rel = mm->get_relative().x; - if (rel == 0) { - return; - } - - bool flip = hint_text == "attenuation"; - - if (flip) { - rel = -rel; - } - - float val = v; - if (val == 0) { - return; - } - bool sg = val < 0; - val = Math::absf(val); - - val = Math::log(val) / Math::log((float)2.0); - //logspace - val += rel * 0.05; - - val = Math::pow(2.0f, val); - if (sg) { - val = -val; - } - - v = val; - easing_draw->update(); - emit_signal(SNAME("variant_changed")); - } -} - -void CustomPropertyEditor::_draw_easing() { - RID ci = easing_draw->get_canvas_item(); - - Size2 s = easing_draw->get_size(); - Rect2 r(Point2(), s); - r = r.grow(3); - easing_draw->get_theme_stylebox(SNAME("normal"), SNAME("LineEdit"))->draw(ci, r); - - int points = 48; - - float prev = 1.0; - float exp = v; - bool flip = hint_text == "attenuation"; - - Ref<Font> f = easing_draw->get_theme_font(SNAME("font"), SNAME("Label")); - int font_size = easing_draw->get_theme_font_size(SNAME("font_size"), SNAME("Label")); - Color color = easing_draw->get_theme_color(SNAME("font_color"), SNAME("Label")); - - for (int i = 1; i <= points; i++) { - float ifl = i / float(points); - float iflp = (i - 1) / float(points); - - float h = 1.0 - Math::ease(ifl, exp); - - if (flip) { - ifl = 1.0 - ifl; - iflp = 1.0 - iflp; - } - - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2(iflp * s.width, prev * s.height), Point2(ifl * s.width, h * s.height), color); - prev = h; - } - - f->draw_string(ci, Point2(10, 10 + f->get_ascent(font_size)), String::num(exp, 2), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, color); -} - -void CustomPropertyEditor::_text_edit_changed() { - v = text_edit->get_text(); - emit_signal(SNAME("variant_changed")); -} - -void CustomPropertyEditor::_create_dialog_callback() { - v = create_dialog->get_selected_type(); - emit_signal(SNAME("variant_changed")); -} - -void CustomPropertyEditor::_create_selected_property(const String &p_prop) { - v = p_prop; - emit_signal(SNAME("variant_changed")); -} - -void CustomPropertyEditor::_modified(String p_string) { - if (updating) { - return; - } - - Variant prev_v = v; - - updating = true; - switch (type) { - case Variant::INT: { - String text = TS->parse_number(value_editor[0]->get_text()); - Ref<Expression> expr; - expr.instantiate(); - Error err = expr->parse(text); - if (err != OK) { - v = value_editor[0]->get_text().to_int(); - return; - } else { - v = expr->execute(Array(), nullptr, false, false); - } - - if (v != prev_v) { - emit_signal(SNAME("variant_changed")); - } - } break; - case Variant::FLOAT: { - if (hint != PROPERTY_HINT_EXP_EASING) { - String text = TS->parse_number(value_editor[0]->get_text()); - v = _parse_real_expression(text); - if (v != prev_v) { - emit_signal(SNAME("variant_changed")); - } - } - - } break; - case Variant::STRING: { - v = value_editor[0]->get_text(); - emit_signal(SNAME("variant_changed")); - } break; - case Variant::VECTOR2: { - Vector2 vec; - vec.x = _parse_real_expression(value_editor[0]->get_text()); - vec.y = _parse_real_expression(value_editor[1]->get_text()); - v = vec; - if (v != prev_v) { - _emit_changed_whole_or_field(); - } - - } break; - case Variant::RECT2: { - Rect2 r2; - - r2.position.x = _parse_real_expression(value_editor[0]->get_text()); - r2.position.y = _parse_real_expression(value_editor[1]->get_text()); - r2.size.x = _parse_real_expression(value_editor[2]->get_text()); - r2.size.y = _parse_real_expression(value_editor[3]->get_text()); - v = r2; - if (v != prev_v) { - _emit_changed_whole_or_field(); - } - - } break; - - case Variant::VECTOR3: { - Vector3 vec; - vec.x = _parse_real_expression(value_editor[0]->get_text()); - vec.y = _parse_real_expression(value_editor[1]->get_text()); - vec.z = _parse_real_expression(value_editor[2]->get_text()); - v = vec; - if (v != prev_v) { - _emit_changed_whole_or_field(); - } - - } break; - case Variant::PLANE: { - Plane pl; - pl.normal.x = _parse_real_expression(value_editor[0]->get_text()); - pl.normal.y = _parse_real_expression(value_editor[1]->get_text()); - pl.normal.z = _parse_real_expression(value_editor[2]->get_text()); - pl.d = _parse_real_expression(value_editor[3]->get_text()); - v = pl; - if (v != prev_v) { - _emit_changed_whole_or_field(); - } - - } break; - case Variant::QUATERNION: { - Quaternion q; - q.x = _parse_real_expression(value_editor[0]->get_text()); - q.y = _parse_real_expression(value_editor[1]->get_text()); - q.z = _parse_real_expression(value_editor[2]->get_text()); - q.w = _parse_real_expression(value_editor[3]->get_text()); - v = q; - if (v != prev_v) { - _emit_changed_whole_or_field(); - } - - } break; - case Variant::AABB: { - Vector3 pos; - Vector3 size; - - pos.x = _parse_real_expression(value_editor[0]->get_text()); - pos.y = _parse_real_expression(value_editor[1]->get_text()); - pos.z = _parse_real_expression(value_editor[2]->get_text()); - size.x = _parse_real_expression(value_editor[3]->get_text()); - size.y = _parse_real_expression(value_editor[4]->get_text()); - size.z = _parse_real_expression(value_editor[5]->get_text()); - v = AABB(pos, size); - if (v != prev_v) { - _emit_changed_whole_or_field(); - } - - } break; - case Variant::TRANSFORM2D: { - Transform2D m; - for (int i = 0; i < 6; i++) { - m.columns[i / 2][i % 2] = _parse_real_expression(value_editor[i]->get_text()); - } - - v = m; - if (v != prev_v) { - _emit_changed_whole_or_field(); - } - - } break; - case Variant::BASIS: { - Basis m; - for (int i = 0; i < 9; i++) { - m.rows[i / 3][i % 3] = _parse_real_expression(value_editor[i]->get_text()); - } - - v = m; - if (v != prev_v) { - _emit_changed_whole_or_field(); - } - - } break; - case Variant::TRANSFORM3D: { - Basis basis; - for (int i = 0; i < 9; i++) { - basis.rows[i / 3][i % 3] = _parse_real_expression(value_editor[(i / 3) * 4 + i % 3]->get_text()); - } - - Vector3 origin; - - origin.x = _parse_real_expression(value_editor[3]->get_text()); - origin.y = _parse_real_expression(value_editor[7]->get_text()); - origin.z = _parse_real_expression(value_editor[11]->get_text()); - - v = Transform3D(basis, origin); - if (v != prev_v) { - _emit_changed_whole_or_field(); - } - - } break; - case Variant::COLOR: { - } break; - - case Variant::NODE_PATH: { - v = NodePath(value_editor[0]->get_text()); - if (v != prev_v) { - emit_signal(SNAME("variant_changed")); - } - } break; - case Variant::DICTIONARY: { - } break; - case Variant::PACKED_BYTE_ARRAY: { - } break; - case Variant::PACKED_INT32_ARRAY: { - } break; - case Variant::PACKED_FLOAT32_ARRAY: { - } break; - case Variant::PACKED_STRING_ARRAY: { - } break; - case Variant::PACKED_VECTOR3_ARRAY: { - } break; - case Variant::PACKED_COLOR_ARRAY: { - } break; - default: { - } - } - - updating = false; -} - -real_t CustomPropertyEditor::_parse_real_expression(String text) { - Ref<Expression> expr; - expr.instantiate(); - Error err = expr->parse(text); - real_t out; - if (err != OK) { - out = value_editor[0]->get_text().to_float(); - } else { - out = expr->execute(Array(), nullptr, false, true); - } - return out; -} - -void CustomPropertyEditor::_emit_changed_whole_or_field() { - if (!Input::get_singleton()->is_key_pressed(Key::SHIFT)) { - emit_signal(SNAME("variant_changed")); - } else { - emit_signal(SNAME("variant_field_changed"), field_names[focused_value_editor]); - } -} - -void CustomPropertyEditor::_range_modified(double p_value) { - v = p_value; - emit_signal(SNAME("variant_changed")); -} - -void CustomPropertyEditor::_focus_enter() { - switch (type) { - case Variant::FLOAT: - case Variant::STRING: - case Variant::VECTOR2: - case Variant::RECT2: - case Variant::VECTOR3: - case Variant::PLANE: - case Variant::QUATERNION: - case Variant::AABB: - case Variant::TRANSFORM2D: - case Variant::BASIS: - case Variant::TRANSFORM3D: { - for (int i = 0; i < MAX_VALUE_EDITORS; ++i) { - if (value_editor[i]->has_focus()) { - focused_value_editor = i; - value_editor[i]->select_all(); - break; - } - } - } break; - default: { - } - } -} - -void CustomPropertyEditor::_focus_exit() { - _modified(String()); -} - -void CustomPropertyEditor::config_action_buttons(const List<String> &p_strings) { - Ref<StyleBox> sb = action_buttons[0]->get_theme_stylebox(SNAME("button")); - int margin_top = sb->get_margin(SIDE_TOP); - int margin_left = sb->get_margin(SIDE_LEFT); - int margin_bottom = sb->get_margin(SIDE_BOTTOM); - int margin_right = sb->get_margin(SIDE_RIGHT); - - int max_width = 0; - int height = 0; - - for (int i = 0; i < MAX_ACTION_BUTTONS; i++) { - if (i < p_strings.size()) { - action_buttons[i]->show(); - action_buttons[i]->set_text(p_strings[i]); - - Size2 btn_m_size = action_buttons[i]->get_minimum_size(); - if (btn_m_size.width > max_width) { - max_width = btn_m_size.width; - } - - } else { - action_buttons[i]->hide(); - } - } - - for (int i = 0; i < p_strings.size(); i++) { - Size2 btn_m_size = action_buttons[i]->get_size(); - action_buttons[i]->set_position(Point2(0, height) + Point2(margin_left, margin_top)); - action_buttons[i]->set_size(Size2(max_width, btn_m_size.height)); - - height += btn_m_size.height; - } - set_size(Size2(max_width, height) + Size2(margin_left + margin_right, margin_top + margin_bottom)); -} - -void CustomPropertyEditor::config_value_editors(int p_amount, int p_columns, int p_label_w, const List<String> &p_strings) { - int cell_width = 95; - int cell_height = 25; - int cell_margin = 5; - int rows = ((p_amount - 1) / p_columns) + 1; - - set_size(Size2(cell_margin + p_label_w + (cell_width + cell_margin + p_label_w) * p_columns, cell_margin + (cell_height + cell_margin) * rows) * EDSCALE); - - for (int i = 0; i < MAX_VALUE_EDITORS; i++) { - value_label[i]->get_parent()->remove_child(value_label[i]); - value_editor[i]->get_parent()->remove_child(value_editor[i]); - - int box_id = i / p_columns; - value_hboxes[box_id]->add_child(value_label[i]); - value_hboxes[box_id]->add_child(value_editor[i]); - - if (i < MAX_VALUE_EDITORS / 4) { - if (i <= p_amount / 4) { - value_hboxes[i]->show(); - } else { - value_hboxes[i]->hide(); - } - } - - if (i < p_amount) { - value_editor[i]->show(); - value_label[i]->show(); - value_label[i]->set_text(i < p_strings.size() ? p_strings[i] : String("")); - value_editor[i]->set_editable(!read_only); - } else { - value_editor[i]->hide(); - value_label[i]->hide(); - } - } -} - -void CustomPropertyEditor::_bind_methods() { - ADD_SIGNAL(MethodInfo("variant_changed")); - ADD_SIGNAL(MethodInfo("variant_field_changed", PropertyInfo(Variant::STRING, "field"))); - ADD_SIGNAL(MethodInfo("resource_edit_request")); -} - -CustomPropertyEditor::CustomPropertyEditor() { - value_vbox = memnew(VBoxContainer); - add_child(value_vbox); - - for (int i = 0; i < MAX_VALUE_EDITORS; i++) { - if (i < MAX_VALUE_EDITORS / 4) { - value_hboxes[i] = memnew(HBoxContainer); - value_vbox->add_child(value_hboxes[i]); - value_hboxes[i]->hide(); - } - int hbox_idx = i / 4; - value_label[i] = memnew(Label); - value_hboxes[hbox_idx]->add_child(value_label[i]); - value_label[i]->hide(); - value_editor[i] = memnew(LineEdit); - value_hboxes[hbox_idx]->add_child(value_editor[i]); - value_editor[i]->set_h_size_flags(Control::SIZE_EXPAND_FILL); - value_editor[i]->hide(); - value_editor[i]->connect("text_submitted", callable_mp(this, &CustomPropertyEditor::_modified)); - value_editor[i]->connect("focus_entered", callable_mp(this, &CustomPropertyEditor::_focus_enter)); - value_editor[i]->connect("focus_exited", callable_mp(this, &CustomPropertyEditor::_focus_exit)); - } - focused_value_editor = -1; - - for (int i = 0; i < 4; i++) { - scroll[i] = memnew(HScrollBar); - scroll[i]->hide(); - scroll[i]->set_min(0); - scroll[i]->set_max(1.0); - scroll[i]->set_step(0.01); - add_child(scroll[i]); - } - - checks20gc = memnew(GridContainer); - add_child(checks20gc); - checks20gc->set_columns(11); - - for (int i = 0; i < 20; i++) { - if (i == 5 || i == 15) { - Control *space = memnew(Control); - space->set_custom_minimum_size(Size2(20, 0) * EDSCALE); - checks20gc->add_child(space); - } - - checks20[i] = memnew(CheckBox); - checks20[i]->set_toggle_mode(true); - checks20[i]->set_focus_mode(Control::FOCUS_NONE); - checks20gc->add_child(checks20[i]); - checks20[i]->hide(); - checks20[i]->connect("pressed", callable_mp(this, &CustomPropertyEditor::_action_pressed).bind(i)); - checks20[i]->set_tooltip(vformat(TTR("Bit %d, val %d."), i, 1 << i)); - } - - text_edit = memnew(TextEdit); - value_vbox->add_child(text_edit); - text_edit->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, 5); - text_edit->set_v_size_flags(Control::SIZE_EXPAND_FILL); - text_edit->set_offset(SIDE_BOTTOM, -30); - - text_edit->hide(); - text_edit->connect("text_changed", callable_mp(this, &CustomPropertyEditor::_text_edit_changed)); - - color_picker = nullptr; - - file = memnew(EditorFileDialog); - value_vbox->add_child(file); - file->hide(); - - file->connect("file_selected", callable_mp(this, &CustomPropertyEditor::_file_selected)); - file->connect("dir_selected", callable_mp(this, &CustomPropertyEditor::_file_selected)); - - locale = memnew(EditorLocaleDialog); - value_vbox->add_child(locale); - locale->hide(); - - locale->connect("locale_selected", callable_mp(this, &CustomPropertyEditor::_locale_selected)); - - error = memnew(ConfirmationDialog); - error->set_title(TTR("Error!")); - value_vbox->add_child(error); - - scene_tree = memnew(SceneTreeDialog); - value_vbox->add_child(scene_tree); - scene_tree->connect("selected", callable_mp(this, &CustomPropertyEditor::_node_path_selected)); - scene_tree->get_scene_tree()->set_show_enabled_subscene(true); - - texture_preview = memnew(TextureRect); - value_vbox->add_child(texture_preview); - texture_preview->hide(); - - easing_draw = memnew(Control); - value_vbox->add_child(easing_draw); - easing_draw->hide(); - easing_draw->connect("draw", callable_mp(this, &CustomPropertyEditor::_draw_easing)); - easing_draw->connect("gui_input", callable_mp(this, &CustomPropertyEditor::_drag_easing)); - easing_draw->set_default_cursor_shape(Control::CURSOR_MOVE); - - type_button = memnew(MenuButton); - value_vbox->add_child(type_button); - type_button->hide(); - type_button->get_popup()->connect("id_pressed", callable_mp(this, &CustomPropertyEditor::_type_create_selected)); - - menu = memnew(PopupMenu); - // menu->set_pass_on_modal_close_click(false); - value_vbox->add_child(menu); - menu->connect("id_pressed", callable_mp(this, &CustomPropertyEditor::_menu_option)); - - evaluator = nullptr; - - spinbox = memnew(SpinBox); - value_vbox->add_child(spinbox); - spinbox->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, 5); - spinbox->connect("value_changed", callable_mp(this, &CustomPropertyEditor::_range_modified)); - - slider = memnew(HSlider); - value_vbox->add_child(slider); - slider->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, 5); - slider->connect("value_changed", callable_mp(this, &CustomPropertyEditor::_range_modified)); - - action_hboxes = memnew(HBoxContainer); - action_hboxes->set_alignment(BoxContainer::ALIGNMENT_CENTER); - value_vbox->add_child(action_hboxes); - for (int i = 0; i < MAX_ACTION_BUTTONS; i++) { - action_buttons[i] = memnew(Button); - action_buttons[i]->hide(); - action_hboxes->add_child(action_buttons[i]); - action_buttons[i]->connect("pressed", callable_mp(this, &CustomPropertyEditor::_action_pressed).bind(i)); - } - - create_dialog = nullptr; - property_select = nullptr; -} diff --git a/editor/property_editor.h b/editor/property_editor.h deleted file mode 100644 index 195eb89b81..0000000000 --- a/editor/property_editor.h +++ /dev/null @@ -1,168 +0,0 @@ -/*************************************************************************/ -/* property_editor.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 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 PROPERTY_EDITOR_H -#define PROPERTY_EDITOR_H - -#include "editor/editor_locale_dialog.h" -#include "editor/scene_tree_editor.h" -#include "scene/gui/button.h" -#include "scene/gui/check_box.h" -#include "scene/gui/check_button.h" -#include "scene/gui/color_picker.h" -#include "scene/gui/dialogs.h" -#include "scene/gui/grid_container.h" -#include "scene/gui/label.h" -#include "scene/gui/menu_button.h" -#include "scene/gui/split_container.h" -#include "scene/gui/text_edit.h" -#include "scene/gui/texture_rect.h" -#include "scene/gui/tree.h" - -class CreateDialog; -class EditorFileDialog; -class PropertyValueEvaluator; -class PropertySelector; - -class CustomPropertyEditor : public PopupPanel { - GDCLASS(CustomPropertyEditor, PopupPanel); - - enum { - MAX_VALUE_EDITORS = 12, - MAX_ACTION_BUTTONS = 5, - OBJ_MENU_LOAD = 0, - OBJ_MENU_EDIT = 1, - OBJ_MENU_CLEAR = 2, - OBJ_MENU_MAKE_UNIQUE = 3, - OBJ_MENU_COPY = 4, - OBJ_MENU_PASTE = 5, - OBJ_MENU_NEW_SCRIPT = 6, - OBJ_MENU_EXTEND_SCRIPT = 7, - OBJ_MENU_SHOW_IN_FILE_SYSTEM = 8, - TYPE_BASE_ID = 100, - CONVERT_BASE_ID = 1000 - }; - - enum { - EASING_LINEAR, - EASING_EASE_IN, - EASING_EASE_OUT, - EASING_ZERO, - EASING_IN_OUT, - EASING_OUT_IN - }; - - PopupMenu *menu = nullptr; - SceneTreeDialog *scene_tree = nullptr; - EditorFileDialog *file = nullptr; - EditorLocaleDialog *locale = nullptr; - ConfirmationDialog *error = nullptr; - String name; - Variant::Type type; - Variant v; - List<String> field_names; - int hint = 0; - String hint_text; - HBoxContainer *value_hboxes[MAX_VALUE_EDITORS / 4]; - VBoxContainer *value_vbox = nullptr; - LineEdit *value_editor[MAX_VALUE_EDITORS]; - int focused_value_editor; - Label *value_label[MAX_VALUE_EDITORS]; - HScrollBar *scroll[4]; - HBoxContainer *action_hboxes = nullptr; - Button *action_buttons[MAX_ACTION_BUTTONS]; - MenuButton *type_button = nullptr; - Vector<String> inheritors_array; - TextureRect *texture_preview = nullptr; - ColorPicker *color_picker = nullptr; - TextEdit *text_edit = nullptr; - bool read_only = false; - bool picking_viewport = false; - GridContainer *checks20gc = nullptr; - CheckBox *checks20[20]; - SpinBox *spinbox = nullptr; - HSlider *slider = nullptr; - - Control *easing_draw = nullptr; - CreateDialog *create_dialog = nullptr; - PropertySelector *property_select = nullptr; - - Object *owner = nullptr; - - bool updating = false; - - PropertyValueEvaluator *evaluator = nullptr; - - void _text_edit_changed(); - void _file_selected(String p_file); - void _locale_selected(String p_locale); - void _modified(String p_string); - - real_t _parse_real_expression(String text); - - void _range_modified(double p_value); - void _focus_enter(); - void _focus_exit(); - void _action_pressed(int p_which); - void _type_create_selected(int p_idx); - void _create_dialog_callback(); - void _create_selected_property(const String &p_prop); - - void _color_changed(const Color &p_color); - void _draw_easing(); - void _menu_option(int p_which); - - void _drag_easing(const Ref<InputEvent> &p_ev); - - void _node_path_selected(NodePath p_path); - void show_value_editors(int p_amount); - void config_value_editors(int p_amount, int p_columns, int p_label_w, const List<String> &p_strings); - void config_action_buttons(const List<String> &p_strings); - - void _emit_changed_whole_or_field(); - -protected: - void _notification(int p_what); - static void _bind_methods(); - -public: - void hide_menu(); - - Variant get_variant() const; - String get_name() const; - - void set_read_only(bool p_read_only) { read_only = p_read_only; } - - bool edit(Object *p_owner, const String &p_name, Variant::Type p_type, const Variant &p_variant, int p_hint, String p_hint_text); - - CustomPropertyEditor(); -}; - -#endif // PROPERTY_EDITOR_H diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index c74a4c884d..a77687677b 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -375,7 +375,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { } if (p_node->has_meta("_edit_group_")) { - item->add_button(0, get_theme_icon(SNAME("Group"), SNAME("EditorIcons")), BUTTON_GROUP, false, TTR("Children are not selectable.\nClick to make selectable.")); + item->add_button(0, get_theme_icon(SNAME("Group"), SNAME("EditorIcons")), BUTTON_GROUP, false, TTR("Children are not selectable.\nClick to make them selectable.")); } bool v = p_node->call("is_visible"); @@ -407,7 +407,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { } if (p_node->has_meta("_edit_group_")) { - item->add_button(0, get_theme_icon(SNAME("Group"), SNAME("EditorIcons")), BUTTON_GROUP, false, TTR("Children are not selectable.\nClick to make selectable.")); + item->add_button(0, get_theme_icon(SNAME("Group"), SNAME("EditorIcons")), BUTTON_GROUP, false, TTR("Children are not selectable.\nClick to make them selectable.")); } bool v = p_node->call("is_visible"); |