diff options
Diffstat (limited to 'editor/plugins')
20 files changed, 581 insertions, 182 deletions
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index cc7fc57cde..d7762a66df 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -55,79 +55,87 @@ void AnimationPlayerEditor::_gui_input(Ref<InputEvent> p_event) { } void AnimationPlayerEditor::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_PROCESS: { - if (p_what == NOTIFICATION_PROCESS) { - - if (!player) - return; + if (!player) + return; - updating = true; + updating = true; - if (player->is_playing()) { + if (player->is_playing()) { - { - String animname = player->get_current_animation(); + { + String animname = player->get_current_animation(); - if (player->has_animation(animname)) { - Ref<Animation> anim = player->get_animation(animname); - if (!anim.is_null()) { + if (player->has_animation(animname)) { + Ref<Animation> anim = player->get_animation(animname); + if (!anim.is_null()) { - frame->set_max(anim->get_length()); + frame->set_max(anim->get_length()); + } } } + frame->set_value(player->get_current_animation_pos()); + key_editor->set_anim_pos(player->get_current_animation_pos()); + EditorNode::get_singleton()->get_property_editor()->refresh(); + + } else if (last_active) { + //need the last frame after it stopped + + frame->set_value(player->get_current_animation_pos()); } - frame->set_value(player->get_current_animation_pos()); - key_editor->set_anim_pos(player->get_current_animation_pos()); - EditorNode::get_singleton()->get_property_editor()->refresh(); - } else if (last_active) { - //need the last frame after it stopped + last_active = player->is_playing(); + //seek->set_val(player->get_position()); + updating = false; - frame->set_value(player->get_current_animation_pos()); - } + } break; - last_active = player->is_playing(); - //seek->set_val(player->get_position()); - updating = false; - } + case NOTIFICATION_ENTER_TREE: { + + save_anim->get_popup()->connect("id_pressed", this, "_animation_save_menu"); + + tool_anim->get_popup()->connect("id_pressed", this, "_animation_tool_menu"); + + blend_editor.next->connect("item_selected", this, "_blend_editor_next_changed"); - if (p_what == NOTIFICATION_ENTER_TREE) { - - //editor->connect("hide_animation_player_editors",this,"_hide_anim_editors"); - add_anim->set_icon(get_icon("New", "EditorIcons")); - rename_anim->set_icon(get_icon("Rename", "EditorIcons")); - duplicate_anim->set_icon(get_icon("Duplicate", "EditorIcons")); - autoplay->set_icon(get_icon("AutoPlay", "EditorIcons")); - load_anim->set_icon(get_icon("Folder", "EditorIcons")); - save_anim->set_icon(get_icon("Save", "EditorIcons")); - save_anim->get_popup()->connect("id_pressed", this, "_animation_save_menu"); - remove_anim->set_icon(get_icon("Remove", "EditorIcons")); - - blend_anim->set_icon(get_icon("Blend", "EditorIcons")); - play->set_icon(get_icon("PlayStart", "EditorIcons")); - play_from->set_icon(get_icon("Play", "EditorIcons")); - play_bw->set_icon(get_icon("PlayStartBackwards", "EditorIcons")); - play_bw_from->set_icon(get_icon("PlayBackwards", "EditorIcons")); - - autoplay_icon = get_icon("AutoPlay", "EditorIcons"); - stop->set_icon(get_icon("Stop", "EditorIcons")); - resource_edit_anim->set_icon(get_icon("EditResource", "EditorIcons")); - pin->set_icon(get_icon("Pin", "EditorIcons")); - tool_anim->set_icon(get_icon("Tools", "EditorIcons")); - tool_anim->get_popup()->connect("id_pressed", this, "_animation_tool_menu"); - - blend_editor.next->connect("item_selected", this, "_blend_editor_next_changed"); - - /* - anim_editor_load->set_normal_texture( get_icon("AnimGet","EditorIcons")); - anim_editor_store->set_normal_texture( get_icon("AnimSet","EditorIcons")); - anim_editor_load->set_pressed_texture( get_icon("AnimGet","EditorIcons")); - anim_editor_store->set_pressed_texture( get_icon("AnimSet","EditorIcons")); - anim_editor_load->set_hover_texture( get_icon("AnimGetHl","EditorIcons")); - anim_editor_store->set_hover_texture( get_icon("AnimSetHl","EditorIcons")); -*/ - - get_tree()->connect("node_removed", this, "_node_removed"); + get_tree()->connect("node_removed", this, "_node_removed"); + + add_style_override("panel", editor->get_gui_base()->get_stylebox("panel", "Panel")); + add_constant_override("separation", get_constant("separation", "VBoxContainer")); + } break; + + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { + + add_style_override("panel", editor->get_gui_base()->get_stylebox("panel", "Panel")); + add_constant_override("separation", get_constant("separation", "VBoxContainer")); + } break; + + case NOTIFICATION_THEME_CHANGED: { + + add_anim->set_icon(get_icon("New", "EditorIcons")); + rename_anim->set_icon(get_icon("Rename", "EditorIcons")); + duplicate_anim->set_icon(get_icon("Duplicate", "EditorIcons")); + autoplay->set_icon(get_icon("AutoPlay", "EditorIcons")); + load_anim->set_icon(get_icon("Folder", "EditorIcons")); + save_anim->set_icon(get_icon("Save", "EditorIcons")); + + remove_anim->set_icon(get_icon("Remove", "EditorIcons")); + + blend_anim->set_icon(get_icon("Blend", "EditorIcons")); + play->set_icon(get_icon("PlayStart", "EditorIcons")); + play_from->set_icon(get_icon("Play", "EditorIcons")); + play_bw->set_icon(get_icon("PlayStartBackwards", "EditorIcons")); + play_bw_from->set_icon(get_icon("PlayBackwards", "EditorIcons")); + + autoplay_icon = get_icon("AutoPlay", "EditorIcons"); + stop->set_icon(get_icon("Stop", "EditorIcons")); + resource_edit_anim->set_icon(get_icon("EditResource", "EditorIcons")); + pin->set_icon(get_icon("Pin", "EditorIcons")); + tool_anim->set_icon(get_icon("Tools", "EditorIcons")); + + } break; } } @@ -1176,7 +1184,6 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) { set_focus_mode(FOCUS_ALL); player = NULL; - add_style_override("panel", editor->get_gui_base()->get_stylebox("panel", "Panel")); Label *l; @@ -1376,7 +1383,6 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) { key_editor = memnew(AnimationKeyEditor); add_child(key_editor); - add_constant_override("separation", get_constant("separation", "VBoxContainer")); key_editor->set_v_size_flags(SIZE_EXPAND_FILL); key_editor->connect("timeline_changed", this, "_animation_key_editor_seek"); key_editor->connect("animation_len_changed", this, "_animation_key_editor_anim_len_changed"); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 3b74601e78..2b2358f3d0 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -580,7 +580,8 @@ void CanvasItemEditor::_key_move(const Vector2 &p_dir, bool p_snap, KeyMoveMODE } else { // p_move_mode==MOVE_LOCAL_BASE || p_move_mode==MOVE_LOCAL_WITH_ROT - if (Node2D *node_2d = Object::cast_to<Node2D>(canvas_item)) { + Node2D *node_2d = Object::cast_to<Node2D>(canvas_item); + if (node_2d) { if (p_move_mode == MOVE_LOCAL_WITH_ROT) { Transform2D m; @@ -589,9 +590,10 @@ void CanvasItemEditor::_key_move(const Vector2 &p_dir, bool p_snap, KeyMoveMODE } node_2d->set_position(node_2d->get_position() + drag); - } else if (Control *control = Object::cast_to<Control>(canvas_item)) { - - control->set_position(control->get_position() + drag); + } else { + Control *control = Object::cast_to<Control>(canvas_item); + if (control) + control->set_position(control->get_position() + drag); } } } @@ -742,7 +744,8 @@ float CanvasItemEditor::_anchor_snap(float p_anchor, bool *p_snapped, float p_op float radius = 0.05 / zoom; float basic_anchors[3] = { 0.0, 0.5, 1.0 }; for (int i = 0; i < 3; i++) { - if ((dist = fabs(p_anchor - basic_anchors[i])) < radius) { + dist = fabs(p_anchor - basic_anchors[i]); + if (dist < radius) { if (!snapped || dist <= dist_min) { p_anchor = basic_anchors[i]; dist_min = dist; @@ -750,7 +753,8 @@ float CanvasItemEditor::_anchor_snap(float p_anchor, bool *p_snapped, float p_op } } } - if (p_opposite_anchor >= 0 && (dist = fabs(p_anchor - p_opposite_anchor)) < radius) { + dist = fabs(p_anchor - p_opposite_anchor); + if (p_opposite_anchor >= 0 && dist < radius) { if (!snapped || dist <= dist_min) { p_anchor = p_opposite_anchor; dist_min = dist; @@ -1019,6 +1023,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 +1506,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"); @@ -1469,7 +1519,7 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) { } if (drag == DRAG_NONE) { - if ((m->get_button_mask() & BUTTON_MASK_LEFT && tool == TOOL_PAN) || m->get_button_mask() & BUTTON_MASK_MIDDLE || (m->get_button_mask() & BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE))) { + if (((m->get_button_mask() & BUTTON_MASK_LEFT) && tool == TOOL_PAN) || (m->get_button_mask() & BUTTON_MASK_MIDDLE) || ((m->get_button_mask() & BUTTON_MASK_LEFT) && Input::get_singleton()->is_key_pressed(KEY_SPACE))) { // Pan the viewport Point2i relative; if (bool(EditorSettings::get_singleton()->get("editors/2d/warped_mouse_panning"))) { @@ -2223,6 +2273,8 @@ void CanvasItemEditor::_notification(int p_what) { if (p_what == NOTIFICATION_FIXED_PROCESS) { + EditorNode::get_singleton()->get_scene_root()->set_snap_controls_to_pixels(GLOBAL_GET("gui/common/snap_controls_to_pixels")); + List<Node *> &selection = editor_selection->get_selected_node_list(); bool all_control = true; @@ -3562,29 +3614,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 +3848,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 +3874,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 +3950,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 +4004,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..2e1a2eac5f 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -34,7 +34,6 @@ #include "editor/editor_plugin.h" #include "scene/2d/canvas_item.h" #include "scene/gui/box_container.h" -#include "scene/gui/button_group.h" #include "scene/gui/check_box.h" #include "scene/gui/label.h" #include "scene/gui/panel_container.h" @@ -324,6 +323,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 +459,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/collision_polygon_2d_editor_plugin.h b/editor/plugins/collision_polygon_2d_editor_plugin.h index bc3c5a1659..4715abd2e6 100644 --- a/editor/plugins/collision_polygon_2d_editor_plugin.h +++ b/editor/plugins/collision_polygon_2d_editor_plugin.h @@ -33,7 +33,6 @@ #include "editor/editor_node.h" #include "editor/editor_plugin.h" #include "scene/2d/collision_polygon_2d.h" -#include "scene/gui/button_group.h" #include "scene/gui/tool_button.h" /** diff --git a/editor/plugins/collision_polygon_editor_plugin.h b/editor/plugins/collision_polygon_editor_plugin.h index 0150d8a9d7..0f63810443 100644 --- a/editor/plugins/collision_polygon_editor_plugin.h +++ b/editor/plugins/collision_polygon_editor_plugin.h @@ -35,7 +35,6 @@ #include "scene/3d/collision_polygon.h" #include "scene/3d/immediate_geometry.h" #include "scene/3d/mesh_instance.h" -#include "scene/gui/button_group.h" #include "scene/gui/tool_button.h" /** diff --git a/editor/plugins/cube_grid_theme_editor_plugin.cpp b/editor/plugins/cube_grid_theme_editor_plugin.cpp index 08b38c2ca2..1c17daf425 100644 --- a/editor/plugins/cube_grid_theme_editor_plugin.cpp +++ b/editor/plugins/cube_grid_theme_editor_plugin.cpp @@ -88,7 +88,7 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, if (mesh.is_null()) continue; - int id = p_library->find_item_name(mi->get_name()); + int id = p_library->find_item_by_name(mi->get_name()); if (id < 0) { id = p_library->get_last_unused_item_id(); @@ -111,7 +111,8 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, sb->get_shape_owners(&shapes); for (List<uint32_t>::Element *E = shapes.front(); E; E = E->next()) { - if (sb->is_shape_owner_disabled(E->get())) continue; + if (sb->is_shape_owner_disabled(E->get())) + continue; //Transform shape_transform = sb->shape_owner_get_transform(E->get()); @@ -120,7 +121,7 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, for (int k = 0; k < sb->shape_owner_get_shape_count(E->get()); k++) { Ref<Shape> collision = sb->shape_owner_get_shape(E->get(), k); - if (collision.is_valid()) + if (!collision.is_valid()) continue; MeshLibrary::ShapeData shape_data; shape_data.shape = collision; diff --git a/editor/plugins/light_occluder_2d_editor_plugin.h b/editor/plugins/light_occluder_2d_editor_plugin.h index 7a4f18963d..b270dcb6e5 100644 --- a/editor/plugins/light_occluder_2d_editor_plugin.h +++ b/editor/plugins/light_occluder_2d_editor_plugin.h @@ -33,7 +33,6 @@ #include "editor/editor_node.h" #include "editor/editor_plugin.h" #include "scene/2d/light_occluder_2d.h" -#include "scene/gui/button_group.h" #include "scene/gui/tool_button.h" /** diff --git a/editor/plugins/line_2d_editor_plugin.h b/editor/plugins/line_2d_editor_plugin.h index dea77ec248..dea0433084 100644 --- a/editor/plugins/line_2d_editor_plugin.h +++ b/editor/plugins/line_2d_editor_plugin.h @@ -34,7 +34,6 @@ #include "editor/editor_plugin.h" #include "scene/2d/line_2d.h" #include "scene/2d/path_2d.h" -#include "scene/gui/button_group.h" #include "scene/gui/tool_button.h" class CanvasItemEditor; diff --git a/editor/plugins/navigation_polygon_editor_plugin.h b/editor/plugins/navigation_polygon_editor_plugin.h index 33f9d5c785..7dd555e9c9 100644 --- a/editor/plugins/navigation_polygon_editor_plugin.h +++ b/editor/plugins/navigation_polygon_editor_plugin.h @@ -33,7 +33,6 @@ #include "editor/editor_node.h" #include "editor/editor_plugin.h" #include "scene/2d/navigation_polygon.h" -#include "scene/gui/button_group.h" #include "scene/gui/tool_button.h" /** diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h index c195845244..f0f5d4d637 100644 --- a/editor/plugins/path_2d_editor_plugin.h +++ b/editor/plugins/path_2d_editor_plugin.h @@ -33,7 +33,6 @@ #include "editor/editor_node.h" #include "editor/editor_plugin.h" #include "scene/2d/path_2d.h" -#include "scene/gui/button_group.h" #include "scene/gui/tool_button.h" /** diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index f7008298f0..3917c700f0 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -395,7 +395,7 @@ bool Polygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) { if (mm.is_valid()) { - if (edited_point != -1 && (wip_active || mm->get_button_mask() & BUTTON_MASK_LEFT)) { + if (edited_point != -1 && (wip_active || (mm->get_button_mask() & BUTTON_MASK_LEFT))) { Vector2 gpoint = mm->get_position(); Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); @@ -554,7 +554,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { if (mm.is_valid()) { - if (mm->get_button_mask() & BUTTON_MASK_MIDDLE || Input::get_singleton()->is_key_pressed(KEY_SPACE)) { + if ((mm->get_button_mask() & BUTTON_MASK_MIDDLE) || Input::get_singleton()->is_key_pressed(KEY_SPACE)) { Vector2 drag(mm->get_relative().x, mm->get_relative().y); uv_hscroll->set_value(uv_hscroll->get_value() - drag.x); diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h index 38148ca7e3..f9d6a6b4b6 100644 --- a/editor/plugins/polygon_2d_editor_plugin.h +++ b/editor/plugins/polygon_2d_editor_plugin.h @@ -33,7 +33,6 @@ #include "editor/editor_node.h" #include "editor/editor_plugin.h" #include "scene/2d/polygon_2d.h" -#include "scene/gui/button_group.h" #include "scene/gui/tool_button.h" /** diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index a529f152dc..6f03d086ca 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -972,6 +972,14 @@ void ScriptEditor::_menu_option(int p_option) { EditorNode::get_singleton()->show_warning("Can't obtain the script for running"); break; } + + current->apply_code(); + Error err = scr->reload(false); //hard reload script before running always + + if (err != OK) { + EditorNode::get_singleton()->show_warning("Script failed reloading, check console for errors."); + return; + } if (!scr->is_tool()) { EditorNode::get_singleton()->show_warning("Script is not in tool mode, will not be able to run"); @@ -1149,8 +1157,6 @@ void ScriptEditor::_notification(int p_what) { case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - tab_container->add_style_override("panel", editor->get_gui_base()->get_stylebox("ScriptPanel", "EditorStyles")); - help_search->set_icon(get_icon("HelpSearch", "EditorIcons")); site_search->set_icon(get_icon("Instance", "EditorIcons")); class_search->set_icon(get_icon("ClassList", "EditorIcons")); @@ -1417,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)); } } } @@ -1539,8 +1545,14 @@ bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool bool open_dominant = EditorSettings::get_singleton()->get("text_editor/files/open_dominant_script_on_scene_change"); + if (p_script->get_language()->overrides_external_editor()) { + Error err = p_script->get_language()->open_in_external_editor(p_script, p_line >= 0 ? p_line : 0, p_col); + if (err != OK) + ERR_PRINT("Couldn't open script in the overridden external text editor"); + return false; + } + if ((debugger->get_dump_stack_script() != p_script || debugger->get_debug_with_external_editor()) && - p_script->get_language()->open_in_external_editor(p_script, p_line >= 0 ? p_line : 0, p_col) == OK && p_script->get_path().is_resource_file() && bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) { @@ -2210,7 +2222,6 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { members_overview->set_v_size_flags(SIZE_EXPAND_FILL); tab_container = memnew(TabContainer); - tab_container->add_style_override("panel", p_editor->get_gui_base()->get_stylebox("ScriptPanel", "EditorStyles")); tab_container->set_tabs_visible(false); script_split->add_child(tab_container); @@ -2405,6 +2416,9 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { use_space_indentation = false; ScriptServer::edit_request_func = _open_script_request; + + add_style_override("panel", editor->get_gui_base()->get_stylebox("ScriptEditorPanel", "EditorStyles")); + tab_container->add_style_override("panel", editor->get_gui_base()->get_stylebox("ScriptEditor", "EditorStyles")); } ScriptEditor::~ScriptEditor() { @@ -2506,9 +2520,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/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 33890d890d..2192d3ac49 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -75,14 +75,9 @@ void ScriptTextEditor::_load_theme_settings() { text_edit->clear_colors(); - /* color from color_theme or from editor color */ - - Color background_color = EDITOR_DEF("text_editor/highlighting/background_color", Color(0, 0, 0, 0)); - if (EDITOR_DEF("text_editor/theme/adapted_code_editor_background_color", false)) - background_color = get_color("dark_color_1", "Editor"); - /* keyword color */ - text_edit->add_color_override("background_color", background_color); + + text_edit->add_color_override("background_color", EDITOR_DEF("text_editor/highlighting/background_color", Color(0, 0, 0, 0))); text_edit->add_color_override("completion_background_color", EDITOR_DEF("text_editor/highlighting/completion_background_color", Color(0, 0, 0, 0))); text_edit->add_color_override("completion_selected_color", EDITOR_DEF("text_editor/highlighting/completion_selected_color", Color::html("434244"))); text_edit->add_color_override("completion_existing_color", EDITOR_DEF("text_editor/highlighting/completion_existing_color", Color::html("21dfdfdf"))); @@ -629,7 +624,7 @@ void ScriptTextEditor::_code_complete_script(const String &p_code, List<String> } String hint; Error err = script->get_language()->complete_code(p_code, script->get_path().get_base_dir(), base, r_options, r_force, hint); - if (hint != "") { + if (err == OK && hint != "") { code_editor->get_text_edit()->set_code_hint(hint); } } diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 13b0391a87..1b02f18d85 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -164,6 +164,8 @@ void ShaderTextEditor::_code_complete_script(const String &p_code, List<String> String calltip; Error err = sl.complete(p_code, ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types(), r_options, calltip); + if (err != OK) + ERR_PRINT("Shaderlang complete failed"); if (calltip != "") { get_text_edit()->set_code_hint(calltip); @@ -289,6 +291,8 @@ void ShaderEditor::_editor_settings_changed() { shader_editor->get_text_edit()->cursor_set_blink_speed(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink_speed")); shader_editor->get_text_edit()->add_constant_override("line_spacing", EditorSettings::get_singleton()->get("text_editor/theme/line_spacing")); shader_editor->get_text_edit()->cursor_set_block_mode(EditorSettings::get_singleton()->get("text_editor/cursor/block_caret")); + shader_editor->get_text_edit()->set_smooth_scroll_enabled(EditorSettings::get_singleton()->get("text_editor/open_scripts/smooth_scrolling")); + shader_editor->get_text_edit()->set_v_scroll_speed(EditorSettings::get_singleton()->get("text_editor/open_scripts/v_scroll_speed")); } void ShaderEditor::_bind_methods() { @@ -401,13 +405,7 @@ void ShaderEditorPlugin::edit(Object *p_object) { bool ShaderEditorPlugin::handles(Object *p_object) const { - bool handles = true; Shader *shader = Object::cast_to<Shader>(p_object); - /* - if (Object::cast_to<ShaderGraph>(shader)) // Don't handle ShaderGraph's - handles = false; - */ - return shader != NULL; } diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index d9fc2f32f7..93d12fd3d2 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" @@ -73,40 +76,35 @@ void SpatialEditorViewport::_update_camera(float p_interp_delta) { } else camera->set_perspective(get_fov(), get_znear(), get_zfar()); - Transform new_transform = to_camera_transform(cursor); - Transform old_transform = camera->get_global_transform(); - Transform transform; + float inertia = EDITOR_DEF("editors/3d/orbit_inertia", 0.5); + inertia = MAX(0, inertia); + + Cursor old_camera_cursor = camera_cursor; + camera_cursor = cursor; + + camera_cursor.x_rot = Math::lerp(old_camera_cursor.x_rot, cursor.x_rot, p_interp_delta * (1 / inertia)); + camera_cursor.y_rot = Math::lerp(old_camera_cursor.y_rot, cursor.y_rot, p_interp_delta * (1 / inertia)); bool disable_interp = (Input::get_singleton()->get_mouse_button_mask() & (2 | 4)) || Input::get_singleton()->is_key_pressed(KEY_SHIFT) || Input::get_singleton()->is_key_pressed(KEY_ALT) || Input::get_singleton()->is_key_pressed(KEY_CONTROL); - if (p_interp_delta && !disable_interp) { - //interpolate - float interp_speed = 14; //maybe should be made configuration - transform = old_transform.interpolate_with(new_transform, MIN(1.0, p_interp_delta * interp_speed)); - } else { - transform = new_transform; + if (p_interp_delta == 0 || disable_interp || is_freelook_active()) { + camera_cursor = cursor; } float tolerance = 0.0001; bool equal = true; - for (int i = 0; i < 3; i++) { - if (transform.basis[i].distance_to(old_transform.basis[i]) > tolerance) { - equal = false; - break; - } - } + if (Math::abs(old_camera_cursor.x_rot - camera_cursor.x_rot) > tolerance || Math::abs(old_camera_cursor.y_rot - camera_cursor.y_rot) > tolerance) + equal = false; - if (equal && transform.origin.distance_to(old_transform.origin) > tolerance) { + if (equal && old_camera_cursor.pos.distance_squared_to(camera_cursor.pos) > tolerance * tolerance) equal = false; - } - if (equal) { - transform = new_transform; - } + if (equal && Math::abs(old_camera_cursor.distance - camera_cursor.distance) > tolerance) + equal = false; + + if (!equal || p_interp_delta == 0 || is_freelook_active()) { - if (!equal || p_interp_delta == 0) { - //print_line(transform); - camera->set_global_transform(transform); + camera->set_global_transform(to_camera_transform(camera_cursor)); update_transform_gizmo_view(); } } @@ -228,7 +226,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 +698,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()); @@ -1532,6 +1535,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { Vector3 pos = camera_transform.xform(Vector3(0, 0, 0)); Vector3 diff = camera->get_translation() - pos; cursor.pos += diff; + freelook_target_position += diff; name = ""; _update_name(); @@ -1653,7 +1657,7 @@ void SpatialEditorViewport::scale_cursor_distance(real_t scale) { Point2i SpatialEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const { Point2i relative; - if (bool(EditorSettings::get_singleton()->get("editors/3d/warped_mouse_panning"))) { + if (bool(EDITOR_DEF("editors/3d/warped_mouse_panning", false))) { relative = Input::get_singleton()->warp_mouse_motion(p_ev_mouse_motion, surface->get_global_rect()); } else { relative = p_ev_mouse_motion->get_relative(); @@ -1664,7 +1668,7 @@ Point2i SpatialEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMous void SpatialEditorViewport::_update_freelook(real_t delta) { if (!is_freelook_active()) { - freelook_velocity = Vector3(); + freelook_target_position = cursor.pos; return; } @@ -1681,60 +1685,47 @@ void SpatialEditorViewport::_update_freelook(real_t delta) { int key_speed_modifier = Object::cast_to<InputEventKey>(ED_GET_SHORTCUT("spatial_editor/freelook_speed_modifier")->get_shortcut().ptr())->get_scancode(); Vector3 direction; - bool pressed = false; bool speed_modifier = false; const Input &input = *Input::get_singleton(); if (input.is_key_pressed(key_left)) { direction -= right; - pressed = true; } if (input.is_key_pressed(key_right)) { direction += right; - pressed = true; } if (input.is_key_pressed(key_forward)) { direction += forward; - pressed = true; } if (input.is_key_pressed(key_backwards)) { direction -= forward; - pressed = true; } if (input.is_key_pressed(key_up)) { direction += up; - pressed = true; } if (input.is_key_pressed(key_down)) { direction -= up; - pressed = true; } if (input.is_key_pressed(key_speed_modifier)) { speed_modifier = true; } - const EditorSettings &s = *EditorSettings::get_singleton(); - real_t inertia = s.get("editors/3d/freelook_inertia"); - if (inertia < 0) - inertia = 0; - - const real_t base_speed = s.get("editors/3d/freelook_base_speed"); - const real_t modifier_speed_factor = s.get("editors/3d/freelook_modifier_speed_factor"); + real_t inertia = EDITOR_DEF("editors/3d/freelook_inertia", 0.2); + inertia = MAX(0, inertia); + const real_t base_speed = EDITOR_DEF("editors/3d/freelook_base_speed", 0.5); + const real_t modifier_speed_factor = EDITOR_DEF("editors/3d/freelook_modifier_speed_factor", 5); real_t speed = base_speed * cursor.distance; if (speed_modifier) speed *= modifier_speed_factor; - Vector3 instant_velocity = direction * speed; - // Higher inertia should increase "lag" (lerp with factor between 0 and 1) - // Inertia of zero should produce instant movement (lerp with factor of 1) - // Takes reference of 60fps for units, so that inertia of 1 gives approximate lerp factor of 0.5 - real_t factor = 1.0 / (1.0 + inertia * delta * 60.f); - freelook_velocity = freelook_velocity.linear_interpolate(instant_velocity, CLAMP(factor, 0, 1)); + // Inertia of zero should produce instant movement (lerp with factor of 1) in this case it returns a really high value and gets clamped to 1. - cursor.pos += freelook_velocity * delta; + freelook_target_position += direction * speed; + real_t factor = (1.0 / (inertia + 0.001)) * delta; + cursor.pos = cursor.pos.linear_interpolate(freelook_target_position, CLAMP(factor, 0, 1)); } void SpatialEditorViewport::set_message(String p_message, float p_time) { @@ -1895,6 +1886,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 +2417,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 +2425,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 +2476,292 @@ 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); + + 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 +2772,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 +2791,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 +2856,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 +2867,8 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed info->add_child(info_label); info->hide(); + accept = NULL; + freelook_active = false; selection_menu = memnew(PopupMenu); @@ -3119,13 +3405,6 @@ void SpatialEditor::set_state(const Dictionary &p_state) { settings_znear->set_value(float(d["znear"])); if (d.has("fov")) settings_fov->set_value(float(d["fov"])); - - if (d.has("default_srgb")) { - bool use = d["default_srgb"]; - - //viewport_environment->set_enable_fx(Environment::FX_SRGB,use); - //view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_DEFAULT_SRGB), use ); - } if (d.has("show_grid")) { bool use = d["show_grid"]; @@ -4000,6 +4279,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 +4327,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 +4364,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 +4499,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..5f3ef2dbee 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; @@ -122,7 +131,7 @@ private: float gizmo_scale; bool freelook_active; - Vector3 freelook_velocity; + Vector3 freelook_target_position; PanelContainer *info; Label *info_label; @@ -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; @@ -230,7 +239,7 @@ private: distance = 4; region_select = false; } - } cursor; + } cursor, camera_cursor; void scale_cursor_distance(real_t scale); @@ -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/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index c2c26bfe6c..7b40f69082 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -244,8 +244,22 @@ void SpriteFramesEditor::_down_pressed() { void SpriteFramesEditor::_delete_pressed() { + ERR_FAIL_COND(!frames->has_animation(edited_anim)); + if (tree->get_current() < 0) return; + + int to_delete = tree->get_current(); + if (to_delete < 0 || to_delete >= frames->get_frame_count(edited_anim)) { + return; + } + + undo_redo->create_action(TTR("Delete Resource")); + undo_redo->add_do_method(frames, "remove_frame", edited_anim, to_delete); + undo_redo->add_undo_method(frames, "add_frame", edited_anim, frames->get_frame(edited_anim, to_delete), to_delete); + undo_redo->add_do_method(this, "_update_library"); + undo_redo->add_undo_method(this, "_update_library"); + undo_redo->commit_action(); } void SpriteFramesEditor::_animation_select() { diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h index cb6f086de6..16b2da94d1 100644 --- a/editor/plugins/theme_editor_plugin.h +++ b/editor/plugins/theme_editor_plugin.h @@ -30,7 +30,6 @@ #ifndef THEME_EDITOR_PLUGIN_H #define THEME_EDITOR_PLUGIN_H -#include "scene/gui/button_group.h" #include "scene/gui/check_box.h" #include "scene/gui/file_dialog.h" #include "scene/gui/option_button.h" diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index f943ee5f6d..43856116a6 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -550,7 +550,6 @@ void TileMapEditor::_draw_fill_preview(int p_cell, const Point2i &p_point, bool PoolVector<Vector2> points = _bucket_fill(p_point, false, true); PoolVector<Vector2>::Read pr = points.read(); int len = points.size(); - int time_after = OS::get_singleton()->get_ticks_msec(); for (int i = 0; i < len; ++i) { _draw_cell(p_cell, pr[i], p_flip_h, p_flip_v, p_transpose, p_xform); |