diff options
Diffstat (limited to 'editor')
-rw-r--r-- | editor/editor_inspector.cpp | 93 | ||||
-rw-r--r-- | editor/editor_inspector.h | 15 | ||||
-rw-r--r-- | editor/editor_node.cpp | 5 | ||||
-rw-r--r-- | editor/editor_properties.cpp | 334 | ||||
-rw-r--r-- | editor/editor_properties.h | 58 | ||||
-rw-r--r-- | editor/editor_properties_array_dict.cpp | 21 | ||||
-rw-r--r-- | editor/plugins/root_motion_editor_plugin.cpp | 2 | ||||
-rw-r--r-- | editor/plugins/root_motion_editor_plugin.h | 2 | ||||
-rw-r--r-- | editor/plugins/shader_editor_plugin.cpp | 10 | ||||
-rw-r--r-- | editor/plugins/style_box_editor_plugin.cpp | 2 | ||||
-rw-r--r-- | editor/plugins/style_box_editor_plugin.h | 2 | ||||
-rw-r--r-- | editor/plugins/visual_shader_editor_plugin.cpp | 10 | ||||
-rw-r--r-- | editor/plugins/visual_shader_editor_plugin.h | 2 | ||||
-rw-r--r-- | editor/project_settings_editor.cpp | 5 | ||||
-rw-r--r-- | editor/project_settings_editor.h | 2 | ||||
-rw-r--r-- | editor/shader_globals_editor.cpp | 452 | ||||
-rw-r--r-- | editor/shader_globals_editor.h | 38 |
17 files changed, 1019 insertions, 34 deletions
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index a0f8b59117..8fcd5bacb6 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -66,6 +66,11 @@ Size2 EditorProperty::get_minimum_size() const { ms.width += key->get_width() + get_theme_constant("hseparator", "Tree"); } + if (deletable) { + Ref<Texture2D> key = get_theme_icon("Close", "EditorIcons"); + ms.width += key->get_width() + get_theme_constant("hseparator", "Tree"); + } + if (checkable) { Ref<Texture2D> check = get_theme_icon("checked", "CheckBox"); ms.width += check->get_width() + get_theme_constant("hseparation", "CheckBox") + get_theme_constant("hseparator", "Tree"); @@ -154,6 +159,18 @@ void EditorProperty::_notification(int p_what) { text_size -= key->get_width() + 4 * EDSCALE; } } + + if (deletable) { + Ref<Texture2D> close; + + close = get_theme_icon("Close", "EditorIcons"); + + rect.size.x -= close->get_width() + get_theme_constant("hseparator", "Tree"); + + if (no_children) { + text_size -= close->get_width() + 4 * EDSCALE; + } + } } //set children @@ -278,6 +295,25 @@ void EditorProperty::_notification(int p_what) { } else { keying_rect = Rect2(); } + + if (deletable) { + Ref<Texture2D> close; + + close = get_theme_icon("Close", "EditorIcons"); + + ofs = size.width - close->get_width() - get_theme_constant("hseparator", "Tree"); + + Color color2(1, 1, 1); + if (delete_hover) { + color2.r *= 1.2; + color2.g *= 1.2; + color2.b *= 1.2; + } + delete_rect = Rect2(ofs, ((size.height - close->get_height()) / 2), close->get_width(), close->get_height()); + draw_texture(close, delete_rect.position, color2); + } else { + delete_rect = Rect2(); + } } } @@ -547,6 +583,16 @@ void EditorProperty::set_keying(bool p_keying) { queue_sort(); } +void EditorProperty::set_deletable(bool p_deletable) { + deletable = p_deletable; + update(); + queue_sort(); +} + +bool EditorProperty::is_deletable() const { + return deletable; +} + bool EditorProperty::is_keying() const { return keying; } @@ -619,6 +665,12 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) { update(); } + bool new_delete_hover = delete_rect.has_point(me->get_position()) && !button_left; + if (new_delete_hover != delete_hover) { + delete_hover = new_delete_hover; + update(); + } + bool new_revert_hover = revert_rect.has_point(me->get_position()) && !button_left; if (new_revert_hover != revert_hover) { revert_hover = new_revert_hover; @@ -662,6 +714,9 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) { call_deferred("update_property"); } } + if (delete_rect.has_point(mb->get_position())) { + emit_signal("property_deleted", property); + } if (revert_rect.has_point(mb->get_position())) { @@ -821,6 +876,9 @@ void EditorProperty::_bind_methods() { ClassDB::bind_method(D_METHOD("set_keying", "keying"), &EditorProperty::set_keying); ClassDB::bind_method(D_METHOD("is_keying"), &EditorProperty::is_keying); + ClassDB::bind_method(D_METHOD("set_deletable", "deletable"), &EditorProperty::set_deletable); + ClassDB::bind_method(D_METHOD("is_deletable"), &EditorProperty::is_deletable); + ClassDB::bind_method(D_METHOD("get_edited_property"), &EditorProperty::get_edited_property); ClassDB::bind_method(D_METHOD("get_edited_object"), &EditorProperty::get_edited_object); @@ -839,9 +897,11 @@ void EditorProperty::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "checked"), "set_checked", "is_checked"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_red"), "set_draw_red", "is_draw_red"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keying"), "set_keying", "is_keying"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deletable"), "set_deletable", "is_deletable"); ADD_SIGNAL(MethodInfo("property_changed", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT))); ADD_SIGNAL(MethodInfo("multiple_properties_changed", PropertyInfo(Variant::PACKED_STRING_ARRAY, "properties"), PropertyInfo(Variant::ARRAY, "value"))); ADD_SIGNAL(MethodInfo("property_keyed", PropertyInfo(Variant::STRING_NAME, "property"))); + ADD_SIGNAL(MethodInfo("property_deleted", PropertyInfo(Variant::STRING_NAME, "property"))); ADD_SIGNAL(MethodInfo("property_keyed_with_value", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT))); ADD_SIGNAL(MethodInfo("property_checked", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::STRING, "bool"))); ADD_SIGNAL(MethodInfo("resource_selected", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource"))); @@ -865,6 +925,7 @@ EditorProperty::EditorProperty() { checked = false; draw_red = false; keying = false; + deletable = false; keying_hover = false; revert_hover = false; check_hover = false; @@ -926,7 +987,7 @@ void EditorInspectorPlugin::parse_category(Object *p_object, const String &p_par } } -bool EditorInspectorPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) { +bool EditorInspectorPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) { if (get_script_instance()) { Variant arg[6] = { @@ -1276,11 +1337,11 @@ EditorInspectorSection::~EditorInspectorSection() { Ref<EditorInspectorPlugin> EditorInspector::inspector_plugins[MAX_PLUGINS]; int EditorInspector::inspector_plugin_count = 0; -EditorProperty *EditorInspector::instantiate_property_editor(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) { +EditorProperty *EditorInspector::instantiate_property_editor(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) { for (int i = inspector_plugin_count - 1; i >= 0; i--) { - inspector_plugins[i]->parse_property(p_object, p_type, p_path, p_hint, p_hint_text, p_usage); + inspector_plugins[i]->parse_property(p_object, p_type, p_path, p_hint, p_hint_text, p_usage, p_wide); if (inspector_plugins[i]->added_editors.size()) { for (int j = 1; j < inspector_plugins[i]->added_editors.size(); j++) { //only keep first one memdelete(inspector_plugins[i]->added_editors[j].property_editor); @@ -1362,6 +1423,7 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit ep->object = object; ep->connect("property_changed", callable_mp(this, &EditorInspector::_property_changed)); ep->connect("property_keyed", callable_mp(this, &EditorInspector::_property_keyed)); + ep->connect("property_deleted", callable_mp(this, &EditorInspector::_property_deleted), varray(), CONNECT_DEFERRED); ep->connect("property_keyed_with_value", callable_mp(this, &EditorInspector::_property_keyed_with_value)); ep->connect("property_checked", callable_mp(this, &EditorInspector::_property_checked)); ep->connect("selected", callable_mp(this, &EditorInspector::_property_selected)); @@ -1394,6 +1456,7 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit ep->set_read_only(read_only); ep->update_property(); ep->update_reload_status(); + ep->set_deletable(deletable_properties); } } ped->added_editors.clear(); @@ -1762,7 +1825,7 @@ void EditorInspector::update_tree() { for (List<Ref<EditorInspectorPlugin>>::Element *E = valid_plugins.front(); E; E = E->next()) { Ref<EditorInspectorPlugin> ped = E->get(); - bool exclusive = ped->parse_property(object, p.type, p.name, p.hint, p.hint_string, p.usage); + bool exclusive = ped->parse_property(object, p.type, p.name, p.hint, p.hint_string, p.usage, wide_editors); List<EditorInspectorPlugin::AddedEditor> editors = ped->added_editors; //make a copy, since plugins may be used again in a sub-inspector ped->added_editors.clear(); @@ -1806,6 +1869,7 @@ void EditorInspector::update_tree() { ep->set_keying(keying); ep->set_read_only(read_only); + ep->set_deletable(deletable_properties); } current_vbox->add_child(F->get().property_editor); @@ -1817,6 +1881,7 @@ void EditorInspector::update_tree() { ep->connect("property_changed", callable_mp(this, &EditorInspector::_property_changed_update_all), varray(), CONNECT_DEFERRED); } ep->connect("property_keyed", callable_mp(this, &EditorInspector::_property_keyed)); + ep->connect("property_deleted", callable_mp(this, &EditorInspector::_property_deleted), varray(), CONNECT_DEFERRED); ep->connect("property_keyed_with_value", callable_mp(this, &EditorInspector::_property_keyed_with_value)); ep->connect("property_checked", callable_mp(this, &EditorInspector::_property_checked)); ep->connect("selected", callable_mp(this, &EditorInspector::_property_selected)); @@ -2000,6 +2065,10 @@ int EditorInspector::get_scroll_offset() const { return get_v_scroll(); } +void EditorInspector::set_use_wide_editors(bool p_enable) { + wide_editors = p_enable; +} + void EditorInspector::set_sub_inspector(bool p_enable) { sub_inspector = p_enable; @@ -2013,6 +2082,10 @@ void EditorInspector::set_sub_inspector(bool p_enable) { } } +void EditorInspector::set_use_deletable_properties(bool p_enabled) { + deletable_properties = p_enabled; +} + void EditorInspector::_edit_request_change(Object *p_object, const String &p_property) { if (object != p_object) //may be undoing/redoing for a non edited object, so ignore @@ -2145,6 +2218,15 @@ void EditorInspector::_property_keyed(const String &p_path, bool p_advance) { emit_signal("property_keyed", p_path, object->get(p_path), p_advance); //second param is deprecated } +void EditorInspector::_property_deleted(const String &p_path) { + + print_line("deleted pressed?"); + if (!object) + return; + + emit_signal("property_deleted", p_path); //second param is deprecated +} + void EditorInspector::_property_keyed_with_value(const String &p_path, const Variant &p_value, bool p_advance) { if (!object) @@ -2348,6 +2430,7 @@ void EditorInspector::_bind_methods() { ADD_SIGNAL(MethodInfo("property_selected", PropertyInfo(Variant::STRING, "property"))); ADD_SIGNAL(MethodInfo("property_keyed", PropertyInfo(Variant::STRING, "property"))); + ADD_SIGNAL(MethodInfo("property_deleted", PropertyInfo(Variant::STRING, "property"))); ADD_SIGNAL(MethodInfo("resource_selected", PropertyInfo(Variant::OBJECT, "res"), PropertyInfo(Variant::STRING, "prop"))); ADD_SIGNAL(MethodInfo("object_id_selected", PropertyInfo(Variant::INT, "id"))); ADD_SIGNAL(MethodInfo("property_edited", PropertyInfo(Variant::STRING, "property"))); @@ -2365,6 +2448,7 @@ EditorInspector::EditorInspector() { set_enable_h_scroll(false); set_enable_v_scroll(true); + wide_editors = false; show_categories = false; hide_script = true; use_doc_hints = false; @@ -2383,6 +2467,7 @@ EditorInspector::EditorInspector() { set_process(true); property_focusable = -1; sub_inspector = false; + deletable_properties = false; get_v_scrollbar()->connect("value_changed", callable_mp(this, &EditorInspector::_vscroll_changed)); update_scroll_request = -1; diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index b49a4424f6..c8c1ecc49a 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -64,6 +64,7 @@ private: bool checked; bool draw_red; bool keying; + bool deletable; Rect2 right_child_rect; Rect2 bottom_child_rect; @@ -74,6 +75,8 @@ private: bool revert_hover; Rect2 check_rect; bool check_hover; + Rect2 delete_rect; + bool delete_hover; bool can_revert; @@ -133,6 +136,8 @@ public: void set_keying(bool p_keying); bool is_keying() const; + void set_deletable(bool p_enable); + bool is_deletable() const; void add_focusable(Control *p_control); void select(int p_focusable = -1); void deselect(); @@ -190,7 +195,7 @@ public: virtual bool can_handle(Object *p_object); virtual void parse_begin(Object *p_object); virtual void parse_category(Object *p_object, const String &p_parse_category); - virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage); + virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide = false); virtual void parse_end(); }; @@ -283,6 +288,8 @@ class EditorInspector : public ScrollContainer { bool read_only; bool keying; bool sub_inspector; + bool wide_editors; + bool deletable_properties; float refresh_countdown; bool update_tree_pending; @@ -307,6 +314,7 @@ class EditorInspector : public ScrollContainer { void _multiple_properties_changed(Vector<String> p_paths, Array p_values); void _property_keyed(const String &p_path, bool p_advance); void _property_keyed_with_value(const String &p_path, const Variant &p_value, bool p_advance); + void _property_deleted(const String &p_path); void _property_checked(const String &p_path, bool p_checked); @@ -337,7 +345,7 @@ public: static void remove_inspector_plugin(const Ref<EditorInspectorPlugin> &p_plugin); static void cleanup_plugins(); - static EditorProperty *instantiate_property_editor(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage); + static EditorProperty *instantiate_property_editor(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide = false); void set_undo_redo(UndoRedo *p_undo_redo); @@ -380,8 +388,11 @@ public: void set_object_class(const String &p_class); String get_object_class() const; + void set_use_wide_editors(bool p_enable); void set_sub_inspector(bool p_enable); + void set_use_deletable_properties(bool p_enabled); + EditorInspector(); }; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 6f6287ccb5..fddc5dc231 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -708,6 +708,11 @@ void EditorNode::_sources_changed(bool p_exist) { if (waiting_for_first_scan) { waiting_for_first_scan = false; + // Reload the global shader variables, but this time + // loading texures, as they are now properly imported. + print_line("done scanning, reload textures"); + RenderingServer::get_singleton()->global_variables_load_settings(true); + // Start preview thread now that it's safe. if (!singleton->cmdline_export_mode) { EditorResourcePreview::get_singleton()->start(); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index cf478f20e5..5213d7ec15 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -1150,12 +1150,15 @@ void EditorPropertyVector2::setup(double p_min, double p_max, double p_step, boo } } -EditorPropertyVector2::EditorPropertyVector2() { +EditorPropertyVector2::EditorPropertyVector2(bool p_force_wide) { bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector2_editing"); BoxContainer *bc; - if (horizontal) { + if (p_force_wide) { + bc = memnew(HBoxContainer); + add_child(bc); + } else if (horizontal) { bc = memnew(HBoxContainer); add_child(bc); set_bottom_editor(bc); @@ -1231,13 +1234,16 @@ void EditorPropertyRect2::setup(double p_min, double p_max, double p_step, bool } } -EditorPropertyRect2::EditorPropertyRect2() { +EditorPropertyRect2::EditorPropertyRect2(bool p_force_wide) { - bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); + bool horizontal = !p_force_wide && bool(EDITOR_GET("interface/inspector/horizontal_vector_types_editing")); BoxContainer *bc; - if (horizontal) { + if (p_force_wide) { + bc = memnew(HBoxContainer); + add_child(bc); + } else if (horizontal) { bc = memnew(HBoxContainer); add_child(bc); set_bottom_editor(bc); @@ -1311,12 +1317,15 @@ void EditorPropertyVector3::setup(double p_min, double p_max, double p_step, boo } } -EditorPropertyVector3::EditorPropertyVector3() { +EditorPropertyVector3::EditorPropertyVector3(bool p_force_wide) { bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); BoxContainer *bc; - if (horizontal) { + if (p_force_wide) { + bc = memnew(HBoxContainer); + add_child(bc); + } else if (horizontal) { bc = memnew(HBoxContainer); add_child(bc); set_bottom_editor(bc); @@ -1343,6 +1352,255 @@ EditorPropertyVector3::EditorPropertyVector3() { } setting = false; } + +///////////////////// VECTOR2i ///////////////////////// + +void EditorPropertyVector2i::_value_changed(double val, const String &p_name) { + if (setting) + return; + + Vector2i v2; + v2.x = spin[0]->get_value(); + v2.y = spin[1]->get_value(); + emit_changed(get_edited_property(), v2, p_name); +} + +void EditorPropertyVector2i::update_property() { + Vector2i val = get_edited_object()->get(get_edited_property()); + setting = true; + spin[0]->set_value(val.x); + spin[1]->set_value(val.y); + setting = false; +} + +void EditorPropertyVector2i::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + Color base = get_theme_color("accent_color", "Editor"); + for (int i = 0; i < 2; i++) { + + Color c = base; + c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v()); + spin[i]->set_custom_label_color(true, c); + } + } +} + +void EditorPropertyVector2i::_bind_methods() { +} + +void EditorPropertyVector2i::setup(int p_min, int p_max, bool p_no_slider) { + for (int i = 0; i < 2; i++) { + spin[i]->set_min(p_min); + spin[i]->set_max(p_max); + spin[i]->set_step(1); + spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_allow_greater(true); + spin[i]->set_allow_lesser(true); + } +} + +EditorPropertyVector2i::EditorPropertyVector2i(bool p_force_wide) { + bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector2_editing"); + + BoxContainer *bc; + + if (p_force_wide) { + bc = memnew(HBoxContainer); + add_child(bc); + } else if (horizontal) { + bc = memnew(HBoxContainer); + add_child(bc); + set_bottom_editor(bc); + } else { + bc = memnew(VBoxContainer); + add_child(bc); + } + + static const char *desc[2] = { "x", "y" }; + for (int i = 0; i < 2; i++) { + spin[i] = memnew(EditorSpinSlider); + spin[i]->set_flat(true); + spin[i]->set_label(desc[i]); + bc->add_child(spin[i]); + add_focusable(spin[i]); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyVector2i::_value_changed), varray(desc[i])); + if (horizontal) { + spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); + } + } + + if (!horizontal) { + set_label_reference(spin[0]); //show text and buttons around this + } + setting = false; +} + +///////////////////// RECT2 ///////////////////////// + +void EditorPropertyRect2i::_value_changed(double val, const String &p_name) { + if (setting) + return; + + Rect2i r2; + r2.position.x = spin[0]->get_value(); + r2.position.y = spin[1]->get_value(); + r2.size.x = spin[2]->get_value(); + r2.size.y = spin[3]->get_value(); + emit_changed(get_edited_property(), r2, p_name); +} + +void EditorPropertyRect2i::update_property() { + Rect2i val = get_edited_object()->get(get_edited_property()); + setting = true; + spin[0]->set_value(val.position.x); + spin[1]->set_value(val.position.y); + spin[2]->set_value(val.size.x); + spin[3]->set_value(val.size.y); + setting = false; +} +void EditorPropertyRect2i::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + Color base = get_theme_color("accent_color", "Editor"); + for (int i = 0; i < 4; i++) { + + Color c = base; + c.set_hsv(float(i % 2) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v()); + spin[i]->set_custom_label_color(true, c); + } + } +} +void EditorPropertyRect2i::_bind_methods() { +} + +void EditorPropertyRect2i::setup(int p_min, int p_max, bool p_no_slider) { + for (int i = 0; i < 4; i++) { + spin[i]->set_min(p_min); + spin[i]->set_max(p_max); + spin[i]->set_step(1); + spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_allow_greater(true); + spin[i]->set_allow_lesser(true); + } +} + +EditorPropertyRect2i::EditorPropertyRect2i(bool p_force_wide) { + + bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); + + BoxContainer *bc; + + if (p_force_wide) { + bc = memnew(HBoxContainer); + add_child(bc); + } else if (horizontal) { + bc = memnew(HBoxContainer); + add_child(bc); + set_bottom_editor(bc); + } else { + bc = memnew(VBoxContainer); + add_child(bc); + } + + static const char *desc[4] = { "x", "y", "w", "h" }; + for (int i = 0; i < 4; i++) { + spin[i] = memnew(EditorSpinSlider); + spin[i]->set_label(desc[i]); + spin[i]->set_flat(true); + bc->add_child(spin[i]); + add_focusable(spin[i]); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyRect2i::_value_changed), varray(desc[i])); + if (horizontal) { + spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); + } + } + + if (!horizontal) { + set_label_reference(spin[0]); //show text and buttons around this + } + setting = false; +} + +///////////////////// VECTOR3 ///////////////////////// + +void EditorPropertyVector3i::_value_changed(double val, const String &p_name) { + if (setting) + return; + + Vector3i v3; + v3.x = spin[0]->get_value(); + v3.y = spin[1]->get_value(); + v3.z = spin[2]->get_value(); + emit_changed(get_edited_property(), v3, p_name); +} + +void EditorPropertyVector3i::update_property() { + Vector3i val = get_edited_object()->get(get_edited_property()); + setting = true; + spin[0]->set_value(val.x); + spin[1]->set_value(val.y); + spin[2]->set_value(val.z); + setting = false; +} +void EditorPropertyVector3i::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + Color base = get_theme_color("accent_color", "Editor"); + for (int i = 0; i < 3; i++) { + + Color c = base; + c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v()); + spin[i]->set_custom_label_color(true, c); + } + } +} +void EditorPropertyVector3i::_bind_methods() { +} + +void EditorPropertyVector3i::setup(int p_min, int p_max, bool p_no_slider) { + for (int i = 0; i < 3; i++) { + spin[i]->set_min(p_min); + spin[i]->set_max(p_max); + spin[i]->set_step(1); + spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_allow_greater(true); + spin[i]->set_allow_lesser(true); + } +} + +EditorPropertyVector3i::EditorPropertyVector3i(bool p_force_wide) { + bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); + + BoxContainer *bc; + if (p_force_wide) { + bc = memnew(HBoxContainer); + add_child(bc); + } else if (horizontal) { + bc = memnew(HBoxContainer); + add_child(bc); + set_bottom_editor(bc); + } else { + bc = memnew(VBoxContainer); + add_child(bc); + } + + static const char *desc[3] = { "x", "y", "z" }; + for (int i = 0; i < 3; i++) { + spin[i] = memnew(EditorSpinSlider); + spin[i]->set_flat(true); + spin[i]->set_label(desc[i]); + bc->add_child(spin[i]); + add_focusable(spin[i]); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyVector3i::_value_changed), varray(desc[i])); + if (horizontal) { + spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); + } + } + + if (!horizontal) { + set_label_reference(spin[0]); //show text and buttons around this + } + setting = false; +} + ///////////////////// PLANE ///////////////////////// void EditorPropertyPlane::_value_changed(double val, const String &p_name) { @@ -1391,13 +1649,16 @@ void EditorPropertyPlane::setup(double p_min, double p_max, double p_step, bool } } -EditorPropertyPlane::EditorPropertyPlane() { +EditorPropertyPlane::EditorPropertyPlane(bool p_force_wide) { bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); BoxContainer *bc; - if (horizontal) { + if (p_force_wide) { + bc = memnew(HBoxContainer); + add_child(bc); + } else if (horizontal) { bc = memnew(HBoxContainer); add_child(bc); set_bottom_editor(bc); @@ -2877,7 +3138,7 @@ void EditorInspectorDefaultPlugin::parse_begin(Object *p_object) { //do none } -bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) { +bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) { float default_float_step = EDITOR_GET("interface/inspector/default_float_step"); @@ -3083,7 +3344,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ // math types case Variant::VECTOR2: { - EditorPropertyVector2 *editor = memnew(EditorPropertyVector2); + EditorPropertyVector2 *editor = memnew(EditorPropertyVector2(p_wide)); double min = -65535, max = 65535, step = default_float_step; bool hide_slider = true; @@ -3100,8 +3361,23 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ add_property_editor(p_path, editor); } break; + case Variant::VECTOR2I: { + EditorPropertyVector2i *editor = memnew(EditorPropertyVector2i(p_wide)); + int min = -65535, max = 65535; + bool hide_slider = true; + + if (p_hint == PROPERTY_HINT_RANGE && p_hint_text.get_slice_count(",") >= 2) { + min = p_hint_text.get_slice(",", 0).to_double(); + max = p_hint_text.get_slice(",", 1).to_double(); + hide_slider = false; + } + + editor->setup(min, max, hide_slider); + add_property_editor(p_path, editor); + + } break; case Variant::RECT2: { - EditorPropertyRect2 *editor = memnew(EditorPropertyRect2); + EditorPropertyRect2 *editor = memnew(EditorPropertyRect2(p_wide)); double min = -65535, max = 65535, step = default_float_step; bool hide_slider = true; @@ -3117,8 +3393,22 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ editor->setup(min, max, step, hide_slider); add_property_editor(p_path, editor); } break; + case Variant::RECT2I: { + EditorPropertyRect2i *editor = memnew(EditorPropertyRect2i(p_wide)); + int min = -65535, max = 65535; + bool hide_slider = true; + + if (p_hint == PROPERTY_HINT_RANGE && p_hint_text.get_slice_count(",") >= 2) { + min = p_hint_text.get_slice(",", 0).to_double(); + max = p_hint_text.get_slice(",", 1).to_double(); + hide_slider = false; + } + + editor->setup(min, max, hide_slider); + add_property_editor(p_path, editor); + } break; case Variant::VECTOR3: { - EditorPropertyVector3 *editor = memnew(EditorPropertyVector3); + EditorPropertyVector3 *editor = memnew(EditorPropertyVector3(p_wide)); double min = -65535, max = 65535, step = default_float_step; bool hide_slider = true; @@ -3135,6 +3425,22 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ add_property_editor(p_path, editor); } break; + case Variant::VECTOR3I: { + EditorPropertyVector3i *editor = memnew(EditorPropertyVector3i(p_wide)); + int min = -65535, max = 65535; + bool hide_slider = true; + + if (p_hint == PROPERTY_HINT_RANGE && p_hint_text.get_slice_count(",") >= 2) { + min = p_hint_text.get_slice(",", 0).to_double(); + max = p_hint_text.get_slice(",", 1).to_double(); + + hide_slider = false; + } + + editor->setup(min, max, hide_slider); + add_property_editor(p_path, editor); + + } break; case Variant::TRANSFORM2D: { EditorPropertyTransform2D *editor = memnew(EditorPropertyTransform2D); double min = -65535, max = 65535, step = default_float_step; @@ -3154,7 +3460,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ } break; case Variant::PLANE: { - EditorPropertyPlane *editor = memnew(EditorPropertyPlane); + EditorPropertyPlane *editor = memnew(EditorPropertyPlane(p_wide)); double min = -65535, max = 65535, step = default_float_step; bool hide_slider = true; diff --git a/editor/editor_properties.h b/editor/editor_properties.h index c5fc8aaf77..61c11f4534 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -361,7 +361,7 @@ protected: public: virtual void update_property(); void setup(double p_min, double p_max, double p_step, bool p_no_slider); - EditorPropertyVector2(); + EditorPropertyVector2(bool p_force_wide = false); }; class EditorPropertyRect2 : public EditorProperty { @@ -377,7 +377,7 @@ protected: public: virtual void update_property(); void setup(double p_min, double p_max, double p_step, bool p_no_slider); - EditorPropertyRect2(); + EditorPropertyRect2(bool p_force_wide = false); }; class EditorPropertyVector3 : public EditorProperty { @@ -393,7 +393,55 @@ protected: public: virtual void update_property(); void setup(double p_min, double p_max, double p_step, bool p_no_slider); - EditorPropertyVector3(); + EditorPropertyVector3(bool p_force_wide = false); +}; + +class EditorPropertyVector2i : public EditorProperty { + GDCLASS(EditorPropertyVector2i, EditorProperty); + EditorSpinSlider *spin[2]; + bool setting; + void _value_changed(double p_val, const String &p_name); + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + virtual void update_property(); + void setup(int p_min, int p_max, bool p_no_slider); + EditorPropertyVector2i(bool p_force_wide = false); +}; + +class EditorPropertyRect2i : public EditorProperty { + GDCLASS(EditorPropertyRect2i, EditorProperty); + EditorSpinSlider *spin[4]; + bool setting; + void _value_changed(double p_val, const String &p_name); + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + virtual void update_property(); + void setup(int p_min, int p_max, bool p_no_slider); + EditorPropertyRect2i(bool p_force_wide = false); +}; + +class EditorPropertyVector3i : public EditorProperty { + GDCLASS(EditorPropertyVector3i, EditorProperty); + EditorSpinSlider *spin[3]; + bool setting; + void _value_changed(double p_val, const String &p_name); + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + virtual void update_property(); + void setup(int p_min, int p_max, bool p_no_slider); + EditorPropertyVector3i(bool p_force_wide = false); }; class EditorPropertyPlane : public EditorProperty { @@ -409,7 +457,7 @@ protected: public: virtual void update_property(); void setup(double p_min, double p_max, double p_step, bool p_no_slider); - EditorPropertyPlane(); + EditorPropertyPlane(bool p_force_wide = false); }; class EditorPropertyQuat : public EditorProperty { @@ -626,7 +674,7 @@ class EditorInspectorDefaultPlugin : public EditorInspectorPlugin { public: virtual bool can_handle(Object *p_object); virtual void parse_begin(Object *p_object); - virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage); + virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide = false); virtual void parse_end(); }; diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index b4ce60171b..fdd5bd8db6 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -742,6 +742,13 @@ void EditorPropertyDictionary::update_property() { prop = editor; } break; + case Variant::VECTOR2I: { + + EditorPropertyVector2i *editor = memnew(EditorPropertyVector2i); + editor->setup(-100000, 100000, true); + prop = editor; + + } break; case Variant::RECT2: { EditorPropertyRect2 *editor = memnew(EditorPropertyRect2); @@ -749,6 +756,13 @@ void EditorPropertyDictionary::update_property() { prop = editor; } break; + case Variant::RECT2I: { + + EditorPropertyRect2i *editor = memnew(EditorPropertyRect2i); + editor->setup(-100000, 100000, true); + prop = editor; + + } break; case Variant::VECTOR3: { EditorPropertyVector3 *editor = memnew(EditorPropertyVector3); @@ -756,6 +770,13 @@ void EditorPropertyDictionary::update_property() { prop = editor; } break; + case Variant::VECTOR3I: { + + EditorPropertyVector3i *editor = memnew(EditorPropertyVector3i); + editor->setup(-100000, 100000, true); + prop = editor; + + } break; case Variant::TRANSFORM2D: { EditorPropertyTransform2D *editor = memnew(EditorPropertyTransform2D); diff --git a/editor/plugins/root_motion_editor_plugin.cpp b/editor/plugins/root_motion_editor_plugin.cpp index 67e836082d..a7120c5d68 100644 --- a/editor/plugins/root_motion_editor_plugin.cpp +++ b/editor/plugins/root_motion_editor_plugin.cpp @@ -288,7 +288,7 @@ void EditorInspectorRootMotionPlugin::parse_begin(Object *p_object) { //do none } -bool EditorInspectorRootMotionPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) { +bool EditorInspectorRootMotionPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) { if (p_path == "root_motion_track" && p_object->is_class("AnimationTree") && p_type == Variant::NODE_PATH) { EditorPropertyRootMotion *editor = memnew(EditorPropertyRootMotion); diff --git a/editor/plugins/root_motion_editor_plugin.h b/editor/plugins/root_motion_editor_plugin.h index 8a7691de5d..f72ad1ec05 100644 --- a/editor/plugins/root_motion_editor_plugin.h +++ b/editor/plugins/root_motion_editor_plugin.h @@ -65,7 +65,7 @@ class EditorInspectorRootMotionPlugin : public EditorInspectorPlugin { public: virtual bool can_handle(Object *p_object); virtual void parse_begin(Object *p_object); - virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage); + virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide = false); virtual void parse_end(); }; diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 2a36700105..9ef8148241 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -193,6 +193,12 @@ void ShaderTextEditor::_check_shader_mode() { } } +static ShaderLanguage::DataType _get_global_variable_type(const StringName &p_variable) { + + RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_variable); + return RS::global_variable_type_get_shader_datatype(gvt); +} + void ShaderTextEditor::_code_complete_script(const String &p_code, List<ScriptCodeCompletionOption> *r_options) { _check_shader_mode(); @@ -200,7 +206,7 @@ void ShaderTextEditor::_code_complete_script(const String &p_code, List<ScriptCo ShaderLanguage sl; String calltip; - sl.complete(p_code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types(), r_options, calltip); + sl.complete(p_code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type, r_options, calltip); get_text_edit()->set_code_hint(calltip); } @@ -215,7 +221,7 @@ void ShaderTextEditor::_validate_script() { ShaderLanguage sl; - Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types()); + Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type); if (err != OK) { String error_text = "error(" + itos(sl.get_error_line()) + "): " + sl.get_error_text(); diff --git a/editor/plugins/style_box_editor_plugin.cpp b/editor/plugins/style_box_editor_plugin.cpp index fbb6616dea..eb6e261305 100644 --- a/editor/plugins/style_box_editor_plugin.cpp +++ b/editor/plugins/style_box_editor_plugin.cpp @@ -45,7 +45,7 @@ void EditorInspectorPluginStyleBox::parse_begin(Object *p_object) { preview->edit(sb); add_custom_control(preview); } -bool EditorInspectorPluginStyleBox::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) { +bool EditorInspectorPluginStyleBox::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) { return false; //do not want } void EditorInspectorPluginStyleBox::parse_end() { diff --git a/editor/plugins/style_box_editor_plugin.h b/editor/plugins/style_box_editor_plugin.h index f4a72d9d1c..1eea9260b2 100644 --- a/editor/plugins/style_box_editor_plugin.h +++ b/editor/plugins/style_box_editor_plugin.h @@ -62,7 +62,7 @@ class EditorInspectorPluginStyleBox : public EditorInspectorPlugin { public: virtual bool can_handle(Object *p_object); virtual void parse_begin(Object *p_object); - virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage); + virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide = false); virtual void parse_end(); }; diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 294ce2c4cd..d5128db0d5 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -2261,6 +2261,12 @@ void VisualShaderEditor::_show_preview_text() { } } +static ShaderLanguage::DataType _get_global_variable_type(const StringName &p_variable) { + + RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_variable); + return RS::global_variable_type_get_shader_datatype(gvt); +} + void VisualShaderEditor::_update_preview() { if (!preview_showed) { @@ -2274,7 +2280,7 @@ void VisualShaderEditor::_update_preview() { ShaderLanguage sl; - Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderTypes::get_singleton()->get_types()); + Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type); for (int i = 0; i < preview_text->get_line_count(); i++) { preview_text->set_line_as_marked(i, false); @@ -3291,7 +3297,7 @@ void EditorInspectorShaderModePlugin::parse_begin(Object *p_object) { //do none } -bool EditorInspectorShaderModePlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) { +bool EditorInspectorShaderModePlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) { if (p_path == "mode" && p_object->is_class("VisualShader") && p_type == Variant::INT) { diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index 473c1bb070..a495b09b5c 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -338,7 +338,7 @@ class EditorInspectorShaderModePlugin : public EditorInspectorPlugin { public: virtual bool can_handle(Object *p_object); virtual void parse_begin(Object *p_object); - virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage); + virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide = false); virtual void parse_end(); }; diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 42493191a8..49c02dc895 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -2135,6 +2135,11 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { tab_container->add_child(autoload_settings); autoload_settings->connect("autoload_changed", callable_mp(this, &ProjectSettingsEditor::_settings_changed)); + shaders_global_variables_editor = memnew(ShaderGlobalsEditor); + shaders_global_variables_editor->set_name(TTR("Shader Globals")); + tab_container->add_child(shaders_global_variables_editor); + shaders_global_variables_editor->connect("globals_changed", callable_mp(this, &ProjectSettingsEditor::_settings_changed)); + plugin_settings = memnew(EditorPluginSettings); plugin_settings->set_name(TTR("Plugins")); tab_container->add_child(plugin_settings); diff --git a/editor/project_settings_editor.h b/editor/project_settings_editor.h index 2cecb13198..5475bb5508 100644 --- a/editor/project_settings_editor.h +++ b/editor/project_settings_editor.h @@ -36,6 +36,7 @@ #include "editor/editor_data.h" #include "editor/editor_plugin_settings.h" #include "editor/editor_sectioned_inspector.h" +#include "editor/shader_globals_editor.h" #include "scene/gui/dialogs.h" #include "scene/gui/tab_container.h" @@ -85,6 +86,7 @@ class ProjectSettingsEditor : public AcceptDialog { OptionButton *device_index; Label *device_index_label; MenuButton *popup_copy_to_feature; + ShaderGlobalsEditor *shaders_global_variables_editor; LineEdit *action_name; Button *action_add; diff --git a/editor/shader_globals_editor.cpp b/editor/shader_globals_editor.cpp new file mode 100644 index 0000000000..566ac54612 --- /dev/null +++ b/editor/shader_globals_editor.cpp @@ -0,0 +1,452 @@ +#include "shader_globals_editor.h" +#include "editor_node.h" + +static const char *global_var_type_names[RS::GLOBAL_VAR_TYPE_MAX] = { + "bool", + "bvec2", + "bvec3", + "bvec4", + "int", + "ivec2", + "ivec3", + "ivec4", + "rect2i", + "uint", + "uvec2", + "uvec3", + "uvec4", + "float", + "vec2", + "vec3", + "vec4", + "color", + "rect2", + "mat2", + "mat3", + "mat4", + "transform_2d", + "transform", + "sampler2D", + "sampler2DArray", + "sampler3D", + "samplerCube", +}; + +class ShaderGlobalsEditorInterface : public Object { + GDCLASS(ShaderGlobalsEditorInterface, Object) + + void _var_changed() { + emit_signal("var_changed"); + } + +protected: + static void _bind_methods() { + ClassDB::bind_method("_var_changed", &ShaderGlobalsEditorInterface::_var_changed); + ADD_SIGNAL(MethodInfo("var_changed")); + } + + bool _set(const StringName &p_name, const Variant &p_value) { + Variant existing = RS::get_singleton()->global_variable_get(p_name); + + if (existing.get_type() == Variant::NIL) { + return false; + } + + UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo(); + + undo_redo->create_action("Set Shader Global Variable"); + undo_redo->add_do_method(RS::get_singleton(), "global_variable_set", p_name, p_value); + undo_redo->add_undo_method(RS::get_singleton(), "global_variable_set", p_name, existing); + RS::GlobalVariableType type = RS::get_singleton()->global_variable_get_type(p_name); + Dictionary gv; + gv["type"] = global_var_type_names[type]; + if (type >= RS::GLOBAL_VAR_TYPE_SAMPLER2D) { + RES res = p_value; + if (res.is_valid()) { + gv["value"] = res->get_path(); + } else { + gv["value"] = ""; + } + } else { + gv["value"] = p_value; + } + + String path = "shader_globals/" + String(p_name); + undo_redo->add_do_property(ProjectSettings::get_singleton(), path, gv); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), path, ProjectSettings::get_singleton()->get(path)); + undo_redo->add_do_method(this, "_var_changed"); + undo_redo->add_undo_method(this, "_var_changed"); + block_update = true; + undo_redo->commit_action(); + block_update = false; + + print_line("all good?"); + return true; + } + + bool _get(const StringName &p_name, Variant &r_ret) const { + r_ret = RS::get_singleton()->global_variable_get(p_name); + return r_ret.get_type() != Variant::NIL; + } + void _get_property_list(List<PropertyInfo> *p_list) const { + Vector<StringName> variables; + variables = RS::get_singleton()->global_variable_get_list(); + for (int i = 0; i < variables.size(); i++) { + PropertyInfo pinfo; + pinfo.name = variables[i]; + + switch (RS::get_singleton()->global_variable_get_type(variables[i])) { + case RS::GLOBAL_VAR_TYPE_BOOL: { + pinfo.type = Variant::BOOL; + } break; + case RS::GLOBAL_VAR_TYPE_BVEC2: { + pinfo.type = Variant::INT; + pinfo.hint = PROPERTY_HINT_FLAGS; + pinfo.hint_string = "x,y"; + } break; + case RS::GLOBAL_VAR_TYPE_BVEC3: { + pinfo.type = Variant::INT; + pinfo.hint = PROPERTY_HINT_FLAGS; + pinfo.hint_string = "x,y,z"; + } break; + case RS::GLOBAL_VAR_TYPE_BVEC4: { + pinfo.type = Variant::INT; + pinfo.hint = PROPERTY_HINT_FLAGS; + pinfo.hint_string = "x,y,z,w"; + } break; + case RS::GLOBAL_VAR_TYPE_INT: { + pinfo.type = Variant::INT; + } break; + case RS::GLOBAL_VAR_TYPE_IVEC2: { + pinfo.type = Variant::VECTOR2I; + } break; + case RS::GLOBAL_VAR_TYPE_IVEC3: { + pinfo.type = Variant::VECTOR3I; + } break; + case RS::GLOBAL_VAR_TYPE_IVEC4: { + pinfo.type = Variant::PACKED_INT32_ARRAY; + } break; + case RS::GLOBAL_VAR_TYPE_RECT2I: { + pinfo.type = Variant::RECT2I; + } break; + case RS::GLOBAL_VAR_TYPE_UINT: { + pinfo.type = Variant::INT; + } break; + case RS::GLOBAL_VAR_TYPE_UVEC2: { + pinfo.type = Variant::VECTOR2I; + } break; + case RS::GLOBAL_VAR_TYPE_UVEC3: { + pinfo.type = Variant::VECTOR3I; + } break; + case RS::GLOBAL_VAR_TYPE_UVEC4: { + pinfo.type = Variant::PACKED_INT32_ARRAY; + } break; + case RS::GLOBAL_VAR_TYPE_FLOAT: { + pinfo.type = Variant::FLOAT; + } break; + case RS::GLOBAL_VAR_TYPE_VEC2: { + pinfo.type = Variant::VECTOR2; + } break; + case RS::GLOBAL_VAR_TYPE_VEC3: { + pinfo.type = Variant::VECTOR3; + } break; + case RS::GLOBAL_VAR_TYPE_VEC4: { + pinfo.type = Variant::PLANE; + } break; + case RS::GLOBAL_VAR_TYPE_RECT2: { + pinfo.type = Variant::RECT2; + } break; + case RS::GLOBAL_VAR_TYPE_COLOR: { + pinfo.type = Variant::COLOR; + } break; + case RS::GLOBAL_VAR_TYPE_MAT2: { + pinfo.type = Variant::PACKED_INT32_ARRAY; + } break; + case RS::GLOBAL_VAR_TYPE_MAT3: { + pinfo.type = Variant::BASIS; + } break; + case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: { + pinfo.type = Variant::TRANSFORM2D; + } break; + case RS::GLOBAL_VAR_TYPE_TRANSFORM: { + pinfo.type = Variant::TRANSFORM; + } break; + case RS::GLOBAL_VAR_TYPE_MAT4: { + pinfo.type = Variant::PACKED_INT32_ARRAY; + } break; + case RS::GLOBAL_VAR_TYPE_SAMPLER2D: { + pinfo.type = Variant::OBJECT; + pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE; + pinfo.hint_string = "Texture2D"; + } break; + case RS::GLOBAL_VAR_TYPE_SAMPLER2DARRAY: { + pinfo.type = Variant::OBJECT; + pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE; + pinfo.hint_string = "Texture2DArray"; + } break; + case RS::GLOBAL_VAR_TYPE_SAMPLER3D: { + pinfo.type = Variant::OBJECT; + pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE; + pinfo.hint_string = "Texture3D"; + } break; + case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE: { + pinfo.type = Variant::OBJECT; + pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE; + pinfo.hint_string = "Cubemap"; + } break; + default: { + + } break; + } + + p_list->push_back(pinfo); + } + } + +public: + bool block_update = false; + + ShaderGlobalsEditorInterface() { + } +}; + +static Variant create_var(RS::GlobalVariableType p_type) { + switch (p_type) { + case RS::GLOBAL_VAR_TYPE_BOOL: { + return false; + } + case RS::GLOBAL_VAR_TYPE_BVEC2: { + return 0; //bits + } + case RS::GLOBAL_VAR_TYPE_BVEC3: { + return 0; //bits + } + case RS::GLOBAL_VAR_TYPE_BVEC4: { + return 0; //bits + } + case RS::GLOBAL_VAR_TYPE_INT: { + return 0; //bits + } + case RS::GLOBAL_VAR_TYPE_IVEC2: { + return Vector2i(); + } + case RS::GLOBAL_VAR_TYPE_IVEC3: { + return Vector3i(); + } + case RS::GLOBAL_VAR_TYPE_IVEC4: { + Vector<int> v4; + v4.resize(4); + v4.write[0] = 0; + v4.write[1] = 0; + v4.write[2] = 0; + v4.write[3] = 0; + return v4; + } + case RS::GLOBAL_VAR_TYPE_RECT2I: { + return Rect2i(); + } + case RS::GLOBAL_VAR_TYPE_UINT: { + return 0; + } + case RS::GLOBAL_VAR_TYPE_UVEC2: { + return Vector2i(); + } + case RS::GLOBAL_VAR_TYPE_UVEC3: { + return Vector3i(); + } + case RS::GLOBAL_VAR_TYPE_UVEC4: { + return Rect2i(); + } + case RS::GLOBAL_VAR_TYPE_FLOAT: { + return 0.0; + } + case RS::GLOBAL_VAR_TYPE_VEC2: { + return Vector2(); + } + case RS::GLOBAL_VAR_TYPE_VEC3: { + return Vector3(); + } + case RS::GLOBAL_VAR_TYPE_VEC4: { + return Plane(); + } + case RS::GLOBAL_VAR_TYPE_RECT2: { + return Rect2(); + } + case RS::GLOBAL_VAR_TYPE_COLOR: { + return Color(); + } + case RS::GLOBAL_VAR_TYPE_MAT2: { + Vector<real_t> xform; + xform.resize(4); + xform.write[0] = 1; + xform.write[1] = 0; + xform.write[2] = 0; + xform.write[3] = 1; + return xform; + } + case RS::GLOBAL_VAR_TYPE_MAT3: { + return Basis(); + } + case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: { + return Transform2D(); + } + case RS::GLOBAL_VAR_TYPE_TRANSFORM: { + return Transform(); + } + case RS::GLOBAL_VAR_TYPE_MAT4: { + Vector<real_t> xform; + xform.resize(4); + xform.write[0] = 1; + xform.write[1] = 0; + xform.write[2] = 0; + xform.write[3] = 0; + + xform.write[4] = 0; + xform.write[5] = 1; + xform.write[6] = 0; + xform.write[7] = 0; + + xform.write[8] = 0; + xform.write[9] = 0; + xform.write[10] = 1; + xform.write[11] = 0; + + xform.write[12] = 0; + xform.write[13] = 0; + xform.write[14] = 0; + xform.write[15] = 1; + + return xform; + } + case RS::GLOBAL_VAR_TYPE_SAMPLER2D: { + return ""; + } + case RS::GLOBAL_VAR_TYPE_SAMPLER2DARRAY: { + return ""; + } + case RS::GLOBAL_VAR_TYPE_SAMPLER3D: { + return ""; + } + case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE: { + return ""; + } + default: { + return Variant(); + } + } +} + +void ShaderGlobalsEditor::_variable_added() { + + String var = variable_name->get_text().strip_edges(); + if (var == "" || !var.is_valid_identifier()) { + EditorNode::get_singleton()->show_warning(TTR("Please specify a valid variable identifier name.")); + return; + } + + if (RenderingServer::get_singleton()->global_variable_get(var).get_type() != Variant::NIL) { + EditorNode::get_singleton()->show_warning(vformat(TTR("Global variable '%s' already exists'"), var)); + return; + } + + List<String> keywords; + ShaderLanguage::get_keyword_list(&keywords); + + if (keywords.find(var) != nullptr || var == "script") { + EditorNode::get_singleton()->show_warning(vformat(TTR("Name '%s' is a reserved shader language keyword."), var)); + return; + } + + UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo(); + + Variant value = create_var(RS::GlobalVariableType(variable_type->get_selected())); + + undo_redo->create_action("Add Shader Global Variable"); + undo_redo->add_do_method(RS::get_singleton(), "global_variable_add", var, RS::GlobalVariableType(variable_type->get_selected()), value); + undo_redo->add_undo_method(RS::get_singleton(), "global_variable_remove", var); + Dictionary gv; + gv["type"] = global_var_type_names[variable_type->get_selected()]; + gv["value"] = value; + + undo_redo->add_do_property(ProjectSettings::get_singleton(), "shader_globals/" + var, gv); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "shader_globals/" + var, Variant()); + undo_redo->add_do_method(this, "_changed"); + undo_redo->add_undo_method(this, "_changed"); + undo_redo->commit_action(); +} + +void ShaderGlobalsEditor::_variable_deleted(const String &p_variable) { + + print_line("deleted " + p_variable); + UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo(); + + undo_redo->create_action("Add Shader Global Variable"); + undo_redo->add_do_method(RS::get_singleton(), "global_variable_remove", p_variable); + undo_redo->add_undo_method(RS::get_singleton(), "global_variable_add", p_variable, RS::get_singleton()->global_variable_get_type(p_variable), RS::get_singleton()->global_variable_get(p_variable)); + + undo_redo->add_do_property(ProjectSettings::get_singleton(), "shader_globals/" + p_variable, Variant()); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "shader_globals/" + p_variable, ProjectSettings::get_singleton()->get("shader_globals/" + p_variable)); + undo_redo->add_do_method(this, "_changed"); + undo_redo->add_undo_method(this, "_changed"); + undo_redo->commit_action(); +} + +void ShaderGlobalsEditor::_changed() { + emit_signal("globals_changed"); + if (!interface->block_update) { + interface->_change_notify(); + } +} + +void ShaderGlobalsEditor::_bind_methods() { + ClassDB::bind_method("_changed", &ShaderGlobalsEditor::_changed); + ADD_SIGNAL(MethodInfo("globals_changed")); +} + +void ShaderGlobalsEditor::_notification(int p_what) { + if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { + if (is_visible_in_tree()) { + print_line("OK load settings in globalseditor"); + inspector->edit(interface); + } + } +} + +ShaderGlobalsEditor::ShaderGlobalsEditor() { + + HBoxContainer *add_menu_hb = memnew(HBoxContainer); + add_child(add_menu_hb); + + add_menu_hb->add_child(memnew(Label(TTR("Name:")))); + variable_name = memnew(LineEdit); + variable_name->set_h_size_flags(SIZE_EXPAND_FILL); + add_menu_hb->add_child(variable_name); + + add_menu_hb->add_child(memnew(Label(TTR("Type:")))); + variable_type = memnew(OptionButton); + variable_type->set_h_size_flags(SIZE_EXPAND_FILL); + add_menu_hb->add_child(variable_type); + + for (int i = 0; i < RS::GLOBAL_VAR_TYPE_MAX; i++) { + variable_type->add_item(global_var_type_names[i]); + } + + variable_add = memnew(Button(TTR("Add"))); + add_menu_hb->add_child(variable_add); + variable_add->connect("pressed", callable_mp(this, &ShaderGlobalsEditor::_variable_added)); + + inspector = memnew(EditorInspector); + inspector->set_v_size_flags(SIZE_EXPAND_FILL); + add_child(inspector); + inspector->set_use_wide_editors(true); + inspector->set_enable_capitalize_paths(false); + inspector->set_use_deletable_properties(true); + inspector->connect("property_deleted", callable_mp(this, &ShaderGlobalsEditor::_variable_deleted), varray(), CONNECT_DEFERRED); + + interface = memnew(ShaderGlobalsEditorInterface); + interface->connect("var_changed", Callable(this, "_changed")); +} +ShaderGlobalsEditor::~ShaderGlobalsEditor() { + inspector->edit(NULL); + memdelete(interface); +} diff --git a/editor/shader_globals_editor.h b/editor/shader_globals_editor.h new file mode 100644 index 0000000000..59cdeddd8d --- /dev/null +++ b/editor/shader_globals_editor.h @@ -0,0 +1,38 @@ +#ifndef SHADER_GLOBALS_EDITOR_H +#define SHADER_GLOBALS_EDITOR_H + +#include "core/undo_redo.h" +#include "editor/editor_autoload_settings.h" +#include "editor/editor_data.h" +#include "editor/editor_plugin_settings.h" +#include "editor/editor_sectioned_inspector.h" +#include "scene/gui/dialogs.h" +#include "scene/gui/tab_container.h" + +class ShaderGlobalsEditorInterface; + +class ShaderGlobalsEditor : public VBoxContainer { + + GDCLASS(ShaderGlobalsEditor, VBoxContainer) + + ShaderGlobalsEditorInterface *interface; + EditorInspector *inspector; + + LineEdit *variable_name; + OptionButton *variable_type; + Button *variable_add; + + void _variable_added(); + void _variable_deleted(const String &p_variable); + void _changed(); + +protected: + static void _bind_methods(); + void _notification(int p_what); + +public: + ShaderGlobalsEditor(); + ~ShaderGlobalsEditor(); +}; + +#endif // SHADER_GLOBALS_EDITOR_H |