diff options
Diffstat (limited to 'scene')
-rw-r--r-- | scene/animation/animation_player.cpp | 2 | ||||
-rw-r--r-- | scene/gui/base_button.cpp | 3 | ||||
-rw-r--r-- | scene/gui/code_edit.cpp | 3 | ||||
-rw-r--r-- | scene/gui/color_picker.cpp | 12 | ||||
-rw-r--r-- | scene/gui/control.cpp | 14 | ||||
-rw-r--r-- | scene/gui/control.h | 5 | ||||
-rw-r--r-- | scene/gui/file_dialog.cpp | 108 | ||||
-rw-r--r-- | scene/gui/file_dialog.h | 2 | ||||
-rw-r--r-- | scene/gui/gradient_edit.cpp | 4 | ||||
-rw-r--r-- | scene/gui/graph_edit.cpp | 13 | ||||
-rw-r--r-- | scene/gui/label.cpp | 3 | ||||
-rw-r--r-- | scene/gui/menu_bar.cpp | 15 | ||||
-rw-r--r-- | scene/gui/menu_bar.h | 2 | ||||
-rw-r--r-- | scene/gui/menu_button.cpp | 14 | ||||
-rw-r--r-- | scene/gui/option_button.cpp | 20 | ||||
-rw-r--r-- | scene/gui/popup.cpp | 3 | ||||
-rw-r--r-- | scene/gui/popup_menu.cpp | 156 | ||||
-rw-r--r-- | scene/gui/rich_text_label.cpp | 29 | ||||
-rw-r--r-- | scene/gui/scroll_container.cpp | 5 | ||||
-rw-r--r-- | scene/main/window.h | 1 | ||||
-rw-r--r-- | scene/register_scene_types.cpp | 6 | ||||
-rw-r--r-- | scene/resources/animation_library.cpp | 2 | ||||
-rw-r--r-- | scene/resources/packed_scene.cpp | 47 | ||||
-rw-r--r-- | scene/resources/visual_shader_nodes.cpp | 404 | ||||
-rw-r--r-- | scene/resources/visual_shader_nodes.h | 126 |
25 files changed, 802 insertions, 197 deletions
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 0e2598cbc7..073f61bfdd 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -1501,7 +1501,7 @@ bool AnimationPlayer::has_animation(const StringName &p_name) const { } Ref<Animation> AnimationPlayer::get_animation(const StringName &p_name) const { - ERR_FAIL_COND_V_MSG(!animation_set.has(p_name), Ref<Animation>(), vformat("Animation not found: %s.", p_name)); + ERR_FAIL_COND_V_MSG(!animation_set.has(p_name), Ref<Animation>(), vformat("Animation not found: \"%s\".", p_name)); const AnimationData &data = animation_set[p_name]; diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index 87a7355bb2..cee7c049a9 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -65,8 +65,9 @@ void BaseButton::gui_input(const Ref<InputEvent> &p_event) { bool button_masked = mouse_button.is_valid() && (mouse_button_to_mask(mouse_button->get_button_index()) & button_mask) != MouseButton::NONE; if (button_masked || ui_accept) { was_mouse_pressed = button_masked; - on_action_event(p_event); + was_mouse_pressed = false; + return; } diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index b9760499ef..e54ba7ce13 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -36,7 +36,8 @@ void CodeEdit::_notification(int p_what) { switch (p_what) { - case NOTIFICATION_THEME_CHANGED: { + case NOTIFICATION_THEME_CHANGED: + case NOTIFICATION_ENTER_TREE: { style_normal = get_theme_stylebox(SNAME("normal")); font = get_theme_font(SNAME("font")); diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 93aafba886..a417e7b9e2 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -63,8 +63,8 @@ void ColorPicker::_notification(int p_what) { } } #endif - } break; - + [[fallthrough]]; + } case NOTIFICATION_THEME_CHANGED: { btn_pick->set_icon(get_theme_icon(SNAME("screen_picker"), SNAME("ColorPicker"))); btn_add_preset->set_icon(get_theme_icon(SNAME("add_preset"))); @@ -536,7 +536,7 @@ void ColorPicker::_add_preset_button(int p_size, const Color &p_color) { btn_preset->set_preset_color(p_color); btn_preset->set_custom_minimum_size(Size2(p_size, p_size)); btn_preset->connect("gui_input", callable_mp(this, &ColorPicker::_preset_input).bind(p_color)); - btn_preset->set_tooltip(vformat(RTR("Color: #%s\nLMB: Apply color\nRMB: Remove preset"), p_color.to_html(p_color.a < 1))); + btn_preset->set_tooltip_text(vformat(RTR("Color: #%s\nLMB: Apply color\nRMB: Remove preset"), p_color.to_html(p_color.a < 1))); preset_container->add_child(btn_preset); } @@ -1236,7 +1236,7 @@ ColorPicker::ColorPicker() : btn_pick->set_flat(true); hb_smpl->add_child(btn_pick); btn_pick->set_toggle_mode(true); - btn_pick->set_tooltip(RTR("Pick a color from the editor window.")); + btn_pick->set_tooltip_text(RTR("Pick a color from the editor window.")); btn_pick->connect("pressed", callable_mp(this, &ColorPicker::_screen_pick_pressed)); VBoxContainer *vbl = memnew(VBoxContainer); @@ -1276,7 +1276,7 @@ ColorPicker::ColorPicker() : text_type = memnew(Button); hhb->add_child(text_type); text_type->set_text("#"); - text_type->set_tooltip(RTR("Switch between hexadecimal and code values.")); + text_type->set_tooltip_text(RTR("Switch between hexadecimal and code values.")); if (Engine::get_singleton()->is_editor_hint()) { text_type->connect("pressed", callable_mp(this, &ColorPicker::_text_type_toggled)); } else { @@ -1337,7 +1337,7 @@ ColorPicker::ColorPicker() : btn_add_preset = memnew(Button); btn_add_preset->set_icon_alignment(HORIZONTAL_ALIGNMENT_CENTER); - btn_add_preset->set_tooltip(RTR("Add current color as a preset.")); + btn_add_preset->set_tooltip_text(RTR("Add current color as a preset.")); btn_add_preset->connect("pressed", callable_mp(this, &ColorPicker::_add_preset_pressed)); preset_container->add_child(btn_add_preset); } diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 9b6a19c50a..299c796091 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -3062,12 +3062,12 @@ bool Control::is_auto_translating() const { // Extra properties. -void Control::set_tooltip(const String &p_tooltip) { - data.tooltip = p_tooltip; +void Control::set_tooltip_text(const String &p_hint) { + data.tooltip = p_hint; update_configuration_warnings(); } -String Control::_get_tooltip() const { +String Control::get_tooltip_text() const { return data.tooltip; } @@ -3383,9 +3383,9 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("set_v_grow_direction", "direction"), &Control::set_v_grow_direction); ClassDB::bind_method(D_METHOD("get_v_grow_direction"), &Control::get_v_grow_direction); - ClassDB::bind_method(D_METHOD("set_tooltip", "tooltip"), &Control::set_tooltip); + ClassDB::bind_method(D_METHOD("set_tooltip_text", "hint"), &Control::set_tooltip_text); + ClassDB::bind_method(D_METHOD("get_tooltip_text"), &Control::get_tooltip_text); ClassDB::bind_method(D_METHOD("get_tooltip", "at_position"), &Control::get_tooltip, DEFVAL(Point2())); - ClassDB::bind_method(D_METHOD("_get_tooltip"), &Control::_get_tooltip); ClassDB::bind_method(D_METHOD("set_default_cursor_shape", "shape"), &Control::set_default_cursor_shape); ClassDB::bind_method(D_METHOD("get_default_cursor_shape"), &Control::get_default_cursor_shape); @@ -3475,8 +3475,8 @@ void Control::_bind_methods() { ADD_GROUP("Auto Translate", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_translate"), "set_auto_translate", "is_auto_translating"); - ADD_GROUP("Hint", "hint_"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "hint_tooltip", PROPERTY_HINT_MULTILINE_TEXT), "set_tooltip", "_get_tooltip"); + ADD_GROUP("Tooltip", "tooltip_"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "tooltip_text", PROPERTY_HINT_MULTILINE_TEXT), "set_tooltip_text", "get_tooltip_text"); ADD_GROUP("Focus", "focus_"); ADD_PROPERTYI(PropertyInfo(Variant::NODE_PATH, "focus_neighbor_left", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_neighbor", "get_focus_neighbor", SIDE_LEFT); diff --git a/scene/gui/control.h b/scene/gui/control.h index aa076370e5..6215594ae0 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -312,7 +312,7 @@ private: // Extra properties. - String _get_tooltip() const; + String get_tooltip_text() const; protected: // Dynamic properties. @@ -357,7 +357,6 @@ public: NOTIFICATION_MOUSE_EXIT = 42, NOTIFICATION_FOCUS_ENTER = 43, NOTIFICATION_FOCUS_EXIT = 44, - // This doesn't need to be paired with `NOTIFICATION_ENTER_TREE`. NOTIFICATION_THEME_CHANGED = 45, NOTIFICATION_SCROLL_BEGIN = 47, NOTIFICATION_SCROLL_END = 48, @@ -605,7 +604,7 @@ public: // Extra properties. - void set_tooltip(const String &p_tooltip); + void set_tooltip_text(const String &text); virtual String get_tooltip(const Point2 &p_pos) const; virtual Control *make_custom_tooltip(const String &p_text) const; diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index df295a8049..57655afb4c 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -59,6 +59,38 @@ VBoxContainer *FileDialog::get_vbox() { return vbox; } +void FileDialog::_theme_changed() { + Color font_color = vbox->get_theme_color(SNAME("font_color"), SNAME("Button")); + Color font_hover_color = vbox->get_theme_color(SNAME("font_hover_color"), SNAME("Button")); + Color font_focus_color = vbox->get_theme_color(SNAME("font_focus_color"), SNAME("Button")); + Color font_pressed_color = vbox->get_theme_color(SNAME("font_pressed_color"), SNAME("Button")); + + dir_up->add_theme_color_override("icon_normal_color", font_color); + dir_up->add_theme_color_override("icon_hover_color", font_hover_color); + dir_up->add_theme_color_override("icon_focus_color", font_focus_color); + dir_up->add_theme_color_override("icon_pressed_color", font_pressed_color); + + dir_prev->add_theme_color_override("icon_color_normal", font_color); + dir_prev->add_theme_color_override("icon_color_hover", font_hover_color); + dir_prev->add_theme_color_override("icon_focus_color", font_focus_color); + dir_prev->add_theme_color_override("icon_color_pressed", font_pressed_color); + + dir_next->add_theme_color_override("icon_color_normal", font_color); + dir_next->add_theme_color_override("icon_color_hover", font_hover_color); + dir_next->add_theme_color_override("icon_focus_color", font_focus_color); + dir_next->add_theme_color_override("icon_color_pressed", font_pressed_color); + + refresh->add_theme_color_override("icon_normal_color", font_color); + refresh->add_theme_color_override("icon_hover_color", font_hover_color); + refresh->add_theme_color_override("icon_focus_color", font_focus_color); + refresh->add_theme_color_override("icon_pressed_color", font_pressed_color); + + show_hidden->add_theme_color_override("icon_normal_color", font_color); + show_hidden->add_theme_color_override("icon_hover_color", font_hover_color); + show_hidden->add_theme_color_override("icon_focus_color", font_focus_color); + show_hidden->add_theme_color_override("icon_pressed_color", font_pressed_color); +} + void FileDialog::_notification(int p_what) { switch (p_what) { case NOTIFICATION_VISIBILITY_CHANGED: { @@ -67,51 +99,22 @@ void FileDialog::_notification(int p_what) { } } break; - case NOTIFICATION_TRANSLATION_CHANGED: { - update_filters(); - } break; - - case NOTIFICATION_THEME_CHANGED: { - dir_up->set_icon(get_theme_icon(SNAME("parent_folder"), SNAME("FileDialog"))); + case NOTIFICATION_ENTER_TREE: { + dir_up->set_icon(vbox->get_theme_icon(SNAME("parent_folder"), SNAME("FileDialog"))); if (vbox->is_layout_rtl()) { - dir_prev->set_icon(get_theme_icon(SNAME("forward_folder"), SNAME("FileDialog"))); - dir_next->set_icon(get_theme_icon(SNAME("back_folder"), SNAME("FileDialog"))); + dir_prev->set_icon(vbox->get_theme_icon(SNAME("forward_folder"), SNAME("FileDialog"))); + dir_next->set_icon(vbox->get_theme_icon(SNAME("back_folder"), SNAME("FileDialog"))); } else { - dir_prev->set_icon(get_theme_icon(SNAME("back_folder"), SNAME("FileDialog"))); - dir_next->set_icon(get_theme_icon(SNAME("forward_folder"), SNAME("FileDialog"))); + dir_prev->set_icon(vbox->get_theme_icon(SNAME("back_folder"), SNAME("FileDialog"))); + dir_next->set_icon(vbox->get_theme_icon(SNAME("forward_folder"), SNAME("FileDialog"))); } - refresh->set_icon(get_theme_icon(SNAME("reload"), SNAME("FileDialog"))); - show_hidden->set_icon(get_theme_icon(SNAME("toggle_hidden"), SNAME("FileDialog"))); - - Color font_color = get_theme_color(SNAME("font_color"), SNAME("Button")); - Color font_hover_color = get_theme_color(SNAME("font_hover_color"), SNAME("Button")); - Color font_focus_color = get_theme_color(SNAME("font_focus_color"), SNAME("Button")); - Color font_pressed_color = get_theme_color(SNAME("font_pressed_color"), SNAME("Button")); - - dir_up->add_theme_color_override("icon_normal_color", font_color); - dir_up->add_theme_color_override("icon_hover_color", font_hover_color); - dir_up->add_theme_color_override("icon_focus_color", font_focus_color); - dir_up->add_theme_color_override("icon_pressed_color", font_pressed_color); - - dir_prev->add_theme_color_override("icon_color_normal", font_color); - dir_prev->add_theme_color_override("icon_color_hover", font_hover_color); - dir_prev->add_theme_color_override("icon_focus_color", font_focus_color); - dir_prev->add_theme_color_override("icon_color_pressed", font_pressed_color); - - dir_next->add_theme_color_override("icon_color_normal", font_color); - dir_next->add_theme_color_override("icon_color_hover", font_hover_color); - dir_next->add_theme_color_override("icon_focus_color", font_focus_color); - dir_next->add_theme_color_override("icon_color_pressed", font_pressed_color); - - refresh->add_theme_color_override("icon_normal_color", font_color); - refresh->add_theme_color_override("icon_hover_color", font_hover_color); - refresh->add_theme_color_override("icon_focus_color", font_focus_color); - refresh->add_theme_color_override("icon_pressed_color", font_pressed_color); - - show_hidden->add_theme_color_override("icon_normal_color", font_color); - show_hidden->add_theme_color_override("icon_hover_color", font_hover_color); - show_hidden->add_theme_color_override("icon_focus_color", font_focus_color); - show_hidden->add_theme_color_override("icon_pressed_color", font_pressed_color); + refresh->set_icon(vbox->get_theme_icon(SNAME("reload"), SNAME("FileDialog"))); + show_hidden->set_icon(vbox->get_theme_icon(SNAME("toggle_hidden"), SNAME("FileDialog"))); + _theme_changed(); + } break; + + case NOTIFICATION_TRANSLATION_CHANGED: { + update_filters(); } break; } } @@ -503,10 +506,10 @@ void FileDialog::update_file_list() { } TreeItem *root = tree->create_item(); - Ref<Texture2D> folder = get_theme_icon(SNAME("folder"), SNAME("FileDialog")); - Ref<Texture2D> file_icon = get_theme_icon(SNAME("file"), SNAME("FileDialog")); - const Color folder_color = get_theme_color(SNAME("folder_icon_modulate"), SNAME("FileDialog")); - const Color file_color = get_theme_color(SNAME("file_icon_modulate"), SNAME("FileDialog")); + Ref<Texture2D> folder = vbox->get_theme_icon(SNAME("folder"), SNAME("FileDialog")); + Ref<Texture2D> file_icon = vbox->get_theme_icon(SNAME("file"), SNAME("FileDialog")); + const Color folder_color = vbox->get_theme_color(SNAME("folder_icon_modulate"), SNAME("FileDialog")); + const Color file_color = vbox->get_theme_color(SNAME("file_icon_modulate"), SNAME("FileDialog")); List<String> files; List<String> dirs; @@ -603,7 +606,7 @@ void FileDialog::update_file_list() { ti->set_icon_modulate(0, file_color); if (mode == FILE_MODE_OPEN_DIR) { - ti->set_custom_color(0, get_theme_color(SNAME("files_disabled"), SNAME("FileDialog"))); + ti->set_custom_color(0, vbox->get_theme_color(SNAME("files_disabled"), SNAME("FileDialog"))); ti->set_selectable(0, false); } Dictionary d; @@ -1003,6 +1006,7 @@ FileDialog::FileDialog() { vbox = memnew(VBoxContainer); add_child(vbox, false, INTERNAL_MODE_FRONT); + vbox->connect("theme_changed", callable_mp(this, &FileDialog::_theme_changed)); mode = FILE_MODE_SAVE_FILE; set_title(TTRC("Save a File")); @@ -1011,13 +1015,13 @@ FileDialog::FileDialog() { dir_prev = memnew(Button); dir_prev->set_flat(true); - dir_prev->set_tooltip(RTR("Go to previous folder.")); + dir_prev->set_tooltip_text(RTR("Go to previous folder.")); dir_next = memnew(Button); dir_next->set_flat(true); - dir_next->set_tooltip(RTR("Go to next folder.")); + dir_next->set_tooltip_text(RTR("Go to next folder.")); dir_up = memnew(Button); dir_up->set_flat(true); - dir_up->set_tooltip(RTR("Go to parent folder.")); + dir_up->set_tooltip_text(RTR("Go to parent folder.")); hbc->add_child(dir_prev); hbc->add_child(dir_next); hbc->add_child(dir_up); @@ -1041,7 +1045,7 @@ FileDialog::FileDialog() { refresh = memnew(Button); refresh->set_flat(true); - refresh->set_tooltip(RTR("Refresh files.")); + refresh->set_tooltip_text(RTR("Refresh files.")); refresh->connect("pressed", callable_mp(this, &FileDialog::update_file_list)); hbc->add_child(refresh); @@ -1049,7 +1053,7 @@ FileDialog::FileDialog() { show_hidden->set_flat(true); show_hidden->set_toggle_mode(true); show_hidden->set_pressed(is_showing_hidden_files()); - show_hidden->set_tooltip(RTR("Toggle the visibility of hidden files.")); + show_hidden->set_tooltip_text(RTR("Toggle the visibility of hidden files.")); show_hidden->connect("toggled", callable_mp(this, &FileDialog::set_show_hidden_files)); hbc->add_child(show_hidden); diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h index 4ea39691c1..4945094086 100644 --- a/scene/gui/file_dialog.h +++ b/scene/gui/file_dialog.h @@ -143,6 +143,8 @@ private: virtual void _post_popup() override; protected: + void _theme_changed(); + void _notification(int p_what); static void _bind_methods(); //bind helpers diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp index be097f7543..cc27a6b7c2 100644 --- a/scene/gui/gradient_edit.cpp +++ b/scene/gui/gradient_edit.cpp @@ -292,8 +292,8 @@ void GradientEdit::_notification(int p_what) { if (!picker->is_connected("color_changed", callable_mp(this, &GradientEdit::_color_changed))) { picker->connect("color_changed", callable_mp(this, &GradientEdit::_color_changed)); } - } break; - + [[fallthrough]]; + } case NOTIFICATION_THEME_CHANGED: { draw_spacing = BASE_SPACING * get_theme_default_base_scale(); draw_point_width = BASE_POINT_WIDTH * get_theme_default_base_scale(); diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 256d4b3d11..00f2e48601 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -424,6 +424,7 @@ void GraphEdit::remove_child_notify(Node *p_child) { void GraphEdit::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { port_hotzone_inner_extent = get_theme_constant("port_hotzone_inner_extent"); port_hotzone_outer_extent = get_theme_constant("port_hotzone_outer_extent"); @@ -2495,28 +2496,28 @@ GraphEdit::GraphEdit() { zoom_minus = memnew(Button); zoom_minus->set_flat(true); zoom_hb->add_child(zoom_minus); - zoom_minus->set_tooltip(RTR("Zoom Out")); + zoom_minus->set_tooltip_text(RTR("Zoom Out")); zoom_minus->connect("pressed", callable_mp(this, &GraphEdit::_zoom_minus)); zoom_minus->set_focus_mode(FOCUS_NONE); zoom_reset = memnew(Button); zoom_reset->set_flat(true); zoom_hb->add_child(zoom_reset); - zoom_reset->set_tooltip(RTR("Zoom Reset")); + zoom_reset->set_tooltip_text(RTR("Zoom Reset")); zoom_reset->connect("pressed", callable_mp(this, &GraphEdit::_zoom_reset)); zoom_reset->set_focus_mode(FOCUS_NONE); zoom_plus = memnew(Button); zoom_plus->set_flat(true); zoom_hb->add_child(zoom_plus); - zoom_plus->set_tooltip(RTR("Zoom In")); + zoom_plus->set_tooltip_text(RTR("Zoom In")); zoom_plus->connect("pressed", callable_mp(this, &GraphEdit::_zoom_plus)); zoom_plus->set_focus_mode(FOCUS_NONE); snap_button = memnew(Button); snap_button->set_flat(true); snap_button->set_toggle_mode(true); - snap_button->set_tooltip(RTR("Enable snap and show grid.")); + snap_button->set_tooltip_text(RTR("Enable snap and show grid.")); snap_button->connect("pressed", callable_mp(this, &GraphEdit::_snap_toggled)); snap_button->set_pressed(true); snap_button->set_focus_mode(FOCUS_NONE); @@ -2533,7 +2534,7 @@ GraphEdit::GraphEdit() { minimap_button = memnew(Button); minimap_button->set_flat(true); minimap_button->set_toggle_mode(true); - minimap_button->set_tooltip(RTR("Enable grid minimap.")); + minimap_button->set_tooltip_text(RTR("Enable grid minimap.")); minimap_button->connect("pressed", callable_mp(this, &GraphEdit::_minimap_toggled)); minimap_button->set_pressed(true); minimap_button->set_focus_mode(FOCUS_NONE); @@ -2542,7 +2543,7 @@ GraphEdit::GraphEdit() { layout_button = memnew(Button); layout_button->set_flat(true); zoom_hb->add_child(layout_button); - layout_button->set_tooltip(RTR("Arrange nodes.")); + layout_button->set_tooltip_text(RTR("Arrange nodes.")); layout_button->connect("pressed", callable_mp(this, &GraphEdit::arrange_nodes)); layout_button->set_focus_mode(FOCUS_NONE); diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index b15578f222..fa7d4195cb 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -908,9 +908,10 @@ void Label::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_text"), "set_clip_text", "is_clipping_text"); ADD_PROPERTY(PropertyInfo(Variant::INT, "text_overrun_behavior", PROPERTY_HINT_ENUM, "Trim Nothing,Trim Characters,Trim Words,Ellipsis,Word Ellipsis"), "set_text_overrun_behavior", "get_text_overrun_behavior"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "uppercase"), "set_uppercase", "is_uppercase"); + + ADD_GROUP("Displayed Text", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "lines_skipped", PROPERTY_HINT_RANGE, "0,999,1"), "set_lines_skipped", "get_lines_skipped"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_lines_visible", PROPERTY_HINT_RANGE, "-1,999,1"), "set_max_lines_visible", "get_max_lines_visible"); - // Note: "visible_characters" and "visible_ratio" should be set after "text" to be correctly applied. ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_characters", PROPERTY_HINT_RANGE, "-1,128000,1"), "set_visible_characters", "get_visible_characters"); ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_characters_behavior", PROPERTY_HINT_ENUM, "Characters Before Shaping,Characters After Shaping,Glyphs (Layout Direction),Glyphs (Left-to-Right),Glyphs (Right-to-Left)"), "set_visible_characters_behavior", "get_visible_characters_behavior"); diff --git a/scene/gui/menu_bar.cpp b/scene/gui/menu_bar.cpp index 9eba2feaf7..9b7b67d83e 100644 --- a/scene/gui/menu_bar.cpp +++ b/scene/gui/menu_bar.cpp @@ -60,7 +60,7 @@ void MenuBar::gui_input(const Ref<InputEvent> &p_event) { if (active_menu >= 0) { get_menu_popup(active_menu)->hide(); } - _open_popup(selected_menu); + _open_popup(selected_menu, true); } return; } else if (p_event->is_action("ui_right") && p_event->is_pressed()) { @@ -82,7 +82,7 @@ void MenuBar::gui_input(const Ref<InputEvent> &p_event) { if (active_menu >= 0) { get_menu_popup(active_menu)->hide(); } - _open_popup(selected_menu); + _open_popup(selected_menu, true); } return; } @@ -110,7 +110,7 @@ void MenuBar::gui_input(const Ref<InputEvent> &p_event) { } } -void MenuBar::_open_popup(int p_index) { +void MenuBar::_open_popup(int p_index, bool p_focus_item) { ERR_FAIL_INDEX(p_index, menu_cache.size()); PopupMenu *pm = get_menu_popup(p_index); @@ -134,6 +134,15 @@ void MenuBar::_open_popup(int p_index) { pm->set_parent_rect(Rect2(Point2(screen_pos - pm->get_position()), Size2(screen_size.x, screen_pos.y))); pm->popup(); + if (p_focus_item) { + for (int i = 0; i < pm->get_item_count(); i++) { + if (!pm->is_item_disabled(i)) { + pm->set_current_index(i); + break; + } + } + } + update(); } diff --git a/scene/gui/menu_bar.h b/scene/gui/menu_bar.h index 3c4a25fd06..b7d9933ab2 100644 --- a/scene/gui/menu_bar.h +++ b/scene/gui/menu_bar.h @@ -84,7 +84,7 @@ class MenuBar : public Control { Vector<PopupMenu *> _get_popups() const; int get_menu_idx_from_control(PopupMenu *p_child) const; - void _open_popup(int p_index); + void _open_popup(int p_index, bool p_focus_item = false); void _popup_visibility_changed(bool p_visible); void _update_submenu(const String &p_menu_name, PopupMenu *p_child); void _clear_menu(); diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index e6e17cc881..f779f87ae7 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -103,9 +103,14 @@ void MenuButton::pressed() { popup->set_position(gp); popup->set_parent_rect(Rect2(Point2(gp - popup->get_position()), size)); - // If not triggered by the mouse, start the popup with its first item selected. - if (popup->get_item_count() > 0 && !_was_pressed_by_mouse()) { - popup->set_current_index(0); + // If not triggered by the mouse, start the popup with its first enabled item focused. + if (!_was_pressed_by_mouse()) { + for (int i = 0; i < popup->get_item_count(); i++) { + if (!popup->is_item_disabled(i)) { + popup->set_current_index(i); + break; + } + } } popup->popup(); @@ -161,7 +166,10 @@ void MenuButton::_notification(int p_what) { if (menu_btn_other && menu_btn_other != this && menu_btn_other->is_switch_on_hover() && !menu_btn_other->is_disabled() && (get_parent()->is_ancestor_of(menu_btn_other) || menu_btn_other->get_parent()->is_ancestor_of(popup))) { popup->hide(); + menu_btn_other->pressed(); + // As the popup wasn't triggered by a mouse click, the item focus needs to be removed manually. + menu_btn_other->get_popup()->set_current_index(-1); } } break; } diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index 881acdbf3a..a87c46e8ac 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -207,12 +207,24 @@ void OptionButton::pressed() { popup->set_position(get_screen_position() + Size2(0, size.height * get_global_transform().get_scale().y)); popup->set_size(Size2(size.width, 0)); - // If not triggered by the mouse, start the popup with the checked item selected. - if (popup->get_item_count() > 0) { + // If not triggered by the mouse, start the popup with the checked item (or the first enabled one) focused. + if (current != NONE_SELECTED && !popup->is_item_disabled(current)) { if (!_was_pressed_by_mouse()) { - popup->set_current_index(current > -1 ? current : 0); + popup->set_current_index(current); } else { - popup->scroll_to_item(current > -1 ? current : 0); + popup->scroll_to_item(current); + } + } else { + for (int i = 0; i < popup->get_item_count(); i++) { + if (!popup->is_item_disabled(i)) { + if (!_was_pressed_by_mouse()) { + popup->set_current_index(i); + } else { + popup->scroll_to_item(i); + } + + break; + } } } diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp index 7461f48a6c..c4396f636a 100644 --- a/scene/gui/popup.cpp +++ b/scene/gui/popup.cpp @@ -240,7 +240,8 @@ void PopupPanel::_notification(int p_what) { panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), get_class_name())); } break; - case NOTIFICATION_ENTER_TREE: { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_READY: { panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), get_class_name())); _update_child_rects(); } break; diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 4e2aec0278..c8bb9fd530 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -216,9 +216,14 @@ void PopupMenu::_activate_submenu(int p_over, bool p_by_keyboard) { submenu_pum->activated_by_keyboard = p_by_keyboard; - // If not triggered by the mouse, start the popup with its first item selected. - if (submenu_pum->get_item_count() > 0 && p_by_keyboard) { - submenu_pum->set_current_index(0); + // If not triggered by the mouse, start the popup with its first enabled item focused. + if (p_by_keyboard) { + for (int i = 0; i < submenu_pum->get_item_count(); i++) { + if (!submenu_pum->is_item_disabled(i)) { + submenu_pum->set_current_index(i); + break; + } + } } submenu_pum->popup(); @@ -278,102 +283,104 @@ void PopupMenu::_submenu_timeout() { void PopupMenu::gui_input(const Ref<InputEvent> &p_event) { ERR_FAIL_COND(p_event.is_null()); - if (p_event->is_action("ui_down") && p_event->is_pressed()) { - int search_from = mouse_over + 1; - if (search_from >= items.size()) { - search_from = 0; - } - - bool match_found = false; - for (int i = search_from; i < items.size(); i++) { - if (!items[i].separator && !items[i].disabled) { - mouse_over = i; - emit_signal(SNAME("id_focused"), i); - scroll_to_item(i); - control->update(); - set_input_as_handled(); - match_found = true; - break; + if (!items.is_empty()) { + if (p_event->is_action("ui_down") && p_event->is_pressed()) { + int search_from = mouse_over + 1; + if (search_from >= items.size()) { + search_from = 0; } - } - if (!match_found) { - // If the last item is not selectable, try re-searching from the start. - for (int i = 0; i < search_from; i++) { + bool match_found = false; + for (int i = search_from; i < items.size(); i++) { if (!items[i].separator && !items[i].disabled) { mouse_over = i; emit_signal(SNAME("id_focused"), i); scroll_to_item(i); control->update(); set_input_as_handled(); + match_found = true; break; } } - } - } else if (p_event->is_action("ui_up") && p_event->is_pressed()) { - int search_from = mouse_over - 1; - if (search_from < 0) { - search_from = items.size() - 1; - } - bool match_found = false; - for (int i = search_from; i >= 0; i--) { - if (!items[i].separator && !items[i].disabled) { - mouse_over = i; - emit_signal(SNAME("id_focused"), i); - scroll_to_item(i); - control->update(); - set_input_as_handled(); - match_found = true; - break; + if (!match_found) { + // If the last item is not selectable, try re-searching from the start. + for (int i = 0; i < search_from; i++) { + if (!items[i].separator && !items[i].disabled) { + mouse_over = i; + emit_signal(SNAME("id_focused"), i); + scroll_to_item(i); + control->update(); + set_input_as_handled(); + break; + } + } + } + } else if (p_event->is_action("ui_up") && p_event->is_pressed()) { + int search_from = mouse_over - 1; + if (search_from < 0) { + search_from = items.size() - 1; } - } - if (!match_found) { - // If the first item is not selectable, try re-searching from the end. - for (int i = items.size() - 1; i >= search_from; i--) { + bool match_found = false; + for (int i = search_from; i >= 0; i--) { if (!items[i].separator && !items[i].disabled) { mouse_over = i; emit_signal(SNAME("id_focused"), i); scroll_to_item(i); control->update(); set_input_as_handled(); + match_found = true; break; } } - } - } else if (p_event->is_action("ui_left") && p_event->is_pressed()) { - Node *n = get_parent(); - if (n) { - if (Object::cast_to<PopupMenu>(n)) { - hide(); - set_input_as_handled(); - } else if (Object::cast_to<MenuBar>(n)) { - Object::cast_to<MenuBar>(n)->gui_input(p_event); - set_input_as_handled(); - return; + + if (!match_found) { + // If the first item is not selectable, try re-searching from the end. + for (int i = items.size() - 1; i >= search_from; i--) { + if (!items[i].separator && !items[i].disabled) { + mouse_over = i; + emit_signal(SNAME("id_focused"), i); + scroll_to_item(i); + control->update(); + set_input_as_handled(); + break; + } + } } - } - } else if (p_event->is_action("ui_right") && p_event->is_pressed()) { - if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator && !items[mouse_over].submenu.is_empty() && submenu_over != mouse_over) { - _activate_submenu(mouse_over, true); - set_input_as_handled(); - } else { + } else if (p_event->is_action("ui_left") && p_event->is_pressed()) { Node *n = get_parent(); - if (n && Object::cast_to<MenuBar>(n)) { - Object::cast_to<MenuBar>(n)->gui_input(p_event); - set_input_as_handled(); - return; + if (n) { + if (Object::cast_to<PopupMenu>(n)) { + hide(); + set_input_as_handled(); + } else if (Object::cast_to<MenuBar>(n)) { + Object::cast_to<MenuBar>(n)->gui_input(p_event); + set_input_as_handled(); + return; + } } - } - } else if (p_event->is_action("ui_accept") && p_event->is_pressed()) { - if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator) { - if (!items[mouse_over].submenu.is_empty() && submenu_over != mouse_over) { + } else if (p_event->is_action("ui_right") && p_event->is_pressed()) { + if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator && !items[mouse_over].submenu.is_empty() && submenu_over != mouse_over) { _activate_submenu(mouse_over, true); + set_input_as_handled(); } else { - activate_item(mouse_over); + Node *n = get_parent(); + if (n && Object::cast_to<MenuBar>(n)) { + Object::cast_to<MenuBar>(n)->gui_input(p_event); + set_input_as_handled(); + return; + } + } + } else if (p_event->is_action("ui_accept") && p_event->is_pressed()) { + if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator) { + if (!items[mouse_over].submenu.is_empty() && submenu_over != mouse_over) { + _activate_submenu(mouse_over, true); + } else { + activate_item(mouse_over); + } + set_input_as_handled(); } - set_input_as_handled(); } } @@ -1532,14 +1539,19 @@ bool PopupMenu::is_item_shortcut_disabled(int p_idx) const { } void PopupMenu::set_current_index(int p_idx) { - ERR_FAIL_INDEX(p_idx, items.size()); + if (p_idx != -1) { + ERR_FAIL_INDEX(p_idx, items.size()); + } if (mouse_over == p_idx) { return; } mouse_over = p_idx; - scroll_to_item(mouse_over); + if (mouse_over != -1) { + scroll_to_item(mouse_over); + } + control->update(); } diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 3f1f16cd51..8ce8663091 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -5172,31 +5172,36 @@ void RichTextLabel::_bind_methods() { // Note: set "bbcode_enabled" first, to avoid unnecessary "text" resets. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bbcode_enabled"), "set_use_bbcode", "is_using_bbcode"); - - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "threaded"), "set_threaded", "is_threaded"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "progress_bar_delay", PROPERTY_HINT_NONE, "suffix:ms"), "set_progress_bar_delay", "get_progress_bar_delay"); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_size", PROPERTY_HINT_RANGE, "0,24,1"), "set_tab_size", "get_tab_size"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT), "set_text", "get_text"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fit_content_height"), "set_fit_content_height", "is_fit_content_height_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_active"), "set_scroll_active", "is_scroll_active"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_following"), "set_scroll_follow", "is_scroll_following"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selection_enabled"), "set_selection_enabled", "is_selection_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_selected_font_color"), "set_override_selected_font_color", "is_overriding_selected_font_color"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deselect_on_focus_loss_enabled"), "set_deselect_on_focus_loss_enabled", "is_deselect_on_focus_loss_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "autowrap_mode", PROPERTY_HINT_ENUM, "Off,Arbitrary,Word,Word (Smart)"), "set_autowrap_mode", "get_autowrap_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_size", PROPERTY_HINT_RANGE, "0,24,1"), "set_tab_size", "get_tab_size"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_keys_enabled"), "set_shortcut_keys_enabled", "is_shortcut_keys_enabled"); + + ADD_GROUP("Markup", ""); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "custom_effects", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "RichTextEffect"), (PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE)), "set_effects", "get_effects"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "meta_underlined"), "set_meta_underline", "is_meta_underlined"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hint_underlined"), "set_hint_underline", "is_hint_underlined"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "autowrap_mode", PROPERTY_HINT_ENUM, "Off,Arbitrary,Word,Word (Smart)"), "set_autowrap_mode", "get_autowrap_mode"); + ADD_GROUP("Threading", ""); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "threaded"), "set_threaded", "is_threaded"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "progress_bar_delay", PROPERTY_HINT_NONE, "suffix:ms"), "set_progress_bar_delay", "get_progress_bar_delay"); + + ADD_GROUP("Text Selection", ""); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selection_enabled"), "set_selection_enabled", "is_selection_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_selected_font_color"), "set_override_selected_font_color", "is_overriding_selected_font_color"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deselect_on_focus_loss_enabled"), "set_deselect_on_focus_loss_enabled", "is_deselect_on_focus_loss_enabled"); + + ADD_GROUP("Displayed Text", ""); // Note: "visible_characters" and "visible_ratio" should be set after "text" to be correctly applied. ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_characters", PROPERTY_HINT_RANGE, "-1,128000,1"), "set_visible_characters", "get_visible_characters"); ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_characters_behavior", PROPERTY_HINT_ENUM, "Characters Before Shaping,Characters After Shaping,Glyphs (Layout Direction),Glyphs (Left-to-Right),Glyphs (Right-to-Left)"), "set_visible_characters_behavior", "get_visible_characters_behavior"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visible_ratio", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_visible_ratio", "get_visible_ratio"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_keys_enabled"), "set_shortcut_keys_enabled", "is_shortcut_keys_enabled"); - ADD_GROUP("BiDi", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "set_language", "get_language"); diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index f58cb0fe70..8fd547813d 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -317,9 +317,10 @@ void ScrollContainer::_reposition_children() { void ScrollContainer::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: - case NOTIFICATION_TRANSLATION_CHANGED: - case NOTIFICATION_THEME_CHANGED: { + case NOTIFICATION_TRANSLATION_CHANGED: { _updating_scrollbars = true; call_deferred(SNAME("_update_scrollbar_position")); } break; diff --git a/scene/main/window.h b/scene/main/window.h index ebaf8fea75..a5b6b26104 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -168,7 +168,6 @@ public: enum { NOTIFICATION_VISIBILITY_CHANGED = 30, NOTIFICATION_POST_POPUP = 31, - // This doesn't need to be paired with `NOTIFICATION_ENTER_TREE`. NOTIFICATION_THEME_CHANGED = 32 }; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 8b43f778e5..5243d4bdca 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -611,6 +611,7 @@ void register_scene_types() { GDREGISTER_CLASS(VisualShaderNodeColorFunc); GDREGISTER_CLASS(VisualShaderNodeTransformFunc); GDREGISTER_CLASS(VisualShaderNodeUVFunc); + GDREGISTER_CLASS(VisualShaderNodeUVPolarCoord); GDREGISTER_CLASS(VisualShaderNodeDotProduct); GDREGISTER_CLASS(VisualShaderNodeVectorLen); GDREGISTER_CLASS(VisualShaderNodeDeterminant); @@ -649,6 +650,7 @@ void register_scene_types() { GDREGISTER_CLASS(VisualShaderNodeTexture2DArrayUniform); GDREGISTER_CLASS(VisualShaderNodeTexture3DUniform); GDREGISTER_CLASS(VisualShaderNodeCubemapUniform); + GDREGISTER_CLASS(VisualShaderNodeLinearSceneDepth); GDREGISTER_CLASS(VisualShaderNodeIf); GDREGISTER_CLASS(VisualShaderNodeSwitch); GDREGISTER_CLASS(VisualShaderNodeFresnel); @@ -658,6 +660,10 @@ void register_scene_types() { GDREGISTER_CLASS(VisualShaderNodeCompare); GDREGISTER_CLASS(VisualShaderNodeMultiplyAdd); GDREGISTER_CLASS(VisualShaderNodeBillboard); + GDREGISTER_CLASS(VisualShaderNodeDistanceFade); + GDREGISTER_CLASS(VisualShaderNodeProximityFade); + GDREGISTER_CLASS(VisualShaderNodeRandomRange); + GDREGISTER_CLASS(VisualShaderNodeRemap); GDREGISTER_ABSTRACT_CLASS(VisualShaderNodeVarying); GDREGISTER_CLASS(VisualShaderNodeVaryingSetter); GDREGISTER_CLASS(VisualShaderNodeVaryingGetter); diff --git a/scene/resources/animation_library.cpp b/scene/resources/animation_library.cpp index 5f725b2fbe..427d418551 100644 --- a/scene/resources/animation_library.cpp +++ b/scene/resources/animation_library.cpp @@ -85,7 +85,7 @@ bool AnimationLibrary::has_animation(const StringName &p_name) const { } Ref<Animation> AnimationLibrary::get_animation(const StringName &p_name) const { - ERR_FAIL_COND_V(!animations.has(p_name), Ref<Animation>()); + ERR_FAIL_COND_V_MSG(!animations.has(p_name), Ref<Animation>(), vformat("Animation not found: \"%s\".", p_name)); return animations[p_name]; } diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 0e1b18d584..33334801c3 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -279,25 +279,36 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const { Ref<Resource> res = value; if (res.is_valid()) { if (res->is_local_to_scene()) { - HashMap<Ref<Resource>, Ref<Resource>>::Iterator E = resources_local_to_scene.find(res); - - if (E) { - value = E->value; + // In a situation where a local-to-scene resource is used in a child node of a non-editable instance, + // we need to avoid the parent scene from overriding the resource potentially also used in the root + // of the instantiated scene. That would to the instance having two different instances of the resource. + // Since at this point it's too late to propagate the resource instance in the parent scene to all the relevant + // nodes in the instance (and that would require very complex bookkepping), what we do instead is + // tampering the resource object already there with the values from the node in the parent scene and + // then tell this node to reference that resource. + if (n.instance >= 0) { + Ref<Resource> node_res = node->get(snames[nprops[j].name]); + if (node_res.is_valid()) { + node_res->copy_from(res); + node_res->configure_for_local_scene(node, resources_local_to_scene); + value = node_res; + } } else { + HashMap<Ref<Resource>, Ref<Resource>>::Iterator E = resources_local_to_scene.find(res); Node *base = i == 0 ? node : ret_nodes[0]; - - if (p_edit_state == GEN_EDIT_STATE_MAIN || p_edit_state == GEN_EDIT_STATE_MAIN_INHERITED) { - //for the main scene, use the resource as is - res->configure_for_local_scene(base, resources_local_to_scene); - resources_local_to_scene[res] = res; - + if (E) { + value = E->value; } else { - //for instances, a copy must be made - Node *base2 = i == 0 ? node : ret_nodes[0]; - Ref<Resource> local_dupe = res->duplicate_for_local_scene(base2, resources_local_to_scene); - resources_local_to_scene[res] = local_dupe; - res = local_dupe; - value = local_dupe; + if (p_edit_state == GEN_EDIT_STATE_MAIN) { + //for the main scene, use the resource as is + res->configure_for_local_scene(base, resources_local_to_scene); + resources_local_to_scene[res] = res; + } else { + //for instances, a copy must be made + Ref<Resource> local_dupe = res->duplicate_for_local_scene(base, resources_local_to_scene); + resources_local_to_scene[res] = local_dupe; + value = local_dupe; + } } } //must make a copy, because this res is local to scene @@ -398,7 +409,9 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const { } for (KeyValue<Ref<Resource>, Ref<Resource>> &E : resources_local_to_scene) { - E.value->setup_local_to_scene(); + if (E.value->get_local_scene() == ret_nodes[0]) { + E.value->setup_local_to_scene(); + } } //do connections diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 2911d726b4..3b2b58516d 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -1606,6 +1606,51 @@ VisualShaderNodeCubemap::VisualShaderNodeCubemap() { simple_decl = false; } +////////////// Linear Depth + +String VisualShaderNodeLinearSceneDepth::get_caption() const { + return "LinearSceneDepth"; +} + +int VisualShaderNodeLinearSceneDepth::get_input_port_count() const { + return 0; +} + +VisualShaderNodeLinearSceneDepth::PortType VisualShaderNodeLinearSceneDepth::get_input_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeLinearSceneDepth::get_input_port_name(int p_port) const { + return ""; +} + +int VisualShaderNodeLinearSceneDepth::get_output_port_count() const { + return 1; +} + +VisualShaderNodeLinearSceneDepth::PortType VisualShaderNodeLinearSceneDepth::get_output_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeLinearSceneDepth::get_output_port_name(int p_port) const { + return "linear depth"; +} + +String VisualShaderNodeLinearSceneDepth::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String code; + + code += " float _log_depth = texture(DEPTH_TEXTURE, SCREEN_UV).x;\n"; + code += " vec3 _depth_ndc = vec3(SCREEN_UV * 2.0 - 1.0, _log_depth);\n"; + code += " vec4 _depth_view = INV_PROJECTION_MATRIX * vec4(_depth_ndc, 1.0);\n"; + code += " _depth_view.xyz /= _depth_view.w;"; + code += vformat(" %s = -_depth_view.z;", p_output_vars[0]); + + return code; +} + +VisualShaderNodeLinearSceneDepth::VisualShaderNodeLinearSceneDepth() { +} + ////////////// Float Op String VisualShaderNodeFloatOp::get_caption() const { @@ -3090,6 +3135,107 @@ VisualShaderNodeUVFunc::VisualShaderNodeUVFunc() { set_input_port_default_value(2, Vector2()); // offset } +////////////// UV PolarCoord + +String VisualShaderNodeUVPolarCoord::get_caption() const { + return "UVPolarCoord"; +} + +int VisualShaderNodeUVPolarCoord::get_input_port_count() const { + return 4; +} + +VisualShaderNodeUVPolarCoord::PortType VisualShaderNodeUVPolarCoord::get_input_port_type(int p_port) const { + switch (p_port) { + case 0: + return PORT_TYPE_VECTOR_2D; // uv + case 1: + return PORT_TYPE_VECTOR_2D; // center + case 2: + return PORT_TYPE_SCALAR; // zoom + case 3: + return PORT_TYPE_SCALAR; // repeat + default: + break; + } + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeUVPolarCoord::get_input_port_name(int p_port) const { + switch (p_port) { + case 0: + return "uv"; + case 1: + return "scale"; + case 2: + return "zoom strength"; + case 3: + return "repeat"; + default: + break; + } + return ""; +} + +bool VisualShaderNodeUVPolarCoord::is_input_port_default(int p_port, Shader::Mode p_mode) const { + if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) { + if (p_port == 0) { + return true; + } + } + return false; +} + +int VisualShaderNodeUVPolarCoord::get_output_port_count() const { + return 1; +} + +VisualShaderNodeUVPolarCoord::PortType VisualShaderNodeUVPolarCoord::get_output_port_type(int p_port) const { + return PORT_TYPE_VECTOR_2D; +} + +String VisualShaderNodeUVPolarCoord::get_output_port_name(int p_port) const { + return "uv"; +} + +String VisualShaderNodeUVPolarCoord::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String code; + + String uv; + if (p_input_vars[0].is_empty()) { + if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) { + uv = "UV"; + } else { + uv = "vec2(0.0)"; + } + } else { + uv = vformat("%s", p_input_vars[0]); + } + String center = vformat("%s", p_input_vars[1]); + String zoom = vformat("%s", p_input_vars[2]); + String repeat = vformat("%s", p_input_vars[3]); + + if (p_mode == Shader::MODE_CANVAS_ITEM) { + code += vformat(" vec2 __dir = %s - %s;\n", uv, center); + code += " float __radius = length(__dir) * 2.0;\n"; + code += " float __angle = atan(__dir.y, __dir.x) * 1.0/(PI * 2.0);\n"; + code += vformat(" %s = mod(vec2(__radius * %s, __angle * %s), 1.0);\n", p_output_vars[0], zoom, repeat); + } else { + code += vformat(" vec2 __dir = %s - %s;\n", uv, center); + code += " float __radius = length(__dir) * 2.0;\n"; + code += " float __angle = atan(__dir.y, __dir.x) * 1.0/(PI * 2.0);\n"; + code += vformat(" %s = vec2(__radius * %s, __angle * %s);\n", p_output_vars[0], zoom, repeat); + } + + return code; +} + +VisualShaderNodeUVPolarCoord::VisualShaderNodeUVPolarCoord() { + set_input_port_default_value(1, Vector2(0.5, 0.5)); // center + set_input_port_default_value(2, 1.0); // zoom + set_input_port_default_value(3, 1.0); // repeat +} + ////////////// Dot Product String VisualShaderNodeDotProduct::get_caption() const { @@ -7010,3 +7156,261 @@ void VisualShaderNodeBillboard::_bind_methods() { VisualShaderNodeBillboard::VisualShaderNodeBillboard() { simple_decl = false; } + +////////////// DistanceFade + +String VisualShaderNodeDistanceFade::get_caption() const { + return "DistanceFade"; +} + +int VisualShaderNodeDistanceFade::get_input_port_count() const { + return 2; +} + +VisualShaderNodeDistanceFade::PortType VisualShaderNodeDistanceFade::get_input_port_type(int p_port) const { + switch (p_port) { + case 0: + return PORT_TYPE_SCALAR; + case 1: + return PORT_TYPE_SCALAR; + } + + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeDistanceFade::get_input_port_name(int p_port) const { + switch (p_port) { + case 0: + return "min"; + case 1: + return "max"; + } + + return ""; +} + +int VisualShaderNodeDistanceFade::get_output_port_count() const { + return 1; +} + +VisualShaderNodeDistanceFade::PortType VisualShaderNodeDistanceFade::get_output_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeDistanceFade::get_output_port_name(int p_port) const { + return "amount"; +} + +String VisualShaderNodeDistanceFade::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String code; + code += vformat(" %s = clamp(smoothstep(%s, %s,-VERTEX.z),0.0,1.0);\n", p_output_vars[0], p_input_vars[0], p_input_vars[1]); + return code; +} + +VisualShaderNodeDistanceFade::VisualShaderNodeDistanceFade() { + set_input_port_default_value(0, 0.0); + set_input_port_default_value(1, 10.0); +} + +////////////// ProximityFade + +String VisualShaderNodeProximityFade::get_caption() const { + return "ProximityFade"; +} + +int VisualShaderNodeProximityFade::get_input_port_count() const { + return 1; +} + +VisualShaderNodeProximityFade::PortType VisualShaderNodeProximityFade::get_input_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeProximityFade::get_input_port_name(int p_port) const { + return "distance"; +} + +int VisualShaderNodeProximityFade::get_output_port_count() const { + return 1; +} + +VisualShaderNodeProximityFade::PortType VisualShaderNodeProximityFade::get_output_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeProximityFade::get_output_port_name(int p_port) const { + return "fade"; +} + +String VisualShaderNodeProximityFade::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String code; + + String proximity_fade_distance = vformat("%s", p_input_vars[0]); + code += " float __depth_tex = textureLod(DEPTH_TEXTURE, SCREEN_UV, 0.0).r;\n"; + code += " vec4 __depth_world_pos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV * 2.0 - 1.0, __depth_tex, 1.0);\n"; + code += " __depth_world_pos.xyz /= __depth_world_pos.z;\n"; + code += vformat(" %s = clamp(1.0 - smoothstep(__depth_world_pos.z + %s, __depth_world_pos.z, VERTEX.z), 0.0, 1.0);\n", p_output_vars[0], p_input_vars[0]); + + return code; +} + +VisualShaderNodeProximityFade::VisualShaderNodeProximityFade() { + set_input_port_default_value(0, 1.0); +} + +////////////// Random Range + +String VisualShaderNodeRandomRange::get_caption() const { + return "RandomRange"; +} + +int VisualShaderNodeRandomRange::get_input_port_count() const { + return 3; +} + +VisualShaderNodeRandomRange::PortType VisualShaderNodeRandomRange::get_input_port_type(int p_port) const { + switch (p_port) { + case 0: + return PORT_TYPE_VECTOR_3D; + case 1: + return PORT_TYPE_SCALAR; + case 2: + return PORT_TYPE_SCALAR; + default: + break; + } + + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeRandomRange::get_input_port_name(int p_port) const { + switch (p_port) { + case 0: + return "seed"; + case 1: + return "min"; + case 2: + return "max"; + default: + break; + } + + return ""; +} + +int VisualShaderNodeRandomRange::get_output_port_count() const { + return 1; +} + +VisualShaderNodeRandomRange::PortType VisualShaderNodeRandomRange::get_output_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeRandomRange::get_output_port_name(int p_port) const { + return "value"; +} + +String VisualShaderNodeRandomRange::generate_global_per_node(Shader::Mode p_mode, int p_id) const { + String code; + + code += "\n\n"; + code += "// 3D Noise with friendly permission by Inigo Quilez\n"; + code += "vec3 hash_noise_range( vec3 p ) {\n"; + code += " p *= mat3(vec3(127.1, 311.7, -53.7), vec3(269.5, 183.3, 77.1), vec3(-301.7, 27.3, 215.3));\n"; + code += " return 2.0 * fract(fract(p)*4375.55) -1.;\n"; + code += "}\n"; + code += "\n"; + + return code; +} + +String VisualShaderNodeRandomRange::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String code; + + code += vformat(" %s = mix(%s, %s, hash_noise_range(%s).x);\n", p_output_vars[0], p_input_vars[1], p_input_vars[2], p_input_vars[0]); + + return code; +} + +VisualShaderNodeRandomRange::VisualShaderNodeRandomRange() { + set_input_port_default_value(0, Vector3(1.0, 1.0, 1.0)); + set_input_port_default_value(1, 0.0); + set_input_port_default_value(2, 1.0); +} + +////////////// Remap + +String VisualShaderNodeRemap::get_caption() const { + return "Remap"; +} + +int VisualShaderNodeRemap::get_input_port_count() const { + return 5; +} + +VisualShaderNodeRemap::PortType VisualShaderNodeRemap::get_input_port_type(int p_port) const { + switch (p_port) { + case 0: + return PORT_TYPE_SCALAR; + case 1: + return PORT_TYPE_SCALAR; + case 2: + return PORT_TYPE_SCALAR; + case 3: + return PORT_TYPE_SCALAR; + case 4: + return PORT_TYPE_SCALAR; + default: + break; + } + + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeRemap::get_input_port_name(int p_port) const { + switch (p_port) { + case 0: + return "value"; + case 1: + return "input min"; + case 2: + return "input max"; + case 3: + return "output min"; + case 4: + return "output max"; + default: + break; + } + + return ""; +} + +int VisualShaderNodeRemap::get_output_port_count() const { + return 1; +} + +VisualShaderNodeRemap::PortType VisualShaderNodeRemap::get_output_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeRemap::get_output_port_name(int p_port) const { + return "value"; +} + +String VisualShaderNodeRemap::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String code; + + code += vformat(" float _input_range = %s - %s;\n", p_input_vars[2], p_input_vars[1]); + code += vformat(" float _output_range = %s - %s;\n", p_input_vars[4], p_input_vars[3]); + code += vformat(" %s = %s + _output_range * ((%s - %s) / _input_range);\n", p_output_vars[0], p_input_vars[3], p_input_vars[0], p_input_vars[1]); + + return code; +} + +VisualShaderNodeRemap::VisualShaderNodeRemap() { + set_input_port_default_value(1, 0.0); + set_input_port_default_value(2, 1.0); + set_input_port_default_value(3, 0.0); + set_input_port_default_value(4, 1.0); +} diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index ffcb41072d..c603a10eae 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -622,6 +622,27 @@ VARIANT_ENUM_CAST(VisualShaderNodeCubemap::TextureType) VARIANT_ENUM_CAST(VisualShaderNodeCubemap::Source) /////////////////////////////////////// + +class VisualShaderNodeLinearSceneDepth : public VisualShaderNode { + GDCLASS(VisualShaderNodeLinearSceneDepth, VisualShaderNode); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeLinearSceneDepth(); +}; + +/////////////////////////////////////// /// OPS /////////////////////////////////////// @@ -1231,6 +1252,30 @@ public: VARIANT_ENUM_CAST(VisualShaderNodeUVFunc::Function) /////////////////////////////////////// +/// UV POLARCOORD +/////////////////////////////////////// + +class VisualShaderNodeUVPolarCoord : public VisualShaderNode { + GDCLASS(VisualShaderNodeUVPolarCoord, VisualShaderNode); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + virtual bool is_input_port_default(int p_port, Shader::Mode p_mode) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeUVPolarCoord(); +}; + +/////////////////////////////////////// /// DOT /////////////////////////////////////// @@ -2574,4 +2619,85 @@ public: VARIANT_ENUM_CAST(VisualShaderNodeBillboard::BillboardType) +/////////////////////////////////////// +/// DistanceFade +/////////////////////////////////////// + +class VisualShaderNodeDistanceFade : public VisualShaderNode { + GDCLASS(VisualShaderNodeDistanceFade, VisualShaderNode); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeDistanceFade(); +}; + +class VisualShaderNodeProximityFade : public VisualShaderNode { + GDCLASS(VisualShaderNodeProximityFade, VisualShaderNode); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeProximityFade(); +}; + +class VisualShaderNodeRandomRange : public VisualShaderNode { + GDCLASS(VisualShaderNodeRandomRange, VisualShaderNode); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_global_per_node(Shader::Mode p_mode, int p_id) const override; + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeRandomRange(); +}; + +class VisualShaderNodeRemap : public VisualShaderNode { + GDCLASS(VisualShaderNodeRemap, VisualShaderNode); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeRemap(); +}; + #endif // VISUAL_SHADER_NODES_H |