diff options
Diffstat (limited to 'editor')
29 files changed, 261 insertions, 146 deletions
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 74e8df60f9..7183d34d4f 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -5727,16 +5727,24 @@ void AnimationTrackEditor::_show_imported_anim_warning() const { } void AnimationTrackEditor::_select_all_tracks_for_copy() { + TreeItem *track = track_copy_select->get_root()->get_children(); + if (!track) + return; + + bool all_selected = true; + while (track) { + if (!track->is_checked(0)) + all_selected = false; + + track = track->get_next(); + } + + track = track_copy_select->get_root()->get_children(); while (track) { - track->set_checked(0, selected_all_tracks); + track->set_checked(0, !all_selected); track = track->get_next(); } - selected_all_tracks = !selected_all_tracks; - if (selected_all_tracks) - select_all_button->set_text(TTR("Select All")); - else - select_all_button->set_text(TTR("Select None")); } void AnimationTrackEditor::_bind_methods() { @@ -6067,25 +6075,22 @@ AnimationTrackEditor::AnimationTrackEditor() { track_copy_dialog = memnew(ConfirmationDialog); add_child(track_copy_dialog); - track_copy_dialog->set_title(TTR("Select tracks to copy:")); + track_copy_dialog->set_title(TTR("Select Tracks to Copy")); track_copy_dialog->get_ok()->set_text(TTR("Copy")); VBoxContainer *track_vbox = memnew(VBoxContainer); track_copy_dialog->add_child(track_vbox); - selected_all_tracks = true; + Button *select_all_button = memnew(Button); + select_all_button->set_text(TTR("Select All/None")); + select_all_button->connect("pressed", this, "_select_all_tracks_for_copy"); + track_vbox->add_child(select_all_button); track_copy_select = memnew(Tree); track_copy_select->set_h_size_flags(SIZE_EXPAND_FILL); track_copy_select->set_v_size_flags(SIZE_EXPAND_FILL); track_copy_select->set_hide_root(true); track_vbox->add_child(track_copy_select); - track_copy_options = memnew(HBoxContainer); - track_vbox->add_child(track_copy_options); - select_all_button = memnew(Button); - select_all_button->set_text(TTR("Select All")); - select_all_button->connect("pressed", this, "_select_all_tracks_for_copy"); - track_copy_options->add_child(select_all_button); track_copy_dialog->connect("confirmed", this, "_edit_menu_pressed", varray(EDIT_COPY_TRACKS_CONFIRM)); animation_changing_awaiting_update = false; } diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h index 830d5b52d3..fd28d8f4d1 100644 --- a/editor/animation_track_editor.h +++ b/editor/animation_track_editor.h @@ -465,11 +465,8 @@ class AnimationTrackEditor : public VBoxContainer { void _selection_changed(); - bool selected_all_tracks; ConfirmationDialog *track_copy_dialog; Tree *track_copy_select; - HBoxContainer *track_copy_options; - Button *select_all_button; struct TrackClipboard { NodePath full_path; diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp index 226eef9c1e..3e0b644b20 100644 --- a/editor/animation_track_editor_plugins.cpp +++ b/editor/animation_track_editor_plugins.cpp @@ -337,7 +337,7 @@ AnimationTrackEditAudio::AnimationTrackEditAudio() { AudioStreamPreviewGenerator::get_singleton()->connect("preview_updated", this, "_preview_changed"); } -/// SPRITE FRAME /// +/// SPRITE FRAME / FRAME_COORDS /// int AnimationTrackEditSpriteFrame::get_key_height() const { @@ -439,14 +439,24 @@ void AnimationTrackEditSpriteFrame::draw_key(int p_index, float p_pixels_sec, in if (Object::cast_to<Sprite>(object) || Object::cast_to<Sprite3D>(object)) { - int frame = get_animation()->track_get_key_value(get_track(), p_index); - texture = object->call("get_texture"); if (!texture.is_valid()) { AnimationTrackEdit::draw_key(p_index, p_pixels_sec, p_x, p_selected, p_clip_left, p_clip_right); return; } + int hframes = object->call("get_hframes"); + int vframes = object->call("get_vframes"); + + Vector2 coords; + if (is_coords) { + coords = get_animation()->track_get_key_value(get_track(), p_index); + } else { + int frame = get_animation()->track_get_key_value(get_track(), p_index); + coords.x = frame % hframes; + coords.y = frame / hframes; + } + region.size = texture->get_size(); if (bool(object->call("is_region"))) { @@ -454,9 +464,6 @@ void AnimationTrackEditSpriteFrame::draw_key(int p_index, float p_pixels_sec, in region = Rect2(object->call("get_region_rect")); } - int hframes = object->call("get_hframes"); - int vframes = object->call("get_vframes"); - if (hframes > 1) { region.size.x /= hframes; } @@ -464,8 +471,8 @@ void AnimationTrackEditSpriteFrame::draw_key(int p_index, float p_pixels_sec, in region.size.y /= vframes; } - region.position.x += region.size.x * (frame % hframes); - region.position.y += region.size.y * (frame / hframes); + region.position.x += region.size.x * coords.x; + region.position.y += region.size.y * coords.y; } else if (Object::cast_to<AnimatedSprite>(object) || Object::cast_to<AnimatedSprite3D>(object)) { @@ -532,6 +539,11 @@ void AnimationTrackEditSpriteFrame::set_node(Object *p_object) { id = p_object->get_instance_id(); } +void AnimationTrackEditSpriteFrame::set_as_coords() { + + is_coords = true; +} + /// SUB ANIMATION /// int AnimationTrackEditSubAnim::get_key_height() const { @@ -1297,6 +1309,14 @@ AnimationTrackEdit *AnimationTrackEditDefaultPlugin::create_value_track_edit(Obj return sprite; } + if (p_property == "frame_coords" && (p_object->is_class("Sprite") || p_object->is_class("Sprite3D"))) { + + AnimationTrackEditSpriteFrame *sprite = memnew(AnimationTrackEditSpriteFrame); + sprite->set_as_coords(); + sprite->set_node(p_object); + return sprite; + } + if (p_property == "current_animation" && (p_object->is_class("AnimationPlayer"))) { AnimationTrackEditSubAnim *player = memnew(AnimationTrackEditSubAnim); diff --git a/editor/animation_track_editor_plugins.h b/editor/animation_track_editor_plugins.h index 5f0ea6196c..1013cccf72 100644 --- a/editor/animation_track_editor_plugins.h +++ b/editor/animation_track_editor_plugins.h @@ -81,6 +81,7 @@ class AnimationTrackEditSpriteFrame : public AnimationTrackEdit { GDCLASS(AnimationTrackEditSpriteFrame, AnimationTrackEdit); ObjectID id; + bool is_coords; public: virtual int get_key_height() const; @@ -89,6 +90,9 @@ public: virtual void draw_key(int p_index, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right); void set_node(Object *p_object); + void set_as_coords(); + + AnimationTrackEditSpriteFrame() { is_coords = false; } }; class AnimationTrackEditSubAnim : public AnimationTrackEdit { diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index 1e5eabc24e..f5a01dfb04 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -417,6 +417,7 @@ ConnectDialog::ConnectDialog() { dst_method = memnew(LineEdit); dst_method->set_h_size_flags(SIZE_EXPAND_FILL); + dst_method->connect("text_entered", this, "_builtin_text_entered"); dstm_hb->add_child(dst_method); advanced = memnew(CheckButton); diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index 9510092a86..7ae8a9e0ce 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -376,6 +376,12 @@ Error EditorExportPlatform::_save_zip_file(void *p_userdata, const String &p_pat return OK; } +Ref<ImageTexture> EditorExportPlatform::get_option_icon(int p_index) const { + Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme(); + ERR_FAIL_COND_V(theme.is_null(), Ref<ImageTexture>()); + return theme->get_icon("Play", "EditorIcons"); +} + String EditorExportPlatform::find_export_template(String template_file_name, String *err) const { String current_version = VERSION_FULL_CONFIG; @@ -1403,7 +1409,7 @@ bool EditorExport::poll_export_platforms() { bool changed = false; for (int i = 0; i < export_platforms.size(); i++) { - if (export_platforms.write[i]->poll_devices()) { + if (export_platforms.write[i]->poll_export()) { changed = true; } } diff --git a/editor/editor_export.h b/editor/editor_export.h index 11dc464b5a..b0e27af629 100644 --- a/editor/editor_export.h +++ b/editor/editor_export.h @@ -243,10 +243,12 @@ public: Error save_pack(const Ref<EditorExportPreset> &p_preset, const String &p_path, Vector<SharedObject> *p_so_files = NULL, bool p_embed = false, int64_t *r_embedded_start = NULL, int64_t *r_embedded_size = NULL); Error save_zip(const Ref<EditorExportPreset> &p_preset, const String &p_path); - virtual bool poll_devices() { return false; } - virtual int get_device_count() const { return 0; } - virtual String get_device_name(int p_device) const { return ""; } - virtual String get_device_info(int p_device) const { return ""; } + virtual bool poll_export() { return false; } + virtual int get_options_count() const { return 0; } + virtual String get_options_tooltip() const { return ""; } + virtual Ref<ImageTexture> get_option_icon(int p_index) const; + virtual String get_option_label(int p_device) const { return ""; } + virtual String get_option_tooltip(int p_device) const { return ""; } enum DebugFlags { DEBUG_FLAG_DUMB_CLIENT = 1, diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp index b6d27d84e0..97c796c707 100644 --- a/editor/editor_fonts.cpp +++ b/editor/editor_fonts.cpp @@ -64,7 +64,7 @@ Ref<DynamicFont> m_name; \ m_name.instance(); \ m_name->set_size(m_size); \ - if (CustomFont.is_valid()) { \ + if (CustomFontBold.is_valid()) { \ m_name->set_font_data(CustomFontBold); \ m_name->add_fallback(DefaultFontBold); \ } else { \ diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 4a1e93eaad..690538f44c 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -1467,6 +1467,11 @@ void EditorHelp::_notification(int p_what) { _update_doc(); } break; + case NOTIFICATION_THEME_CHANGED: { + if (is_visible_in_tree()) { + _class_desc_resized(); + } + } break; default: break; } } diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 78e058eeaa..96b6a32914 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -644,7 +644,19 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) { emit_signal("property_keyed", property, use_keying_next()); if (use_keying_next()) { - call_deferred("emit_changed", property, object->get(property).operator int64_t() + 1, "", false); + if (property == "frame_coords" && (object->is_class("Sprite") || object->is_class("Sprite3D"))) { + Vector2 new_coords = object->get(property); + new_coords.x++; + if (new_coords.x >= object->get("hframes").operator int64_t()) { + new_coords.x = 0; + new_coords.y++; + } + + call_deferred("emit_changed", property, new_coords, "", false); + } else { + call_deferred("emit_changed", property, object->get(property).operator int64_t() + 1, "", false); + } + call_deferred("update_property"); } } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index be40384f7c..9fa33044e1 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -57,6 +57,7 @@ #include "editor/editor_help.h" #include "editor/editor_properties.h" #include "editor/editor_settings.h" +#include "editor/editor_spin_slider.h" #include "editor/editor_themes.h" #include "editor/import/editor_import_collada.h" #include "editor/import/editor_scene_importer_gltf.h" @@ -371,7 +372,7 @@ void EditorNode::_notification(int p_what) { case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { scene_tabs->set_tab_close_display_policy((bool(EDITOR_GET("interface/scene_tabs/always_show_close_button")) ? Tabs::CLOSE_BUTTON_SHOW_ALWAYS : Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY)); - Ref<Theme> theme = create_editor_theme(theme_base->get_theme()); + theme = create_editor_theme(theme_base->get_theme()); theme_base->set_theme(theme); gui_base->set_theme(theme); @@ -1470,7 +1471,7 @@ void EditorNode::_dialog_action(String p_file) { config.instance(); Error err = config->load(EditorSettings::get_singleton()->get_editor_layouts_config()); - if (err == ERR_CANT_OPEN) { + if (err == ERR_FILE_CANT_OPEN || err == ERR_FILE_NOT_FOUND) { config.instance(); // new config } else if (err != OK) { show_warning(TTR("Error trying to save layout!")); @@ -3559,6 +3560,7 @@ void EditorNode::register_editor_types() { ClassDB::register_class<AnimationTrackEditPlugin>(); ClassDB::register_class<ScriptCreateDialog>(); ClassDB::register_class<EditorFeatureProfile>(); + ClassDB::register_class<EditorSpinSlider>(); // FIXME: Is this stuff obsolete, or should it be ported to new APIs? ClassDB::register_class<EditorScenePostImport>(); @@ -5651,6 +5653,9 @@ EditorNode::EditorNode() { editor_export = memnew(EditorExport); add_child(editor_export); + // Exporters might need the theme + theme = create_custom_theme(); + register_exporters(); GLOBAL_DEF("editor/main_run_args", ""); @@ -5692,7 +5697,6 @@ EditorNode::EditorNode() { theme_base->add_child(gui_base); gui_base->set_anchors_and_margins_preset(Control::PRESET_WIDE); - Ref<Theme> theme = create_custom_theme(); theme_base->set_theme(theme); gui_base->set_theme(theme); gui_base->add_style_override("panel", gui_base->get_stylebox("Background", "EditorStyles")); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index e978713c34..d3d91e6e0d 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -2205,7 +2205,14 @@ void EditorPropertyResource::_menu_option(int p_which) { case OBJ_MENU_NEW_SCRIPT: { if (Object::cast_to<Node>(get_edited_object())) { - EditorNode::get_singleton()->get_scene_tree_dock()->open_script_dialog(Object::cast_to<Node>(get_edited_object())); + EditorNode::get_singleton()->get_scene_tree_dock()->open_script_dialog(Object::cast_to<Node>(get_edited_object()), false); + } + + } break; + case OBJ_MENU_EXTEND_SCRIPT: { + + if (Object::cast_to<Node>(get_edited_object())) { + EditorNode::get_singleton()->get_scene_tree_dock()->open_script_dialog(Object::cast_to<Node>(get_edited_object()), true); } } break; @@ -2338,7 +2345,8 @@ void EditorPropertyResource::_update_menu_items() { menu->clear(); if (get_edited_property() == "script" && base_type == "Script" && Object::cast_to<Node>(get_edited_object())) { - menu->add_icon_item(get_icon("Script", "EditorIcons"), TTR("New Script"), OBJ_MENU_NEW_SCRIPT); + menu->add_icon_item(get_icon("ScriptCreate", "EditorIcons"), TTR("New Script"), OBJ_MENU_NEW_SCRIPT); + menu->add_icon_item(get_icon("ScriptExtend", "EditorIcons"), TTR("Extend Script"), OBJ_MENU_EXTEND_SCRIPT); menu->add_separator(); } else if (base_type != "") { int idx = 0; @@ -2399,19 +2407,11 @@ void EditorPropertyResource::_update_menu_items() { inheritors_array.push_back(t); - int id = TYPE_BASE_ID + idx; - - if (!icon.is_valid() && has_icon(t, "EditorIcons")) { - icon = get_icon(t, "EditorIcons"); - } - - if (icon.is_valid()) { + if (!icon.is_valid()) + icon = get_icon(has_icon(t, "EditorIcons") ? t : "Object", "EditorIcons"); - menu->add_icon_item(icon, vformat(TTR("New %s"), t), id); - } else { - - menu->add_item(vformat(TTR("New %s"), t), id); - } + int id = TYPE_BASE_ID + idx; + menu->add_icon_item(icon, vformat(TTR("New %s"), t), id); idx++; } @@ -2615,14 +2615,6 @@ void EditorPropertyResource::update_property() { get_tree()->call_deferred("call_group", "_editor_resource_properties", "_fold_other_editors", this); } opened_editor = true; - /* - Button *open_in_editor = memnew(Button); - open_in_editor->set_text(TTR("Open Editor")); - open_in_editor->set_icon(get_icon("Edit", "EditorIcons")); - sub_inspector_vbox->add_child(open_in_editor); - open_in_editor->connect("pressed", this, "_open_editor_pressed"); - open_in_editor->set_h_size_flags(SIZE_SHRINK_CENTER); - */ } } @@ -2649,10 +2641,9 @@ void EditorPropertyResource::update_property() { if (res == RES()) { assign->set_icon(Ref<Texture>()); assign->set_text(TTR("[empty]")); - assign->set_tooltip(""); } else { - assign->set_icon(EditorNode::get_singleton()->get_object_icon(res.operator->(), "Node")); + assign->set_icon(EditorNode::get_singleton()->get_object_icon(res.operator->(), "Object")); if (res->get_name() != String()) { assign->set_text(res->get_name()); @@ -2925,7 +2916,7 @@ void EditorInspectorDefaultPlugin::parse_begin(Object *p_object) { bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) { - double default_float_step = EDITOR_GET("interface/inspector/default_float_step"); + float default_float_step = EDITOR_GET("interface/inspector/default_float_step"); switch (p_type) { diff --git a/editor/editor_properties.h b/editor/editor_properties.h index b8d6aa00c2..952b0447e2 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -550,7 +550,8 @@ class EditorPropertyResource : public EditorProperty { OBJ_MENU_COPY = 5, OBJ_MENU_PASTE = 6, OBJ_MENU_NEW_SCRIPT = 7, - OBJ_MENU_SHOW_IN_FILE_SYSTEM = 8, + OBJ_MENU_EXTEND_SCRIPT = 8, + OBJ_MENU_SHOW_IN_FILE_SYSTEM = 9, TYPE_BASE_ID = 100, CONVERT_BASE_ID = 1000 diff --git a/editor/editor_run_native.cpp b/editor/editor_run_native.cpp index 585ea0ec69..64e90f2488 100644 --- a/editor/editor_run_native.cpp +++ b/editor/editor_run_native.cpp @@ -75,20 +75,18 @@ void EditorRunNative::_notification(int p_what) { Ref<EditorExportPlatform> eep = EditorExport::get_singleton()->get_export_platform(E->key()); MenuButton *mb = E->get(); - int dc = eep->get_device_count(); + int dc = eep->get_options_count(); if (dc == 0) { mb->hide(); } else { mb->get_popup()->clear(); mb->show(); - if (dc == 1) { - mb->set_tooltip(eep->get_device_name(0) + "\n\n" + eep->get_device_info(0).strip_edges()); - } else { - mb->set_tooltip("Select device from the list"); + mb->set_tooltip(eep->get_options_tooltip()); + if (dc > 1) { for (int i = 0; i < dc; i++) { - mb->get_popup()->add_icon_item(get_icon("Play", "EditorIcons"), eep->get_device_name(i)); - mb->get_popup()->set_item_tooltip(mb->get_popup()->get_item_count() - 1, eep->get_device_info(i).strip_edges()); + mb->get_popup()->add_icon_item(eep->get_option_icon(i), eep->get_option_label(i)); + mb->get_popup()->set_item_tooltip(mb->get_popup()->get_item_count() - 1, eep->get_option_tooltip(i)); } } } @@ -111,7 +109,7 @@ void EditorRunNative::_run_native(int p_idx, int p_platform) { ERR_FAIL_COND(eep.is_null()); if (p_idx == -1) { - if (eep->get_device_count() == 1) { + if (eep->get_options_count() == 1) { menus[p_platform]->get_popup()->hide(); p_idx = 0; } else { diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 3ea59115b0..672844117d 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -559,8 +559,6 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { hints["editors/3d/freelook/freelook_base_speed"] = PropertyInfo(Variant::REAL, "editors/3d/freelook/freelook_base_speed", PROPERTY_HINT_RANGE, "0.0, 10, 0.01"); _initial_set("editors/3d/freelook/freelook_activation_modifier", 0); hints["editors/3d/freelook/freelook_activation_modifier"] = PropertyInfo(Variant::INT, "editors/3d/freelook/freelook_activation_modifier", PROPERTY_HINT_ENUM, "None,Shift,Alt,Meta,Ctrl"); - _initial_set("editors/3d/freelook/freelook_modifier_speed_factor", 3.0); - hints["editors/3d/freelook/freelook_modifier_speed_factor"] = PropertyInfo(Variant::REAL, "editors/3d/freelook/freelook_modifier_speed_factor", PROPERTY_HINT_RANGE, "0.0, 10.0, 0.1"); _initial_set("editors/3d/freelook/freelook_speed_zoom_link", false); // 2D diff --git a/editor/icons/icon_crypto_key.svg b/editor/icons/icon_crypto_key.svg new file mode 100644 index 0000000000..45b53c815d --- /dev/null +++ b/editor/icons/icon_crypto_key.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 4.233 4.233" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2.397.34-.374.373-.375.374v.375l.188.187-1.497 1.496v.375l.374.374h.374l.187-.188.282-.092.092-.282.282-.093.093-.28.094-.28.28-.095.187-.187.187.187h.374l.375-.375.373-.373.001-.374-1.122-1.122zm.374.858a.264.264 0 1 1 .002.528.264.264 0 0 1 -.002-.528z" fill="#e0e0e0"/></svg>
\ No newline at end of file diff --git a/editor/icons/icon_x509_certificate.svg b/editor/icons/icon_x509_certificate.svg new file mode 100644 index 0000000000..e175fa3234 --- /dev/null +++ b/editor/icons/icon_x509_certificate.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 4.233 4.233" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3.967.263-3.704.001v2.646h1.427a.993.993 0 0 1 -.022-.096.993.993 0 0 1 -.012-.099.993.993 0 0 1 -.002-.07.993.993 0 0 1 .005-.1.993.993 0 0 1 .014-.097.993.993 0 0 1 .025-.096.993.993 0 0 1 .034-.093.993.993 0 0 1 .043-.09.993.993 0 0 1 .052-.085.993.993 0 0 1 .06-.079.993.993 0 0 1 .068-.072.993.993 0 0 1 .074-.066.993.993 0 0 1 .08-.057.993.993 0 0 1 .087-.05.993.993 0 0 1 .09-.04.993.993 0 0 1 .095-.031.993.993 0 0 1 .096-.022.993.993 0 0 1 .099-.012.993.993 0 0 1 .07-.003.993.993 0 0 1 .099.006.993.993 0 0 1 .098.014.993.993 0 0 1 .096.025.993.993 0 0 1 .094.034.993.993 0 0 1 .089.043.993.993 0 0 1 .084.052.993.993 0 0 1 .08.06.993.993 0 0 1 .072.068.993.993 0 0 1 .065.074.993.993 0 0 1 .058.08.993.993 0 0 1 .05.087.993.993 0 0 1 .04.09.993.993 0 0 1 .031.095.993.993 0 0 1 .022.096.993.993 0 0 1 .012.099.993.993 0 0 1 .002.07.993.993 0 0 1 -.004.1.993.993 0 0 1 -.015.097.993.993 0 0 1 -.017.068h.365z" fill="#e0e0e0"/><g fill="#ff8484"><path d="m2.116 3.175v.793l.53-.253.529.253v-.793z"/><circle cx="2.646" cy="2.645" r=".794"/></g></svg>
\ No newline at end of file diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp index 49091dc812..fcf0e4af6f 100644 --- a/editor/import/editor_scene_importer_gltf.cpp +++ b/editor/import/editor_scene_importer_gltf.cpp @@ -1973,7 +1973,7 @@ Error EditorSceneImporterGLTF::_reparent_to_fake_joint(GLTFState &state, GLTFSke state.nodes.push_back(fake_joint); // We better not be a joint, or we messed up in our logic - if (node->joint == true) + if (node->joint) return FAILED; fake_joint->translation = node->translation; diff --git a/editor/node_dock.cpp b/editor/node_dock.cpp index d6df3bd369..7ba1796600 100644 --- a/editor/node_dock.cpp +++ b/editor/node_dock.cpp @@ -129,6 +129,7 @@ NodeDock::NodeDock() { select_a_node = memnew(Label); select_a_node->set_text(TTR("Select a single node to edit its signals and groups.")); + select_a_node->set_custom_minimum_size(Size2(100 * EDSCALE, 0)); select_a_node->set_v_size_flags(SIZE_EXPAND_FILL); select_a_node->set_valign(Label::VALIGN_CENTER); select_a_node->set_align(Label::ALIGN_CENTER); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 117b88bc7e..f9a7b7caf1 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -1197,7 +1197,7 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bo //Pan the viewport panning = true; } - } else if (panning) { + } else { if (!k->is_pressed()) { // Stop panning the viewport (for any mouse button press) panning = false; @@ -2721,8 +2721,10 @@ void CanvasItemEditor::_draw_ruler_tool() { viewport->draw_string(font, text_pos, vformat("%.2f px", length_vector.length()), font_color); if (draw_secondary_lines) { - int horizontal_axis_angle = round(180 * atan2(length_vector.y, length_vector.x) / Math_PI); - int vertictal_axis_angle = 90 - horizontal_axis_angle; + const float horizontal_angle_rad = atan2(length_vector.y, length_vector.x); + const float vertical_angle_rad = Math_PI / 2.0 - horizontal_angle_rad; + const int horizontal_angle = round(180 * horizontal_angle_rad / Math_PI); + const int vertical_angle = round(180 * vertical_angle_rad / Math_PI); Point2 text_pos2 = text_pos; text_pos2.x = begin.x < text_pos.x ? MIN(text_pos.x - text_width, begin.x - text_width / 2) : MAX(text_pos.x + text_width, begin.x - text_width / 2); @@ -2731,7 +2733,7 @@ void CanvasItemEditor::_draw_ruler_tool() { Point2 v_angle_text_pos = Point2(); v_angle_text_pos.x = CLAMP(begin.x - angle_text_width / 2, angle_text_width / 2, viewport->get_rect().size.x - angle_text_width); v_angle_text_pos.y = begin.y < end.y ? MIN(text_pos2.y - 2 * text_height, begin.y - text_height * 0.5) : MAX(text_pos2.y + text_height * 3, begin.y + text_height * 1.5); - viewport->draw_string(font, v_angle_text_pos, vformat("%d deg", vertictal_axis_angle), font_secondary_color); + viewport->draw_string(font, v_angle_text_pos, vformat("%d deg", vertical_angle), font_secondary_color); text_pos2 = text_pos; text_pos2.y = end.y < text_pos.y ? MIN(text_pos.y - text_height * 2, end.y - text_height / 2) : MAX(text_pos.y + text_height * 2, end.y - text_height / 2); @@ -2752,7 +2754,35 @@ void CanvasItemEditor::_draw_ruler_tool() { h_angle_text_pos.y = MIN(text_pos.y - height_multiplier * text_height, MIN(end.y - text_height * 0.5, text_pos2.y - height_multiplier * text_height)); } } - viewport->draw_string(font, h_angle_text_pos, vformat("%d deg", horizontal_axis_angle), font_secondary_color); + viewport->draw_string(font, h_angle_text_pos, vformat("%d deg", horizontal_angle), font_secondary_color); + + // Angle arcs + int arc_point_count = 8; + float arc_radius_max_length_percent = 0.1; + float ruler_length = length_vector.length() * zoom; + float arc_max_radius = 50.0; + float arc_line_width = 2.0; + + const Vector2 end_to_begin = (end - begin); + + float arc_1_start_angle = + end_to_begin.x < 0 ? + (end_to_begin.y < 0 ? 3.0 * Math_PI / 2.0 - vertical_angle_rad : Math_PI / 2.0) : + (end_to_begin.y < 0 ? 3.0 * Math_PI / 2.0 : Math_PI / 2.0 - vertical_angle_rad); + float arc_1_end_angle = arc_1_start_angle + vertical_angle_rad; + // Constrain arc to triangle height & max size + float arc_1_radius = MIN(MIN(arc_radius_max_length_percent * ruler_length, ABS(end_to_begin.y)), arc_max_radius); + + float arc_2_start_angle = + end_to_begin.x < 0 ? + (end_to_begin.y < 0 ? 0.0 : -horizontal_angle_rad) : + (end_to_begin.y < 0 ? Math_PI - horizontal_angle_rad : Math_PI); + float arc_2_end_angle = arc_2_start_angle + horizontal_angle_rad; + // Constrain arc to triangle width & max size + float arc_2_radius = MIN(MIN(arc_radius_max_length_percent * ruler_length, ABS(end_to_begin.x)), arc_max_radius); + + viewport->draw_arc(begin, arc_1_radius, arc_1_start_angle, arc_1_end_angle, arc_point_count, ruler_primary_color, Math::round(EDSCALE * arc_line_width)); + viewport->draw_arc(end, arc_2_radius, arc_2_start_angle, arc_2_end_angle, arc_point_count, ruler_primary_color, Math::round(EDSCALE * arc_line_width)); } if (is_snap_active) { @@ -4894,7 +4924,7 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) { if (state.has("grid_snap_active")) { grid_snap_active = state["grid_snap_active"]; - grid_snap_button->set_pressed(smart_snap_active); + grid_snap_button->set_pressed(grid_snap_active); } if (state.has("snap_node_parent")) { diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index ecb2354aa1..5bccb36252 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -1186,7 +1186,7 @@ void ScriptTextEditor::_edit_option(int p_op) { if (expression.parse(line) == OK) { Variant result = expression.execute(Array(), Variant(), false); if (expression.get_error_text() == "") { - results.append(whitespace + (String)result); + results.append(whitespace + result.get_construct_string()); } else { results.append(line); } diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index 095350d0e1..1d8fd38858 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -2049,12 +2049,11 @@ void SpatialEditorViewport::_update_freelook(real_t delta) { return; } - Vector3 forward = camera->get_transform().basis.xform(Vector3(0, 0, -1)); - Vector3 right = camera->get_transform().basis.xform(Vector3(1, 0, 0)); - Vector3 up = camera->get_transform().basis.xform(Vector3(0, 1, 0)); + const Vector3 forward = camera->get_transform().basis.xform(Vector3(0, 0, -1)); + const Vector3 right = camera->get_transform().basis.xform(Vector3(1, 0, 0)); + const Vector3 up = camera->get_transform().basis.xform(Vector3(0, 1, 0)); Vector3 direction; - bool speed_modifier = false; if (is_shortcut_pressed("spatial_editor/freelook_left")) { direction -= right; @@ -2074,17 +2073,17 @@ void SpatialEditorViewport::_update_freelook(real_t delta) { if (is_shortcut_pressed("spatial_editor/freelook_down")) { direction -= up; } - if (is_shortcut_pressed("spatial_editor/freelook_speed_modifier")) { - speed_modifier = true; - } real_t speed = freelook_speed; - if (speed_modifier) { - real_t modifier_speed_factor = EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_modifier_speed_factor"); - speed *= modifier_speed_factor; + + if (is_shortcut_pressed("spatial_editor/freelook_speed_modifier")) { + speed *= 3.0; + } + if (is_shortcut_pressed("spatial_editor/freelook_slow_modifier")) { + speed *= 0.333333; } - Vector3 motion = direction * speed * delta; + const Vector3 motion = direction * speed * delta; cursor.pos += motion; cursor.eye_pos += motion; } @@ -3588,6 +3587,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed ED_SHORTCUT("spatial_editor/freelook_up", TTR("Freelook Up"), KEY_E); ED_SHORTCUT("spatial_editor/freelook_down", TTR("Freelook Down"), KEY_Q); ED_SHORTCUT("spatial_editor/freelook_speed_modifier", TTR("Freelook Speed Modifier"), KEY_SHIFT); + ED_SHORTCUT("spatial_editor/freelook_slow_modifier", TTR("Freelook Slow Modifier"), KEY_ALT); preview_camera = memnew(CheckBox); preview_camera->set_text(TTR("Preview")); diff --git a/editor/project_export.cpp b/editor/project_export.cpp index 7456396460..adcbddfb04 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -286,11 +286,13 @@ void ProjectExportDialog::_edit_preset(int p_index) { export_templates_error->hide(); export_button->set_disabled(true); + get_ok()->set_disabled(true); } else { export_error->hide(); export_templates_error->hide(); export_button->set_disabled(false); + get_ok()->set_disabled(false); } custom_features->set_text(current->get_custom_features()); @@ -623,6 +625,7 @@ void ProjectExportDialog::_delete_preset_confirm() { int idx = presets->get_current(); _edit_preset(-1); export_button->set_disabled(true); + get_ok()->set_disabled(true); EditorExport::get_singleton()->remove_export_preset(idx); _update_presets(); } @@ -1249,6 +1252,7 @@ ProjectExportDialog::ProjectExportDialog() { export_button->connect("pressed", this, "_export_project"); // Disable initially before we select a valid preset export_button->set_disabled(true); + get_ok()->set_disabled(true); export_all_dialog = memnew(ConfirmationDialog); add_child(export_all_dialog); diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 35187214a6..803c806028 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -1109,6 +1109,8 @@ void ProjectSettingsEditor::drop_data_fw(const Point2 &p_point, const Variant &p TreeItem *selected = input_editor->get_selected(); TreeItem *item = input_editor->get_item_at_position(p_point); + if (!item) + return; TreeItem *target = item->get_parent() == input_editor->get_root() ? item : item->get_parent(); String selected_name = "input/" + selected->get_text(0); diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index ecb272876d..ce82d44164 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -246,7 +246,13 @@ void CustomPropertyEditor::_menu_option(int p_which) { case OBJ_MENU_NEW_SCRIPT: { if (Object::cast_to<Node>(owner)) - EditorNode::get_singleton()->get_scene_tree_dock()->open_script_dialog(Object::cast_to<Node>(owner)); + EditorNode::get_singleton()->get_scene_tree_dock()->open_script_dialog(Object::cast_to<Node>(owner), false); + + } break; + case OBJ_MENU_EXTEND_SCRIPT: { + + if (Object::cast_to<Node>(owner)) + EditorNode::get_singleton()->get_scene_tree_dock()->open_script_dialog(Object::cast_to<Node>(owner), true); } break; case OBJ_MENU_SHOW_IN_FILE_SYSTEM: { diff --git a/editor/property_editor.h b/editor/property_editor.h index 029c2211d5..b1c61c5e25 100644 --- a/editor/property_editor.h +++ b/editor/property_editor.h @@ -77,7 +77,8 @@ class CustomPropertyEditor : public Popup { OBJ_MENU_COPY = 4, OBJ_MENU_PASTE = 5, OBJ_MENU_NEW_SCRIPT = 6, - OBJ_MENU_SHOW_IN_FILE_SYSTEM = 7, + OBJ_MENU_EXTEND_SCRIPT = 7, + OBJ_MENU_SHOW_IN_FILE_SYSTEM = 8, TYPE_BASE_ID = 100, CONVERT_BASE_ID = 1000 }; diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 98ab1bfb54..0884620e5d 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -421,53 +421,11 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { create_dialog->popup_create(false, true, selected->get_class()); } break; + case TOOL_EXTEND_SCRIPT: { + attach_script_to_selected(true); + } break; case TOOL_ATTACH_SCRIPT: { - - if (!profile_allow_script_editing) { - break; - } - - List<Node *> selection = editor_selection->get_selected_node_list(); - if (selection.empty()) - break; - - Node *selected = scene_tree->get_selected(); - if (!selected) - selected = selection.front()->get(); - - Ref<Script> existing = selected->get_script(); - - String path = selected->get_filename(); - if (path == "") { - String root_path = editor_data->get_edited_scene_root()->get_filename(); - if (root_path == "") { - path = String("res://").plus_file(selected->get_name()); - } else { - path = root_path.get_base_dir().plus_file(selected->get_name()); - } - } - - String inherits = selected->get_class(); - if (existing.is_valid()) { - for (int i = 0; i < ScriptServer::get_language_count(); i++) { - ScriptLanguage *l = ScriptServer::get_language(i); - if (l->get_type() == existing->get_class()) { - String name = l->get_global_class_name(existing->get_path()); - if (ScriptServer::is_global_class(name) && EDITOR_GET("interface/editors/derive_script_globals_by_name").operator bool()) { - inherits = name; - } else if (l->can_inherit_from_file()) { - inherits = "\"" + existing->get_path() + "\""; - } - break; - } - } - } - script_create_dialog->connect("script_created", this, "_script_created"); - script_create_dialog->connect("popup_hide", this, "_script_creation_closed"); - script_create_dialog->set_inheritance_base_type("Node"); - script_create_dialog->config(inherits, path); - script_create_dialog->popup_centered(); - + attach_script_to_selected(false); } break; case TOOL_CLEAR_SCRIPT: { @@ -2482,10 +2440,9 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { if (profile_allow_script_editing) { if (selection.size() == 1) { - if (!existing_script.is_valid()) { - menu->add_icon_shortcut(get_icon("ScriptCreate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/attach_script"), TOOL_ATTACH_SCRIPT); - } else { - menu->add_icon_shortcut(get_icon("ScriptExtend", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/extend_script"), TOOL_ATTACH_SCRIPT); + menu->add_icon_shortcut(get_icon("ScriptCreate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/attach_script"), TOOL_ATTACH_SCRIPT); + if (existing_script.is_valid()) { + menu->add_icon_shortcut(get_icon("ScriptExtend", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/extend_script"), TOOL_EXTEND_SCRIPT); } } if (selection.size() > 1 || (existing_script.is_valid() && exisiting_script_removable)) { @@ -2595,10 +2552,64 @@ void SceneTreeDock::_focus_node() { } } -void SceneTreeDock::open_script_dialog(Node *p_for_node) { +void SceneTreeDock::attach_script_to_selected(bool p_extend) { + if (!profile_allow_script_editing) { + return; + } + + List<Node *> selection = editor_selection->get_selected_node_list(); + if (selection.empty()) + return; + + Node *selected = scene_tree->get_selected(); + if (!selected) + selected = selection.front()->get(); + + Ref<Script> existing = selected->get_script(); + + String path = selected->get_filename(); + if (path == "") { + String root_path = editor_data->get_edited_scene_root()->get_filename(); + if (root_path == "") { + path = String("res://").plus_file(selected->get_name()); + } else { + path = root_path.get_base_dir().plus_file(selected->get_name()); + } + } + + String inherits = selected->get_class(); + + if (p_extend && existing.is_valid()) { + for (int i = 0; i < ScriptServer::get_language_count(); i++) { + ScriptLanguage *l = ScriptServer::get_language(i); + if (l->get_type() == existing->get_class()) { + String name = l->get_global_class_name(existing->get_path()); + if (ScriptServer::is_global_class(name) && EDITOR_GET("interface/editors/derive_script_globals_by_name").operator bool()) { + inherits = name; + } else if (l->can_inherit_from_file()) { + inherits = "\"" + existing->get_path() + "\""; + } + break; + } + } + } + + script_create_dialog->connect("script_created", this, "_script_created"); + script_create_dialog->connect("popup_hide", this, "_script_creation_closed"); + script_create_dialog->set_inheritance_base_type("Node"); + script_create_dialog->config(inherits, path); + script_create_dialog->popup_centered(); +} + +void SceneTreeDock::open_script_dialog(Node *p_for_node, bool p_extend) { scene_tree->set_selected(p_for_node, false); - _tool_selected(TOOL_ATTACH_SCRIPT); + + if (p_extend) { + _tool_selected(TOOL_EXTEND_SCRIPT); + } else { + _tool_selected(TOOL_ATTACH_SCRIPT); + } } void SceneTreeDock::add_remote_tree_editor(Control *p_remote) { diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index 014ce58e88..4e78b84c53 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -64,6 +64,7 @@ class SceneTreeDock : public VBoxContainer { TOOL_RENAME, TOOL_BATCH_RENAME, TOOL_REPLACE, + TOOL_EXTEND_SCRIPT, TOOL_ATTACH_SCRIPT, TOOL_CLEAR_SCRIPT, TOOL_MOVE_UP, @@ -259,7 +260,8 @@ public: void replace_node(Node *p_node, Node *p_by_node, bool p_keep_properties = true, bool p_remove_old = true); - void open_script_dialog(Node *p_for_node); + void attach_script_to_selected(bool p_extend); + void open_script_dialog(Node *p_for_node, bool p_extend); ScriptCreateDialog *get_script_create_dialog() { return script_create_dialog; } diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp index 89d275a90b..ccee38422c 100644 --- a/editor/script_editor_debugger.cpp +++ b/editor/script_editor_debugger.cpp @@ -597,7 +597,19 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da if (var.is_zero()) { var = RES(); } else if (var.get_type() == Variant::STRING) { - var = ResourceLoader::load(var); + String path = var; + if (path.find("::") != -1) { + // built-in resource + String base_path = path.get_slice("::", 0); + if (ResourceLoader::get_resource_type(base_path) == "PackedScene") { + if (!EditorNode::get_singleton()->is_scene_open(base_path)) { + EditorNode::get_singleton()->load_scene(base_path); + } + } else { + EditorNode::get_singleton()->load_resource(base_path); + } + } + var = ResourceLoader::load(path); if (pinfo.hint_string == "Script") debugObj->set_script(var); |