diff options
Diffstat (limited to 'editor/plugins')
114 files changed, 994 insertions, 635 deletions
diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp index 7f023af848..c8a36a3a99 100644 --- a/editor/plugins/abstract_polygon_2d_editor.cpp +++ b/editor/plugins/abstract_polygon_2d_editor.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,6 +32,7 @@ #include "canvas_item_editor_plugin.h" #include "core/os/keyboard.h" +#include "editor/editor_scale.h" AbstractPolygon2DEditor::Vertex::Vertex() : polygon(-1), diff --git a/editor/plugins/abstract_polygon_2d_editor.h b/editor/plugins/abstract_polygon_2d_editor.h index a00cdd0cf6..6ed6d0a257 100644 --- a/editor/plugins/abstract_polygon_2d_editor.h +++ b/editor/plugins/abstract_polygon_2d_editor.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/animation_blend_space_1d_editor.cpp b/editor/plugins/animation_blend_space_1d_editor.cpp index e07f041eb1..d743d1ac2f 100644 --- a/editor/plugins/animation_blend_space_1d_editor.cpp +++ b/editor/plugins/animation_blend_space_1d_editor.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -31,6 +31,7 @@ #include "animation_blend_space_1d_editor.h" #include "core/os/keyboard.h" +#include "editor/editor_scale.h" #include "scene/animation/animation_blend_tree.h" StringName AnimationNodeBlendSpace1DEditor::get_blend_position_path() const { @@ -702,13 +703,13 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() { bottom_hb->set_h_size_flags(SIZE_EXPAND_FILL); min_value = memnew(SpinBox); - min_value->set_max(0); min_value->set_min(-10000); + min_value->set_max(0); min_value->set_step(0.01); max_value = memnew(SpinBox); - max_value->set_max(10000); max_value->set_min(0.01); + max_value->set_max(10000); max_value->set_step(0.01); label_value = memnew(LineEdit); diff --git a/editor/plugins/animation_blend_space_1d_editor.h b/editor/plugins/animation_blend_space_1d_editor.h index 4a924b46c1..346ad36cff 100644 --- a/editor/plugins/animation_blend_space_1d_editor.h +++ b/editor/plugins/animation_blend_space_1d_editor.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp index b422e3e927..dc7754ba9a 100644 --- a/editor/plugins/animation_blend_space_2d_editor.cpp +++ b/editor/plugins/animation_blend_space_2d_editor.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -35,6 +35,7 @@ #include "core/os/input.h" #include "core/os/keyboard.h" #include "core/project_settings.h" +#include "editor/editor_scale.h" #include "scene/animation/animation_blend_tree.h" #include "scene/animation/animation_player.h" #include "scene/gui/menu_button.h" diff --git a/editor/plugins/animation_blend_space_2d_editor.h b/editor/plugins/animation_blend_space_2d_editor.h index 850a6201bb..50b0d9a06c 100644 --- a/editor/plugins/animation_blend_space_2d_editor.h +++ b/editor/plugins/animation_blend_space_2d_editor.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index e147206ec4..2de224c043 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -35,9 +35,11 @@ #include "core/os/keyboard.h" #include "core/project_settings.h" #include "editor/editor_inspector.h" +#include "editor/editor_scale.h" #include "scene/animation/animation_player.h" #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" +#include "scene/gui/progress_bar.h" #include "scene/main/viewport.h" void AnimationNodeBlendTreeEditor::add_custom_type(const String &p_name, const Ref<Script> &p_script) { @@ -145,7 +147,7 @@ void AnimationNodeBlendTreeEditor::_update_graph() { node->add_child(name); node->set_slot(0, false, 0, Color(), true, 0, get_color("font_color", "Label")); name->connect("text_entered", this, "_node_renamed", varray(agnode)); - name->connect("focus_exited", this, "_node_renamed_focus_out", varray(name, agnode)); + name->connect("focus_exited", this, "_node_renamed_focus_out", varray(name, agnode), CONNECT_DEFERRED); base = 1; node->set_show_close_button(true); node->connect("close_request", this, "_delete_request", varray(E->get()), CONNECT_DEFERRED); diff --git a/editor/plugins/animation_blend_tree_editor_plugin.h b/editor/plugins/animation_blend_tree_editor_plugin.h index 77b57a50d0..4f5badea9f 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.h +++ b/editor/plugins/animation_blend_tree_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -41,6 +41,8 @@ #include "scene/gui/popup.h" #include "scene/gui/tree.h" +class ProgressBar; + class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin { GDCLASS(AnimationNodeBlendTreeEditor, AnimationTreeNodeEditorPlugin); diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 80353bab01..5e69ce4e69 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -36,6 +36,7 @@ #include "core/os/keyboard.h" #include "core/project_settings.h" #include "editor/animation_track_editor.h" +#include "editor/editor_scale.h" #include "editor/editor_settings.h" // For onion skinning. @@ -85,6 +86,9 @@ void AnimationPlayerEditor::_notification(int p_what) { track_editor->set_anim_pos(player->get_current_animation_position()); EditorNode::get_singleton()->get_inspector()->refresh(); + } else if (!player->is_valid()) { + // Reset timeline when the player has been stopped externally + frame->set_value(0); } else if (last_active) { // Need the last frame after it stopped. frame->set_value(player->get_current_animation_position()); @@ -993,9 +997,9 @@ void AnimationPlayerEditor::_animation_duplicate() { String new_name = current; while (player->has_animation(new_name)) { - new_name = new_name + " (copy)"; } + new_anim->set_name(new_name); undo_redo->create_action(TTR("Duplicate Animation")); undo_redo->add_do_method(player, "add_animation", new_name, new_anim); @@ -1089,8 +1093,6 @@ void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos, bool p_drag) if (!player->has_animation(player->get_assigned_animation())) return; - Ref<Animation> anim = player->get_animation(player->get_assigned_animation()); - updating = true; frame->set_value(Math::stepify(p_pos, _get_editor_step())); updating = false; diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h index 663ffd57f3..55c2f365ce 100644 --- a/editor/plugins/animation_player_editor_plugin.h +++ b/editor/plugins/animation_player_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index ce400ad6dd..2a582a1249 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -35,6 +35,7 @@ #include "core/os/input.h" #include "core/os/keyboard.h" #include "core/project_settings.h" +#include "editor/editor_scale.h" #include "scene/animation/animation_blend_tree.h" #include "scene/animation/animation_player.h" #include "scene/gui/menu_button.h" @@ -262,7 +263,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv if (connecting_to_node != StringName()) { if (state_machine->has_transition(connecting_from, connecting_to_node)) { - EditorNode::get_singleton()->show_warning("Transition exists!"); + EditorNode::get_singleton()->show_warning(TTR("Transition exists!")); } else { @@ -1329,7 +1330,7 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() { top_hb->add_spacer(); - top_hb->add_child(memnew(Label("Play Mode:"))); + top_hb->add_child(memnew(Label(TTR("Play Mode:")))); play_mode = memnew(OptionButton); top_hb->add_child(play_mode); diff --git a/editor/plugins/animation_state_machine_editor.h b/editor/plugins/animation_state_machine_editor.h index 8b0a5a0b00..132e66b28d 100644 --- a/editor/plugins/animation_state_machine_editor.h +++ b/editor/plugins/animation_state_machine_editor.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp index 28dc5bf5c8..8dc7e4638d 100644 --- a/editor/plugins/animation_tree_editor_plugin.cpp +++ b/editor/plugins/animation_tree_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -39,6 +39,7 @@ #include "core/os/input.h" #include "core/os/keyboard.h" #include "core/project_settings.h" +#include "editor/editor_scale.h" #include "scene/animation/animation_blend_tree.h" #include "scene/animation/animation_player.h" #include "scene/gui/menu_button.h" @@ -284,7 +285,7 @@ AnimationTreeEditorPlugin::AnimationTreeEditorPlugin(EditorNode *p_node) { editor = p_node; anim_tree_editor = memnew(AnimationTreeEditor); - anim_tree_editor->set_custom_minimum_size(Size2(0, 300)); + anim_tree_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE); button = editor->add_bottom_panel_item(TTR("AnimationTree"), anim_tree_editor); button->hide(); diff --git a/editor/plugins/animation_tree_editor_plugin.h b/editor/plugins/animation_tree_editor_plugin.h index 4ecbf2e05e..0b93b0fd8e 100644 --- a/editor/plugins/animation_tree_editor_plugin.h +++ b/editor/plugins/animation_tree_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/animation_tree_player_editor_plugin.cpp b/editor/plugins/animation_tree_player_editor_plugin.cpp index c99ad7f441..2b365feec5 100644 --- a/editor/plugins/animation_tree_player_editor_plugin.cpp +++ b/editor/plugins/animation_tree_player_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -34,6 +34,7 @@ #include "core/os/input.h" #include "core/os/keyboard.h" #include "core/project_settings.h" +#include "editor/editor_scale.h" #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" #include "scene/main/viewport.h" @@ -923,17 +924,18 @@ void AnimationTreePlayerEditor::_notification(int p_what) { _draw_cos_line(source, dest, col); } + const Ref<Font> f = get_font("font", "Label"); + const Point2 status_offset = Point2(5, 25) * EDSCALE + Point2(0, f->get_ascent()); + switch (anim_tree->get_last_error()) { case AnimationTreePlayer::CONNECT_OK: { - Ref<Font> f = get_font("font", "Label"); - f->draw(get_canvas_item(), Point2(5, 25 + f->get_ascent()), TTR("Animation tree is valid."), Color(0, 1, 0.6, 0.8)); + f->draw(get_canvas_item(), status_offset, TTR("Animation tree is valid."), Color(0, 1, 0.6, 0.8)); } break; default: { - Ref<Font> f = get_font("font", "Label"); - f->draw(get_canvas_item(), Point2(5, 25 + f->get_ascent()), TTR("Animation tree is invalid."), Color(1, 0.6, 0.0, 0.8)); + f->draw(get_canvas_item(), status_offset, TTR("Animation tree is invalid."), Color(1, 0.6, 0.0, 0.8)); } break; } @@ -1300,7 +1302,7 @@ AnimationTreePlayerEditor::AnimationTreePlayerEditor() { p->connect("id_pressed", this, "_add_menu_item"); play_button = memnew(Button); - play_button->set_position(Point2(25, 0)); + play_button->set_position(Point2(25, 0) * EDSCALE); play_button->set_size(Point2(25, 15)); add_child(play_button); play_button->set_toggle_mode(true); @@ -1439,7 +1441,7 @@ AnimationTreePlayerEditorPlugin::AnimationTreePlayerEditorPlugin(EditorNode *p_n editor = p_node; anim_tree_editor = memnew(AnimationTreePlayerEditor); - anim_tree_editor->set_custom_minimum_size(Size2(0, 300)); + anim_tree_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE); button = editor->add_bottom_panel_item(TTR("AnimationTree"), anim_tree_editor); button->hide(); diff --git a/editor/plugins/animation_tree_player_editor_plugin.h b/editor/plugins/animation_tree_player_editor_plugin.h index 03bc559b86..d3fd6ae362 100644 --- a/editor/plugins/animation_tree_player_editor_plugin.h +++ b/editor/plugins/animation_tree_player_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index 95767a96d8..2428bf82d4 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -33,7 +33,9 @@ #include "core/io/json.h" #include "core/version.h" #include "editor/editor_node.h" +#include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/project_settings_editor.h" void EditorAssetLibraryItem::configure(const String &p_title, int p_asset_id, const String &p_category, int p_category_id, const String &p_author, int p_author_id, const String &p_cost) { @@ -137,8 +139,6 @@ EditorAssetLibraryItem::EditorAssetLibraryItem() { set_custom_minimum_size(Size2(250, 100) * EDSCALE); set_h_size_flags(SIZE_EXPAND_FILL); - - set_mouse_filter(MOUSE_FILTER_PASS); } ////////////////////////////////////////////////////////////////////////////// @@ -160,7 +160,7 @@ void EditorAssetLibraryItemDescription::set_image(int p_type, int p_index, const Ref<Image> overlay = get_icon("PlayOverlay", "EditorIcons")->get_data(); Ref<Image> thumbnail = p_image->get_data(); thumbnail = thumbnail->duplicate(); - Point2 overlay_pos = Point2((thumbnail->get_width() - overlay->get_width() / 2) / 2, (thumbnail->get_height() - overlay->get_height() / 2) / 2); + Point2 overlay_pos = Point2((thumbnail->get_width() - overlay->get_width()) / 2, (thumbnail->get_height() - overlay->get_height()) / 2); // Overlay and thumbnail need the same format for `blend_rect` to work. thumbnail->convert(Image::FORMAT_RGBA8); @@ -433,7 +433,10 @@ void EditorAssetLibraryItemDownload::_notification(int p_what) { String::humanize_size(download->get_body_size()))); } else { // Total file size is unknown, so it cannot be displayed. - status->set_text(TTR("Downloading...")); + progress->set_modulate(Color(0, 0, 0, 0)); + status->set_text(vformat( + TTR("Downloading...") + " (%s)", + String::humanize_size(download->get_downloaded_bytes()))); } } @@ -652,12 +655,12 @@ const char *EditorAssetLibrary::sort_key[SORT_MAX] = { }; const char *EditorAssetLibrary::sort_text[SORT_MAX] = { - "Recently Updated", - "Least Recently Updated", - "Name (A-Z)", - "Name (Z-A)", - "License (A-Z)", // "cost" stores the SPDX license name in the Godot Asset Library. - "License (Z-A)", // "cost" stores the SPDX license name in the Godot Asset Library. + TTRC("Recently Updated"), + TTRC("Least Recently Updated"), + TTRC("Name (A-Z)"), + TTRC("Name (Z-A)"), + TTRC("License (A-Z)"), // "cost" stores the SPDX license name in the Godot Asset Library. + TTRC("License (Z-A)"), // "cost" stores the SPDX license name in the Godot Asset Library. }; const char *EditorAssetLibrary::support_key[SUPPORT_MAX] = { @@ -724,9 +727,9 @@ void EditorAssetLibrary::_image_update(bool use_cache, bool final, const PoolByt uint8_t jpg_signature[3] = { 255, 216, 255 }; if (r.ptr()) { - if (memcmp(&r[0], &png_signature[0], 8) == 0) { + if ((memcmp(&r[0], &png_signature[0], 8) == 0) && Image::_png_mem_loader_func) { image->copy_internals_from(Image::_png_mem_loader_func(r.ptr(), len)); - } else if (memcmp(&r[0], &jpg_signature[0], 3) == 0) { + } else if ((memcmp(&r[0], &jpg_signature[0], 3) == 0) && Image::_jpg_mem_loader_func) { image->copy_internals_from(Image::_jpg_mem_loader_func(r.ptr(), len)); } } @@ -807,7 +810,7 @@ void EditorAssetLibrary::_image_request_completed(int p_status, int p_code, cons _image_update(p_code == HTTPClient::RESPONSE_NOT_MODIFIED, true, p_data, p_queue_id); } else { - WARN_PRINTS("Error getting image file from URL: " + image_queue[p_queue_id].image_url); + WARN_PRINT("Error getting image file from URL: " + image_queue[p_queue_id].image_url); Object *obj = ObjectDB::get_instance(image_queue[p_queue_id].target); if (obj) { obj->call("set_image", image_queue[p_queue_id].image_type, image_queue[p_queue_id].image_index, get_icon("FileBrokenBigThumb", "EditorIcons")); @@ -1383,7 +1386,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) { search_hb2->add_child(memnew(Label(TTR("Sort:") + " "))); sort = memnew(OptionButton); for (int i = 0; i < SORT_MAX; i++) { - sort->add_item(sort_text[i]); + sort->add_item(TTRGET(sort_text[i])); } search_hb2->add_child(sort); @@ -1450,7 +1453,6 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) { library_scroll->add_child(library_vb_border); library_vb_border->add_style_override("panel", border2); library_vb_border->set_h_size_flags(SIZE_EXPAND_FILL); - library_vb_border->set_mouse_filter(MOUSE_FILTER_PASS); library_vb = memnew(VBoxContainer); library_vb->set_h_size_flags(SIZE_EXPAND_FILL); @@ -1494,6 +1496,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) { error_label->add_color_override("color", get_color("error_color", "Editor")); error_hb->add_child(error_label); error_tr = memnew(TextureRect); + error_tr->set_v_size_flags(Control::SIZE_SHRINK_CENTER); error_hb->add_child(error_tr); description = NULL; diff --git a/editor/plugins/asset_library_editor_plugin.h b/editor/plugins/asset_library_editor_plugin.h index 70ffbd9eed..aa3c735810 100644 --- a/editor/plugins/asset_library_editor_plugin.h +++ b/editor/plugins/asset_library_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/audio_stream_editor_plugin.cpp b/editor/plugins/audio_stream_editor_plugin.cpp index 0ab3d26c85..60cb2ff54d 100644 --- a/editor/plugins/audio_stream_editor_plugin.cpp +++ b/editor/plugins/audio_stream_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,6 +32,8 @@ #include "core/io/resource_loader.h" #include "core/project_settings.h" +#include "editor/audio_stream_preview.h" +#include "editor/editor_scale.h" #include "editor/editor_settings.h" void AudioStreamEditor::_notification(int p_what) { @@ -207,7 +209,7 @@ void AudioStreamEditor::_bind_methods() { AudioStreamEditor::AudioStreamEditor() { - set_custom_minimum_size(Size2(1, 100)); + set_custom_minimum_size(Size2(1, 100) * EDSCALE); _current = 0; _dragging = false; diff --git a/editor/plugins/audio_stream_editor_plugin.h b/editor/plugins/audio_stream_editor_plugin.h index 12e4faef94..2191b541f6 100644 --- a/editor/plugins/audio_stream_editor_plugin.h +++ b/editor/plugins/audio_stream_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/baked_lightmap_editor_plugin.cpp b/editor/plugins/baked_lightmap_editor_plugin.cpp index d75f06de12..7db936ccb8 100644 --- a/editor/plugins/baked_lightmap_editor_plugin.cpp +++ b/editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/baked_lightmap_editor_plugin.h b/editor/plugins/baked_lightmap_editor_plugin.h index ff4b59244f..8b94257a62 100644 --- a/editor/plugins/baked_lightmap_editor_plugin.h +++ b/editor/plugins/baked_lightmap_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/camera_editor_plugin.cpp b/editor/plugins/camera_editor_plugin.cpp index 2531d59d1b..6f5bc69bd1 100644 --- a/editor/plugins/camera_editor_plugin.cpp +++ b/editor/plugins/camera_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/camera_editor_plugin.h b/editor/plugins/camera_editor_plugin.h index 400aee132d..9758a1ffbd 100644 --- a/editor/plugins/camera_editor_plugin.h +++ b/editor/plugins/camera_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 20b4cf43bf..bf21abb455 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -35,6 +35,7 @@ #include "core/print_string.h" #include "core/project_settings.h" #include "editor/editor_node.h" +#include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/plugins/animation_player_editor_plugin.h" #include "editor/plugins/script_editor_plugin.h" @@ -47,6 +48,7 @@ #include "scene/2d/touch_screen_button.h" #include "scene/gui/grid_container.h" #include "scene/gui/nine_patch_rect.h" +#include "scene/gui/viewport_container.h" #include "scene/main/canvas_layer.h" #include "scene/main/viewport.h" #include "scene/resources/packed_scene.h" @@ -54,8 +56,9 @@ #define MIN_ZOOM 0.01 #define MAX_ZOOM 100 -#define RULER_WIDTH 15 * EDSCALE +#define RULER_WIDTH (15 * EDSCALE) #define SCALE_HANDLE_DISTANCE 25 +#define MOVE_HANDLE_DISTANCE 25 class SnapDialog : public ConfirmationDialog { @@ -1111,7 +1114,11 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve if (dragged_guide_index >= 0) { vguides.remove(dragged_guide_index); undo_redo->create_action(TTR("Remove Vertical Guide")); - undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", vguides); + if (vguides.empty()) { + undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "remove_meta", "_edit_vertical_guides_"); + } else { + undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", vguides); + } undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", prev_vguides); undo_redo->add_undo_method(viewport, "update"); undo_redo->commit_action(); @@ -1140,7 +1147,11 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve if (dragged_guide_index >= 0) { hguides.remove(dragged_guide_index); undo_redo->create_action(TTR("Remove Horizontal Guide")); - undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", hguides); + if (hguides.empty()) { + undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "remove_meta", "_edit_horizontal_guides_"); + } else { + undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", hguides); + } undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", prev_hguides); undo_redo->add_undo_method(viewport, "update"); undo_redo->commit_action(); @@ -1482,7 +1493,9 @@ bool CanvasItemEditor::_gui_input_rotate(const Ref<InputEvent> &p_event) { for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { CanvasItem *canvas_item = E->get(); drag_to = transform.affine_inverse().xform(m->get_position()); - canvas_item->_edit_set_rotation(snap_angle(canvas_item->_edit_get_rotation() + (drag_from - drag_rotation_center).angle_to(drag_to - drag_rotation_center), canvas_item->_edit_get_rotation())); + //Rotate the opposite way if the canvas item's compounded scale has an uneven number of negative elements + bool opposite = (canvas_item->get_global_transform().get_scale().sign().dot(canvas_item->get_transform().get_scale().sign()) == 0); + canvas_item->_edit_set_rotation(snap_angle(canvas_item->_edit_get_rotation() + (opposite ? -1 : 1) * (drag_from - drag_rotation_center).angle_to(drag_to - drag_rotation_center), canvas_item->_edit_get_rotation())); viewport->update(); } return true; @@ -1738,8 +1751,18 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) { Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse(); - Point2 drag_to_snapped_begin = snap_point(xform.affine_inverse().xform(current_begin) + (drag_to - drag_from), SNAP_NODE_ANCHORS | SNAP_NODE_PARENT | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, canvas_item); - Point2 drag_to_snapped_end = snap_point(xform.affine_inverse().xform(current_end) + (drag_to - drag_from), SNAP_NODE_ANCHORS | SNAP_NODE_PARENT | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, canvas_item); + Point2 drag_to_snapped_begin; + Point2 drag_to_snapped_end; + + // last call decides which snapping lines are drawn + if (drag_type == DRAG_LEFT || drag_type == DRAG_TOP || drag_type == DRAG_TOP_LEFT) { + drag_to_snapped_end = snap_point(xform.affine_inverse().xform(current_end) + (drag_to - drag_from), SNAP_NODE_ANCHORS | SNAP_NODE_PARENT | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, canvas_item); + drag_to_snapped_begin = snap_point(xform.affine_inverse().xform(current_begin) + (drag_to - drag_from), SNAP_NODE_ANCHORS | SNAP_NODE_PARENT | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, canvas_item); + } else { + drag_to_snapped_begin = snap_point(xform.affine_inverse().xform(current_begin) + (drag_to - drag_from), SNAP_NODE_ANCHORS | SNAP_NODE_PARENT | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, canvas_item); + drag_to_snapped_end = snap_point(xform.affine_inverse().xform(current_end) + (drag_to - drag_from), SNAP_NODE_ANCHORS | SNAP_NODE_PARENT | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, canvas_item); + } + Point2 drag_begin = xform.xform(drag_to_snapped_begin); Point2 drag_end = xform.xform(drag_to_snapped_end); @@ -1844,14 +1867,16 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) { drag_type = DRAG_SCALE_BOTH; - Size2 scale_factor = Size2(SCALE_HANDLE_DISTANCE, SCALE_HANDLE_DISTANCE); - Rect2 x_handle_rect = Rect2(scale_factor.x * EDSCALE, -5 * EDSCALE, 10 * EDSCALE, 10 * EDSCALE); - if (x_handle_rect.has_point(simple_xform.affine_inverse().xform(b->get_position()))) { - drag_type = DRAG_SCALE_X; - } - Rect2 y_handle_rect = Rect2(-5 * EDSCALE, -(scale_factor.y + 10) * EDSCALE, 10 * EDSCALE, 10 * EDSCALE); - if (y_handle_rect.has_point(simple_xform.affine_inverse().xform(b->get_position()))) { - drag_type = DRAG_SCALE_Y; + if (show_transformation_gizmos) { + Size2 scale_factor = Size2(SCALE_HANDLE_DISTANCE, SCALE_HANDLE_DISTANCE); + Rect2 x_handle_rect = Rect2(scale_factor.x * EDSCALE, -5 * EDSCALE, 10 * EDSCALE, 10 * EDSCALE); + if (x_handle_rect.has_point(simple_xform.affine_inverse().xform(b->get_position()))) { + drag_type = DRAG_SCALE_X; + } + Rect2 y_handle_rect = Rect2(-5 * EDSCALE, scale_factor.y * EDSCALE, 10 * EDSCALE, 10 * EDSCALE); + if (y_handle_rect.has_point(simple_xform.affine_inverse().xform(b->get_position()))) { + drag_type = DRAG_SCALE_Y; + } } drag_from = transform.affine_inverse().xform(b->get_position()); @@ -1902,7 +1927,7 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) { scale.y = scale.x * ratio; } } else if (drag_type == DRAG_SCALE_Y) { - scale.y += scale_factor.y; + scale.y -= scale_factor.y; if (uniform) { scale.x = scale.y / ratio; } @@ -1961,6 +1986,24 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { if (selection.size() > 0) { drag_type = DRAG_MOVE; + + CanvasItem *canvas_item = drag_selection[0]; + Transform2D parent_xform = canvas_item->get_global_transform_with_canvas() * canvas_item->get_transform().affine_inverse(); + Transform2D unscaled_transform = (transform * parent_xform * canvas_item->_edit_get_transform()).orthonormalized(); + Transform2D simple_xform = viewport->get_transform() * unscaled_transform; + + if (show_transformation_gizmos) { + Size2 move_factor = Size2(MOVE_HANDLE_DISTANCE, MOVE_HANDLE_DISTANCE); + Rect2 x_handle_rect = Rect2(move_factor.x * EDSCALE, -5 * EDSCALE, 10 * EDSCALE, 10 * EDSCALE); + if (x_handle_rect.has_point(simple_xform.affine_inverse().xform(b->get_position()))) { + drag_type = DRAG_MOVE_X; + } + Rect2 y_handle_rect = Rect2(-5 * EDSCALE, move_factor.y * EDSCALE, 10 * EDSCALE, 10 * EDSCALE); + if (y_handle_rect.has_point(simple_xform.affine_inverse().xform(b->get_position()))) { + drag_type = DRAG_MOVE_Y; + } + } + drag_from = transform.affine_inverse().xform(b->get_position()); drag_selection = selection; _save_canvas_item_state(drag_selection); @@ -1970,7 +2013,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { } } - if (drag_type == DRAG_MOVE) { + if (drag_type == DRAG_MOVE || drag_type == DRAG_MOVE_X || drag_type == DRAG_MOVE_Y) { // Move the nodes if (m.is_valid()) { @@ -1992,7 +2035,15 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { } else { previous_pos = _get_encompassing_rect_from_list(drag_selection).position; } + Point2 new_pos = snap_point(previous_pos + (drag_to - drag_from), SNAP_GRID | SNAP_GUIDES | SNAP_PIXEL | SNAP_NODE_PARENT | SNAP_NODE_ANCHORS | SNAP_OTHER_NODES, 0, NULL, drag_selection); + + if (drag_type == DRAG_MOVE_X) { + new_pos.y = previous_pos.y; + } else if (drag_type == DRAG_MOVE_Y) { + new_pos.x = previous_pos.x; + } + bool single_axis = m->get_shift(); if (single_axis) { if (ABS(new_pos.x - previous_pos.x) > ABS(new_pos.y - previous_pos.y)) { @@ -2238,6 +2289,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { // Clear the selection if not additive editor_selection->clear(); viewport->update(); + selected_from_canvas = true; }; drag_from = click; @@ -2576,14 +2628,14 @@ void CanvasItemEditor::_draw_guides() { Color text_color = get_color("font_color", "Editor"); text_color.a = 0.5; if (drag_type == DRAG_DOUBLE_GUIDE || drag_type == DRAG_V_GUIDE) { - String str = vformat("%d px", xform.affine_inverse().xform(dragged_guide_pos).x); + String str = vformat("%d px", Math::round(xform.affine_inverse().xform(dragged_guide_pos).x)); Ref<Font> font = get_font("font", "Label"); Size2 text_size = font->get_string_size(str); viewport->draw_string(font, Point2(dragged_guide_pos.x + 10, RULER_WIDTH + text_size.y / 2 + 10), str, text_color); viewport->draw_line(Point2(dragged_guide_pos.x, 0), Point2(dragged_guide_pos.x, viewport->get_size().y), guide_color, Math::round(EDSCALE)); } if (drag_type == DRAG_DOUBLE_GUIDE || drag_type == DRAG_H_GUIDE) { - String str = vformat("%d px", xform.affine_inverse().xform(dragged_guide_pos).y); + String str = vformat("%d px", Math::round(xform.affine_inverse().xform(dragged_guide_pos).y)); Ref<Font> font = get_font("font", "Label"); Size2 text_size = font->get_string_size(str); viewport->draw_string(font, Point2(RULER_WIDTH + 10, dragged_guide_pos.y + text_size.y / 2 + 10), str, text_color); @@ -3201,7 +3253,7 @@ void CanvasItemEditor::_draw_selection() { int next = (i + 1) % 4; Vector2 ofs = ((endpoints[i] - endpoints[prev]).normalized() + ((endpoints[i] - endpoints[next]).normalized())).normalized(); - ofs *= 1.4144 * (select_handle->get_size().width / 2); + ofs *= Math_SQRT2 * (select_handle->get_size().width / 2); select_handle->draw(ci, (endpoints[i] + ofs - (select_handle->get_size() / 2)).floor()); @@ -3212,10 +3264,39 @@ void CanvasItemEditor::_draw_selection() { } } - // Draw the rescale handles + // Draw the move handles bool is_ctrl = Input::get_singleton()->is_key_pressed(KEY_CONTROL); bool is_alt = Input::get_singleton()->is_key_pressed(KEY_ALT); - if ((is_alt && is_ctrl) || tool == TOOL_SCALE || drag_type == DRAG_SCALE_X || drag_type == DRAG_SCALE_Y) { + if (tool == TOOL_MOVE && show_transformation_gizmos) { + if (_is_node_movable(canvas_item)) { + Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * canvas_item->_edit_get_transform()).orthonormalized(); + Transform2D simple_xform = viewport->get_transform() * unscaled_transform; + + Size2 move_factor = Size2(MOVE_HANDLE_DISTANCE, MOVE_HANDLE_DISTANCE); + viewport->draw_set_transform_matrix(simple_xform); + + Vector<Point2> points; + points.push_back(Vector2(move_factor.x * EDSCALE, 5 * EDSCALE)); + points.push_back(Vector2(move_factor.x * EDSCALE, -5 * EDSCALE)); + points.push_back(Vector2((move_factor.x + 10) * EDSCALE, 0)); + + viewport->draw_colored_polygon(points, get_color("axis_x_color", "Editor")); + viewport->draw_line(Point2(), Point2(move_factor.x * EDSCALE, 0), get_color("axis_x_color", "Editor"), Math::round(EDSCALE), true); + + points.clear(); + points.push_back(Vector2(5 * EDSCALE, move_factor.y * EDSCALE)); + points.push_back(Vector2(-5 * EDSCALE, move_factor.y * EDSCALE)); + points.push_back(Vector2(0, (move_factor.y + 10) * EDSCALE)); + + viewport->draw_colored_polygon(points, get_color("axis_y_color", "Editor")); + viewport->draw_line(Point2(), Point2(0, move_factor.y * EDSCALE), get_color("axis_y_color", "Editor"), Math::round(EDSCALE), true); + + viewport->draw_set_transform_matrix(viewport->get_transform()); + } + } + + // Draw the rescale handles + if (show_transformation_gizmos && ((is_alt && is_ctrl) || tool == TOOL_SCALE || drag_type == DRAG_SCALE_X || drag_type == DRAG_SCALE_Y)) { if (_is_node_movable(canvas_item)) { Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * canvas_item->_edit_get_transform()).orthonormalized(); Transform2D simple_xform = viewport->get_transform() * unscaled_transform; @@ -3230,9 +3311,9 @@ void CanvasItemEditor::_draw_selection() { scale_factor.y += offset.x; } } else if (drag_type == DRAG_SCALE_Y) { - scale_factor.y -= offset.y; + scale_factor.y += offset.y; if (uniform) { - scale_factor.x -= offset.y; + scale_factor.x += offset.y; } } @@ -3241,9 +3322,9 @@ void CanvasItemEditor::_draw_selection() { viewport->draw_rect(x_handle_rect, get_color("axis_x_color", "Editor")); viewport->draw_line(Point2(), Point2(scale_factor.x * EDSCALE, 0), get_color("axis_x_color", "Editor"), Math::round(EDSCALE), true); - Rect2 y_handle_rect = Rect2(-5 * EDSCALE, -(scale_factor.y + 10) * EDSCALE, 10 * EDSCALE, 10 * EDSCALE); + Rect2 y_handle_rect = Rect2(-5 * EDSCALE, scale_factor.y * EDSCALE, 10 * EDSCALE, 10 * EDSCALE); viewport->draw_rect(y_handle_rect, get_color("axis_y_color", "Editor")); - viewport->draw_line(Point2(), Point2(0, -scale_factor.y * EDSCALE), get_color("axis_y_color", "Editor"), Math::round(EDSCALE), true); + viewport->draw_line(Point2(), Point2(0, scale_factor.y * EDSCALE), get_color("axis_y_color", "Editor"), Math::round(EDSCALE), true); viewport->draw_set_transform_matrix(viewport->get_transform()); } @@ -3827,6 +3908,7 @@ void CanvasItemEditor::_notification(int p_what) { key_scale_button->set_icon(get_icon("KeyScale", "EditorIcons")); key_insert_button->set_icon(get_icon("Key", "EditorIcons")); key_auto_insert_button->set_icon(get_icon("AutoKey", "EditorIcons")); + animation_menu->set_icon(get_icon("GuiTabMenu", "EditorIcons")); zoom_minus->set_icon(get_icon("ZoomLess", "EditorIcons")); zoom_plus->set_icon(get_icon("ZoomMore", "EditorIcons")); @@ -3835,50 +3917,50 @@ void CanvasItemEditor::_notification(int p_what) { PopupMenu *p = presets_menu->get_popup(); p->clear(); - p->add_icon_item(get_icon("ControlAlignTopLeft", "EditorIcons"), "Top Left", ANCHORS_AND_MARGINS_PRESET_TOP_LEFT); - p->add_icon_item(get_icon("ControlAlignTopRight", "EditorIcons"), "Top Right", ANCHORS_AND_MARGINS_PRESET_TOP_RIGHT); - p->add_icon_item(get_icon("ControlAlignBottomRight", "EditorIcons"), "Bottom Right", ANCHORS_AND_MARGINS_PRESET_BOTTOM_RIGHT); - p->add_icon_item(get_icon("ControlAlignBottomLeft", "EditorIcons"), "Bottom Left", ANCHORS_AND_MARGINS_PRESET_BOTTOM_LEFT); + p->add_icon_item(get_icon("ControlAlignTopLeft", "EditorIcons"), TTR("Top Left"), ANCHORS_AND_MARGINS_PRESET_TOP_LEFT); + p->add_icon_item(get_icon("ControlAlignTopRight", "EditorIcons"), TTR("Top Right"), ANCHORS_AND_MARGINS_PRESET_TOP_RIGHT); + p->add_icon_item(get_icon("ControlAlignBottomRight", "EditorIcons"), TTR("Bottom Right"), ANCHORS_AND_MARGINS_PRESET_BOTTOM_RIGHT); + p->add_icon_item(get_icon("ControlAlignBottomLeft", "EditorIcons"), TTR("Bottom Left"), ANCHORS_AND_MARGINS_PRESET_BOTTOM_LEFT); p->add_separator(); - p->add_icon_item(get_icon("ControlAlignLeftCenter", "EditorIcons"), "Center Left", ANCHORS_AND_MARGINS_PRESET_CENTER_LEFT); - p->add_icon_item(get_icon("ControlAlignTopCenter", "EditorIcons"), "Center Top", ANCHORS_AND_MARGINS_PRESET_CENTER_TOP); - p->add_icon_item(get_icon("ControlAlignRightCenter", "EditorIcons"), "Center Right", ANCHORS_AND_MARGINS_PRESET_CENTER_RIGHT); - p->add_icon_item(get_icon("ControlAlignBottomCenter", "EditorIcons"), "Center Bottom", ANCHORS_AND_MARGINS_PRESET_CENTER_BOTTOM); - p->add_icon_item(get_icon("ControlAlignCenter", "EditorIcons"), "Center", ANCHORS_AND_MARGINS_PRESET_CENTER); + p->add_icon_item(get_icon("ControlAlignLeftCenter", "EditorIcons"), TTR("Center Left"), ANCHORS_AND_MARGINS_PRESET_CENTER_LEFT); + p->add_icon_item(get_icon("ControlAlignTopCenter", "EditorIcons"), TTR("Center Top"), ANCHORS_AND_MARGINS_PRESET_CENTER_TOP); + p->add_icon_item(get_icon("ControlAlignRightCenter", "EditorIcons"), TTR("Center Right"), ANCHORS_AND_MARGINS_PRESET_CENTER_RIGHT); + p->add_icon_item(get_icon("ControlAlignBottomCenter", "EditorIcons"), TTR("Center Bottom"), ANCHORS_AND_MARGINS_PRESET_CENTER_BOTTOM); + p->add_icon_item(get_icon("ControlAlignCenter", "EditorIcons"), TTR("Center"), ANCHORS_AND_MARGINS_PRESET_CENTER); p->add_separator(); - p->add_icon_item(get_icon("ControlAlignLeftWide", "EditorIcons"), "Left Wide", ANCHORS_AND_MARGINS_PRESET_LEFT_WIDE); - p->add_icon_item(get_icon("ControlAlignTopWide", "EditorIcons"), "Top Wide", ANCHORS_AND_MARGINS_PRESET_TOP_WIDE); - p->add_icon_item(get_icon("ControlAlignRightWide", "EditorIcons"), "Right Wide", ANCHORS_AND_MARGINS_PRESET_RIGHT_WIDE); - p->add_icon_item(get_icon("ControlAlignBottomWide", "EditorIcons"), "Bottom Wide", ANCHORS_AND_MARGINS_PRESET_BOTTOM_WIDE); - p->add_icon_item(get_icon("ControlVcenterWide", "EditorIcons"), "VCenter Wide ", ANCHORS_AND_MARGINS_PRESET_VCENTER_WIDE); - p->add_icon_item(get_icon("ControlHcenterWide", "EditorIcons"), "HCenter Wide ", ANCHORS_AND_MARGINS_PRESET_HCENTER_WIDE); + p->add_icon_item(get_icon("ControlAlignLeftWide", "EditorIcons"), TTR("Left Wide"), ANCHORS_AND_MARGINS_PRESET_LEFT_WIDE); + p->add_icon_item(get_icon("ControlAlignTopWide", "EditorIcons"), TTR("Top Wide"), ANCHORS_AND_MARGINS_PRESET_TOP_WIDE); + p->add_icon_item(get_icon("ControlAlignRightWide", "EditorIcons"), TTR("Right Wide"), ANCHORS_AND_MARGINS_PRESET_RIGHT_WIDE); + p->add_icon_item(get_icon("ControlAlignBottomWide", "EditorIcons"), TTR("Bottom Wide"), ANCHORS_AND_MARGINS_PRESET_BOTTOM_WIDE); + p->add_icon_item(get_icon("ControlVcenterWide", "EditorIcons"), TTR("VCenter Wide"), ANCHORS_AND_MARGINS_PRESET_VCENTER_WIDE); + p->add_icon_item(get_icon("ControlHcenterWide", "EditorIcons"), TTR("HCenter Wide"), ANCHORS_AND_MARGINS_PRESET_HCENTER_WIDE); p->add_separator(); - p->add_icon_item(get_icon("ControlAlignWide", "EditorIcons"), "Full Rect", ANCHORS_AND_MARGINS_PRESET_WIDE); - p->add_icon_item(get_icon("Anchor", "EditorIcons"), "Keep Ratio", ANCHORS_AND_MARGINS_PRESET_KEEP_RATIO); + p->add_icon_item(get_icon("ControlAlignWide", "EditorIcons"), TTR("Full Rect"), ANCHORS_AND_MARGINS_PRESET_WIDE); + p->add_icon_item(get_icon("Anchor", "EditorIcons"), TTR("Keep Ratio"), ANCHORS_AND_MARGINS_PRESET_KEEP_RATIO); p->add_separator(); p->add_submenu_item(TTR("Anchors only"), "Anchors"); p->set_item_icon(21, get_icon("Anchor", "EditorIcons")); anchors_popup->clear(); - anchors_popup->add_icon_item(get_icon("ControlAlignTopLeft", "EditorIcons"), "Top Left", ANCHORS_PRESET_TOP_LEFT); - anchors_popup->add_icon_item(get_icon("ControlAlignTopRight", "EditorIcons"), "Top Right", ANCHORS_PRESET_TOP_RIGHT); - anchors_popup->add_icon_item(get_icon("ControlAlignBottomRight", "EditorIcons"), "Bottom Right", ANCHORS_PRESET_BOTTOM_RIGHT); - anchors_popup->add_icon_item(get_icon("ControlAlignBottomLeft", "EditorIcons"), "Bottom Left", ANCHORS_PRESET_BOTTOM_LEFT); + anchors_popup->add_icon_item(get_icon("ControlAlignTopLeft", "EditorIcons"), TTR("Top Left"), ANCHORS_PRESET_TOP_LEFT); + anchors_popup->add_icon_item(get_icon("ControlAlignTopRight", "EditorIcons"), TTR("Top Right"), ANCHORS_PRESET_TOP_RIGHT); + anchors_popup->add_icon_item(get_icon("ControlAlignBottomRight", "EditorIcons"), TTR("Bottom Right"), ANCHORS_PRESET_BOTTOM_RIGHT); + anchors_popup->add_icon_item(get_icon("ControlAlignBottomLeft", "EditorIcons"), TTR("Bottom Left"), ANCHORS_PRESET_BOTTOM_LEFT); anchors_popup->add_separator(); - anchors_popup->add_icon_item(get_icon("ControlAlignLeftCenter", "EditorIcons"), "Center Left", ANCHORS_PRESET_CENTER_LEFT); - anchors_popup->add_icon_item(get_icon("ControlAlignTopCenter", "EditorIcons"), "Center Top", ANCHORS_PRESET_CENTER_TOP); - anchors_popup->add_icon_item(get_icon("ControlAlignRightCenter", "EditorIcons"), "Center Right", ANCHORS_PRESET_CENTER_RIGHT); - anchors_popup->add_icon_item(get_icon("ControlAlignBottomCenter", "EditorIcons"), "Center Bottom", ANCHORS_PRESET_CENTER_BOTTOM); - anchors_popup->add_icon_item(get_icon("ControlAlignCenter", "EditorIcons"), "Center", ANCHORS_PRESET_CENTER); + anchors_popup->add_icon_item(get_icon("ControlAlignLeftCenter", "EditorIcons"), TTR("Center Left"), ANCHORS_PRESET_CENTER_LEFT); + anchors_popup->add_icon_item(get_icon("ControlAlignTopCenter", "EditorIcons"), TTR("Center Top"), ANCHORS_PRESET_CENTER_TOP); + anchors_popup->add_icon_item(get_icon("ControlAlignRightCenter", "EditorIcons"), TTR("Center Right"), ANCHORS_PRESET_CENTER_RIGHT); + anchors_popup->add_icon_item(get_icon("ControlAlignBottomCenter", "EditorIcons"), TTR("Center Bottom"), ANCHORS_PRESET_CENTER_BOTTOM); + anchors_popup->add_icon_item(get_icon("ControlAlignCenter", "EditorIcons"), TTR("Center"), ANCHORS_PRESET_CENTER); anchors_popup->add_separator(); - anchors_popup->add_icon_item(get_icon("ControlAlignLeftWide", "EditorIcons"), "Left Wide", ANCHORS_PRESET_LEFT_WIDE); - anchors_popup->add_icon_item(get_icon("ControlAlignTopWide", "EditorIcons"), "Top Wide", ANCHORS_PRESET_TOP_WIDE); - anchors_popup->add_icon_item(get_icon("ControlAlignRightWide", "EditorIcons"), "Right Wide", ANCHORS_PRESET_RIGHT_WIDE); - anchors_popup->add_icon_item(get_icon("ControlAlignBottomWide", "EditorIcons"), "Bottom Wide", ANCHORS_PRESET_BOTTOM_WIDE); - anchors_popup->add_icon_item(get_icon("ControlVcenterWide", "EditorIcons"), "VCenter Wide ", ANCHORS_PRESET_VCENTER_WIDE); - anchors_popup->add_icon_item(get_icon("ControlHcenterWide", "EditorIcons"), "HCenter Wide ", ANCHORS_PRESET_HCENTER_WIDE); + anchors_popup->add_icon_item(get_icon("ControlAlignLeftWide", "EditorIcons"), TTR("Left Wide"), ANCHORS_PRESET_LEFT_WIDE); + anchors_popup->add_icon_item(get_icon("ControlAlignTopWide", "EditorIcons"), TTR("Top Wide"), ANCHORS_PRESET_TOP_WIDE); + anchors_popup->add_icon_item(get_icon("ControlAlignRightWide", "EditorIcons"), TTR("Right Wide"), ANCHORS_PRESET_RIGHT_WIDE); + anchors_popup->add_icon_item(get_icon("ControlAlignBottomWide", "EditorIcons"), TTR("Bottom Wide"), ANCHORS_PRESET_BOTTOM_WIDE); + anchors_popup->add_icon_item(get_icon("ControlVcenterWide", "EditorIcons"), TTR("VCenter Wide"), ANCHORS_PRESET_VCENTER_WIDE); + anchors_popup->add_icon_item(get_icon("ControlHcenterWide", "EditorIcons"), TTR("HCenter Wide"), ANCHORS_PRESET_HCENTER_WIDE); anchors_popup->add_separator(); - anchors_popup->add_icon_item(get_icon("ControlAlignWide", "EditorIcons"), "Full Rect", ANCHORS_PRESET_WIDE); + anchors_popup->add_icon_item(get_icon("ControlAlignWide", "EditorIcons"), TTR("Full Rect"), ANCHORS_PRESET_WIDE); anchor_mode_button->set_icon(get_icon("Anchor", "EditorIcons")); } @@ -3976,29 +4058,21 @@ void CanvasItemEditor::_update_scrollbars() { updating_scroll = true; - // Move the zoom buttons + // Move the zoom buttons. Point2 controls_vb_begin = Point2(5, 5); controls_vb_begin += (show_rulers) ? Point2(RULER_WIDTH, RULER_WIDTH) : Point2(); controls_vb->set_begin(controls_vb_begin); - // Move and resize the scrollbars - Size2 size = viewport->get_size(); Size2 hmin = h_scroll->get_minimum_size(); Size2 vmin = v_scroll->get_minimum_size(); - v_scroll->set_begin(Point2(size.width - vmin.width, (show_rulers) ? RULER_WIDTH : 0)); - v_scroll->set_end(Point2(size.width, size.height)); - - h_scroll->set_begin(Point2((show_rulers) ? RULER_WIDTH : 0, size.height - hmin.height)); - h_scroll->set_end(Point2(size.width - vmin.width, size.height)); - - // Get the visible frame + // Get the visible frame. Size2 screen_rect = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height")); Rect2 local_rect = Rect2(Point2(), viewport->get_size() - Size2(vmin.width, hmin.height)); _queue_update_bone_list(); - // Calculate scrollable area + // Calculate scrollable area. Rect2 canvas_item_rect = Rect2(Point2(), screen_rect); if (editor->get_edited_scene()) { Rect2 content_rect = _get_encompassing_rect(editor->get_edited_scene()); @@ -4008,7 +4082,8 @@ void CanvasItemEditor::_update_scrollbars() { canvas_item_rect.size += screen_rect * 2; canvas_item_rect.position -= screen_rect; - // Constraints the view offset and updates the scrollbars + // Constraints the view offset and updates the scrollbars. + Size2 size = viewport->get_size(); Point2 begin = canvas_item_rect.position; Point2 end = canvas_item_rect.position + canvas_item_rect.size - local_rect.size / zoom; bool constrain_editor_view = bool(EditorSettings::get_singleton()->get("editors/2d/constrain_editor_view")); @@ -4055,7 +4130,13 @@ void CanvasItemEditor::_update_scrollbars() { h_scroll->set_page(screen_rect.x); } - // Calculate scrollable area + // Move and resize the scrollbars, avoiding overlap. + v_scroll->set_begin(Point2(size.width - vmin.width, (show_rulers) ? RULER_WIDTH : 0)); + v_scroll->set_end(Point2(size.width, size.height - (h_scroll->is_visible() ? hmin.height : 0))); + h_scroll->set_begin(Point2((show_rulers) ? RULER_WIDTH : 0, size.height - hmin.height)); + h_scroll->set_end(Point2(size.width - (v_scroll->is_visible() ? vmin.width : 0), size.height)); + + // Calculate scrollable area. v_scroll->set_value(view_offset.y); h_scroll->set_value(view_offset.x); @@ -4067,10 +4148,9 @@ void CanvasItemEditor::_popup_warning_depop(Control *p_control) { ERR_FAIL_COND(!popup_temporarily_timers.has(p_control)); Timer *timer = popup_temporarily_timers[p_control]; + timer->queue_delete(); p_control->hide(); - remove_child(timer); popup_temporarily_timers.erase(p_control); - memdelete(timer); info_overlay->set_margin(MARGIN_LEFT, (show_rulers ? RULER_WIDTH : 0) + 10); } @@ -4206,11 +4286,15 @@ void CanvasItemEditor::_zoom_on_position(float p_zoom, Point2 p_position) { void CanvasItemEditor::_update_zoom_label() { String zoom_text; + // The zoom level displayed is relative to the editor scale + // (like in most image editors). Its lower bound is clamped to 1 as some people + // lower the editor scale to increase the available real estate, + // even if their display doesn't have a particularly low DPI. if (zoom >= 10) { - // Don't show a decimal when the zoom level is higher than 1000 % - zoom_text = rtos(Math::round(zoom * 100)) + " %"; + // Don't show a decimal when the zoom level is higher than 1000 %. + zoom_text = rtos(Math::round((zoom / MAX(1, EDSCALE)) * 100)) + " %"; } else { - zoom_text = rtos(Math::stepify(zoom * 100, 0.1)) + " %"; + zoom_text = rtos(Math::stepify((zoom / MAX(1, EDSCALE)) * 100, 0.1)) + " %"; } zoom_reset->set_text(zoom_text); @@ -4221,7 +4305,7 @@ void CanvasItemEditor::_button_zoom_minus() { } void CanvasItemEditor::_button_zoom_reset() { - _zoom_on_position(1.0, viewport_scrollable->get_size() / 2.0); + _zoom_on_position(1.0 * MAX(1, EDSCALE), viewport_scrollable->get_size() / 2.0); } void CanvasItemEditor::_button_zoom_plus() { @@ -4355,10 +4439,8 @@ void CanvasItemEditor::_update_override_camera_button(bool p_game_running) { } void CanvasItemEditor::_popup_callback(int p_op) { - last_option = MenuOption(p_op); switch (p_op) { - case SHOW_GRID: { show_grid = !show_grid; int idx = view_menu->get_popup()->get_item_index(SHOW_GRID); @@ -4383,6 +4465,12 @@ void CanvasItemEditor::_popup_callback(int p_op) { view_menu->get_popup()->set_item_checked(idx, show_edit_locks); viewport->update(); } break; + case SHOW_TRANSFORMATION_GIZMOS: { + show_transformation_gizmos = !show_transformation_gizmos; + int idx = view_menu->get_popup()->get_item_index(SHOW_TRANSFORMATION_GIZMOS); + view_menu->get_popup()->set_item_checked(idx, show_transformation_gizmos); + viewport->update(); + } break; case SNAP_USE_NODE_PARENT: { snap_node_parent = !snap_node_parent; int idx = smartsnap_config_popup->get_item_index(SNAP_USE_NODE_PARENT); @@ -4751,19 +4839,21 @@ void CanvasItemEditor::_popup_callback(int p_op) { } break; case CLEAR_GUIDES: { - if (EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_horizontal_guides_") || EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_vertical_guides_")) { + Node *const root = EditorNode::get_singleton()->get_edited_scene(); + + if (root && (root->has_meta("_edit_horizontal_guides_") || root->has_meta("_edit_vertical_guides_"))) { undo_redo->create_action(TTR("Clear Guides")); - if (EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_horizontal_guides_")) { - Array hguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_horizontal_guides_"); + if (root->has_meta("_edit_horizontal_guides_")) { + Array hguides = root->get_meta("_edit_horizontal_guides_"); - undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", Array()); - undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", hguides); + undo_redo->add_do_method(root, "remove_meta", "_edit_horizontal_guides_"); + undo_redo->add_undo_method(root, "set_meta", "_edit_horizontal_guides_", hguides); } - if (EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_vertical_guides_")) { - Array vguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_vertical_guides_"); + if (root->has_meta("_edit_vertical_guides_")) { + Array vguides = root->get_meta("_edit_vertical_guides_"); - undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", Array()); - undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", vguides); + undo_redo->add_do_method(root, "remove_meta", "_edit_vertical_guides_"); + undo_redo->add_undo_method(root, "set_meta", "_edit_vertical_guides_", vguides); } undo_redo->add_undo_method(viewport, "update"); undo_redo->commit_action(); @@ -4927,8 +5017,8 @@ void CanvasItemEditor::_focus_selection(int p_op) { center = rect.position + rect.size / 2; Vector2 offset = viewport->get_size() / 2 - editor->get_scene_root()->get_global_canvas_transform().xform(center); - view_offset.x -= offset.x / zoom; - view_offset.y -= offset.y / zoom; + view_offset.x -= Math::round(offset.x / zoom); + view_offset.y -= Math::round(offset.y / zoom); update_viewport(); } else { // VIEW_FRAME_TO_SELECTION @@ -4939,6 +5029,7 @@ void CanvasItemEditor::_focus_selection(int p_op) { zoom = scale_x < scale_y ? scale_x : scale_y; zoom *= 0.90; viewport->update(); + _update_zoom_label(); call_deferred("_popup_callback", VIEW_CENTER_TO_SELECTION); } } @@ -4981,7 +5072,8 @@ void CanvasItemEditor::_bind_methods() { Dictionary CanvasItemEditor::get_state() const { Dictionary state; - state["zoom"] = zoom; + // Take the editor scale into account. + state["zoom"] = zoom / MAX(1, EDSCALE); state["ofs"] = view_offset; state["grid_offset"] = grid_offset; state["grid_step"] = grid_step; @@ -5005,6 +5097,7 @@ Dictionary CanvasItemEditor::get_state() const { state["show_helpers"] = show_helpers; state["show_zoom_control"] = zoom_hb->is_visible(); state["show_edit_locks"] = show_edit_locks; + state["show_transformation_gizmos"] = show_transformation_gizmos; state["snap_rotation"] = snap_rotation; state["snap_scale"] = snap_scale; state["snap_relative"] = snap_relative; @@ -5018,7 +5111,9 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) { bool update_scrollbars = false; Dictionary state = p_state; if (state.has("zoom")) { - zoom = p_state["zoom"]; + // Compensate the editor scale, so that the editor scale can be changed + // and the zoom level will still be the same (relative to the editor scale). + zoom = float(p_state["zoom"]) * MAX(1, EDSCALE); _update_zoom_label(); } @@ -5141,6 +5236,12 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) { view_menu->get_popup()->set_item_checked(idx, show_edit_locks); } + if (state.has("show_transformation_gizmos")) { + show_transformation_gizmos = state["show_transformation_gizmos"]; + int idx = view_menu->get_popup()->get_item_index(SHOW_TRANSFORMATION_GIZMOS); + view_menu->get_popup()->set_item_checked(idx, show_transformation_gizmos); + } + if (state.has("show_zoom_control")) { // This one is not user-controllable, but instrumentable zoom_hb->set_visible(state["show_zoom_control"]); @@ -5233,12 +5334,13 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { show_helpers = false; show_rulers = true; show_guides = true; + show_transformation_gizmos = true; show_edit_locks = true; - zoom = 1; + zoom = 1.0 / MAX(1, EDSCALE); view_offset = Point2(-150 - RULER_WIDTH, -95 - RULER_WIDTH); previous_update_view_offset = view_offset; // Moves the view a little bit to the left so that (0,0) is visible. The values a relative to a 16/10 screen grid_offset = Point2(); - grid_step = Point2(10, 10); + grid_step = Point2(8, 8); // A power-of-two value works better as a default primary_grid_steps = 8; // A power-of-two value works better as a default grid_step_multiplier = 0; snap_rotation_offset = 0; @@ -5564,6 +5666,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_origin", TTR("Show Origin")), SHOW_ORIGIN); p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_viewport", TTR("Show Viewport")), SHOW_VIEWPORT); p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_edit_locks", TTR("Show Group And Lock Icons")), SHOW_EDIT_LOCKS); + p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_transformation_gizmos", TTR("Show Transformation Gizmos")), SHOW_TRANSFORMATION_GIZMOS); p->add_separator(); p->add_shortcut(ED_SHORTCUT("canvas_item_editor/center_selection", TTR("Center Selection"), KEY_F), VIEW_CENTER_TO_SELECTION); @@ -5637,7 +5740,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { animation_hb->add_child(key_auto_insert_button); animation_menu = memnew(MenuButton); - animation_menu->set_text(TTR("Animation")); + animation_menu->set_tooltip(TTR("Animation Key and Pose Options")); animation_hb->add_child(animation_menu); animation_menu->get_popup()->connect("id_pressed", this, "_popup_callback"); animation_menu->set_switch_on_hover(true); diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index 74adb882d1..37bc47ecd4 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -119,6 +119,7 @@ private: SHOW_ORIGIN, SHOW_VIEWPORT, SHOW_EDIT_LOCKS, + SHOW_TRANSFORMATION_GIZMOS, LOCK_SELECTED, UNLOCK_SELECTED, GROUP_SELECTED, @@ -189,7 +190,6 @@ private: SKELETON_SHOW_BONES, SKELETON_SET_IK_CHAIN, SKELETON_CLEAR_IK_CHAIN - }; enum DragType { @@ -209,6 +209,8 @@ private: DRAG_ANCHOR_BOTTOM_LEFT, DRAG_ANCHOR_ALL, DRAG_MOVE, + DRAG_MOVE_X, + DRAG_MOVE_Y, DRAG_SCALE_X, DRAG_SCALE_Y, DRAG_SCALE_BOTH, @@ -248,6 +250,8 @@ private: bool show_viewport; bool show_helpers; bool show_edit_locks; + bool show_transformation_gizmos; + float zoom; Point2 view_offset; Point2 previous_update_view_offset; diff --git a/editor/plugins/collision_polygon_2d_editor_plugin.cpp b/editor/plugins/collision_polygon_2d_editor_plugin.cpp index 0179adc148..3d32c0b698 100644 --- a/editor/plugins/collision_polygon_2d_editor_plugin.cpp +++ b/editor/plugins/collision_polygon_2d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/collision_polygon_2d_editor_plugin.h b/editor/plugins/collision_polygon_2d_editor_plugin.h index 3f0734fb19..a4fa7c7b3b 100644 --- a/editor/plugins/collision_polygon_2d_editor_plugin.h +++ b/editor/plugins/collision_polygon_2d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/collision_polygon_editor_plugin.cpp b/editor/plugins/collision_polygon_editor_plugin.cpp index 8cf09406c7..8620437ac6 100644 --- a/editor/plugins/collision_polygon_editor_plugin.cpp +++ b/editor/plugins/collision_polygon_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/collision_polygon_editor_plugin.h b/editor/plugins/collision_polygon_editor_plugin.h index 2a904a53ba..1871c6ee7e 100644 --- a/editor/plugins/collision_polygon_editor_plugin.h +++ b/editor/plugins/collision_polygon_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp index c8561d22a4..179ebca562 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.cpp +++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -448,8 +448,8 @@ void CollisionShape2DEditor::forward_canvas_draw_over_viewport(Control *p_overla float radius = shape->get_radius(); float height = shape->get_height() / 2; - handles.write[0] = Point2(radius, -height); - handles.write[1] = Point2(0, -(height + radius)); + handles.write[0] = Point2(radius, height); + handles.write[1] = Point2(0, height + radius); p_overlay->draw_texture(h, gt.xform(handles[0]) - size); p_overlay->draw_texture(h, gt.xform(handles[1]) - size); @@ -502,8 +502,8 @@ void CollisionShape2DEditor::forward_canvas_draw_over_viewport(Control *p_overla handles.resize(3); Vector2 ext = shape->get_extents(); handles.write[0] = Point2(ext.x, 0); - handles.write[1] = Point2(0, -ext.y); - handles.write[2] = Point2(ext.x, -ext.y); + handles.write[1] = Point2(0, ext.y); + handles.write[2] = Point2(ext.x, ext.y); p_overlay->draw_texture(h, gt.xform(handles[0]) - size); p_overlay->draw_texture(h, gt.xform(handles[1]) - size); diff --git a/editor/plugins/collision_shape_2d_editor_plugin.h b/editor/plugins/collision_shape_2d_editor_plugin.h index 10a1a6bd98..025420a886 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.h +++ b/editor/plugins/collision_shape_2d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.cpp b/editor/plugins/cpu_particles_2d_editor_plugin.cpp index 374900d4c7..655048c271 100644 --- a/editor/plugins/cpu_particles_2d_editor_plugin.cpp +++ b/editor/plugins/cpu_particles_2d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -296,9 +296,9 @@ CPUParticles2DEditorPlugin::CPUParticles2DEditorPlugin(EditorNode *p_node) { emission_mask->add_child(emvb); emission_mask_mode = memnew(OptionButton); emvb->add_margin_child(TTR("Emission Mask"), emission_mask_mode); - emission_mask_mode->add_item("Solid Pixels", EMISSION_MODE_SOLID); - emission_mask_mode->add_item("Border Pixels", EMISSION_MODE_BORDER); - emission_mask_mode->add_item("Directed Border Pixels", EMISSION_MODE_BORDER_DIRECTED); + emission_mask_mode->add_item(TTR("Solid Pixels"), EMISSION_MODE_SOLID); + emission_mask_mode->add_item(TTR("Border Pixels"), EMISSION_MODE_BORDER); + emission_mask_mode->add_item(TTR("Directed Border Pixels"), EMISSION_MODE_BORDER_DIRECTED); emission_colors = memnew(CheckBox); emission_colors->set_text(TTR("Capture from Pixel")); emvb->add_margin_child(TTR("Emission Colors"), emission_colors); diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.h b/editor/plugins/cpu_particles_2d_editor_plugin.h index 84bbfff095..21b06b6489 100644 --- a/editor/plugins/cpu_particles_2d_editor_plugin.h +++ b/editor/plugins/cpu_particles_2d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/cpu_particles_editor_plugin.cpp b/editor/plugins/cpu_particles_editor_plugin.cpp index 93ffce41fa..2074ba6b99 100644 --- a/editor/plugins/cpu_particles_editor_plugin.cpp +++ b/editor/plugins/cpu_particles_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/cpu_particles_editor_plugin.h b/editor/plugins/cpu_particles_editor_plugin.h index 674f00dc9f..deaced9ad9 100644 --- a/editor/plugins/cpu_particles_editor_plugin.h +++ b/editor/plugins/cpu_particles_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp index 727d92ba05..a4fc9b37ad 100644 --- a/editor/plugins/curve_editor_plugin.cpp +++ b/editor/plugins/curve_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -34,6 +34,7 @@ #include "core/core_string_names.h" #include "core/os/input.h" #include "core/os/keyboard.h" +#include "editor/editor_scale.h" CurveEditor::CurveEditor() { _selected_point = -1; @@ -510,8 +511,8 @@ void CurveEditor::set_hover_point_index(int index) { } void CurveEditor::update_view_transform() { - Vector2 control_size = get_size(); - const real_t margin = 24; + Ref<Font> font = get_font("font", "Label"); + const real_t margin = font->get_height() + 2 * EDSCALE; float min_y = 0; float max_y = 1; @@ -521,15 +522,19 @@ void CurveEditor::update_view_transform() { max_y = _curve_ref->get_max_value(); } - Rect2 world_rect = Rect2(Curve::MIN_X, min_y, Curve::MAX_X, max_y - min_y); - Vector2 wm = Vector2(margin, margin) / control_size; - wm.y *= (max_y - min_y); - world_rect.position -= wm; - world_rect.size += 2.0 * wm; + const Rect2 world_rect = Rect2(Curve::MIN_X, min_y, Curve::MAX_X, max_y - min_y); + const Size2 view_margin(margin, margin); + const Size2 view_size = get_size() - view_margin * 2; + const Vector2 scale = view_size / world_rect.size; + + Transform2D world_trans; + world_trans.translate(-world_rect.position - Vector2(0, world_rect.size.y)); + world_trans.scale(Vector2(scale.x, -scale.y)); + + Transform2D view_trans; + view_trans.translate(view_margin); - _world_to_view = Transform2D(); - _world_to_view.translate(-world_rect.position - Vector2(0, world_rect.size.y)); - _world_to_view.scale(Vector2(control_size.x, -control_size.y) / world_rect.size); + _world_to_view = view_trans * world_trans; } Vector2 CurveEditor::get_tangent_view_pos(int i, TangentIndex tangent) const { @@ -735,10 +740,10 @@ void CurveEditor::_draw() { if (_selected_point > 0 && _selected_point + 1 < curve.get_point_count()) { text_color.a *= 0.4; - draw_string(font, Vector2(50, font_height), TTR("Hold Shift to edit tangents individually"), text_color); + draw_string(font, Vector2(50 * EDSCALE, font_height), TTR("Hold Shift to edit tangents individually"), text_color); } else if (curve.get_point_count() == 0) { text_color.a *= 0.4; - draw_string(font, Vector2(50, font_height), TTR("Right click to add point"), text_color); + draw_string(font, Vector2(50 * EDSCALE, font_height), TTR("Right click to add point"), text_color); } } diff --git a/editor/plugins/curve_editor_plugin.h b/editor/plugins/curve_editor_plugin.h index 9071146863..06e2692373 100644 --- a/editor/plugins/curve_editor_plugin.h +++ b/editor/plugins/curve_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -33,6 +33,7 @@ #include "editor/editor_node.h" #include "editor/editor_plugin.h" +#include "editor/editor_resource_preview.h" #include "scene/resources/curve.h" // Edits a y(x) curve diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index 007ce58bd7..9b0d5d3daf 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -40,6 +40,7 @@ #include "scene/resources/dynamic_font.h" #include "scene/resources/material.h" #include "scene/resources/mesh.h" +#include "servers/audio/audio_stream.h" void post_process_preview(Ref<Image> p_image) { @@ -827,19 +828,23 @@ void EditorFontPreviewPlugin::_bind_methods() { bool EditorFontPreviewPlugin::handles(const String &p_type) const { - return ClassDB::is_parent_class(p_type, "DynamicFontData"); + return ClassDB::is_parent_class(p_type, "DynamicFontData") || ClassDB::is_parent_class(p_type, "DynamicFont"); } Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path, const Size2 &p_size) const { - Ref<DynamicFontData> SampledFont; - SampledFont.instance(); - SampledFont->set_font_path(p_path); - + RES res = ResourceLoader::load(p_path); Ref<DynamicFont> sampled_font; - sampled_font.instance(); + if (res->is_class("DynamicFont")) { + sampled_font = res->duplicate(); + if (sampled_font->get_outline_color() == Color(1, 1, 1, 1)) { + sampled_font->set_outline_color(Color(0, 0, 0, 1)); + } + } else if (res->is_class("DynamicFontData")) { + sampled_font.instance(); + sampled_font->set_font_data(res); + } sampled_font->set_size(50); - sampled_font->set_font_data(SampledFont); String sampled_text = "Abg"; Vector2 size = sampled_font->get_string_size(sampled_text); diff --git a/editor/plugins/editor_preview_plugins.h b/editor/plugins/editor_preview_plugins.h index 71a6c0fc08..e6e4aff8de 100644 --- a/editor/plugins/editor_preview_plugins.h +++ b/editor/plugins/editor_preview_plugins.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/gi_probe_editor_plugin.cpp b/editor/plugins/gi_probe_editor_plugin.cpp index a6125af1f7..8914e0ed01 100644 --- a/editor/plugins/gi_probe_editor_plugin.cpp +++ b/editor/plugins/gi_probe_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/gi_probe_editor_plugin.h b/editor/plugins/gi_probe_editor_plugin.h index c33668ae19..5db682835d 100644 --- a/editor/plugins/gi_probe_editor_plugin.h +++ b/editor/plugins/gi_probe_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/gradient_editor_plugin.cpp b/editor/plugins/gradient_editor_plugin.cpp index e85c475ad7..0a3a994eb7 100644 --- a/editor/plugins/gradient_editor_plugin.cpp +++ b/editor/plugins/gradient_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -31,6 +31,7 @@ #include "gradient_editor_plugin.h" #include "canvas_item_editor_plugin.h" +#include "editor/editor_scale.h" #include "spatial_editor_plugin.h" Size2 GradientEditor::get_minimum_size() const { diff --git a/editor/plugins/gradient_editor_plugin.h b/editor/plugins/gradient_editor_plugin.h index a87a5fe0ba..9ebd9610e5 100644 --- a/editor/plugins/gradient_editor_plugin.h +++ b/editor/plugins/gradient_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/item_list_editor_plugin.cpp b/editor/plugins/item_list_editor_plugin.cpp index b3f3ccf501..9f836ed0d3 100644 --- a/editor/plugins/item_list_editor_plugin.cpp +++ b/editor/plugins/item_list_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -31,6 +31,7 @@ #include "item_list_editor_plugin.h" #include "core/io/resource_loader.h" +#include "editor/editor_scale.h" bool ItemListPlugin::_set(const StringName &p_name, const Variant &p_value) { @@ -301,7 +302,7 @@ void ItemListEditor::_delete_pressed() { void ItemListEditor::_edit_items() { - dialog->popup_centered(Vector2(300, 400) * EDSCALE); + dialog->popup_centered_clamped(Vector2(425, 1200) * EDSCALE, 0.8); } void ItemListEditor::edit(Node *p_item_list) { diff --git a/editor/plugins/item_list_editor_plugin.h b/editor/plugins/item_list_editor_plugin.h index 78b176620e..8a73367bf7 100644 --- a/editor/plugins/item_list_editor_plugin.h +++ b/editor/plugins/item_list_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/light_occluder_2d_editor_plugin.cpp b/editor/plugins/light_occluder_2d_editor_plugin.cpp index d8f6259598..22df287f97 100644 --- a/editor/plugins/light_occluder_2d_editor_plugin.cpp +++ b/editor/plugins/light_occluder_2d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/light_occluder_2d_editor_plugin.h b/editor/plugins/light_occluder_2d_editor_plugin.h index 95fa0df2c1..74ae9e0889 100644 --- a/editor/plugins/light_occluder_2d_editor_plugin.h +++ b/editor/plugins/light_occluder_2d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/line_2d_editor_plugin.cpp b/editor/plugins/line_2d_editor_plugin.cpp index 368cf719c6..4ac9d0af3b 100644 --- a/editor/plugins/line_2d_editor_plugin.cpp +++ b/editor/plugins/line_2d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/line_2d_editor_plugin.h b/editor/plugins/line_2d_editor_plugin.h index a7a9813cb5..ef54dbc3f7 100644 --- a/editor/plugins/line_2d_editor_plugin.h +++ b/editor/plugins/line_2d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp index e125c18ef1..750f814319 100644 --- a/editor/plugins/material_editor_plugin.cpp +++ b/editor/plugins/material_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,6 +30,8 @@ #include "material_editor_plugin.h" +#include "editor/editor_scale.h" +#include "scene/gui/viewport_container.h" #include "scene/resources/particles_material.h" void MaterialEditor::_notification(int p_what) { diff --git a/editor/plugins/material_editor_plugin.h b/editor/plugins/material_editor_plugin.h index 1405127ab3..7f0a373dc7 100644 --- a/editor/plugins/material_editor_plugin.h +++ b/editor/plugins/material_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -41,6 +41,8 @@ #include "scene/3d/mesh_instance.h" #include "scene/resources/material.h" +class ViewportContainer; + class MaterialEditor : public Control { GDCLASS(MaterialEditor, Control); diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp index 442110cc84..d06e5b6349 100644 --- a/editor/plugins/mesh_editor_plugin.cpp +++ b/editor/plugins/mesh_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,6 +30,8 @@ #include "mesh_editor_plugin.h" +#include "editor/editor_scale.h" + void MeshEditor::_gui_input(Ref<InputEvent> p_event) { Ref<InputEventMouseMotion> mm = p_event; diff --git a/editor/plugins/mesh_editor_plugin.h b/editor/plugins/mesh_editor_plugin.h index 4c2a81ed70..87c4a1776b 100644 --- a/editor/plugins/mesh_editor_plugin.h +++ b/editor/plugins/mesh_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -36,6 +36,7 @@ #include "scene/3d/camera.h" #include "scene/3d/light.h" #include "scene/3d/mesh_instance.h" +#include "scene/gui/viewport_container.h" #include "scene/resources/material.h" class MeshEditor : public ViewportContainer { diff --git a/editor/plugins/mesh_instance_editor_plugin.cpp b/editor/plugins/mesh_instance_editor_plugin.cpp index 22df8fd8f4..6e5307cebe 100644 --- a/editor/plugins/mesh_instance_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,6 +30,7 @@ #include "mesh_instance_editor_plugin.h" +#include "editor/editor_scale.h" #include "scene/3d/collision_shape.h" #include "scene/3d/navigation_mesh.h" #include "scene/3d/physics_body.h" @@ -59,10 +60,7 @@ void MeshInstanceEditor::_menu_option(int p_option) { } switch (p_option) { - case MENU_OPTION_CREATE_STATIC_TRIMESH_BODY: - case MENU_OPTION_CREATE_STATIC_CONVEX_BODY: { - - bool trimesh_shape = (p_option == MENU_OPTION_CREATE_STATIC_TRIMESH_BODY); + case MENU_OPTION_CREATE_STATIC_TRIMESH_BODY: { EditorSelection *editor_selection = EditorNode::get_singleton()->get_editor_selection(); UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); @@ -70,9 +68,12 @@ void MeshInstanceEditor::_menu_option(int p_option) { List<Node *> selection = editor_selection->get_selected_node_list(); if (selection.empty()) { - Ref<Shape> shape = trimesh_shape ? mesh->create_trimesh_shape() : mesh->create_convex_shape(); - if (shape.is_null()) + Ref<Shape> shape = mesh->create_trimesh_shape(); + if (shape.is_null()) { + err_dialog->set_text(TTR("Couldn't create a Trimesh collision shape.")); + err_dialog->popup_centered_minsize(); return; + } CollisionShape *cshape = memnew(CollisionShape); cshape->set_shape(shape); @@ -81,11 +82,7 @@ void MeshInstanceEditor::_menu_option(int p_option) { Node *owner = node == get_tree()->get_edited_scene_root() ? node : node->get_owner(); - if (trimesh_shape) - ur->create_action(TTR("Create Static Trimesh Body")); - else - ur->create_action(TTR("Create Static Convex Body")); - + ur->create_action(TTR("Create Static Trimesh Body")); ur->add_do_method(node, "add_child", body); ur->add_do_method(body, "set_owner", owner); ur->add_do_method(cshape, "set_owner", owner); @@ -107,7 +104,7 @@ void MeshInstanceEditor::_menu_option(int p_option) { if (m.is_null()) continue; - Ref<Shape> shape = trimesh_shape ? m->create_trimesh_shape() : m->create_convex_shape(); + Ref<Shape> shape = m->create_trimesh_shape(); if (shape.is_null()) continue; @@ -157,10 +154,44 @@ void MeshInstanceEditor::_menu_option(int p_option) { ur->add_undo_method(node->get_parent(), "remove_child", cshape); ur->commit_action(); } break; - case MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE: { + case MENU_OPTION_CREATE_SINGLE_CONVEX_COLLISION_SHAPE: { if (node == get_tree()->get_edited_scene_root()) { - err_dialog->set_text(TTR("This doesn't work on scene root!")); + err_dialog->set_text(TTR("Can't create a single convex collision shape for the scene root.")); + err_dialog->popup_centered_minsize(); + return; + } + + Ref<Shape> shape = mesh->create_convex_shape(); + + if (shape.is_null()) { + err_dialog->set_text(TTR("Couldn't create a single convex collision shape.")); + err_dialog->popup_centered_minsize(); + return; + } + UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); + + ur->create_action(TTR("Create Single Convex Shape")); + + CollisionShape *cshape = memnew(CollisionShape); + cshape->set_shape(shape); + cshape->set_transform(node->get_transform()); + + Node *owner = node->get_owner(); + + ur->add_do_method(node->get_parent(), "add_child", cshape); + ur->add_do_method(node->get_parent(), "move_child", cshape, node->get_index() + 1); + ur->add_do_method(cshape, "set_owner", owner); + ur->add_do_reference(cshape); + ur->add_undo_method(node->get_parent(), "remove_child", cshape); + + ur->commit_action(); + + } break; + case MENU_OPTION_CREATE_MULTIPLE_CONVEX_COLLISION_SHAPES: { + + if (node == get_tree()->get_edited_scene_root()) { + err_dialog->set_text(TTR("Can't create multiple convex collision shapes for the scene root.")); err_dialog->popup_centered_minsize(); return; } @@ -168,13 +199,13 @@ void MeshInstanceEditor::_menu_option(int p_option) { Vector<Ref<Shape> > shapes = mesh->convex_decompose(); if (!shapes.size()) { - err_dialog->set_text(TTR("Failed creating shapes!")); + err_dialog->set_text(TTR("Couldn't create any collision shapes.")); err_dialog->popup_centered_minsize(); return; } UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); - ur->create_action(TTR("Create Convex Shape(s)")); + ur->create_action(TTR("Create Multiple Convex Shapes")); for (int i = 0; i < shapes.size(); i++) { @@ -420,13 +451,19 @@ MeshInstanceEditor::MeshInstanceEditor() { options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("MeshInstance", "EditorIcons")); options->get_popup()->add_item(TTR("Create Trimesh Static Body"), MENU_OPTION_CREATE_STATIC_TRIMESH_BODY); + options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a StaticBody and assigns a polygon-based collision shape to it automatically.\nThis is the most accurate (but slowest) option for collision detection.")); options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("Create Trimesh Collision Sibling"), MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE); - options->get_popup()->add_item(TTR("Create Convex Collision Sibling(s)"), MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE); + options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a polygon-based collision shape.\nThis is the most accurate (but slowest) option for collision detection.")); + options->get_popup()->add_item(TTR("Create Single Convex Collision Siblings"), MENU_OPTION_CREATE_SINGLE_CONVEX_COLLISION_SHAPE); + options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a single convex collision shape.\nThis is the fastest (but least accurate) option for collision detection.")); + options->get_popup()->add_item(TTR("Create Multiple Convex Collision Siblings"), MENU_OPTION_CREATE_MULTIPLE_CONVEX_COLLISION_SHAPES); + options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a polygon-based collision shape.\nThis is a performance middle-ground between the two above options.")); options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("Create Navigation Mesh"), MENU_OPTION_CREATE_NAVMESH); options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("Create Outline Mesh..."), MENU_OPTION_CREATE_OUTLINE_MESH); + options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a static outline mesh. The outline mesh will have its normals flipped automatically.\nThis can be used instead of the SpatialMaterial Grow property when using that property isn't possible.")); options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("View UV1"), MENU_OPTION_DEBUG_UV1); options->get_popup()->add_item(TTR("View UV2"), MENU_OPTION_DEBUG_UV2); @@ -456,7 +493,7 @@ MeshInstanceEditor::MeshInstanceEditor() { add_child(err_dialog); debug_uv_dialog = memnew(AcceptDialog); - debug_uv_dialog->set_title("UV Channel Debug"); + debug_uv_dialog->set_title(TTR("UV Channel Debug")); add_child(debug_uv_dialog); debug_uv = memnew(Control); debug_uv->set_custom_minimum_size(Size2(600, 600) * EDSCALE); diff --git a/editor/plugins/mesh_instance_editor_plugin.h b/editor/plugins/mesh_instance_editor_plugin.h index d82af621df..5ca9aa3fec 100644 --- a/editor/plugins/mesh_instance_editor_plugin.h +++ b/editor/plugins/mesh_instance_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -43,9 +43,9 @@ class MeshInstanceEditor : public Control { enum Menu { MENU_OPTION_CREATE_STATIC_TRIMESH_BODY, - MENU_OPTION_CREATE_STATIC_CONVEX_BODY, MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE, - MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE, + MENU_OPTION_CREATE_SINGLE_CONVEX_COLLISION_SHAPE, + MENU_OPTION_CREATE_MULTIPLE_CONVEX_COLLISION_SHAPES, MENU_OPTION_CREATE_NAVMESH, MENU_OPTION_CREATE_OUTLINE_MESH, MENU_OPTION_CREATE_UV2, diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp index 7fbb35e565..92898ff9c3 100644 --- a/editor/plugins/mesh_library_editor_plugin.cpp +++ b/editor/plugins/mesh_library_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -241,7 +241,7 @@ void MeshLibraryEditor::_menu_cbk(int p_option) { } break; case MENU_OPTION_UPDATE_FROM_SCENE: { - cd->set_text("Update from existing scene?:\n" + String(mesh_library->get_meta("_editor_source_scene"))); + cd->set_text(vformat(TTR("Update from existing scene?:\n%s"), String(mesh_library->get_meta("_editor_source_scene")))); cd->popup_centered(Size2(500, 60)); } break; } @@ -273,7 +273,7 @@ MeshLibraryEditor::MeshLibraryEditor(EditorNode *p_editor) { menu = memnew(MenuButton); SpatialEditor::get_singleton()->add_control_to_menu_panel(menu); menu->set_position(Point2(1, 1)); - menu->set_text("Mesh Library"); + menu->set_text(TTR("Mesh Library")); menu->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("MeshLibrary", "EditorIcons")); menu->get_popup()->add_item(TTR("Add Item"), MENU_OPTION_ADD_ITEM); menu->get_popup()->add_item(TTR("Remove Selected Item"), MENU_OPTION_REMOVE_ITEM); diff --git a/editor/plugins/mesh_library_editor_plugin.h b/editor/plugins/mesh_library_editor_plugin.h index 8121ff52bd..74b0a280e3 100644 --- a/editor/plugins/mesh_library_editor_plugin.h +++ b/editor/plugins/mesh_library_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/multimesh_editor_plugin.cpp b/editor/plugins/multimesh_editor_plugin.cpp index 3ea014a38d..5dc222f84c 100644 --- a/editor/plugins/multimesh_editor_plugin.cpp +++ b/editor/plugins/multimesh_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/multimesh_editor_plugin.h b/editor/plugins/multimesh_editor_plugin.h index 5323441bd8..2c7b98cfbc 100644 --- a/editor/plugins/multimesh_editor_plugin.h +++ b/editor/plugins/multimesh_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/navigation_polygon_editor_plugin.cpp b/editor/plugins/navigation_polygon_editor_plugin.cpp index 0d6b649526..c4e61f2488 100644 --- a/editor/plugins/navigation_polygon_editor_plugin.cpp +++ b/editor/plugins/navigation_polygon_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/navigation_polygon_editor_plugin.h b/editor/plugins/navigation_polygon_editor_plugin.h index 2a387a8b1e..1cab336381 100644 --- a/editor/plugins/navigation_polygon_editor_plugin.h +++ b/editor/plugins/navigation_polygon_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/particles_2d_editor_plugin.cpp b/editor/plugins/particles_2d_editor_plugin.cpp index 957ce42304..b036368bc8 100644 --- a/editor/plugins/particles_2d_editor_plugin.cpp +++ b/editor/plugins/particles_2d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -424,9 +424,9 @@ Particles2DEditorPlugin::Particles2DEditorPlugin(EditorNode *p_node) { emission_mask->add_child(emvb); emission_mask_mode = memnew(OptionButton); emvb->add_margin_child(TTR("Emission Mask"), emission_mask_mode); - emission_mask_mode->add_item("Solid Pixels", EMISSION_MODE_SOLID); - emission_mask_mode->add_item("Border Pixels", EMISSION_MODE_BORDER); - emission_mask_mode->add_item("Directed Border Pixels", EMISSION_MODE_BORDER_DIRECTED); + emission_mask_mode->add_item(TTR("Solid Pixels"), EMISSION_MODE_SOLID); + emission_mask_mode->add_item(TTR("Border Pixels"), EMISSION_MODE_BORDER); + emission_mask_mode->add_item(TTR("Directed Border Pixels"), EMISSION_MODE_BORDER_DIRECTED); emission_colors = memnew(CheckBox); emission_colors->set_text(TTR("Capture from Pixel")); emvb->add_margin_child(TTR("Emission Colors"), emission_colors); diff --git a/editor/plugins/particles_2d_editor_plugin.h b/editor/plugins/particles_2d_editor_plugin.h index 0f092aaa4f..29652a1826 100644 --- a/editor/plugins/particles_2d_editor_plugin.h +++ b/editor/plugins/particles_2d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/particles_editor_plugin.cpp b/editor/plugins/particles_editor_plugin.cpp index 31b0539bfe..f869dabf9a 100644 --- a/editor/plugins/particles_editor_plugin.cpp +++ b/editor/plugins/particles_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/particles_editor_plugin.h b/editor/plugins/particles_editor_plugin.h index 1b3a1877a4..4b20d00670 100644 --- a/editor/plugins/particles_editor_plugin.h +++ b/editor/plugins/particles_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp index f02dc0bd6d..3737dbdd57 100644 --- a/editor/plugins/path_2d_editor_plugin.cpp +++ b/editor/plugins/path_2d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -33,6 +33,7 @@ #include "canvas_item_editor_plugin.h" #include "core/os/file_access.h" #include "core/os/keyboard.h" +#include "editor/editor_scale.h" #include "editor/editor_settings.h" void Path2DEditor::_notification(int p_what) { diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h index ecec5f5253..aae0e11c99 100644 --- a/editor/plugins/path_2d_editor_plugin.h +++ b/editor/plugins/path_2d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/path_editor_plugin.cpp b/editor/plugins/path_editor_plugin.cpp index 2493380585..67889bc074 100644 --- a/editor/plugins/path_editor_plugin.cpp +++ b/editor/plugins/path_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/path_editor_plugin.h b/editor/plugins/path_editor_plugin.h index 5482d09377..8ff83911f8 100644 --- a/editor/plugins/path_editor_plugin.h +++ b/editor/plugins/path_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/physical_bone_plugin.cpp b/editor/plugins/physical_bone_plugin.cpp index 96681a105f..28099a927b 100644 --- a/editor/plugins/physical_bone_plugin.cpp +++ b/editor/plugins/physical_bone_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/physical_bone_plugin.h b/editor/plugins/physical_bone_plugin.h index 78c1c331a0..459a67db05 100644 --- a/editor/plugins/physical_bone_plugin.h +++ b/editor/plugins/physical_bone_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index bd532a6418..35c0142d4b 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -34,6 +34,7 @@ #include "core/os/file_access.h" #include "core/os/input.h" #include "core/os/keyboard.h" +#include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "scene/2d/skeleton_2d.h" @@ -91,6 +92,9 @@ void Polygon2DEditor::_notification(int p_what) { b_snap_grid->set_icon(get_icon("Grid", "EditorIcons")); b_snap_enable->set_icon(get_icon("SnapGrid", "EditorIcons")); uv_icon_zoom->set_texture(get_icon("Zoom", "EditorIcons")); + + uv_vscroll->set_anchors_and_margins_preset(PRESET_RIGHT_WIDE); + uv_hscroll->set_anchors_and_margins_preset(PRESET_BOTTOM_WIDE); } break; case NOTIFICATION_VISIBILITY_CHANGED: { @@ -1195,7 +1199,9 @@ void Polygon2DEditor::_uv_draw() { rect.position -= uv_edit_draw->get_size(); rect.size += uv_edit_draw->get_size() * 2.0; + updating_uv_scroll = true; + uv_hscroll->set_min(rect.position.x); uv_hscroll->set_max(rect.position.x + rect.size.x); if (ABS(rect.position.x - (rect.position.x + rect.size.x)) <= uv_edit_draw->get_size().x) { @@ -1215,6 +1221,14 @@ void Polygon2DEditor::_uv_draw() { uv_vscroll->set_page(uv_edit_draw->get_size().y); uv_vscroll->set_value(uv_draw_ofs.y); } + + Size2 hmin = uv_hscroll->get_combined_minimum_size(); + Size2 vmin = uv_vscroll->get_combined_minimum_size(); + + // Avoid scrollbar overlapping. + uv_hscroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, uv_vscroll->is_visible() ? -vmin.width : 0); + uv_vscroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, uv_hscroll->is_visible() ? -hmin.height : 0); + updating_uv_scroll = false; } @@ -1444,7 +1458,7 @@ Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) : uv_mode_hb->add_child(uv_icon_zoom); uv_zoom = memnew(HSlider); uv_zoom->set_min(0.01); - uv_zoom->set_max(4); + uv_zoom->set_max(16); uv_zoom->set_value(1); uv_zoom->set_step(0.01); uv_zoom->set_v_size_flags(SIZE_SHRINK_CENTER); @@ -1460,13 +1474,10 @@ Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) : uv_vscroll = memnew(VScrollBar); uv_vscroll->set_step(0.001); uv_edit_draw->add_child(uv_vscroll); - uv_vscroll->set_anchors_and_margins_preset(PRESET_RIGHT_WIDE); uv_vscroll->connect("value_changed", this, "_uv_scroll_changed"); uv_hscroll = memnew(HScrollBar); uv_hscroll->set_step(0.001); uv_edit_draw->add_child(uv_hscroll); - uv_hscroll->set_anchors_and_margins_preset(PRESET_BOTTOM_WIDE); - uv_hscroll->set_margin(MARGIN_RIGHT, -uv_vscroll->get_size().x * EDSCALE); uv_hscroll->connect("value_changed", this, "_uv_scroll_changed"); bone_scroll_main_vb = memnew(VBoxContainer); diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h index 009501a70c..1454a03325 100644 --- a/editor/plugins/polygon_2d_editor_plugin.h +++ b/editor/plugins/polygon_2d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp index 620bf28415..fb04f50827 100644 --- a/editor/plugins/resource_preloader_editor_plugin.cpp +++ b/editor/plugins/resource_preloader_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,6 +32,7 @@ #include "core/io/resource_loader.h" #include "core/project_settings.h" +#include "editor/editor_scale.h" #include "editor/editor_settings.h" void ResourcePreloaderEditor::_gui_input(Ref<InputEvent> p_event) { @@ -438,7 +439,7 @@ ResourcePreloaderEditorPlugin::ResourcePreloaderEditorPlugin(EditorNode *p_node) editor = p_node; preloader_editor = memnew(ResourcePreloaderEditor); - preloader_editor->set_custom_minimum_size(Size2(0, 250)); + preloader_editor->set_custom_minimum_size(Size2(0, 250) * EDSCALE); button = editor->add_bottom_panel_item(TTR("ResourcePreloader"), preloader_editor); button->hide(); diff --git a/editor/plugins/resource_preloader_editor_plugin.h b/editor/plugins/resource_preloader_editor_plugin.h index 346249b1c5..88e9cf4956 100644 --- a/editor/plugins/resource_preloader_editor_plugin.h +++ b/editor/plugins/resource_preloader_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/root_motion_editor_plugin.cpp b/editor/plugins/root_motion_editor_plugin.cpp index 05f682f469..3489537fa4 100644 --- a/editor/plugins/root_motion_editor_plugin.cpp +++ b/editor/plugins/root_motion_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/root_motion_editor_plugin.h b/editor/plugins/root_motion_editor_plugin.h index af5d8fc122..8a7691de5d 100644 --- a/editor/plugins/root_motion_editor_plugin.h +++ b/editor/plugins/root_motion_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index f7e997a269..1da47196f8 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -37,7 +37,10 @@ #include "core/os/os.h" #include "core/project_settings.h" #include "editor/editor_node.h" +#include "editor/editor_run_script.h" +#include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/filesystem_dock.h" #include "editor/find_in_files.h" #include "editor/node_dock.h" #include "editor/plugins/shader_editor_plugin.h" @@ -987,12 +990,22 @@ Array ScriptEditor::_get_open_scripts() const { return ret; } +bool ScriptEditor::toggle_scripts_panel() { + list_split->set_visible(!list_split->is_visible()); + return list_split->is_visible(); +} + +bool ScriptEditor::is_scripts_panel_toggled() { + return list_split->is_visible(); +} + void ScriptEditor::_menu_option(int p_option) { + ScriptEditorBase *current = _get_current_editor(); switch (p_option) { case FILE_NEW: { - script_create_dialog->config("Node", "new_script"); - script_create_dialog->popup_centered(Size2(300, 300) * EDSCALE); + script_create_dialog->config("Node", "new_script", false, false); + script_create_dialog->popup_centered(); } break; case FILE_NEW_TEXTFILE: { file_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE); @@ -1127,11 +1140,18 @@ void ScriptEditor::_menu_option(int p_option) { debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(DEBUG_WITH_EXTERNAL_EDITOR), debug_with_external_editor); } break; case TOGGLE_SCRIPTS_PANEL: { - list_split->set_visible(!list_split->is_visible()); + if (current) { + ScriptTextEditor *editor = Object::cast_to<ScriptTextEditor>(current); + toggle_scripts_panel(); + if (editor) { + editor->update_toggle_scripts_button(); + } + } else { + toggle_scripts_panel(); + } } } - ScriptEditorBase *current = _get_current_editor(); if (current) { switch (p_option) { @@ -1208,7 +1228,7 @@ void ScriptEditor::_menu_option(int p_option) { Ref<Script> scr = current->get_edited_resource(); if (scr == NULL || scr.is_null()) { - EditorNode::get_singleton()->show_warning("Can't obtain the script for running."); + EditorNode::get_singleton()->show_warning(TTR("Can't obtain the script for running.")); break; } @@ -1216,18 +1236,18 @@ void ScriptEditor::_menu_option(int p_option) { 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."); + EditorNode::get_singleton()->show_warning(TTR("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."); + EditorNode::get_singleton()->show_warning(TTR("Script is not in tool mode, will not be able to run.")); return; } if (!ClassDB::is_parent_class(scr->get_instance_base_type(), "EditorScript")) { - EditorNode::get_singleton()->show_warning("To run this script, it must inherit EditorScript and be set to tool mode."); + EditorNode::get_singleton()->show_warning(TTR("To run this script, it must inherit EditorScript and be set to tool mode.")); return; } @@ -1250,12 +1270,15 @@ void ScriptEditor::_menu_option(int p_option) { _copy_script_path(); } break; case SHOW_IN_FILE_SYSTEM: { - RES script = current->get_edited_resource(); - FileSystemDock *file_system_dock = EditorNode::get_singleton()->get_filesystem_dock(); - file_system_dock->navigate_to_path(script->get_path()); - // Ensure that the FileSystem dock is visible. - TabContainer *tab_container = (TabContainer *)file_system_dock->get_parent_control(); - tab_container->set_current_tab(file_system_dock->get_position_in_parent()); + const RES script = current->get_edited_resource(); + const String path = script->get_path(); + if (!path.empty()) { + FileSystemDock *file_system_dock = EditorNode::get_singleton()->get_filesystem_dock(); + file_system_dock->navigate_to_path(path); + // Ensure that the FileSystem dock is visible. + TabContainer *tab_container = (TabContainer *)file_system_dock->get_parent_control(); + tab_container->set_current_tab(file_system_dock->get_position_in_parent()); + } } break; case CLOSE_DOCS: { _close_docs_tab(); @@ -2497,7 +2520,10 @@ void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(node); EditorHelp *eh = Object::cast_to<EditorHelp>(node); if (se || eh) { - int new_index = script_list->get_item_metadata(script_list->get_item_at_position(p_point)); + int new_index = 0; + if (script_list->get_item_count() > 0) { + new_index = script_list->get_item_metadata(script_list->get_item_at_position(p_point)); + } tab_container->move_child(node, new_index); tab_container->set_current_tab(new_index); _update_script_names(); @@ -2514,7 +2540,10 @@ void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(node); EditorHelp *eh = Object::cast_to<EditorHelp>(node); if (se || eh) { - int new_index = script_list->get_item_metadata(script_list->get_item_at_position(p_point)); + int new_index = 0; + if (script_list->get_item_count() > 0) { + new_index = script_list->get_item_metadata(script_list->get_item_at_position(p_point)); + } tab_container->move_child(node, new_index); tab_container->set_current_tab(new_index); _update_script_names(); @@ -2525,7 +2554,10 @@ void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co Vector<String> files = d["files"]; - int new_index = script_list->get_item_metadata(script_list->get_item_at_position(p_point)); + int new_index = 0; + if (script_list->get_item_count() > 0) { + new_index = script_list->get_item_metadata(script_list->get_item_at_position(p_point)); + } int num_tabs_before = tab_container->get_child_count(); for (int i = 0; i < files.size(); i++) { String file = files[i]; @@ -2551,16 +2583,20 @@ void ScriptEditor::_unhandled_input(const Ref<InputEvent> &p_event) { if (!is_visible_in_tree() || !p_event->is_pressed() || p_event->is_echo()) return; if (ED_IS_SHORTCUT("script_editor/next_script", p_event)) { - int next_tab = script_list->get_current() + 1; - next_tab %= script_list->get_item_count(); - _go_to_tab(script_list->get_item_metadata(next_tab)); - _update_script_names(); + if (script_list->get_item_count() > 1) { + int next_tab = script_list->get_current() + 1; + next_tab %= script_list->get_item_count(); + _go_to_tab(script_list->get_item_metadata(next_tab)); + _update_script_names(); + } } if (ED_IS_SHORTCUT("script_editor/prev_script", p_event)) { - int next_tab = script_list->get_current() - 1; - next_tab = next_tab >= 0 ? next_tab : script_list->get_item_count() - 1; - _go_to_tab(script_list->get_item_metadata(next_tab)); - _update_script_names(); + if (script_list->get_item_count() > 1) { + int next_tab = script_list->get_current() - 1; + next_tab = next_tab >= 0 ? next_tab : script_list->get_item_count() - 1; + _go_to_tab(script_list->get_item_metadata(next_tab)); + _update_script_names(); + } } if (ED_IS_SHORTCUT("script_editor/window_move_up", p_event)) { _menu_option(WINDOW_MOVE_UP); @@ -3173,7 +3209,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { script_list = memnew(ItemList); scripts_vbox->add_child(script_list); - script_list->set_custom_minimum_size(Size2(150, 90) * EDSCALE); //need to give a bit of limit to avoid it from disappearing + script_list->set_custom_minimum_size(Size2(150, 60) * EDSCALE); //need to give a bit of limit to avoid it from disappearing script_list->set_v_size_flags(SIZE_EXPAND_FILL); script_split->set_split_offset(140); _sort_list_on_update = true; @@ -3218,14 +3254,14 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { overview_vbox->add_child(members_overview); members_overview->set_allow_reselect(true); - members_overview->set_custom_minimum_size(Size2(0, 90) * EDSCALE); //need to give a bit of limit to avoid it from disappearing + members_overview->set_custom_minimum_size(Size2(0, 60) * EDSCALE); //need to give a bit of limit to avoid it from disappearing members_overview->set_v_size_flags(SIZE_EXPAND_FILL); members_overview->set_allow_rmb_select(true); help_overview = memnew(ItemList); overview_vbox->add_child(help_overview); help_overview->set_allow_reselect(true); - help_overview->set_custom_minimum_size(Size2(0, 90) * EDSCALE); //need to give a bit of limit to avoid it from disappearing + help_overview->set_custom_minimum_size(Size2(0, 60) * EDSCALE); //need to give a bit of limit to avoid it from disappearing help_overview->set_v_size_flags(SIZE_EXPAND_FILL); tab_container = memnew(TabContainer); @@ -3238,7 +3274,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { ED_SHORTCUT("script_editor/window_move_up", TTR("Move Up"), KEY_MASK_SHIFT | KEY_MASK_ALT | KEY_UP); ED_SHORTCUT("script_editor/window_move_down", TTR("Move Down"), KEY_MASK_SHIFT | KEY_MASK_ALT | KEY_DOWN); ED_SHORTCUT("script_editor/next_script", TTR("Next script"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_PERIOD); // these should be KEY_GREATER and KEY_LESS but those don't work - ED_SHORTCUT("script_editor/prev_script", TTR("Previous script"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_COLON); + ED_SHORTCUT("script_editor/prev_script", TTR("Previous script"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_COMMA); set_process_unhandled_input(true); file_menu = memnew(MenuButton); diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index 294294fc56..a41480c80d 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -419,6 +419,8 @@ protected: public: static ScriptEditor *get_singleton() { return script_editor; } + bool toggle_scripts_panel(); + bool is_scripts_panel_toggled(); void ensure_focus_current(); void apply_scripts() const; void open_script_create_dialog(const String &p_base_name, const String &p_base_path); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index f63445dab8..1432c3fc63 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -33,6 +33,7 @@ #include "core/math/expression.h" #include "core/os/keyboard.h" #include "editor/editor_node.h" +#include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/script_editor_debugger.h" @@ -690,13 +691,16 @@ void ScriptTextEditor::_update_bookmark_list() { bookmarks_menu->add_separator(); for (int i = 0; i < bookmark_list.size(); i++) { - String line = code_editor->get_text_edit()->get_line(bookmark_list[i]).strip_edges(); + // Strip edges to remove spaces or tabs. + // Also replace any tabs by spaces, since we can't print tabs in the menu. + String line = code_editor->get_text_edit()->get_line(bookmark_list[i]).replace("\t", " ").strip_edges(); + // Limit the size of the line if too big. if (line.length() > 50) { line = line.substr(0, 50); } - bookmarks_menu->add_item(String::num((int)bookmark_list[i] + 1) + " - \"" + line + "\""); + bookmarks_menu->add_item(String::num((int)bookmark_list[i] + 1) + " - `" + line + "`"); bookmarks_menu->set_item_metadata(bookmarks_menu->get_item_count() - 1, bookmark_list[i]); } } @@ -707,6 +711,7 @@ void ScriptTextEditor::_bookmark_item_pressed(int p_idx) { _edit_option(bookmarks_menu->get_item_id(p_idx)); } else { code_editor->goto_line(bookmarks_menu->get_item_metadata(p_idx)); + code_editor->get_text_edit()->call_deferred("center_viewport_to_cursor"); //Need to be deferred, because goto uses call_deferred(). } } @@ -839,13 +844,16 @@ void ScriptTextEditor::_update_breakpoint_list() { breakpoints_menu->add_separator(); for (int i = 0; i < breakpoint_list.size(); i++) { - String line = code_editor->get_text_edit()->get_line(breakpoint_list[i]).strip_edges(); + // Strip edges to remove spaces or tabs. + // Also replace any tabs by spaces, since we can't print tabs in the menu. + String line = code_editor->get_text_edit()->get_line(breakpoint_list[i]).replace("\t", " ").strip_edges(); + // Limit the size of the line if too big. if (line.length() > 50) { line = line.substr(0, 50); } - breakpoints_menu->add_item(String::num((int)breakpoint_list[i] + 1) + " - \"" + line + "\""); + breakpoints_menu->add_item(String::num((int)breakpoint_list[i] + 1) + " - `" + line + "`"); breakpoints_menu->set_item_metadata(breakpoints_menu->get_item_count() - 1, breakpoint_list[i]); } } @@ -856,6 +864,7 @@ void ScriptTextEditor::_breakpoint_item_pressed(int p_idx) { _edit_option(breakpoints_menu->get_item_id(p_idx)); } else { code_editor->goto_line(breakpoints_menu->get_item_metadata(p_idx)); + code_editor->get_text_edit()->call_deferred("center_viewport_to_cursor"); //Need to be deferred, because goto uses call_deferred(). } } @@ -964,6 +973,12 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c } } +void ScriptTextEditor::update_toggle_scripts_button() { + if (code_editor != NULL) { + code_editor->update_toggle_scripts_button(); + } +} + void ScriptTextEditor::_update_connected_methods() { TextEdit *text_edit = code_editor->get_text_edit(); text_edit->clear_info_icons(); @@ -1301,12 +1316,14 @@ void ScriptTextEditor::_edit_option(int p_op) { if (line >= bpoints[bpoints.size() - 1]) { tx->unfold_line(bpoints[0]); tx->cursor_set_line(bpoints[0]); + tx->center_viewport_to_cursor(); } else { for (List<int>::Element *E = bpoints.front(); E; E = E->next()) { int bline = E->get(); if (bline > line) { tx->unfold_line(bline); tx->cursor_set_line(bline); + tx->center_viewport_to_cursor(); return; } } @@ -1326,12 +1343,14 @@ void ScriptTextEditor::_edit_option(int p_op) { if (line <= bpoints[0]) { tx->unfold_line(bpoints[bpoints.size() - 1]); tx->cursor_set_line(bpoints[bpoints.size() - 1]); + tx->center_viewport_to_cursor(); } else { for (List<int>::Element *E = bpoints.back(); E; E = E->prev()) { int bline = E->get(); if (bline < line) { tx->unfold_line(bline); tx->cursor_set_line(bline); + tx->center_viewport_to_cursor(); return; } } @@ -1547,7 +1566,7 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data Node *sn = _find_script_node(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root(), script); if (!sn) { - EditorNode::get_singleton()->show_warning("Can't drop nodes because script '" + get_name() + "' is not used in this scene."); + EditorNode::get_singleton()->show_warning(vformat(TTR("Can't drop nodes because script '%s' is not used in this scene."), get_name())); return; } @@ -1756,6 +1775,7 @@ ScriptTextEditor::ScriptTextEditor() { code_editor->get_text_edit()->connect("symbol_lookup", this, "_lookup_symbol"); code_editor->get_text_edit()->connect("info_clicked", this, "_lookup_connections"); code_editor->set_v_size_flags(SIZE_EXPAND_FILL); + code_editor->show_toggle_scripts_button(); warnings_panel = memnew(RichTextLabel); editor_box->add_child(warnings_panel); diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h index 2ba0be8feb..9018e9d3c2 100644 --- a/editor/plugins/script_text_editor.h +++ b/editor/plugins/script_text_editor.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -191,6 +191,7 @@ public: virtual void add_syntax_highlighter(SyntaxHighlighter *p_highlighter); virtual void set_syntax_highlighter(SyntaxHighlighter *p_highlighter); + void update_toggle_scripts_button(); virtual void apply_code(); virtual RES get_edited_resource() const; diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 97f194e40f..a19f0b4975 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -35,6 +35,7 @@ #include "core/os/keyboard.h" #include "core/os/os.h" #include "editor/editor_node.h" +#include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/property_editor.h" #include "servers/visual/shader_types.h" @@ -368,6 +369,7 @@ void ShaderEditor::_editor_settings_changed() { shader_editor->get_text_edit()->set_indent_using_spaces(EditorSettings::get_singleton()->get("text_editor/indent/type")); shader_editor->get_text_edit()->set_auto_indent(EditorSettings::get_singleton()->get("text_editor/indent/auto_indent")); shader_editor->get_text_edit()->set_draw_tabs(EditorSettings::get_singleton()->get("text_editor/indent/draw_tabs")); + shader_editor->get_text_edit()->set_draw_spaces(EditorSettings::get_singleton()->get("text_editor/indent/draw_spaces")); shader_editor->get_text_edit()->set_show_line_numbers(EditorSettings::get_singleton()->get("text_editor/appearance/show_line_numbers")); shader_editor->get_text_edit()->set_syntax_coloring(EditorSettings::get_singleton()->get("text_editor/highlighting/syntax_highlighting")); shader_editor->get_text_edit()->set_highlight_all_occurrences(EditorSettings::get_singleton()->get("text_editor/highlighting/highlight_all_occurrences")); @@ -378,6 +380,11 @@ void ShaderEditor::_editor_settings_changed() { 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/navigation/smooth_scrolling")); shader_editor->get_text_edit()->set_v_scroll_speed(EditorSettings::get_singleton()->get("text_editor/navigation/v_scroll_speed")); + shader_editor->get_text_edit()->set_draw_minimap(EditorSettings::get_singleton()->get("text_editor/navigation/show_minimap")); + shader_editor->get_text_edit()->set_minimap_width((int)EditorSettings::get_singleton()->get("text_editor/navigation/minimap_width") * EDSCALE); + shader_editor->get_text_edit()->set_show_line_length_guideline(EditorSettings::get_singleton()->get("text_editor/appearance/show_line_length_guideline")); + shader_editor->get_text_edit()->set_line_length_guideline_column(EditorSettings::get_singleton()->get("text_editor/appearance/line_length_guideline_column")); + shader_editor->get_text_edit()->set_breakpoint_gutter_enabled(false); } void ShaderEditor::_bind_methods() { @@ -756,7 +763,7 @@ ShaderEditorPlugin::ShaderEditorPlugin(EditorNode *p_node) { editor = p_node; shader_editor = memnew(ShaderEditor(p_node)); - shader_editor->set_custom_minimum_size(Size2(0, 300)); + shader_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE); button = editor->add_bottom_panel_item(TTR("Shader"), shader_editor); button->hide(); } diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h index ca9f489713..900b40bd7a 100644 --- a/editor/plugins/shader_editor_plugin.h +++ b/editor/plugins/shader_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/skeleton_2d_editor_plugin.cpp b/editor/plugins/skeleton_2d_editor_plugin.cpp index 0ccb60e39e..dbe64f202d 100644 --- a/editor/plugins/skeleton_2d_editor_plugin.cpp +++ b/editor/plugins/skeleton_2d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/skeleton_2d_editor_plugin.h b/editor/plugins/skeleton_2d_editor_plugin.h index d8e2d23257..ebc6746b81 100644 --- a/editor/plugins/skeleton_2d_editor_plugin.h +++ b/editor/plugins/skeleton_2d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/skeleton_editor_plugin.cpp b/editor/plugins/skeleton_editor_plugin.cpp index cd360d4caf..9101c64eab 100644 --- a/editor/plugins/skeleton_editor_plugin.cpp +++ b/editor/plugins/skeleton_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -65,7 +65,6 @@ void SkeletonEditor::create_physical_skeleton() { for (int bone_id = 0; bc > bone_id; ++bone_id) { const int parent = skeleton->get_bone_parent(bone_id); - const int parent_parent = skeleton->get_bone_parent(parent); if (parent < 0) { @@ -73,6 +72,8 @@ void SkeletonEditor::create_physical_skeleton() { } else { + const int parent_parent = skeleton->get_bone_parent(parent); + bones_infos.write[bone_id].relative_rest = bones_infos[parent].relative_rest * skeleton->get_bone_rest(bone_id); /// create physical bone on parent @@ -102,8 +103,10 @@ void SkeletonEditor::create_physical_skeleton() { PhysicalBone *SkeletonEditor::create_physical_bone(int bone_id, int bone_child_id, const Vector<BoneInfo> &bones_infos) { - real_t half_height(skeleton->get_bone_rest(bone_child_id).origin.length() * 0.5); - real_t radius(half_height * 0.2); + const Transform child_rest = skeleton->get_bone_rest(bone_child_id); + + const real_t half_height(child_rest.origin.length() * 0.5); + const real_t radius(half_height * 0.2); CapsuleShape *bone_shape_capsule = memnew(CapsuleShape); bone_shape_capsule->set_height((half_height - radius) * 2); @@ -113,7 +116,8 @@ PhysicalBone *SkeletonEditor::create_physical_bone(int bone_id, int bone_child_i bone_shape->set_shape(bone_shape_capsule); Transform body_transform; - body_transform.origin = Vector3(0, 0, -half_height); + body_transform.set_look_at(Vector3(0, 0, 0), child_rest.origin, Vector3(0, 1, 0)); + body_transform.origin = body_transform.basis.xform(Vector3(0, 0, -half_height)); Transform joint_transform; joint_transform.origin = Vector3(0, 0, half_height); diff --git a/editor/plugins/skeleton_editor_plugin.h b/editor/plugins/skeleton_editor_plugin.h index 558e954815..1dce6d12ed 100644 --- a/editor/plugins/skeleton_editor_plugin.h +++ b/editor/plugins/skeleton_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/skeleton_ik_editor_plugin.cpp b/editor/plugins/skeleton_ik_editor_plugin.cpp index 928171950a..eb6ad9498d 100644 --- a/editor/plugins/skeleton_ik_editor_plugin.cpp +++ b/editor/plugins/skeleton_ik_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -41,21 +41,12 @@ void SkeletonIKEditorPlugin::_play() { return; if (play_btn->is_pressed()) { - - initial_bone_poses.resize(skeleton_ik->get_parent_skeleton()->get_bone_count()); - for (int i = 0; i < skeleton_ik->get_parent_skeleton()->get_bone_count(); ++i) { - initial_bone_poses.write[i] = skeleton_ik->get_parent_skeleton()->get_bone_pose(i); - } - skeleton_ik->start(); } else { skeleton_ik->stop(); - if (initial_bone_poses.size() != skeleton_ik->get_parent_skeleton()->get_bone_count()) - return; - for (int i = 0; i < skeleton_ik->get_parent_skeleton()->get_bone_count(); ++i) { - skeleton_ik->get_parent_skeleton()->set_bone_pose(i, initial_bone_poses[i]); + skeleton_ik->get_parent_skeleton()->set_bone_global_pose_override(i, Transform(), 0); } } } diff --git a/editor/plugins/skeleton_ik_editor_plugin.h b/editor/plugins/skeleton_ik_editor_plugin.h index d1ef7c99c5..814eb8ff5b 100644 --- a/editor/plugins/skeleton_ik_editor_plugin.h +++ b/editor/plugins/skeleton_ik_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -44,7 +44,6 @@ class SkeletonIKEditorPlugin : public EditorPlugin { Button *play_btn; EditorNode *editor; - Vector<Transform> initial_bone_poses; void _play(); diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index d187e4ff4a..31e6b65640 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -37,6 +37,7 @@ #include "core/project_settings.h" #include "core/sort_array.h" #include "editor/editor_node.h" +#include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/plugins/animation_player_editor_plugin.h" #include "editor/plugins/script_editor_plugin.h" @@ -47,6 +48,7 @@ #include "scene/3d/mesh_instance.h" #include "scene/3d/physics_body.h" #include "scene/3d/visual_instance.h" +#include "scene/gui/viewport_container.h" #include "scene/resources/packed_scene.h" #include "scene/resources/surface_tool.h" @@ -298,6 +300,7 @@ ObjectID SpatialEditorViewport::_select_ray(const Point2 &p_pos, bool p_append, Vector3 ray = _get_ray(p_pos); Vector3 pos = _get_ray_pos(p_pos); + Vector2 shrinked_pos = p_pos / viewport_container->get_stretch_shrink(); Vector<ObjectID> instances = VisualServer::get_singleton()->instances_cull_ray(pos, ray, get_tree()->get_root()->get_world()->get_scenario()); Set<Ref<EditorSpatialGizmo> > found_gizmos; @@ -326,7 +329,7 @@ ObjectID SpatialEditorViewport::_select_ray(const Point2 &p_pos, bool p_append, Vector3 normal; int handle = -1; - bool inters = seg->intersect_ray(camera, p_pos, point, normal, &handle, p_alt_select); + bool inters = seg->intersect_ray(camera, shrinked_pos, point, normal, &handle, p_alt_select); if (!inters) continue; @@ -425,8 +428,7 @@ Vector3 SpatialEditorViewport::_get_screen_to_space(const Vector3 &p_vector3) { } else { cm.set_perspective(get_fov(), get_size().aspect(), get_znear() + p_vector3.z, get_zfar()); } - float screen_w, screen_h; - cm.get_viewport_size(screen_w, screen_h); + Vector2 screen_he = cm.get_viewport_half_extents(); Transform camera_transform; camera_transform.translate(cursor.pos); @@ -434,7 +436,7 @@ Vector3 SpatialEditorViewport::_get_screen_to_space(const Vector3 &p_vector3) { camera_transform.basis.rotate(Vector3(0, 1, 0), -cursor.y_rot); camera_transform.translate(0, 0, cursor.distance); - return camera_transform.xform(Vector3(((p_vector3.x / get_size().width) * 2.0 - 1.0) * screen_w, ((1.0 - (p_vector3.y / get_size().height)) * 2.0 - 1.0) * screen_h, -(get_znear() + p_vector3.z))); + return camera_transform.xform(Vector3(((p_vector3.x / get_size().width) * 2.0 - 1.0) * screen_he.x, ((1.0 - (p_vector3.y / get_size().height)) * 2.0 - 1.0) * screen_he.y, -(get_znear() + p_vector3.z))); } void SpatialEditorViewport::_select_region() { @@ -521,7 +523,7 @@ void SpatialEditorViewport::_select_region() { if (selected.find(item) != -1) continue; - if (_is_node_locked(Object::cast_to<Spatial>(item))) continue; + if (_is_node_locked(item)) continue; Ref<EditorSpatialGizmo> seg = sp->get_gizmo(); @@ -2132,6 +2134,13 @@ void SpatialEditorViewport::_notification(int p_what) { call_deferred("update_transform_gizmo_view"); } + if (p_what == NOTIFICATION_READY) { + // The crosshair icon doesn't depend on the editor theme. + crosshair->set_texture(get_icon("Crosshair", "EditorIcons")); + // Set the anchors and margins after changing the icon to ensure it's centered correctly. + crosshair->set_anchors_and_margins_preset(PRESET_CENTER); + } + if (p_what == NOTIFICATION_PROCESS) { real_t delta = get_process_delta_time(); @@ -2252,6 +2261,10 @@ void SpatialEditorViewport::_notification(int p_what) { current_camera = camera; } + // Display the crosshair only while freelooking. Hide it otherwise, + // as the crosshair can be distracting. + crosshair->set_visible(freelook_active); + if (show_info) { String text; text += "X: " + rtos(current_camera->get_translation().x).pad_decimals(1) + "\n"; @@ -3543,6 +3556,10 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed camera->make_current(); surface->set_focus_mode(FOCUS_ALL); + crosshair = memnew(TextureRect); + crosshair->set_mouse_filter(MOUSE_FILTER_IGNORE); + surface->add_child(crosshair); + VBoxContainer *vbox = memnew(VBoxContainer); surface->add_child(vbox); vbox->set_position(Point2(10, 10) * EDSCALE); @@ -3595,6 +3612,24 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed view_menu->set_disable_shortcuts(true); + if (OS::get_singleton()->get_current_video_driver() == OS::VIDEO_DRIVER_GLES2) { + // Alternate display modes only work when using the GLES3 renderer; make this explicit. + const int normal_idx = view_menu->get_popup()->get_item_index(VIEW_DISPLAY_NORMAL); + const int wireframe_idx = view_menu->get_popup()->get_item_index(VIEW_DISPLAY_WIREFRAME); + const int overdraw_idx = view_menu->get_popup()->get_item_index(VIEW_DISPLAY_OVERDRAW); + const int shadeless_idx = view_menu->get_popup()->get_item_index(VIEW_DISPLAY_SHADELESS); + const String unsupported_tooltip = TTR("Not available when using the GLES2 renderer."); + + view_menu->get_popup()->set_item_disabled(normal_idx, true); + view_menu->get_popup()->set_item_tooltip(normal_idx, unsupported_tooltip); + view_menu->get_popup()->set_item_disabled(wireframe_idx, true); + view_menu->get_popup()->set_item_tooltip(wireframe_idx, unsupported_tooltip); + view_menu->get_popup()->set_item_disabled(overdraw_idx, true); + view_menu->get_popup()->set_item_tooltip(overdraw_idx, unsupported_tooltip); + view_menu->get_popup()->set_item_disabled(shadeless_idx, true); + view_menu->get_popup()->set_item_tooltip(shadeless_idx, unsupported_tooltip); + } + ED_SHORTCUT("spatial_editor/freelook_left", TTR("Freelook Left"), KEY_A); ED_SHORTCUT("spatial_editor/freelook_right", TTR("Freelook Right"), KEY_D); ED_SHORTCUT("spatial_editor/freelook_forward", TTR("Freelook Forward"), KEY_W); @@ -6142,6 +6177,8 @@ void EditorSpatialGizmoPlugin::create_icon_material(const String &p_name, const icon->set_albedo(color); icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true); + icon->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + icon->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true); icon->set_cull_mode(SpatialMaterial::CULL_DISABLED); icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED); icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h index 65e3c32ca8..5cc2b24cbb 100644 --- a/editor/plugins/spatial_editor_plugin.h +++ b/editor/plugins/spatial_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -41,6 +41,7 @@ class Camera; class SpatialEditor; class EditorSpatialGizmoPlugin; +class ViewportContainer; class EditorSpatialGizmo : public SpatialGizmo { @@ -101,11 +102,11 @@ protected: static void _bind_methods(); public: - void add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard = false); + void add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard = false, const Color &p_modulate = Color(1, 1, 1)); void add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard = false, const Ref<SkinReference> &p_skin_reference = Ref<SkinReference>(), const Ref<Material> &p_material = Ref<Material>()); void add_collision_segments(const Vector<Vector3> &p_lines); void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh); - void add_unscaled_billboard(const Ref<Material> &p_material, float p_scale = 1); + void add_unscaled_billboard(const Ref<Material> &p_material, float p_scale = 1, const Color &p_modulate = Color(1, 1, 1)); void add_handles(const Vector<Vector3> &p_handles, const Ref<Material> &p_material, bool p_billboard = false, bool p_secondary = false); void add_solid_box(Ref<Material> &p_material, Vector3 p_size, Vector3 p_position = Vector3()); @@ -216,6 +217,7 @@ private: bool freelook_active; real_t freelook_speed; + TextureRect *crosshair; Label *info_label; Label *fps_label; Label *cinema_label; diff --git a/editor/plugins/sprite_editor_plugin.cpp b/editor/plugins/sprite_editor_plugin.cpp index 40734cffc4..6757b180a3 100644 --- a/editor/plugins/sprite_editor_plugin.cpp +++ b/editor/plugins/sprite_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -31,6 +31,7 @@ #include "sprite_editor_plugin.h" #include "canvas_item_editor_plugin.h" +#include "editor/editor_scale.h" #include "scene/2d/collision_polygon_2d.h" #include "scene/2d/light_occluder_2d.h" #include "scene/2d/mesh_instance_2d.h" @@ -125,7 +126,7 @@ void SpriteEditor::_menu_option(int p_option) { case MENU_OPTION_CONVERT_TO_MESH_2D: { debug_uv_dialog->get_ok()->set_text(TTR("Create Mesh2D")); - debug_uv_dialog->set_title("Mesh2D Preview"); + debug_uv_dialog->set_title(TTR("Mesh2D Preview")); _update_mesh_data(); debug_uv_dialog->popup_centered(); @@ -135,7 +136,7 @@ void SpriteEditor::_menu_option(int p_option) { case MENU_OPTION_CONVERT_TO_POLYGON_2D: { debug_uv_dialog->get_ok()->set_text(TTR("Create Polygon2D")); - debug_uv_dialog->set_title("Polygon2D Preview"); + debug_uv_dialog->set_title(TTR("Polygon2D Preview")); _update_mesh_data(); debug_uv_dialog->popup_centered(); @@ -144,7 +145,7 @@ void SpriteEditor::_menu_option(int p_option) { case MENU_OPTION_CREATE_COLLISION_POLY_2D: { debug_uv_dialog->get_ok()->set_text(TTR("Create CollisionPolygon2D")); - debug_uv_dialog->set_title("CollisionPolygon2D Preview"); + debug_uv_dialog->set_title(TTR("CollisionPolygon2D Preview")); _update_mesh_data(); debug_uv_dialog->popup_centered(); @@ -154,7 +155,7 @@ void SpriteEditor::_menu_option(int p_option) { case MENU_OPTION_CREATE_LIGHT_OCCLUDER_2D: { debug_uv_dialog->get_ok()->set_text(TTR("Create LightOccluder2D")); - debug_uv_dialog->set_title("LightOccluder2D Preview"); + debug_uv_dialog->set_title(TTR("LightOccluder2D Preview")); _update_mesh_data(); debug_uv_dialog->popup_centered(); @@ -473,69 +474,6 @@ void SpriteEditor::_add_as_sibling_or_child(Node *p_own_node, Node *p_new_node) p_new_node->set_owner(this->get_tree()->get_edited_scene_root()); } -#if 0 -void SpriteEditor::_create_uv_lines() { - - Ref<Mesh> sprite = node->get_sprite(); - ERR_FAIL_COND(!sprite.is_valid()); - - Set<SpriteEditorEdgeSort> edges; - uv_lines.clear(); - for (int i = 0; i < sprite->get_surface_count(); i++) { - if (sprite->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) - continue; - Array a = sprite->surface_get_arrays(i); - - PoolVector<Vector2> uv = a[p_layer == 0 ? Mesh::ARRAY_TEX_UV : Mesh::ARRAY_TEX_UV2]; - if (uv.size() == 0) { - err_dialog->set_text(TTR("Model has no UV in this layer")); - err_dialog->popup_centered_minsize(); - return; - } - - PoolVector<Vector2>::Read r = uv.read(); - - PoolVector<int> indices = a[Mesh::ARRAY_INDEX]; - PoolVector<int>::Read ri; - - int ic; - bool use_indices; - - if (indices.size()) { - ic = indices.size(); - ri = indices.read(); - use_indices = true; - } else { - ic = uv.size(); - use_indices = false; - } - - for (int j = 0; j < ic; j += 3) { - - for (int k = 0; k < 3; k++) { - - SpriteEditorEdgeSort edge; - if (use_indices) { - edge.a = r[ri[j + k]]; - edge.b = r[ri[j + ((k + 1) % 3)]]; - } else { - edge.a = r[j + k]; - edge.b = r[j + ((k + 1) % 3)]; - } - - if (edges.has(edge)) - continue; - - uv_lines.push_back(edge.a); - uv_lines.push_back(edge.b); - edges.insert(edge); - } - } - } - - debug_uv_dialog->popup_centered_minsize(); -} -#endif void SpriteEditor::_debug_uv_draw() { Ref<Texture> tex = node->get_texture(); diff --git a/editor/plugins/sprite_editor_plugin.h b/editor/plugins/sprite_editor_plugin.h index 4ca7bca1a8..13177c9142 100644 --- a/editor/plugins/sprite_editor_plugin.h +++ b/editor/plugins/sprite_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 34780af59e..4101980e29 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,8 +32,10 @@ #include "core/io/resource_loader.h" #include "core/project_settings.h" +#include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "scene/3d/sprite_3d.h" +#include "scene/gui/center_container.h" void SpriteFramesEditor::_gui_input(Ref<InputEvent> p_event) { } @@ -202,7 +204,7 @@ void SpriteFramesEditor::_prepare_sprite_sheet(const String &p_file) { Ref<Resource> texture = ResourceLoader::load(p_file); if (!texture.is_valid()) { - EditorNode::get_singleton()->show_warning("Unable to load images"); + EditorNode::get_singleton()->show_warning(TTR("Unable to load images")); ERR_FAIL_COND(!texture.is_valid()); } if (texture != split_sheet_preview->get_texture()) { @@ -403,7 +405,6 @@ void SpriteFramesEditor::_up_pressed() { sel = to_move; sel -= 1; - Ref<Texture> r = frames->get_frame(edited_anim, to_move); undo_redo->create_action(TTR("Delete Resource")); undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move, frames->get_frame(edited_anim, to_move - 1)); undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move - 1, frames->get_frame(edited_anim, to_move)); @@ -428,7 +429,6 @@ void SpriteFramesEditor::_down_pressed() { sel = to_move; sel += 1; - Ref<Texture> r = frames->get_frame(edited_anim, to_move); undo_redo->create_action(TTR("Delete Resource")); undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move, frames->get_frame(edited_anim, to_move + 1)); undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move + 1, frames->get_frame(edited_anim, to_move)); diff --git a/editor/plugins/sprite_frames_editor_plugin.h b/editor/plugins/sprite_frames_editor_plugin.h index f20b54f910..aa683605ed 100644 --- a/editor/plugins/sprite_frames_editor_plugin.h +++ b/editor/plugins/sprite_frames_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/style_box_editor_plugin.cpp b/editor/plugins/style_box_editor_plugin.cpp index c4a9803ff4..eebcd567a4 100644 --- a/editor/plugins/style_box_editor_plugin.cpp +++ b/editor/plugins/style_box_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,6 +30,8 @@ #include "style_box_editor_plugin.h" +#include "editor/editor_scale.h" + bool EditorInspectorPluginStyleBox::can_handle(Object *p_object) { return Object::cast_to<StyleBox>(p_object) != NULL; @@ -68,7 +70,14 @@ void StyleBoxPreview::_sb_changed() { void StyleBoxPreview::_redraw() { if (stylebox.is_valid()) { - preview->draw_style_box(stylebox, preview->get_rect()); + Rect2 preview_rect = preview->get_rect(); + + // Re-adjust preview panel to fit all drawn content + Rect2 draw_rect = stylebox->get_draw_rect(preview_rect); + preview_rect.size -= draw_rect.size - preview_rect.size; + preview_rect.position -= draw_rect.position - preview_rect.position; + + preview->draw_style_box(stylebox, preview_rect); } } @@ -81,6 +90,7 @@ void StyleBoxPreview::_bind_methods() { StyleBoxPreview::StyleBoxPreview() { preview = memnew(Control); preview->set_custom_minimum_size(Size2(0, 150 * EDSCALE)); + preview->set_clip_contents(true); preview->connect("draw", this, "_redraw"); add_margin_child(TTR("Preview:"), preview); } diff --git a/editor/plugins/style_box_editor_plugin.h b/editor/plugins/style_box_editor_plugin.h index fead8e0de8..f4a72d9d1c 100644 --- a/editor/plugins/style_box_editor_plugin.h +++ b/editor/plugins/style_box_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp index 0cef5a8b6f..57447abf47 100644 --- a/editor/plugins/text_editor.cpp +++ b/editor/plugins/text_editor.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -713,7 +713,7 @@ TextEditor::TextEditor() { goto_menu->get_popup()->add_separator(); bookmarks_menu = memnew(PopupMenu); - bookmarks_menu->set_name(TTR("Bookmarks")); + bookmarks_menu->set_name("Bookmarks"); goto_menu->get_popup()->add_child(bookmarks_menu); goto_menu->get_popup()->add_submenu_item(TTR("Bookmarks"), "Bookmarks"); _update_bookmark_list(); diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h index 7d441a187d..fe157a29e6 100644 --- a/editor/plugins/text_editor.h +++ b/editor/plugins/text_editor.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp index 6d71c56ead..9489836984 100644 --- a/editor/plugins/texture_editor_plugin.cpp +++ b/editor/plugins/texture_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/texture_editor_plugin.h b/editor/plugins/texture_editor_plugin.h index ed25783303..f587579902 100644 --- a/editor/plugins/texture_editor_plugin.h +++ b/editor/plugins/texture_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index a2f4040152..94aef60f1f 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -33,6 +33,7 @@ #include "core/core_string_names.h" #include "core/os/input.h" #include "core/os/keyboard.h" +#include "editor/editor_scale.h" #include "scene/gui/check_box.h" /** @@ -135,13 +136,19 @@ void TextureRegionEditor::_region_draw() { Ref<Texture> select_handle = get_icon("EditorHandle", "EditorIcons"); - Rect2 scroll_rect; + Rect2 scroll_rect(Point2(), base_tex->get_size()); - Vector2 endpoints[4] = { - mtx.basis_xform(rect.position), - mtx.basis_xform(rect.position + Vector2(rect.size.x, 0)), - mtx.basis_xform(rect.position + rect.size), - mtx.basis_xform(rect.position + Vector2(0, rect.size.y)) + const Vector2 raw_endpoints[4] = { + rect.position, + rect.position + Vector2(rect.size.x, 0), + rect.position + rect.size, + rect.position + Vector2(0, rect.size.y) + }; + const Vector2 endpoints[4] = { + mtx.basis_xform(raw_endpoints[0]), + mtx.basis_xform(raw_endpoints[1]), + mtx.basis_xform(raw_endpoints[2]), + mtx.basis_xform(raw_endpoints[3]) }; Color color = get_color("mono_color", "Editor"); for (int i = 0; i < 4; i++) { @@ -150,7 +157,7 @@ void TextureRegionEditor::_region_draw() { int next = (i + 1) % 4; Vector2 ofs = ((endpoints[i] - endpoints[prev]).normalized() + ((endpoints[i] - endpoints[next]).normalized())).normalized(); - ofs *= 1.4144 * (select_handle->get_size().width / 2); + ofs *= Math_SQRT2 * (select_handle->get_size().width / 2); edit_draw->draw_line(endpoints[i] - draw_ofs * draw_zoom, endpoints[next] - draw_ofs * draw_zoom, color, 2); @@ -163,33 +170,43 @@ void TextureRegionEditor::_region_draw() { if (snap_mode != SNAP_AUTOSLICE) edit_draw->draw_texture(select_handle, (endpoints[i] + ofs - (select_handle->get_size() / 2)).floor() - draw_ofs * draw_zoom); - scroll_rect.expand_to(endpoints[i]); + scroll_rect.expand_to(raw_endpoints[i]); } - scroll_rect.position -= edit_draw->get_size(); - scroll_rect.size += edit_draw->get_size() * 2.0; + const Size2 scroll_margin = edit_draw->get_size() / draw_zoom; + scroll_rect.position -= scroll_margin; + scroll_rect.size += scroll_margin * 2; updating_scroll = true; + hscroll->set_min(scroll_rect.position.x); hscroll->set_max(scroll_rect.position.x + scroll_rect.size.x); - if (ABS(scroll_rect.position.x - (scroll_rect.position.x + scroll_rect.size.x)) <= edit_draw->get_size().x) { + if (ABS(scroll_rect.position.x - (scroll_rect.position.x + scroll_rect.size.x)) <= scroll_margin.x) { hscroll->hide(); } else { hscroll->show(); - hscroll->set_page(edit_draw->get_size().x); + hscroll->set_page(scroll_margin.x); hscroll->set_value(draw_ofs.x); } vscroll->set_min(scroll_rect.position.y); vscroll->set_max(scroll_rect.position.y + scroll_rect.size.y); - if (ABS(scroll_rect.position.y - (scroll_rect.position.y + scroll_rect.size.y)) <= edit_draw->get_size().y) { + if (ABS(scroll_rect.position.y - (scroll_rect.position.y + scroll_rect.size.y)) <= scroll_margin.y) { vscroll->hide(); draw_ofs.y = scroll_rect.position.y; } else { vscroll->show(); - vscroll->set_page(edit_draw->get_size().y); + vscroll->set_page(scroll_margin.y); vscroll->set_value(draw_ofs.y); } + + Size2 hmin = hscroll->get_combined_minimum_size(); + Size2 vmin = vscroll->get_combined_minimum_size(); + + // Avoid scrollbar overlapping. + hscroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, vscroll->is_visible() ? -vmin.width : 0); + vscroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, hscroll->is_visible() ? -hmin.height : 0); + updating_scroll = false; if (node_ninepatch || obj_styleBox.is_valid()) { @@ -225,15 +242,19 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { mtx.elements[2] = -draw_ofs * draw_zoom; mtx.scale_basis(Vector2(draw_zoom, draw_zoom)); - Vector2 endpoints[8] = { - mtx.xform(rect.position) + Vector2(-4, -4), - mtx.xform(rect.position + Vector2(rect.size.x / 2, 0)) + Vector2(0, -4), - mtx.xform(rect.position + Vector2(rect.size.x, 0)) + Vector2(4, -4), - mtx.xform(rect.position + Vector2(rect.size.x, rect.size.y / 2)) + Vector2(4, 0), - mtx.xform(rect.position + rect.size) + Vector2(4, 4), - mtx.xform(rect.position + Vector2(rect.size.x / 2, rect.size.y)) + Vector2(0, 4), - mtx.xform(rect.position + Vector2(0, rect.size.y)) + Vector2(-4, 4), - mtx.xform(rect.position + Vector2(0, rect.size.y / 2)) + Vector2(-4, 0) + const real_t handle_radius = 8 * EDSCALE; + const real_t handle_offset = 4 * EDSCALE; + + // Position of selection handles. + const Vector2 endpoints[8] = { + mtx.xform(rect.position) + Vector2(-handle_offset, -handle_offset), + mtx.xform(rect.position + Vector2(rect.size.x / 2, 0)) + Vector2(0, -handle_offset), + mtx.xform(rect.position + Vector2(rect.size.x, 0)) + Vector2(handle_offset, -handle_offset), + mtx.xform(rect.position + Vector2(rect.size.x, rect.size.y / 2)) + Vector2(handle_offset, 0), + mtx.xform(rect.position + rect.size) + Vector2(handle_offset, handle_offset), + mtx.xform(rect.position + Vector2(rect.size.x / 2, rect.size.y)) + Vector2(0, handle_offset), + mtx.xform(rect.position + Vector2(0, rect.size.y)) + Vector2(-handle_offset, handle_offset), + mtx.xform(rect.position + Vector2(0, rect.size.y / 2)) + Vector2(-handle_offset, 0) }; Ref<InputEventMouseButton> mb = p_input; @@ -346,7 +367,7 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { for (int i = 0; i < 8; i++) { Vector2 tuv = endpoints[i]; - if (tuv.distance_to(Vector2(mb->get_position().x, mb->get_position().y)) < 8) { + if (tuv.distance_to(Vector2(mb->get_position().x, mb->get_position().y)) < handle_radius) { drag_index = i; } } @@ -525,6 +546,17 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { edit_draw->update(); } } + + Ref<InputEventMagnifyGesture> magnify_gesture = p_input; + if (magnify_gesture.is_valid()) { + _zoom_on_position(draw_zoom * magnify_gesture->get_factor(), magnify_gesture->get_position()); + } + + Ref<InputEventPanGesture> pan_gesture = p_input; + if (pan_gesture.is_valid()) { + hscroll->set_value(hscroll->get_value() + hscroll->get_page() * pan_gesture->get_delta().x / 8); + vscroll->set_value(vscroll->get_value() + vscroll->get_page() * pan_gesture->get_delta().y / 8); + } } void TextureRegionEditor::_scroll_changed(float) { @@ -715,6 +747,9 @@ void TextureRegionEditor::_notification(int p_what) { zoom_out->set_icon(get_icon("ZoomLess", "EditorIcons")); zoom_reset->set_icon(get_icon("ZoomReset", "EditorIcons")); zoom_in->set_icon(get_icon("ZoomMore", "EditorIcons")); + + vscroll->set_anchors_and_margins_preset(PRESET_RIGHT_WIDE); + hscroll->set_anchors_and_margins_preset(PRESET_BOTTOM_WIDE); } break; case NOTIFICATION_VISIBILITY_CHANGED: { if (snap_mode == SNAP_AUTOSLICE && is_visible() && autoslice_is_dirty) { @@ -989,25 +1024,22 @@ TextureRegionEditor::TextureRegionEditor(EditorNode *p_editor) { zoom_hb->add_child(zoom_out); zoom_reset = memnew(ToolButton); - zoom_out->set_tooltip(TTR("Zoom Reset")); + zoom_reset->set_tooltip(TTR("Zoom Reset")); zoom_reset->connect("pressed", this, "_zoom_reset"); zoom_hb->add_child(zoom_reset); zoom_in = memnew(ToolButton); - zoom_out->set_tooltip(TTR("Zoom In")); + zoom_in->set_tooltip(TTR("Zoom In")); zoom_in->connect("pressed", this, "_zoom_in"); zoom_hb->add_child(zoom_in); vscroll = memnew(VScrollBar); vscroll->set_step(0.001); edit_draw->add_child(vscroll); - vscroll->set_anchors_and_margins_preset(PRESET_RIGHT_WIDE); vscroll->connect("value_changed", this, "_scroll_changed"); hscroll = memnew(HScrollBar); hscroll->set_step(0.001); edit_draw->add_child(hscroll); - hscroll->set_anchors_and_margins_preset(PRESET_BOTTOM_WIDE); - hscroll->set_margin(MARGIN_RIGHT, -vscroll->get_size().x * EDSCALE); hscroll->connect("value_changed", this, "_scroll_changed"); updating_scroll = false; diff --git a/editor/plugins/texture_region_editor_plugin.h b/editor/plugins/texture_region_editor_plugin.h index 4eb84ae176..d877cf9436 100644 --- a/editor/plugins/texture_region_editor_plugin.h +++ b/editor/plugins/texture_region_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index d501a04016..22105f7ed4 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,6 +32,8 @@ #include "core/os/file_access.h" #include "core/version.h" +#include "editor/editor_scale.h" +#include "scene/gui/progress_bar.h" void ThemeEditor::edit(const Ref<Theme> &p_theme) { @@ -870,7 +872,7 @@ ThemeEditor::ThemeEditor() { add_del_dialog->get_ok()->connect("pressed", this, "_dialog_cbk"); file_dialog = memnew(EditorFileDialog); - file_dialog->add_filter("*.theme ; Theme File"); + file_dialog->add_filter("*.theme ; " + TTR("Theme File")); add_child(file_dialog); file_dialog->connect("file_selected", this, "_save_template_cbk"); } @@ -908,7 +910,7 @@ ThemeEditorPlugin::ThemeEditorPlugin(EditorNode *p_node) { editor = p_node; theme_editor = memnew(ThemeEditor); - theme_editor->set_custom_minimum_size(Size2(0, 200)); + theme_editor->set_custom_minimum_size(Size2(0, 200) * EDSCALE); button = editor->add_bottom_panel_item(TTR("Theme"), theme_editor); button->hide(); diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h index 6ffee46569..c51583593d 100644 --- a/editor/plugins/theme_editor_plugin.h +++ b/editor/plugins/theme_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index 385ba4cfda..0c3e29028c 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -52,12 +52,6 @@ void TileMapEditor::_notification(int p_what) { case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - bool new_show_tile_info = EditorSettings::get_singleton()->get("editors/tile_map/show_tile_info_on_hover"); - if (new_show_tile_info != show_tile_info) { - show_tile_info = new_show_tile_info; - tile_info->set_visible(show_tile_info); - } - if (is_visible_in_tree()) { _update_palette(); } @@ -633,13 +627,14 @@ PoolVector<Vector2> TileMapEditor::_bucket_fill(const Point2i &p_start, bool era if (r != bucket_cache_rect) _clear_bucket_cache(); // Cache grid is not initialized - if (bucket_cache_visited == 0) { + if (bucket_cache_visited == NULL) { bucket_cache_visited = new bool[area]; invalidate_cache = true; } // Tile ID changed or position wasn't visited by the previous fill - int loc = (p_start.x - r.position.x) + (p_start.y - r.position.y) * r.get_size().x; - if (prev_id != bucket_cache_tile || !bucket_cache_visited[loc]) { + const int loc = (p_start.x - r.position.x) + (p_start.y - r.position.y) * r.get_size().x; + const bool in_range = 0 <= loc && loc < area; + if (prev_id != bucket_cache_tile || (in_range && !bucket_cache_visited[loc])) { invalidate_cache = true; } if (invalidate_cache) { @@ -899,7 +894,7 @@ void TileMapEditor::_draw_fill_preview(Control *p_viewport, int p_cell, const Po void TileMapEditor::_clear_bucket_cache() { if (bucket_cache_visited) { delete[] bucket_cache_visited; - bucket_cache_visited = 0; + bucket_cache_visited = NULL; } } @@ -1250,14 +1245,13 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { CanvasItemEditor::get_singleton()->update_viewport(); } - if (show_tile_info) { - int tile_under = node->get_cell(over_tile.x, over_tile.y); - String tile_name = "none"; + int tile_under = node->get_cell(over_tile.x, over_tile.y); + String tile_name = "none"; - if (node->get_tileset()->has_tile(tile_under)) - tile_name = node->get_tileset()->tile_get_name(tile_under); - tile_info->set_text(String::num(over_tile.x) + ", " + String::num(over_tile.y) + " [" + tile_name + "]"); - } + if (node->get_tileset()->has_tile(tile_under)) + tile_name = node->get_tileset()->tile_get_name(tile_under); + tile_info->show(); + tile_info->set_text(String::num(over_tile.x) + ", " + String::num(over_tile.y) + " [" + tile_name + "]"); if (tool == TOOL_PAINTING) { @@ -1925,14 +1919,13 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { tool = TOOL_NONE; selection_active = false; mouse_over = false; - show_tile_info = true; flip_h = false; flip_v = false; transpose = false; bucket_cache_tile = -1; - bucket_cache_visited = 0; + bucket_cache_visited = NULL; invalid_cell.resize(1); invalid_cell.write[0] = TileMap::INVALID_CELL; @@ -2033,13 +2026,13 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { toolbar->add_child(bucket_fill_button); picker_button = memnew(ToolButton); - picker_button->set_shortcut(ED_SHORTCUT("tile_map_editor/pick_tile", TTR("Pick Tile"), KEY_CONTROL)); + picker_button->set_shortcut(ED_SHORTCUT("tile_map_editor/pick_tile", TTR("Pick Tile"), KEY_I)); picker_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_PICKING)); picker_button->set_toggle_mode(true); toolbar->add_child(picker_button); select_button = memnew(ToolButton); - select_button->set_shortcut(ED_SHORTCUT("tile_map_editor/select", TTR("Select"), KEY_MASK_CMD + KEY_B)); + select_button->set_shortcut(ED_SHORTCUT("tile_map_editor/select", TTR("Select"), KEY_M)); select_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_SELECTING)); select_button->set_toggle_mode(true); toolbar->add_child(select_button); @@ -2055,7 +2048,12 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { // Tile position. tile_info = memnew(Label); - toolbar_right->add_child(tile_info); + tile_info->set_modulate(Color(1, 1, 1, 0.8)); + tile_info->set_mouse_filter(MOUSE_FILTER_IGNORE); + tile_info->add_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_font("main", "EditorFonts")); + // The tile info is only displayed after a tile has been hovered. + tile_info->hide(); + CanvasItemEditor::get_singleton()->add_control_to_info_overlay(tile_info); // Menu. options = memnew(MenuButton); @@ -2151,6 +2149,10 @@ void TileMapEditorPlugin::make_visible(bool p_visible) { tile_map_editor->show(); tile_map_editor->get_toolbar()->show(); tile_map_editor->get_toolbar_right()->show(); + // `tile_info` isn't shown here, as it's displayed after a tile has been hovered. + // Otherwise, a translucent black rectangle would be visible as there would be an + // empty Label in the CanvasItemEditor's info overlay. + // Change to TOOL_SELECT when TileMap node is selected, to prevent accidental movement. CanvasItemEditor::get_singleton()->set_current_tool(CanvasItemEditor::TOOL_SELECT); } else { @@ -2158,6 +2160,7 @@ void TileMapEditorPlugin::make_visible(bool p_visible) { tile_map_editor->hide(); tile_map_editor->get_toolbar()->hide(); tile_map_editor->get_toolbar_right()->hide(); + tile_map_editor->get_tile_info()->hide(); tile_map_editor->edit(NULL); } } @@ -2170,7 +2173,6 @@ TileMapEditorPlugin::TileMapEditorPlugin(EditorNode *p_node) { EDITOR_DEF("editors/tile_map/show_tile_ids", false); EDITOR_DEF("editors/tile_map/sort_tiles_by_name", true); EDITOR_DEF("editors/tile_map/bucket_fill_preview", true); - EDITOR_DEF("editors/tile_map/show_tile_info_on_hover", true); EDITOR_DEF("editors/tile_map/editor_side", 1); EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "editors/tile_map/editor_side", PROPERTY_HINT_ENUM, "Left,Right")); diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h index e3d678c2fd..927f0887bb 100644 --- a/editor/plugins/tile_map_editor_plugin.h +++ b/editor/plugins/tile_map_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -109,7 +109,6 @@ class TileMapEditor : public VBoxContainer { bool selection_active; bool mouse_over; - bool show_tile_info; bool flip_h; bool flip_v; @@ -218,6 +217,7 @@ protected: public: HBoxContainer *get_toolbar() const { return toolbar; } HBoxContainer *get_toolbar_right() const { return toolbar_right; } + Label *get_tile_info() const { return tile_info; } bool forward_gui_input(const Ref<InputEvent> &p_event); void forward_canvas_draw_over_viewport(Control *p_overlay); diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index a8cf5b46e1..b24d5add9f 100644 --- a/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,6 +32,7 @@ #include "core/os/input.h" #include "core/os/keyboard.h" +#include "editor/editor_scale.h" #include "editor/plugins/canvas_item_editor_plugin.h" #include "scene/2d/physics_body_2d.h" #include "scene/2d/sprite.h" @@ -404,10 +405,15 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) { HBoxContainer *tool_hb = memnew(HBoxContainer); Ref<ButtonGroup> g(memnew(ButtonGroup)); - String workspace_label[WORKSPACE_MODE_MAX] = { "Edit", "New Single Tile", "New Autotile", "New Atlas" }; + String workspace_label[WORKSPACE_MODE_MAX] = { + TTR("Edit"), + TTR("New Single Tile"), + TTR("New Autotile"), + TTR("New Atlas") + }; for (int i = 0; i < (int)WORKSPACE_MODE_MAX; i++) { tool_workspacemode[i] = memnew(Button); - tool_workspacemode[i]->set_text(TTR(workspace_label[i])); + tool_workspacemode[i]->set_text(workspace_label[i]); tool_workspacemode[i]->set_toggle_mode(true); tool_workspacemode[i]->set_button_group(g); tool_workspacemode[i]->connect("pressed", this, "_on_workspace_mode_changed", varray(i)); @@ -445,7 +451,16 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) { tool_hb = memnew(HBoxContainer); g = Ref<ButtonGroup>(memnew(ButtonGroup)); - String label[EDITMODE_MAX] = { "Region", "Collision", "Occlusion", "Navigation", "Bitmask", "Priority", "Icon", "Z Index" }; + String label[EDITMODE_MAX] = { + TTR("Region"), + TTR("Collision"), + TTR("Occlusion"), + TTR("Navigation"), + TTR("Bitmask"), + TTR("Priority"), + TTR("Icon"), + TTR("Z Index") + }; for (int i = 0; i < (int)EDITMODE_MAX; i++) { tool_editmode[i] = memnew(Button); tool_editmode[i]->set_text(label[i]); @@ -637,8 +652,8 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) { tile_names_visible = false; // Config scale. - max_scale = 10.0f; - min_scale = 0.1f; + max_scale = 16.0f; + min_scale = 0.01f; scale_ratio = 1.2f; } @@ -1176,6 +1191,31 @@ void TileSetEditor::_on_workspace_overlay_draw() { } } +int TileSetEditor::get_grabbed_point(const Vector2 &p_mouse_pos, real_t p_grab_threshold) { + Transform2D xform = workspace->get_transform(); + + int grabbed_point = -1; + real_t min_distance = 1e10; + + for (int i = 0; i < current_shape.size(); i++) { + const real_t distance = xform.xform(current_shape[i]).distance_to(xform.xform(p_mouse_pos)); + if (distance < p_grab_threshold && distance < min_distance) { + min_distance = distance; + grabbed_point = i; + } + } + + return grabbed_point; +} + +bool TileSetEditor::is_within_grabbing_distance_of_first_point(const Vector2 &p_pos, real_t p_grab_threshold) { + Transform2D xform = workspace->get_transform(); + + const real_t distance = xform.xform(current_shape[0]).distance_to(xform.xform(p_pos)); + + return distance < p_grab_threshold; +} + void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { if (tileset.is_null() || !get_current_texture().is_valid()) @@ -1263,12 +1303,14 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { Size2 tile_workspace_size = edited_region.position + edited_region.size + WORKSPACE_MARGIN * 2; Size2 workspace_minsize = workspace->get_custom_minimum_size(); - if (tile_workspace_size.x > workspace_minsize.x && tile_workspace_size.y > workspace_minsize.y) { - undo_redo->add_do_method(workspace, "set_custom_minimum_size", tile_workspace_size); + // If the new region is bigger, just directly change the workspace size to avoid checking all other tiles. + if (tile_workspace_size.x > workspace_minsize.x || tile_workspace_size.y > workspace_minsize.y) { + Size2 max_workspace_size = Size2(MAX(tile_workspace_size.x, workspace_minsize.x), MAX(tile_workspace_size.y, workspace_minsize.y)); + undo_redo->add_do_method(workspace, "set_custom_minimum_size", max_workspace_size); undo_redo->add_undo_method(workspace, "set_custom_minimum_size", workspace_minsize); - undo_redo->add_do_method(workspace_container, "set_custom_minimum_size", tile_workspace_size); + undo_redo->add_do_method(workspace_container, "set_custom_minimum_size", max_workspace_size); undo_redo->add_undo_method(workspace_container, "set_custom_minimum_size", workspace_minsize); - undo_redo->add_do_method(workspace_overlay, "set_custom_minimum_size", tile_workspace_size); + undo_redo->add_do_method(workspace_overlay, "set_custom_minimum_size", max_workspace_size); undo_redo->add_undo_method(workspace_overlay, "set_custom_minimum_size", workspace_minsize); } else if (workspace_minsize.x > get_current_texture()->get_size().x + WORKSPACE_MARGIN.x * 2 || workspace_minsize.y > get_current_texture()->get_size().y + WORKSPACE_MARGIN.y * 2) { undo_redo->add_do_method(this, "update_workspace_minsize"); @@ -1528,18 +1570,19 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { shape_anchor.x *= (size.x + spacing); shape_anchor.y *= (size.y + spacing); } + const real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius"); shape_anchor += current_tile_region.position; if (tools[TOOL_SELECT]->is_pressed()) { if (mb.is_valid()) { if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { if (edit_mode != EDITMODE_PRIORITY && current_shape.size() > 0) { - for (int i = 0; i < current_shape.size(); i++) { - if ((current_shape[i] - mb->get_position()).length_squared() <= grab_threshold) { - dragging_point = i; - workspace->update(); - return; - } + int grabbed_point = get_grabbed_point(mb->get_position(), grab_threshold); + + if (grabbed_point >= 0) { + dragging_point = grabbed_point; + workspace->update(); + return; } } if ((tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) && current_tile_region.has_point(mb->get_position())) { @@ -1633,13 +1676,12 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { Vector2 pos = mb->get_position(); pos = snap_point(pos); if (creating_shape) { - if (current_shape.size() > 0) { - if ((pos - current_shape[0]).length_squared() <= grab_threshold) { - if (current_shape.size() > 2) { - close_shape(shape_anchor); - workspace->update(); - return; - } + if (current_shape.size() > 2) { + + if (is_within_grabbing_distance_of_first_point(mb->get_position(), grab_threshold)) { + close_shape(shape_anchor); + workspace->update(); + return; } } current_shape.push_back(pos); @@ -1685,12 +1727,15 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { } } else if (!mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { if (creating_shape) { - if ((current_shape[0] - current_shape[1]).length_squared() <= grab_threshold) { + + // if the first two corners are within grabbing distance of one another, expand the rect to fill the tile + if (is_within_grabbing_distance_of_first_point(current_shape[1], grab_threshold)) { current_shape.set(0, snap_point(shape_anchor)); current_shape.set(1, snap_point(shape_anchor + Vector2(current_tile_region.size.x, 0))); current_shape.set(2, snap_point(shape_anchor + current_tile_region.size)); current_shape.set(3, snap_point(shape_anchor + Vector2(0, current_tile_region.size.y))); } + close_shape(shape_anchor); workspace->update(); return; @@ -1760,8 +1805,6 @@ void TileSetEditor::_on_tool_clicked(int p_tool) { Ref<ConvexPolygonShape2D> _convex = memnew(ConvexPolygonShape2D); edited_collision_shape = _convex; _set_edited_shape_points(_get_collision_shape_points(concave)); - } else { - // Shouldn't happen } for (int i = 0; i < sd.size(); i++) { if (sd[i].get("shape") == previous_shape) { @@ -1994,10 +2037,10 @@ void TileSetEditor::_update_toggle_shape_button() { tools[SHAPE_TOGGLE_TYPE]->hide(); } else if (concave.is_valid()) { tools[SHAPE_TOGGLE_TYPE]->set_icon(get_icon("ConvexPolygonShape2D", "EditorIcons")); - tools[SHAPE_TOGGLE_TYPE]->set_text("Make Convex"); + tools[SHAPE_TOGGLE_TYPE]->set_text(TTR("Make Convex")); } else if (convex.is_valid()) { tools[SHAPE_TOGGLE_TYPE]->set_icon(get_icon("ConcavePolygonShape2D", "EditorIcons")); - tools[SHAPE_TOGGLE_TYPE]->set_text("Make Concave"); + tools[SHAPE_TOGGLE_TYPE]->set_text(TTR("Make Concave")); } else { // Shouldn't happen separator_shape_toggle->hide(); @@ -2535,7 +2578,7 @@ void TileSetEditor::draw_grid_snap() { if (i == 0 && snap_offset.y != 0) { last_p = snap_offset.y; } - if (snap_separation.x != 0) { + if (snap_separation.y != 0) { if (i != 0) { workspace->draw_rect(Rect2(0, last_p, s.width, snap_separation.y), grid_color); last_p += snap_separation.y; @@ -3224,12 +3267,16 @@ void TileSetEditor::update_workspace_minsize() { List<int> *tiles = new List<int>(); tileset->get_tile_list(tiles); for (List<int>::Element *E = tiles->front(); E; E = E->next()) { - if (tileset->tile_get_texture(E->get())->get_rid() == current_texture_rid) { - Rect2i region = tileset->tile_get_region(E->get()); - if (region.position.x + region.size.x > workspace_min_size.x) - workspace_min_size.x = region.position.x + region.size.x; - if (region.position.y + region.size.y > workspace_min_size.y) - workspace_min_size.y = region.position.y + region.size.y; + if (tileset->tile_get_texture(E->get())->get_rid() != current_texture_rid) { + continue; + } + + Rect2i region = tileset->tile_get_region(E->get()); + if (region.position.x + region.size.x > workspace_min_size.x) { + workspace_min_size.x = region.position.x + region.size.x; + } + if (region.position.y + region.size.y > workspace_min_size.y) { + workspace_min_size.y = region.position.y + region.size.y; } } delete tiles; diff --git a/editor/plugins/tile_set_editor_plugin.h b/editor/plugins/tile_set_editor_plugin.h index 944dc04e4e..0e0bd6448c 100644 --- a/editor/plugins/tile_set_editor_plugin.h +++ b/editor/plugins/tile_set_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -244,6 +244,8 @@ private: void update_workspace_tile_mode(); void update_workspace_minsize(); void update_edited_region(const Vector2 &end_point); + int get_grabbed_point(const Vector2 &p_mouse_pos, real_t grab_threshold); + bool is_within_grabbing_distance_of_first_point(const Vector2 &p_pos, real_t p_grab_threshold); int get_current_tile() const; void set_current_tile(int p_id); diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp index aa3bd74c49..3622ca8d61 100644 --- a/editor/plugins/version_control_editor_plugin.cpp +++ b/editor/plugins/version_control_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -33,6 +33,7 @@ #include "core/script_language.h" #include "editor/editor_file_system.h" #include "editor/editor_node.h" +#include "editor/editor_scale.h" VersionControlEditorPlugin *VersionControlEditorPlugin::singleton = NULL; @@ -202,7 +203,7 @@ void VersionControlEditorPlugin::_refresh_stage_area() { } } else { - WARN_PRINT("No VCS addon is initialized. Select a Version Control Addon from Project menu.") + WARN_PRINT("No VCS addon is initialized. Select a Version Control Addon from Project menu."); } } diff --git a/editor/plugins/version_control_editor_plugin.h b/editor/plugins/version_control_editor_plugin.h index f9f8437e15..4a98c8580e 100644 --- a/editor/plugins/version_control_editor_plugin.h +++ b/editor/plugins/version_control_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 1a74779fb5..fb095692bc 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -35,7 +35,9 @@ #include "core/os/input.h" #include "core/os/keyboard.h" #include "core/project_settings.h" +#include "editor/editor_log.h" #include "editor/editor_properties.h" +#include "editor/editor_scale.h" #include "scene/animation/animation_player.h" #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" @@ -554,6 +556,7 @@ void VisualShaderEditor::_update_graph() { } Ref<VisualShaderNodeUniform> uniform = vsnode; + Ref<VisualShaderNodeScalarUniform> scalar_uniform = vsnode; if (uniform.is_valid()) { graph->add_child(node); _update_created_node(node); @@ -568,7 +571,9 @@ void VisualShaderEditor::_update_graph() { //shortcut VisualShaderNode::PortType port_right = vsnode->get_output_port_type(0); node->set_slot(0, false, VisualShaderNode::PORT_TYPE_SCALAR, Color(), true, port_right, type_color[port_right]); - continue; + if (!scalar_uniform.is_valid()) { + continue; + } } port_offset++; } @@ -580,11 +585,16 @@ void VisualShaderEditor::_update_graph() { } } - if (custom_editor && vsnode->get_output_port_count() > 0 && vsnode->get_output_port_name(0) == "" && (vsnode->get_input_port_count() == 0 || vsnode->get_input_port_name(0) == "")) { + if (custom_editor && !scalar_uniform.is_valid() && vsnode->get_output_port_count() > 0 && vsnode->get_output_port_name(0) == "" && (vsnode->get_input_port_count() == 0 || vsnode->get_input_port_name(0) == "")) { //will be embedded in first port } else if (custom_editor) { + port_offset++; node->add_child(custom_editor); + if (scalar_uniform.is_valid()) { + custom_editor->call_deferred("_show_prop_names", true); + continue; + } custom_editor = NULL; } @@ -2850,7 +2860,7 @@ VisualShaderEditorPlugin::VisualShaderEditorPlugin(EditorNode *p_node) { editor = p_node; visual_shader_editor = memnew(VisualShaderEditor); - visual_shader_editor->set_custom_minimum_size(Size2(0, 300)); + visual_shader_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE); button = editor->add_bottom_panel_item(TTR("VisualShader"), visual_shader_editor); button->hide(); @@ -2970,6 +2980,13 @@ public: bool updating; Ref<VisualShaderNode> node; Vector<EditorProperty *> properties; + Vector<Label *> prop_names; + + void _show_prop_names(bool p_show) { + for (int i = 0; i < prop_names.size(); i++) { + prop_names[i]->set_visible(p_show); + } + } void setup(Ref<Resource> p_parent_resource, Vector<EditorProperty *> p_properties, const Vector<StringName> &p_names, Ref<VisualShaderNode> p_node) { parent_resource = p_parent_resource; @@ -2979,7 +2996,20 @@ public: for (int i = 0; i < p_properties.size(); i++) { - add_child(p_properties[i]); + HBoxContainer *hbox = memnew(HBoxContainer); + hbox->set_h_size_flags(SIZE_EXPAND_FILL); + add_child(hbox); + + Label *prop_name = memnew(Label); + String prop_name_str = p_names[i]; + prop_name_str = prop_name_str.capitalize() + ":"; + prop_name->set_text(prop_name_str); + prop_name->set_visible(false); + hbox->add_child(prop_name); + prop_names.push_back(prop_name); + + p_properties[i]->set_h_size_flags(SIZE_EXPAND_FILL); + hbox->add_child(p_properties[i]); bool res_prop = Object::cast_to<EditorPropertyResource>(p_properties[i]); if (res_prop) { @@ -3001,6 +3031,7 @@ public: ClassDB::bind_method("_refresh_request", &VisualShaderNodePluginDefaultEditor::_refresh_request); ClassDB::bind_method("_resource_selected", &VisualShaderNodePluginDefaultEditor::_resource_selected); ClassDB::bind_method("_open_inspector", &VisualShaderNodePluginDefaultEditor::_open_inspector); + ClassDB::bind_method("_show_prop_names", &VisualShaderNodePluginDefaultEditor::_show_prop_names); } }; diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index 5197f8c77f..8c5dd8e82f 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ |