diff options
Diffstat (limited to 'editor')
-rw-r--r-- | editor/editor_about.cpp | 2 | ||||
-rw-r--r-- | editor/editor_help.cpp | 16 | ||||
-rw-r--r-- | editor/editor_node.cpp | 56 | ||||
-rw-r--r-- | editor/editor_node.h | 3 | ||||
-rw-r--r-- | editor/editor_themes.cpp | 19 | ||||
-rw-r--r-- | editor/plugins/canvas_item_editor_plugin.cpp | 87 | ||||
-rw-r--r-- | editor/plugins/canvas_item_editor_plugin.h | 3 | ||||
-rw-r--r-- | editor/plugins/script_editor_plugin.cpp | 8 | ||||
-rw-r--r-- | editor/plugins/spatial_editor_plugin.cpp | 317 | ||||
-rw-r--r-- | editor/plugins/spatial_editor_plugin.h | 35 | ||||
-rw-r--r-- | editor/project_settings_editor.cpp | 52 | ||||
-rw-r--r-- | editor/project_settings_editor.h | 4 |
12 files changed, 534 insertions, 68 deletions
diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp index 6d2bf10a7d..a48e6c9057 100644 --- a/editor/editor_about.cpp +++ b/editor/editor_about.cpp @@ -77,7 +77,7 @@ ScrollContainer *EditorAbout::_populate_list(const String &p_name, const List<St il->set_same_column_width(true); il->set_auto_height(true); while (*names_ptr) { - il->add_item(String::utf8(*names_ptr++)); + il->add_item(String::utf8(*names_ptr++), NULL, false); } vbc->add_child(il); if (il->get_item_count() == 2) { diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index c9d1548bfb..7fa2c53275 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -1711,6 +1711,11 @@ void EditorHelp::_notification(int p_what) { _update_doc(); } break; + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { + + class_desc->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1))); + } break; + default: break; } } @@ -1785,6 +1790,7 @@ EditorHelp::EditorHelp() { class_desc = memnew(RichTextLabel); background_panel->add_child(class_desc); class_desc->set_area_as_parent_rect(); + class_desc->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1))); class_desc->connect("meta_clicked", this, "_class_desc_select"); class_desc->connect("gui_input", this, "_class_desc_input"); } @@ -1872,6 +1878,15 @@ void EditorHelpBit::_bind_methods() { } void EditorHelpBit::_notification(int p_what) { + + switch (p_what) { + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { + + rich_text->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1))); + } break; + + default: break; + } } void EditorHelpBit::set_text(const String &p_text) { @@ -1886,5 +1901,6 @@ EditorHelpBit::EditorHelpBit() { add_child(rich_text); rich_text->set_area_as_parent_rect(); rich_text->connect("meta_clicked", this, "_meta_clicked"); + rich_text->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1))); set_custom_minimum_size(Size2(0, 70 * EDSCALE)); } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index d4e0aacb0f..91d2ddcd19 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -283,13 +283,22 @@ void EditorNode::_notification(int p_what) { scene_tabs->set_tab_close_display_policy((bool(EDITOR_DEF("interface/always_show_close_button_in_scene_tabs", false)) ? Tabs::CLOSE_BUTTON_SHOW_ALWAYS : Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY)); property_editor->set_enable_capitalize_paths(bool(EDITOR_DEF("interface/capitalize_properties", true))); Ref<Theme> theme = create_editor_theme(theme_base->get_theme()); + theme_base->set_theme(theme); + gui_base->add_style_override("panel", gui_base->get_stylebox("Background", "EditorStyles")); play_button_panel->add_style_override("panel", gui_base->get_stylebox("PlayButtonPanel", "EditorStyles")); scene_root_parent->add_style_override("panel", gui_base->get_stylebox("Content", "EditorStyles")); bottom_panel->add_style_override("panel", gui_base->get_stylebox("panel", "TabContainer")); scene_tabs->add_style_override("tab_fg", gui_base->get_stylebox("SceneTabFG", "EditorStyles")); scene_tabs->add_style_override("tab_bg", gui_base->get_stylebox("SceneTabBG", "EditorStyles")); + + file_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + project_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + debug_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + settings_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + help_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + if (bool(EDITOR_DEF("interface/scene_tabs/resize_if_many_tabs", true))) { scene_tabs->set_min_width(int(EDITOR_DEF("interface/scene_tabs/minimum_width", 50)) * EDSCALE); } else { @@ -2732,6 +2741,14 @@ Dictionary EditorNode::_get_main_scene_state() { state["property_edit_offset"] = get_property_editor()->get_scene_tree()->get_vscroll_bar()->get_value(); state["saved_version"] = saved_version; state["node_filter"] = scene_tree_dock->get_filter(); + int current = -1; + for (int i = 0; i < editor_table.size(); i++) { + if (editor_plugin_screen == editor_table[i]) { + current = i; + break; + } + } + state["editor_index"] = current; return state; } @@ -2742,8 +2759,9 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) { changing_scene = false; - if (get_edited_scene()) { + if (p_state.has("editor_index")) { + int index = p_state["editor_index"]; int current = -1; for (int i = 0; i < editor_table.size(); i++) { if (editor_plugin_screen == editor_table[i]) { @@ -2752,15 +2770,18 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) { } } - if (current < 2) { - //use heuristic instead - - int n2d = 0, n3d = 0; - _find_node_types(get_edited_scene(), n2d, n3d); - if (n2d > n3d) { - _editor_select(EDITOR_2D); - } else if (n3d > n2d) { - _editor_select(EDITOR_3D); + if (current < 2) { //if currently in spatial/2d, only switch to spatial/2d. if curently in script, stay there + if (index < 2 || !get_edited_scene()) { + _editor_select(index); + } else { + //use heuristic instead + int n2d = 0, n3d = 0; + _find_node_types(get_edited_scene(), n2d, n3d); + if (n2d > n3d) { + _editor_select(EDITOR_2D); + } else if (n3d > n2d) { + _editor_select(EDITOR_3D); + } } } } @@ -4829,9 +4850,10 @@ EditorNode::EditorNode() { } file_menu = memnew(MenuButton); + file_menu->set_flat(false); file_menu->set_text(TTR("Scene")); - left_menu_hb->add_child(file_menu); file_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + left_menu_hb->add_child(file_menu); prev_scene = memnew(ToolButton); prev_scene->set_icon(gui_base->get_icon("PrevScene", "EditorIcons")); @@ -4919,6 +4941,7 @@ EditorNode::EditorNode() { p->add_item(TTR("Quit"), FILE_QUIT, KEY_MASK_CMD + KEY_Q); project_menu = memnew(MenuButton); + project_menu->set_flat(false); project_menu->set_tooltip(TTR("Miscellaneous project or scene-wide tools.")); project_menu->set_text(TTR("Project")); project_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); @@ -4952,9 +4975,11 @@ EditorNode::EditorNode() { menu_hb->add_child(editor_region); debug_menu = memnew(MenuButton); + debug_menu->set_flat(false); debug_menu->set_text(TTR("Debug")); debug_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); left_menu_hb->add_child(debug_menu); + p = debug_menu->get_popup(); p->set_hide_on_item_selection(false); p->add_check_item(TTR("Deploy with Remote Debug"), RUN_DEPLOY_REMOTE_DEBUG); @@ -4976,9 +5001,10 @@ EditorNode::EditorNode() { menu_hb->add_spacer(); settings_menu = memnew(MenuButton); - left_menu_hb->add_child(settings_menu); + settings_menu->set_flat(false); settings_menu->set_text(TTR("Editor")); settings_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + left_menu_hb->add_child(settings_menu); p = settings_menu->get_popup(); p->add_item(TTR("Editor Settings"), SETTINGS_PREFERENCES); @@ -4993,10 +5019,12 @@ EditorNode::EditorNode() { p->add_item(TTR("Manage Export Templates"), SETTINGS_MANAGE_EXPORT_TEMPLATES); // Help Menu - MenuButton *help_menu = memnew(MenuButton); - left_menu_hb->add_child(help_menu); + help_menu = memnew(MenuButton); + help_menu->set_flat(false); help_menu->set_text(TTR("Help")); help_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + left_menu_hb->add_child(help_menu); + p = help_menu->get_popup(); p->connect("id_pressed", this, "_menu_option"); p->add_icon_item(gui_base->get_icon("ClassList", "EditorIcons"), TTR("Classes"), HELP_CLASSES); diff --git a/editor/editor_node.h b/editor/editor_node.h index c3ceee350a..ea74bcbd9d 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -236,11 +236,12 @@ private: MenuButton *file_menu; MenuButton *project_menu; MenuButton *debug_menu; + MenuButton *settings_menu; + MenuButton *help_menu; PopupMenu *tool_menu; ToolButton *export_button; ToolButton *prev_scene; MenuButton *object_menu; - MenuButton *settings_menu; ToolButton *play_button; MenuButton *native_play_button; ToolButton *pause_button; diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 728801d90b..1a7ee0e970 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -237,8 +237,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Color dark_color_2 = base_color.linear_interpolate(Color(0, 0, 0, 1), contrast * 1.5); Color dark_color_3 = base_color.linear_interpolate(Color(0, 0, 0, 1), contrast * 2); - Color contrast_color_1 = base_color.linear_interpolate((dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)), 0.3); - Color contrast_color_2 = base_color.linear_interpolate((dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)), 0.5); + Color contrast_color_1 = base_color.linear_interpolate((dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)), MAX(contrast, default_contrast)); + Color contrast_color_2 = base_color.linear_interpolate((dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)), MAX(contrast * 1.5, default_contrast * 1.5)); Color font_color = dark_theme ? Color(1, 1, 1) : Color(0, 0, 0); Color font_color_disabled = dark_theme ? Color(0.6, 0.6, 0.6) : Color(0.45, 0.45, 0.45); @@ -303,12 +303,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Ref<StyleBoxFlat> style_menu_hover_bg = make_flat_stylebox(dark_color_2, 4, 4, 4, 4); style_menu_hover_border->set_draw_center(false); - style_menu_hover_border->set_border_width(MARGIN_BOTTOM, border_width); + style_menu_hover_border->set_border_width(MARGIN_BOTTOM, 2 * EDSCALE); style_menu_hover_border->set_border_color_all(highlight_color); - style_menu_hover_border->set_expand_margin_size(MARGIN_BOTTOM, border_width); theme->set_stylebox("normal", "MenuButton", style_menu); - theme->set_stylebox("hover", "MenuButton", style_menu_hover_border); + theme->set_stylebox("hover", "MenuButton", style_menu); theme->set_stylebox("pressed", "MenuButton", style_menu); theme->set_stylebox("focus", "MenuButton", style_menu); theme->set_stylebox("disabled", "MenuButton", style_menu); @@ -358,6 +357,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("pressed", "Button", change_border_color(style_button_type, highlight_color)); theme->set_stylebox("focus", "Button", change_border_color(style_button_type, highlight_color)); theme->set_stylebox("disabled", "Button", style_button_type_disabled); + theme->set_color("font_color", "Button", button_font_color); theme->set_color("font_color_hover", "Button", HIGHLIGHT_COLOR_FONT); theme->set_color("font_color_pressed", "Button", highlight_color); @@ -367,13 +367,12 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("icon_color_pressed", "Button", Color(highlight_color.r * 1.15, highlight_color.g * 1.15, highlight_color.b * 1.15, highlight_color.a)); // OptionButton - Ref<StyleBoxFlat> style_option_button = make_flat_stylebox(dark_color_1, 4, 4, 4, 4); - style_option_button->set_border_width_all(border_width); + theme->set_stylebox("normal", "OptionButton", style_button_type); theme->set_stylebox("hover", "OptionButton", change_border_color(style_button_type, contrast_color_1)); theme->set_stylebox("pressed", "OptionButton", change_border_color(style_button_type, HIGHLIGHT_COLOR_FONT)); theme->set_stylebox("focus", "OptionButton", change_border_color(style_button_type, highlight_color)); theme->set_stylebox("disabled", "OptionButton", style_button_type_disabled); - theme->set_stylebox("normal", "OptionButton", style_button_type); + theme->set_color("font_color", "OptionButton", button_font_color); theme->set_color("font_color_hover", "OptionButton", HIGHLIGHT_COLOR_FONT); theme->set_color("font_color_pressed", "OptionButton", highlight_color); @@ -386,6 +385,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // CheckButton theme->set_icon("on", "CheckButton", theme->get_icon("GuiToggleOn", "EditorIcons")); theme->set_icon("off", "CheckButton", theme->get_icon("GuiToggleOff", "EditorIcons")); + theme->set_color("font_color", "CheckButton", button_font_color); theme->set_color("font_color_hover", "CheckButton", HIGHLIGHT_COLOR_FONT); theme->set_color("font_color_pressed", "CheckButton", highlight_color); @@ -436,7 +436,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("custom_button_pressed", "Tree", make_empty_stylebox()); theme->set_stylebox("custom_button_hover", "Tree", style_button_type); theme->set_color("custom_button_font_highlight", "Tree", HIGHLIGHT_COLOR_FONT); - theme->set_color("font_color", "Tree", font_color_disabled); + theme->set_color("font_color", "Tree", font_color); theme->set_color("font_color_selected", "Tree", font_color); Ref<StyleBox> style_tree_btn = make_flat_stylebox(contrast_color_1, 2, 4, 2, 4); @@ -526,6 +526,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // LineEdit Ref<StyleBoxFlat> style_line_edit = make_flat_stylebox(dark_color_1, 6, 4, 6, 4); + style_line_edit->set_border_width_all(border_width); style_line_edit = change_border_color(style_line_edit, contrast_color_1); Ref<StyleBoxFlat> style_line_edit_disabled = change_border_color(style_line_edit, dark_color_1); style_line_edit_disabled->set_bg_color(Color(0, 0, 0, .1)); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 3b74601e78..df4598793c 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -1019,6 +1019,51 @@ void CanvasItemEditor::_list_select(const Ref<InputEventMouseButton> &b) { } } +void CanvasItemEditor::_update_cursor() { + + CursorShape c = CURSOR_ARROW; + switch (drag) { + case DRAG_NONE: + if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_MIDDLE) || Input::get_singleton()->is_key_pressed(KEY_SPACE)) { + c = CURSOR_DRAG; + } else { + switch (tool) { + case TOOL_MOVE: + c = CURSOR_MOVE; + break; + case TOOL_EDIT_PIVOT: + c = CURSOR_CROSS; + break; + case TOOL_PAN: + c = CURSOR_DRAG; + break; + } + } + break; + case DRAG_LEFT: + case DRAG_RIGHT: + c = CURSOR_HSIZE; + break; + case DRAG_TOP: + case DRAG_BOTTOM: + c = CURSOR_VSIZE; + break; + case DRAG_TOP_LEFT: + case DRAG_BOTTOM_RIGHT: + c = CURSOR_FDIAGSIZE; + break; + case DRAG_TOP_RIGHT: + case DRAG_BOTTOM_LEFT: + c = CURSOR_BDIAGSIZE; + break; + case DRAG_ALL: + case DRAG_NODE_2D: + c = CURSOR_MOVE; + break; + } + viewport->set_default_cursor_shape(c); +} + void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) { { @@ -1457,6 +1502,7 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseMotion> m = p_event; if (m.is_valid()) { // Mouse motion event + _update_cursor(); if (!viewport->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field())) viewport->call_deferred("grab_focus"); @@ -3562,29 +3608,31 @@ void CanvasItemEditorViewport::_create_preview(const Vector<String> &files) cons Sprite *sprite = memnew(Sprite); sprite->set_texture(texture); sprite->set_modulate(Color(1, 1, 1, 0.7f)); - preview->add_child(sprite); + preview_node->add_child(sprite); label->show(); label_desc->show(); } else { if (scene.is_valid()) { Node *instance = scene->instance(); if (instance) { - preview->add_child(instance); + preview_node->add_child(instance); } } } - editor->get_scene_root()->add_child(preview); + editor->get_scene_root()->add_child(preview_node); } } } void CanvasItemEditorViewport::_remove_preview() { - if (preview->get_parent()) { - editor->get_scene_root()->remove_child(preview); - for (int i = preview->get_child_count() - 1; i >= 0; i--) { - Node *node = preview->get_child(i); - memdelete(node); + if (preview_node->get_parent()) { + for (int i = preview_node->get_child_count() - 1; i >= 0; i--) { + Node *node = preview_node->get_child(i); + node->queue_delete(); + preview_node->remove_child(node); } + editor->get_scene_root()->remove_child(preview_node); + label->hide(); label_desc->hide(); } @@ -3794,11 +3842,11 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian break; } if (can_instance) { - if (!preview->get_parent()) { // create preview only once + if (!preview_node->get_parent()) { // create preview only once _create_preview(files); } Transform2D trans = canvas->get_canvas_transform(); - preview->set_position((p_point - trans.get_origin()) / trans.get_scale().x); + preview_node->set_position((p_point - trans.get_origin()) / trans.get_scale().x); label->set_text(vformat(TTR("Adding %s..."), default_type)); } return can_instance; @@ -3820,11 +3868,16 @@ void CanvasItemEditorViewport::drop_data(const Point2 &p_point, const Variant &p List<Node *> list = editor->get_editor_selection()->get_selected_node_list(); if (list.size() == 0) { - accept->get_ok()->set_text(TTR("OK :(")); - accept->set_text(TTR("No parent to instance a child at.")); - accept->popup_centered_minsize(); - _remove_preview(); - return; + Node *root_node = editor->get_edited_scene(); + if (root_node) { + list.push_back(root_node); + } else { + accept->get_ok()->set_text(TTR("OK :(")); + accept->set_text(TTR("No parent to instance a child at.")); + accept->popup_centered_minsize(); + _remove_preview(); + return; + } } if (list.size() != 1) { accept->get_ok()->set_text(TTR("I see..")); @@ -3891,7 +3944,7 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte editor = p_node; editor_data = editor->get_scene_tree_dock()->get_editor_data(); canvas = p_canvas; - preview = memnew(Node2D); + preview_node = memnew(Node2D); accept = memnew(AcceptDialog); editor->get_gui_base()->add_child(accept); @@ -3945,5 +3998,5 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte } CanvasItemEditorViewport::~CanvasItemEditorViewport() { - memdelete(preview); + memdelete(preview_node); } diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index da217007ea..52b4a37a88 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -324,6 +324,7 @@ class CanvasItemEditor : public VBoxContainer { bool updating_scroll; void _update_scroll(float); void _update_scrollbars(); + void _update_cursor(); void incbeg(float &beg, float &end, float inc, float minsize, bool p_symmetric); void incend(float &beg, float &end, float inc, float minsize, bool p_symmetric); @@ -459,7 +460,7 @@ class CanvasItemEditorViewport : public Control { EditorNode *editor; EditorData *editor_data; CanvasItemEditor *canvas; - Node2D *preview; + Node2D *preview_node; AcceptDialog *accept; WindowDialog *selector; Label *selector_label; diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index b8a4ff9bf3..04be1ba4ab 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -1423,7 +1423,7 @@ void ScriptEditor::_update_script_colors() { int non_zero_hist_size = (hist_size == 0) ? 1 : hist_size; float v = Math::ease((edit_pass - pass) / float(non_zero_hist_size), 0.4); - script_list->set_item_custom_bg_color(i, hot_color.linear_interpolate(cold_color, v)); + script_list->set_item_custom_fg_color(i, hot_color.linear_interpolate(cold_color, v)); } } } @@ -2517,9 +2517,9 @@ ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) { EDITOR_DEF("text_editor/open_scripts/script_temperature_enabled", true); EDITOR_DEF("text_editor/open_scripts/highlight_current_script", true); EDITOR_DEF("text_editor/open_scripts/script_temperature_history_size", 15); - EDITOR_DEF("text_editor/open_scripts/script_temperature_hot_color", Color(1, 0, 0, 0.3)); - EDITOR_DEF("text_editor/open_scripts/script_temperature_cold_color", Color(0, 0, 1, 0.3)); - EDITOR_DEF("text_editor/open_scripts/current_script_background_color", Color(0.81, 0.81, 0.14, 0.63)); + EDITOR_DEF("text_editor/open_scripts/script_temperature_hot_color", Color::html("ed5e5e")); + EDITOR_DEF("text_editor/open_scripts/script_temperature_cold_color", Color(1, 1, 1, 0.3)); + EDITOR_DEF("text_editor/open_scripts/current_script_background_color", Color(1, 1, 1, 0.5)); EDITOR_DEF("text_editor/open_scripts/group_help_pages", true); EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "text_editor/open_scripts/sort_scripts_by", PROPERTY_HINT_ENUM, "Name,Path")); EDITOR_DEF("text_editor/open_scripts/sort_scripts_by", 0); diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index d9fc2f32f7..a5f55835f0 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -35,12 +35,15 @@ #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/plugins/animation_player_editor_plugin.h" +#include "editor/plugins/script_editor_plugin.h" +#include "editor/script_editor_debugger.h" #include "editor/spatial_editor_gizmos.h" #include "os/keyboard.h" #include "print_string.h" #include "project_settings.h" #include "scene/3d/camera.h" #include "scene/3d/visual_instance.h" +#include "scene/resources/packed_scene.h" #include "scene/resources/surface_tool.h" #include "sort.h" @@ -228,7 +231,7 @@ Vector3 SpatialEditorViewport::_get_camera_normal() const { return -_get_camera_transform().basis.get_axis(2); } -Vector3 SpatialEditorViewport::_get_ray(const Vector2 &p_pos) { +Vector3 SpatialEditorViewport::_get_ray(const Vector2 &p_pos) const { return camera->project_ray_normal(p_pos); } @@ -700,6 +703,11 @@ void SpatialEditorViewport::_smouseenter() { surface->grab_focus(); } +void SpatialEditorViewport::_smouseexit() { + + _remove_preview(); +} + void SpatialEditorViewport::_list_select(Ref<InputEventMouseButton> b) { _find_items_at_pos(b->get_position(), clicked_includes_current, selection_results, b->get_shift()); @@ -1895,6 +1903,7 @@ void SpatialEditorViewport::_notification(int p_what) { surface->connect("draw", this, "_draw"); surface->connect("gui_input", this, "_sinput"); surface->connect("mouse_entered", this, "_smouseenter"); + surface->connect("mouse_exited", this, "_smouseexit"); info->add_style_override("panel", get_stylebox("panel", "Panel")); preview_camera->set_icon(get_icon("Camera", "EditorIcons")); _init_gizmo_instance(index); @@ -2425,6 +2434,7 @@ void SpatialEditorViewport::_bind_methods() { ClassDB::bind_method(D_METHOD("_draw"), &SpatialEditorViewport::_draw); ClassDB::bind_method(D_METHOD("_smouseenter"), &SpatialEditorViewport::_smouseenter); + ClassDB::bind_method(D_METHOD("_smouseexit"), &SpatialEditorViewport::_smouseexit); ClassDB::bind_method(D_METHOD("_sinput"), &SpatialEditorViewport::_sinput); ClassDB::bind_method(D_METHOD("_menu_option"), &SpatialEditorViewport::_menu_option); ClassDB::bind_method(D_METHOD("_toggle_camera_preview"), &SpatialEditorViewport::_toggle_camera_preview); @@ -2432,6 +2442,8 @@ void SpatialEditorViewport::_bind_methods() { ClassDB::bind_method(D_METHOD("update_transform_gizmo_view"), &SpatialEditorViewport::update_transform_gizmo_view); ClassDB::bind_method(D_METHOD("_selection_result_pressed"), &SpatialEditorViewport::_selection_result_pressed); ClassDB::bind_method(D_METHOD("_selection_menu_hide"), &SpatialEditorViewport::_selection_menu_hide); + ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &SpatialEditorViewport::can_drop_data_fw); + ClassDB::bind_method(D_METHOD("drop_data_fw"), &SpatialEditorViewport::drop_data_fw); ADD_SIGNAL(MethodInfo("toggle_maximize_view", PropertyInfo(Variant::OBJECT, "viewport"))); } @@ -2481,6 +2493,293 @@ void SpatialEditorViewport::focus_selection() { cursor.pos = center; } +void SpatialEditorViewport::assign_pending_data_pointers(Spatial *p_preview_node, Rect3 *p_preview_bounds, AcceptDialog *p_accept) { + preview_node = p_preview_node; + preview_bounds = p_preview_bounds; + accept = p_accept; +} + +Vector3 SpatialEditorViewport::_get_instance_position(const Point2 &p_pos) const { + const float MAX_DISTANCE = 10; + + Vector3 world_ray = _get_ray(p_pos); + Vector3 world_pos = _get_ray_pos(p_pos); + + Vector<ObjectID> instances = VisualServer::get_singleton()->instances_cull_ray(world_pos, world_ray, get_tree()->get_root()->get_world()->get_scenario()); + Set<Ref<SpatialEditorGizmo> > found_gizmos; + + float closest_dist = MAX_DISTANCE; + + Vector3 point = world_pos + world_ray * MAX_DISTANCE; + Vector3 normal = Vector3(0.0, 0.0, 0.0); + + for (int i = 0; i < instances.size(); i++) { + + MeshInstance *mesh_instance = Object::cast_to<MeshInstance>(ObjectDB::get_instance(instances[i])); + + if (!mesh_instance) + continue; + + Ref<SpatialEditorGizmo> seg = mesh_instance->get_gizmo(); + + if ((!seg.is_valid()) || found_gizmos.has(seg)) { + continue; + } + + found_gizmos.insert(seg); + + int handle = -1; + Vector3 hit_point; + Vector3 hit_normal; + bool inters = seg->intersect_ray(camera, p_pos, hit_point, hit_normal, NULL, false); + + if (!inters) + continue; + + float dist = world_pos.distance_to(hit_point); + + if (dist < 0) + continue; + + if (dist < closest_dist) { + closest_dist = dist; + point = hit_point; + normal = hit_normal; + } + } + Vector3 center = preview_bounds->get_size() * 0.5; + return point + (center * normal); +} + +Rect3 SpatialEditorViewport::_calculate_spatial_bounds(const Spatial *p_parent, const Rect3 p_bounds) { + Rect3 bounds = p_bounds; + for (int i = 0; i < p_parent->get_child_count(); i++) { + Spatial *child = Object::cast_to<Spatial>(p_parent->get_child(i)); + if (child) { + MeshInstance *mesh_instance = Object::cast_to<MeshInstance>(child); + if (mesh_instance) { + Rect3 mesh_instance_bounds = mesh_instance->get_aabb(); + mesh_instance_bounds.position += mesh_instance->get_global_transform().origin - p_parent->get_global_transform().origin; + bounds.merge_with(mesh_instance_bounds); + } + bounds = _calculate_spatial_bounds(child, bounds); + } + } + return bounds; +} + +void SpatialEditorViewport::_create_preview(const Vector<String> &files) const { + for (int i = 0; i < files.size(); i++) { + String path = files[i]; + RES res = ResourceLoader::load(path); + Ref<PackedScene> scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*res)); + if (scene != NULL) { + if (scene.is_valid()) { + Node *instance = scene->instance(); + if (instance) { + preview_node->add_child(instance); + } + } + editor->get_scene_root()->add_child(preview_node); + } + } + *preview_bounds = _calculate_spatial_bounds(preview_node, Rect3()); +} + +void SpatialEditorViewport::_remove_preview() { + if (preview_node->get_parent()) { + for (int i = preview_node->get_child_count() - 1; i >= 0; i--) { + Node *node = preview_node->get_child(i); + node->queue_delete(); + preview_node->remove_child(node); + } + editor->get_scene_root()->remove_child(preview_node); + } +} + +bool SpatialEditorViewport::_cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node) { + if (p_desired_node->get_filename() == p_target_scene_path) { + return true; + } + + int childCount = p_desired_node->get_child_count(); + for (int i = 0; i < childCount; i++) { + Node *child = p_desired_node->get_child(i); + if (_cyclical_dependency_exists(p_target_scene_path, child)) { + return true; + } + } + return false; +} + +bool SpatialEditorViewport::_create_instance(Node *parent, String &path, const Point2 &p_point) { + Ref<PackedScene> sdata = ResourceLoader::load(path); + if (!sdata.is_valid()) { // invalid scene + return false; + } + + Node *instanced_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE); + if (!instanced_scene) { // error on instancing + return false; + } + + if (editor->get_edited_scene()->get_filename() != "") { // cyclical instancing + if (_cyclical_dependency_exists(editor->get_edited_scene()->get_filename(), instanced_scene)) { + memdelete(instanced_scene); + return false; + } + } + + instanced_scene->set_filename(ProjectSettings::get_singleton()->localize_path(path)); + + editor_data->get_undo_redo().add_do_method(parent, "add_child", instanced_scene); + editor_data->get_undo_redo().add_do_method(instanced_scene, "set_owner", editor->get_edited_scene()); + editor_data->get_undo_redo().add_do_reference(instanced_scene); + editor_data->get_undo_redo().add_undo_method(parent, "remove_child", instanced_scene); + + String new_name = parent->validate_child_name(instanced_scene); + ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); + editor_data->get_undo_redo().add_do_method(sed, "live_debug_instance_node", editor->get_edited_scene()->get_path_to(parent), path, new_name); + editor_data->get_undo_redo().add_undo_method(sed, "live_debug_remove_node", NodePath(String(editor->get_edited_scene()->get_path_to(parent)) + "/" + new_name)); + + Transform global_transform; + Spatial *parent_spatial = Object::cast_to<Spatial>(parent); + if (parent_spatial) + global_transform = parent_spatial->get_global_transform(); + + global_transform.origin = _get_instance_position(p_point); + + editor_data->get_undo_redo().add_do_method(instanced_scene, "set_global_transform", global_transform); + + return true; +} + +void SpatialEditorViewport::_perform_drop_data() { + _remove_preview(); + + Vector<String> error_files; + + editor_data->get_undo_redo().create_action(TTR("Create Node")); + + for (int i = 0; i < selected_files.size(); i++) { + String path = selected_files[i]; + RES res = ResourceLoader::load(path); + if (res.is_null()) { + continue; + } + Ref<PackedScene> scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*res)); + if (scene != NULL) { + bool success = _create_instance(target_node, path, drop_pos); + if (!success) { + error_files.push_back(path); + } + } + } + + editor_data->get_undo_redo().commit_action(); + + if (error_files.size() > 0) { + String files_str; + for (int i = 0; i < error_files.size(); i++) { + files_str += error_files[i].get_file().get_basename() + ","; + } + files_str = files_str.substr(0, files_str.length() - 1); + accept->get_ok()->set_text(TTR("Ugh")); + accept->set_text(vformat(TTR("Error instancing scene from %s"), files_str.c_str())); + accept->popup_centered_minsize(); + } +} + +bool SpatialEditorViewport::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const { + + bool can_instance = false; + + if (!preview_node->is_inside_tree()) { + Dictionary d = p_data; + if (d.has("type") && (String(d["type"]) == "files")) { + Vector<String> files = d["files"]; + + List<String> scene_extensions; + ResourceLoader::get_recognized_extensions_for_type("PackedScene", &scene_extensions); + + for (int i = 0; i < files.size(); i++) { + if (scene_extensions.find(files[i].get_extension())) { + RES res = ResourceLoader::load(files[i]); + if (res.is_null()) { + continue; + } + + String type = res->get_class(); + if (type == "PackedScene") { + Ref<PackedScene> sdata = ResourceLoader::load(files[i]); + Node *instanced_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE); + if (!instanced_scene) { + continue; + } + memdelete(instanced_scene); + } + can_instance = true; + break; + } + } + if (can_instance) { + _create_preview(files); + } + } + } else { + can_instance = true; + } + + if (can_instance) { + Transform global_transform = Transform(Basis(), _get_instance_position(p_point)); + preview_node->set_global_transform(global_transform); + } + + return can_instance; +} + +void SpatialEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { + if (!can_drop_data_fw(p_point, p_data, p_from)) + return; + + bool is_shift = Input::get_singleton()->is_key_pressed(KEY_SHIFT); + + selected_files.clear(); + Dictionary d = p_data; + if (d.has("type") && String(d["type"]) == "files") { + selected_files = d["files"]; + } + + List<Node *> list = editor->get_editor_selection()->get_selected_node_list(); + if (list.size() == 0) { + Node *root_node = editor->get_edited_scene(); + if (root_node) { + list.push_back(root_node); + } else { + accept->get_ok()->set_text(TTR("OK :(")); + accept->set_text(TTR("No parent to instance a child at.")); + accept->popup_centered_minsize(); + _remove_preview(); + return; + } + } + if (list.size() != 1) { + accept->get_ok()->set_text(TTR("I see..")); + accept->set_text(TTR("This operation requires a single selected node.")); + accept->popup_centered_minsize(); + _remove_preview(); + return; + } + + target_node = list[0]; + if (is_shift && target_node != editor->get_edited_scene()) { + target_node = target_node->get_parent(); + } + drop_pos = p_point; + + _perform_drop_data(); +} + SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, EditorNode *p_editor, int p_index) { _edit.mode = TRANSFORM_NONE; @@ -2491,6 +2790,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed index = p_index; editor = p_editor; + editor_data = editor->get_scene_tree_dock()->get_editor_data(); editor_selection = editor->get_editor_selection(); undo_redo = editor->get_undo_redo(); clicked = 0; @@ -2509,6 +2809,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed c->add_child(viewport); surface = memnew(Control); + surface->set_drag_forwarding(this); add_child(surface); surface->set_area_as_parent_rect(); surface->set_clip_contents(true); @@ -2573,9 +2874,10 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed preview_camera->hide(); preview_camera->connect("toggled", this, "_toggle_camera_preview"); previewing = NULL; - preview = NULL; gizmo_scale = 1.0; + preview_node = NULL; + info = memnew(PanelContainer); info->set_self_modulate(Color(1, 1, 1, 0.4)); surface->add_child(info); @@ -2583,6 +2885,8 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed info->add_child(info_label); info->hide(); + accept = NULL; + freelook_active = false; selection_menu = memnew(PopupMenu); @@ -4000,6 +4304,10 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { vs = memnew(VSeparator); hbc_menu->add_child(vs); + // Drag and drop support; + preview_node = memnew(Spatial); + preview_bounds = Rect3(); + ED_SHORTCUT("spatial_editor/bottom_view", TTR("Bottom View"), KEY_MASK_ALT + KEY_KP_7); ED_SHORTCUT("spatial_editor/top_view", TTR("Top View"), KEY_KP_7); ED_SHORTCUT("spatial_editor/rear_view", TTR("Rear View"), KEY_MASK_ALT + KEY_KP_1); @@ -4044,6 +4352,9 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { p = view_menu->get_popup(); + accept = memnew(AcceptDialog); + editor->get_gui_base()->add_child(accept); + p->add_check_shortcut(ED_SHORTCUT("spatial_editor/1_viewport", TTR("1 Viewport"), KEY_MASK_CMD + KEY_1), MENU_VIEW_USE_1_VIEWPORT); p->add_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports", TTR("2 Viewports"), KEY_MASK_CMD + KEY_2), MENU_VIEW_USE_2_VIEWPORTS); p->add_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports_alt", TTR("2 Viewports (Alt)"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_2), MENU_VIEW_USE_2_VIEWPORTS_ALT); @@ -4078,6 +4389,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { viewports[i] = memnew(SpatialEditorViewport(this, editor, i)); viewports[i]->connect("toggle_maximize_view", this, "_toggle_maximize_view"); + viewports[i]->assign_pending_data_pointers(preview_node, &preview_bounds, accept); viewport_base->add_child(viewports[i]); } //vbc->add_child(viewport_base); @@ -4212,6 +4524,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { } SpatialEditor::~SpatialEditor() { + memdelete(preview_node); } void SpatialEditorPlugin::make_visible(bool p_visible) { diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h index 374861b5e7..db5abe2b53 100644 --- a/editor/plugins/spatial_editor_plugin.h +++ b/editor/plugins/spatial_editor_plugin.h @@ -106,7 +106,16 @@ private: void _menu_option(int p_option); Size2 prev_size; + Spatial *preview_node; + Rect3 *preview_bounds; + Vector<String> selected_files; + AcceptDialog *accept; + + Node *target_node; + Point2 drop_pos; + EditorNode *editor; + EditorData *editor_data; EditorSelection *editor_selection; UndoRedo *undo_redo; @@ -143,7 +152,7 @@ private: ObjectID _select_ray(const Point2 &p_pos, bool p_append, bool &r_includes_current, int *r_gizmo_handle = NULL, bool p_alt_select = false); void _find_items_at_pos(const Point2 &p_pos, bool &r_includes_current, Vector<_RayResult> &results, bool p_alt_select = false); Vector3 _get_ray_pos(const Vector2 &p_pos) const; - Vector3 _get_ray(const Vector2 &p_pos); + Vector3 _get_ray(const Vector2 &p_pos) const; Point2 _point_to_screen(const Vector3 &p_point); Transform _get_camera_transform() const; int get_selected_count() const; @@ -250,6 +259,7 @@ private: void _draw(); void _smouseenter(); + void _smouseexit(); void _sinput(const Ref<InputEvent> &p_event); void _update_freelook(real_t delta); SpatialEditor *spatial_editor; @@ -266,6 +276,17 @@ private: void _list_select(Ref<InputEventMouseButton> b); Point2i _get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const; + Vector3 _get_instance_position(const Point2 &p_pos) const; + static Rect3 _calculate_spatial_bounds(const Spatial *p_parent, const Rect3 p_bounds); + void _create_preview(const Vector<String> &files) const; + void _remove_preview(); + bool _cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node); + bool _create_instance(Node *parent, String &path, const Point2 &p_point); + void _perform_drop_data(); + + bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; + void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); + protected: void _notification(int p_what); static void _bind_methods(); @@ -281,6 +302,11 @@ public: void focus_selection(); + void assign_pending_data_pointers( + Spatial *p_preview_node, + Rect3 *p_preview_bounds, + AcceptDialog *p_accept); + Viewport *get_viewport_node() { return viewport; } SpatialEditorViewport(SpatialEditor *p_spatial_editor, EditorNode *p_editor, int p_index); @@ -396,6 +422,10 @@ private: Ref<SpatialMaterial> indicator_mat; Ref<SpatialMaterial> cursor_material; + // Scene drag and drop support + Spatial *preview_node; + Rect3 preview_bounds; + /* struct Selected { AABB aabb; @@ -442,6 +472,8 @@ private: MenuButton *transform_menu; MenuButton *view_menu; + AcceptDialog *accept; + ConfirmationDialog *snap_dialog; ConfirmationDialog *xform_dialog; ConfirmationDialog *settings_dialog; @@ -559,6 +591,7 @@ public: Camera *get_camera() { return NULL; } void edit(Spatial *p_spatial); void clear(); + SpatialEditor(EditorNode *p_editor); ~SpatialEditor(); }; diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 9fd31f818e..49687a504f 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -700,6 +700,8 @@ void ProjectSettingsEditor::_update_actions() { action->set_meta("__input", ie); } } + + _action_check(action_name->get_text()); } void ProjectSettingsEditor::popup_project_settings() { @@ -809,28 +811,41 @@ void ProjectSettingsEditor::_item_del() { undo_redo->commit_action(); } -void ProjectSettingsEditor::_action_adds(String) { +void ProjectSettingsEditor::_action_check(String p_action) { - _action_add(); -} + if (p_action == "") { -void ProjectSettingsEditor::_action_add() { + action_add->set_disabled(true); + } else { - String action = action_name->get_text(); - if (action.find("/") != -1 || action.find(":") != -1 || action == "") { - message->set_text(TTR("Invalid action (anything goes but '/' or ':').")); - message->popup_centered(Size2(300, 100) * EDSCALE); - return; + if (p_action.find("/") != -1 || p_action.find(":") != -1) { + action_add->set_text(TTR("Can't contain '/' or ':'")); + action_add->set_disabled(true); + return; + } + if (ProjectSettings::get_singleton()->has("input/" + p_action)) { + action_add->set_text(TTR("Already existing")); + action_add->set_disabled(true); + return; + } + + action_add->set_disabled(false); } - if (ProjectSettings::get_singleton()->has("input/" + action)) { - message->set_text(vformat(TTR("Action '%s' already exists!"), action)); - message->popup_centered(Size2(300, 100) * EDSCALE); - return; + action_add->set_text(TTR("Add")); +} + +void ProjectSettingsEditor::_action_adds(String) { + + if (!action_add->is_disabled()) { + _action_add(); } +} + +void ProjectSettingsEditor::_action_add() { Array va; - String name = "input/" + action; + String name = "input/" + action_name->get_text(); undo_redo->create_action(TTR("Add Input Action Event")); undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, va); undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", name); @@ -854,6 +869,7 @@ void ProjectSettingsEditor::_action_add() { return; r->select(0); input_editor->ensure_cursor_is_visible(); + action_add->set_text(TTR("Add")); } void ProjectSettingsEditor::_item_checked(const String &p_item, bool p_check) { @@ -1336,6 +1352,7 @@ void ProjectSettingsEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("_save"), &ProjectSettingsEditor::_save); ClassDB::bind_method(D_METHOD("_action_add"), &ProjectSettingsEditor::_action_add); ClassDB::bind_method(D_METHOD("_action_adds"), &ProjectSettingsEditor::_action_adds); + ClassDB::bind_method(D_METHOD("_action_check"), &ProjectSettingsEditor::_action_check); ClassDB::bind_method(D_METHOD("_action_selected"), &ProjectSettingsEditor::_action_selected); ClassDB::bind_method(D_METHOD("_action_edited"), &ProjectSettingsEditor::_action_edited); ClassDB::bind_method(D_METHOD("_action_activated"), &ProjectSettingsEditor::_action_activated); @@ -1482,9 +1499,8 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { get_ok()->set_text(TTR("Close")); set_hide_on_ok(true); - message = memnew(ConfirmationDialog); + message = memnew(AcceptDialog); add_child(message); - message->set_hide_on_ok(true); Control *input_base = memnew(Control); input_base->set_name(TTR("Input Map")); @@ -1500,7 +1516,6 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { l = memnew(Label); vbc->add_child(l); - l->set_position(Point2(6, 5) * EDSCALE); l->set_text(TTR("Action:")); hbc = memnew(HBoxContainer); @@ -1510,12 +1525,15 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { action_name->set_h_size_flags(SIZE_EXPAND_FILL); hbc->add_child(action_name); action_name->connect("text_entered", this, "_action_adds"); + action_name->connect("text_changed", this, "_action_check"); add = memnew(Button); hbc->add_child(add); add->set_custom_minimum_size(Size2(150, 0) * EDSCALE); add->set_text(TTR("Add")); + add->set_disabled(true); add->connect("pressed", this, "_action_add"); + action_add = add; input_editor = memnew(Tree); vbc->add_child(input_editor); diff --git a/editor/project_settings_editor.h b/editor/project_settings_editor.h index e58ba9b1c0..7f9b18a968 100644 --- a/editor/project_settings_editor.h +++ b/editor/project_settings_editor.h @@ -66,7 +66,7 @@ class ProjectSettingsEditor : public AcceptDialog { ToolButton *clear_button; HBoxContainer *add_prop_bar; - ConfirmationDialog *message; + AcceptDialog *message; LineEdit *category; LineEdit *property; OptionButton *type; @@ -80,6 +80,7 @@ class ProjectSettingsEditor : public AcceptDialog { MenuButton *popup_copy_to_feature; LineEdit *action_name; + Button *action_add; Tree *input_editor; bool setting; bool updating_translations; @@ -108,6 +109,7 @@ class ProjectSettingsEditor : public AcceptDialog { void _add_item(int p_item, Ref<InputEvent> p_exiting_event = NULL); void _edit_item(Ref<InputEvent> p_exiting_event); + void _action_check(String p_action); void _action_adds(String); void _action_add(); void _device_input_add(); |