summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/animation_bezier_editor.cpp88
-rw-r--r--editor/animation_bezier_editor.h9
-rw-r--r--editor/animation_track_editor.cpp102
-rw-r--r--editor/animation_track_editor.h15
-rw-r--r--editor/connections_dialog.cpp11
-rw-r--r--editor/create_dialog.cpp90
-rw-r--r--editor/create_dialog.h12
-rw-r--r--editor/debugger/editor_debugger_inspector.cpp7
-rw-r--r--editor/debugger/editor_debugger_node.cpp1
-rw-r--r--editor/debugger/script_editor_debugger.cpp132
-rw-r--r--editor/debugger/script_editor_debugger.h10
-rw-r--r--editor/editor_asset_installer.cpp1
-rw-r--r--editor/editor_audio_buses.cpp2
-rw-r--r--editor/editor_export.cpp32
-rw-r--r--editor/editor_export.h3
-rw-r--r--editor/editor_file_dialog.cpp29
-rw-r--r--editor/editor_file_dialog.h2
-rw-r--r--editor/editor_file_system.cpp6
-rw-r--r--editor/editor_file_system.h1
-rw-r--r--editor/editor_log.cpp2
-rw-r--r--editor/editor_node.cpp12
-rw-r--r--editor/editor_node.h1
-rw-r--r--editor/editor_paths.cpp5
-rw-r--r--editor/editor_settings.cpp1
-rw-r--r--editor/editor_themes.cpp24
-rw-r--r--editor/filesystem_dock.cpp6
-rw-r--r--editor/groups_editor.cpp3
-rw-r--r--editor/icons/SnapGrid.svg2
-rw-r--r--editor/import/editor_import_collada.cpp2
-rw-r--r--editor/import/resource_importer_bmfont.cpp742
-rw-r--r--editor/import/resource_importer_layered_texture.cpp7
-rw-r--r--editor/import/resource_importer_texture.cpp19
-rw-r--r--editor/inspector_dock.cpp24
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.cpp6
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp81
-rw-r--r--editor/plugins/animation_player_editor_plugin.h3
-rw-r--r--editor/plugins/asset_library_editor_plugin.cpp40
-rw-r--r--editor/plugins/asset_library_editor_plugin.h5
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.cpp50
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.h9
-rw-r--r--editor/plugins/script_editor_plugin.cpp12
-rw-r--r--editor/plugins/script_text_editor.cpp13
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp16
-rw-r--r--editor/plugins/tiles/tile_data_editors.cpp6
-rw-r--r--editor/plugins/tiles/tiles_editor_plugin.cpp2
-rw-r--r--editor/project_settings_editor.cpp27
-rw-r--r--editor/project_settings_editor.h1
-rw-r--r--editor/rename_dialog.cpp2
-rw-r--r--editor/scene_tree_editor.cpp11
-rw-r--r--editor/scene_tree_editor.h1
50 files changed, 630 insertions, 1058 deletions
diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp
index 1085d34c4e..3678642521 100644
--- a/editor/animation_bezier_editor.cpp
+++ b/editor/animation_bezier_editor.cpp
@@ -32,6 +32,7 @@
#include "editor/editor_node.h"
#include "editor_scale.h"
+#include "scene/gui/view_panner.h"
#include "scene/resources/text_line.h"
float AnimationBezierTrackEdit::_bezier_h_to_pixel(float p_h) {
@@ -216,6 +217,9 @@ void AnimationBezierTrackEdit::_draw_line_clipped(const Vector2 &p_from, const V
}
void AnimationBezierTrackEdit::_notification(int p_what) {
+ if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
+ panner->set_control_scheme((ViewPanner::ControlScheme)EDITOR_GET("interface/editors/animation_editors_panning_scheme").operator int());
+ }
if (p_what == NOTIFICATION_THEME_CHANGED || p_what == NOTIFICATION_ENTER_TREE) {
close_button->set_icon(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
@@ -610,6 +614,11 @@ void AnimationBezierTrackEdit::_select_at_anim(const Ref<Animation> &p_anim, int
void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
+ if (panner->gui_input(p_event)) {
+ accept_event();
+ return;
+ }
+
if (p_event->is_pressed()) {
if (ED_GET_SHORTCUT("animation_editor/duplicate_selection")->matches_event(p_event)) {
duplicate_selection();
@@ -623,40 +632,24 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
}
Ref<InputEventMouseButton> mb = p_event;
- if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::WHEEL_DOWN) {
- const float v_zoom_orig = v_zoom;
- if (mb->is_command_pressed()) {
- timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() / 1.05);
- } else {
+ if (mb.is_valid() && mb->is_pressed() && mb->is_alt_pressed()) {
+ // Alternate zoom (doesn't affect timeline).
+ if (mb->get_button_index() == MouseButton::WHEEL_DOWN) {
+ const float v_zoom_orig = v_zoom;
if (v_zoom < 100000) {
v_zoom *= 1.2;
}
+ v_scroll = v_scroll + (mb->get_position().y - get_size().y / 2) * (v_zoom - v_zoom_orig);
+ update();
}
- v_scroll = v_scroll + (mb->get_position().y - get_size().y / 2) * (v_zoom - v_zoom_orig);
- update();
- }
- if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::WHEEL_UP) {
- const float v_zoom_orig = v_zoom;
- if (mb->is_command_pressed()) {
- timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() * 1.05);
- } else {
+ if (mb->get_button_index() == MouseButton::WHEEL_UP) {
+ const float v_zoom_orig = v_zoom;
if (v_zoom > 0.000001) {
v_zoom /= 1.2;
}
- }
- v_scroll = v_scroll + (mb->get_position().y - get_size().y / 2) * (v_zoom - v_zoom_orig);
- update();
- }
-
- if (mb.is_valid() && mb->get_button_index() == MouseButton::MIDDLE) {
- if (mb->is_pressed()) {
- int x = mb->get_position().x - timeline->get_name_limit();
- panning_timeline_from = x / timeline->get_zoom_scale();
- panning_timeline = true;
- panning_timeline_at = timeline->get_value();
- } else {
- panning_timeline = false;
+ v_scroll = v_scroll + (mb->get_position().y - get_size().y / 2) * (v_zoom - v_zoom_orig);
+ update();
}
}
@@ -934,22 +927,6 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
}
Ref<InputEventMouseMotion> mm = p_event;
- if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_MIDDLE) != MouseButton::NONE) {
- v_scroll += mm->get_relative().y * v_zoom;
- if (v_scroll > 100000) {
- v_scroll = 100000;
- }
- if (v_scroll < -100000) {
- v_scroll = -100000;
- }
-
- int x = mm->get_position().x - timeline->get_name_limit();
- float ofs = x / timeline->get_zoom_scale();
- float diff = ofs - panning_timeline_from;
- timeline->set_value(panning_timeline_at - diff);
-
- update();
- }
if (moving_selection_attempt && mm.is_valid()) {
if (!moving_selection) {
moving_selection = true;
@@ -1038,6 +1015,28 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
}
}
+void AnimationBezierTrackEdit::_scroll_callback(Vector2 p_scroll_vec) {
+ _pan_callback(-p_scroll_vec * 32);
+}
+
+void AnimationBezierTrackEdit::_pan_callback(Vector2 p_scroll_vec) {
+ v_scroll += p_scroll_vec.y * v_zoom;
+ v_scroll = CLAMP(v_scroll, -100000, 100000);
+ timeline->set_value(timeline->get_value() - p_scroll_vec.x / timeline->get_zoom_scale());
+ update();
+}
+
+void AnimationBezierTrackEdit::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin) {
+ const float v_zoom_orig = v_zoom;
+ if (p_scroll_vec.y > 0) {
+ timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() / 1.05);
+ } else {
+ timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() * 1.05);
+ }
+ v_scroll = v_scroll + (p_origin.y - get_size().y / 2) * (v_zoom - v_zoom_orig);
+ update();
+}
+
void AnimationBezierTrackEdit::_menu_selected(int p_index) {
switch (p_index) {
case MENU_KEY_INSERT: {
@@ -1171,6 +1170,11 @@ void AnimationBezierTrackEdit::_bind_methods() {
}
AnimationBezierTrackEdit::AnimationBezierTrackEdit() {
+ panner.instantiate();
+ panner->set_callbacks(callable_mp(this, &AnimationBezierTrackEdit::_scroll_callback), callable_mp(this, &AnimationBezierTrackEdit::_pan_callback), callable_mp(this, &AnimationBezierTrackEdit::_zoom_callback));
+ panner->set_disable_rmb(true);
+ panner->set_control_scheme(ViewPanner::SCROLL_PANS);
+
play_position = memnew(Control);
play_position->set_mouse_filter(MOUSE_FILTER_PASS);
add_child(play_position);
diff --git a/editor/animation_bezier_editor.h b/editor/animation_bezier_editor.h
index d9bc85a258..6a5b97a7da 100644
--- a/editor/animation_bezier_editor.h
+++ b/editor/animation_bezier_editor.h
@@ -33,6 +33,8 @@
#include "animation_track_editor.h"
+class ViewPanner;
+
class AnimationBezierTrackEdit : public Control {
GDCLASS(AnimationBezierTrackEdit, Control);
@@ -123,9 +125,10 @@ class AnimationBezierTrackEdit : public Control {
Set<int> selection;
- bool panning_timeline = false;
- float panning_timeline_from;
- float panning_timeline_at;
+ Ref<ViewPanner> panner;
+ void _scroll_callback(Vector2 p_scroll_vec);
+ void _pan_callback(Vector2 p_scroll_vec);
+ void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin);
void _draw_line_clipped(const Vector2 &p_from, const Vector2 &p_to, const Color &p_color, int p_clip_left, int p_clip_right);
void _draw_track(int p_track, const Color &p_color);
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index f4e719f552..13e9d58744 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -32,12 +32,12 @@
#include "animation_track_editor_plugins.h"
#include "core/input/input.h"
-#include "core/os/keyboard.h"
#include "editor/animation_bezier_editor.h"
#include "editor/plugins/animation_player_editor_plugin.h"
#include "editor_node.h"
#include "editor_scale.h"
#include "scene/animation/animation_player.h"
+#include "scene/gui/view_panner.h"
#include "scene/main/window.h"
#include "scene/scene_string_names.h"
#include "servers/audio/audio_stream.h"
@@ -1458,6 +1458,10 @@ int AnimationTimelineEdit::get_name_limit() const {
}
void AnimationTimelineEdit::_notification(int p_what) {
+ if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
+ panner->set_control_scheme((ViewPanner::ControlScheme)EDITOR_GET("interface/editors/animation_editors_panning_scheme").operator int());
+ }
+
if (p_what == NOTIFICATION_ENTER_TREE) {
add_track->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
loop->set_icon(get_theme_icon(SNAME("Loop"), SNAME("EditorIcons")));
@@ -1760,17 +1764,12 @@ void AnimationTimelineEdit::_play_position_draw() {
void AnimationTimelineEdit::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
- const Ref<InputEventMouseButton> mb = p_event;
-
- if (mb.is_valid() && mb->is_pressed() && mb->is_command_pressed() && mb->get_button_index() == MouseButton::WHEEL_UP) {
- get_zoom()->set_value(get_zoom()->get_value() * 1.05);
+ if (panner->gui_input(p_event)) {
accept_event();
+ return;
}
- if (mb.is_valid() && mb->is_pressed() && mb->is_command_pressed() && mb->get_button_index() == MouseButton::WHEEL_DOWN) {
- get_zoom()->set_value(get_zoom()->get_value() / 1.05);
- accept_event();
- }
+ const Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->is_pressed() && mb->is_alt_pressed() && mb->get_button_index() == MouseButton::WHEEL_UP) {
if (track_edit) {
@@ -1796,29 +1795,19 @@ void AnimationTimelineEdit::gui_input(const Ref<InputEvent> &p_event) {
dragging_hsize = false;
}
if (mb.is_valid() && mb->get_position().x > get_name_limit() && mb->get_position().x < (get_size().width - get_buttons_width())) {
- if (!panning_timeline && mb->get_button_index() == MouseButton::LEFT) {
+ if (!panner->is_panning() && mb->get_button_index() == MouseButton::LEFT) {
int x = mb->get_position().x - get_name_limit();
float ofs = x / get_zoom_scale() + get_value();
emit_signal(SNAME("timeline_changed"), ofs, false, Input::get_singleton()->is_key_pressed(Key::ALT));
dragging_timeline = true;
}
- if (!dragging_timeline && mb->get_button_index() == MouseButton::MIDDLE) {
- int x = mb->get_position().x - get_name_limit();
- panning_timeline_from = x / get_zoom_scale();
- panning_timeline = true;
- panning_timeline_at = get_value();
- }
}
if (dragging_timeline && mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && !mb->is_pressed()) {
dragging_timeline = false;
}
- if (panning_timeline && mb.is_valid() && mb->get_button_index() == MouseButton::MIDDLE && !mb->is_pressed()) {
- panning_timeline = false;
- }
-
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
@@ -1839,17 +1828,29 @@ void AnimationTimelineEdit::gui_input(const Ref<InputEvent> &p_event) {
if (dragging_timeline) {
int x = mm->get_position().x - get_name_limit();
float ofs = x / get_zoom_scale() + get_value();
- emit_signal(SNAME("timeline_changed"), ofs, false, Input::get_singleton()->is_key_pressed(Key::ALT));
- }
- if (panning_timeline) {
- int x = mm->get_position().x - get_name_limit();
- float ofs = x / get_zoom_scale();
- float diff = ofs - panning_timeline_from;
- set_value(panning_timeline_at - diff);
+ emit_signal(SNAME("timeline_changed"), ofs, false, mm->is_alt_pressed());
}
}
}
+void AnimationTimelineEdit::_scroll_callback(Vector2 p_scroll_vec) {
+ // Timeline has no vertical scroll, so we change it to horizontal.
+ p_scroll_vec.x += p_scroll_vec.y;
+ _pan_callback(-p_scroll_vec * 32);
+}
+
+void AnimationTimelineEdit::_pan_callback(Vector2 p_scroll_vec) {
+ set_value(get_value() - p_scroll_vec.x / get_zoom_scale());
+}
+
+void AnimationTimelineEdit::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin) {
+ if (p_scroll_vec.y < 0) {
+ get_zoom()->set_value(get_zoom()->get_value() * 1.05);
+ } else {
+ get_zoom()->set_value(get_zoom()->get_value() / 1.05);
+ }
+}
+
void AnimationTimelineEdit::set_use_fps(bool p_use_fps) {
use_fps = p_use_fps;
update_values();
@@ -1926,10 +1927,14 @@ AnimationTimelineEdit::AnimationTimelineEdit() {
add_track->get_popup()->connect("index_pressed", callable_mp(this, &AnimationTimelineEdit::_track_added));
len_hb->hide();
- panning_timeline = false;
dragging_timeline = false;
dragging_hsize = false;
+ panner.instantiate();
+ panner->set_callbacks(callable_mp(this, &AnimationTimelineEdit::_scroll_callback), callable_mp(this, &AnimationTimelineEdit::_pan_callback), callable_mp(this, &AnimationTimelineEdit::_zoom_callback));
+ panner->set_disable_rmb(true);
+ panner->set_control_scheme(ViewPanner::SCROLL_PANS);
+
set_layout_direction(Control::LAYOUT_DIRECTION_LTR);
}
@@ -4500,6 +4505,10 @@ MenuButton *AnimationTrackEditor::get_edit_menu() {
}
void AnimationTrackEditor::_notification(int p_what) {
+ if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
+ panner->set_control_scheme((ViewPanner::ControlScheme)EDITOR_GET("interface/editors/animation_editors_panning_scheme").operator int());
+ }
+
if (p_what == NOTIFICATION_THEME_CHANGED || p_what == NOTIFICATION_ENTER_TREE) {
zoom_icon->set_texture(get_theme_icon(SNAME("Zoom"), SNAME("EditorIcons")));
snap->set_icon(get_theme_icon(SNAME("Snap"), SNAME("EditorIcons")));
@@ -5212,17 +5221,12 @@ void AnimationTrackEditor::_box_selection_draw() {
}
void AnimationTrackEditor::_scroll_input(const Ref<InputEvent> &p_event) {
- Ref<InputEventMouseButton> mb = p_event;
-
- if (mb.is_valid() && mb->is_pressed() && mb->is_command_pressed() && mb->get_button_index() == MouseButton::WHEEL_UP) {
- timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() * 1.05);
+ if (panner->gui_input(p_event)) {
scroll->accept_event();
+ return;
}
- if (mb.is_valid() && mb->is_pressed() && mb->is_command_pressed() && mb->get_button_index() == MouseButton::WHEEL_DOWN) {
- timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() / 1.05);
- scroll->accept_event();
- }
+ Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->is_pressed() && mb->is_alt_pressed() && mb->get_button_index() == MouseButton::WHEEL_UP) {
goto_prev_step(true);
@@ -5262,10 +5266,6 @@ void AnimationTrackEditor::_scroll_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mm = p_event;
- if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_MIDDLE) != MouseButton::NONE) {
- timeline->set_value(timeline->get_value() - mm->get_relative().x / timeline->get_zoom_scale());
- }
-
if (mm.is_valid() && box_selecting) {
if ((mm->get_button_mask() & MouseButton::MASK_LEFT) == MouseButton::NONE) {
// No longer.
@@ -5302,6 +5302,23 @@ void AnimationTrackEditor::_scroll_input(const Ref<InputEvent> &p_event) {
}
}
+void AnimationTrackEditor::_scroll_callback(Vector2 p_scroll_vec) {
+ _pan_callback(-p_scroll_vec * 32);
+}
+
+void AnimationTrackEditor::_pan_callback(Vector2 p_scroll_vec) {
+ timeline->set_value(timeline->get_value() - p_scroll_vec.x / timeline->get_zoom_scale());
+ scroll->set_v_scroll(scroll->get_v_scroll() - p_scroll_vec.y);
+}
+
+void AnimationTrackEditor::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin) {
+ if (p_scroll_vec.y < 0) {
+ timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() * 1.05);
+ } else {
+ timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() / 1.05);
+ }
+}
+
void AnimationTrackEditor::_cancel_bezier_edit() {
bezier_edit->hide();
scroll->show();
@@ -6088,6 +6105,11 @@ AnimationTrackEditor::AnimationTrackEditor() {
timeline->connect("value_changed", callable_mp(this, &AnimationTrackEditor::_timeline_value_changed));
timeline->connect("length_changed", callable_mp(this, &AnimationTrackEditor::_update_length));
+ panner.instantiate();
+ panner->set_callbacks(callable_mp(this, &AnimationTrackEditor::_scroll_callback), callable_mp(this, &AnimationTrackEditor::_pan_callback), callable_mp(this, &AnimationTrackEditor::_zoom_callback));
+ panner->set_disable_rmb(true);
+ panner->set_control_scheme(ViewPanner::SCROLL_PANS);
+
scroll = memnew(ScrollContainer);
timeline_vbox->add_child(scroll);
scroll->set_v_size_flags(SIZE_EXPAND_FILL);
diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h
index b5d44bc0d3..2a2b20ada9 100644
--- a/editor/animation_track_editor.h
+++ b/editor/animation_track_editor.h
@@ -48,8 +48,8 @@
#include "scene_tree_editor.h"
class AnimationPlayer;
-
class AnimationTrackEdit;
+class ViewPanner;
class AnimationTimelineEdit : public Range {
GDCLASS(AnimationTimelineEdit, Range);
@@ -81,9 +81,11 @@ class AnimationTimelineEdit : public Range {
bool editing;
bool use_fps;
- bool panning_timeline;
- float panning_timeline_from;
- float panning_timeline_at;
+ Ref<ViewPanner> panner;
+ void _scroll_callback(Vector2 p_scroll_vec);
+ void _pan_callback(Vector2 p_scroll_vec);
+ void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin);
+
bool dragging_timeline;
bool dragging_hsize;
float dragging_hsize_from;
@@ -374,6 +376,11 @@ class AnimationTrackEditor : public VBoxContainer {
PropertyInfo _find_hint_for_track(int p_idx, NodePath &r_base_path, Variant *r_current_val = nullptr);
+ Ref<ViewPanner> panner;
+ void _scroll_callback(Vector2 p_scroll_vec);
+ void _pan_callback(Vector2 p_scroll_vec);
+ void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin);
+
void _timeline_value_changed(double);
float insert_key_from_track_call_ofs;
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp
index 0edbb182e1..c23fd6a943 100644
--- a/editor/connections_dialog.cpp
+++ b/editor/connections_dialog.cpp
@@ -922,8 +922,14 @@ void ConnectionsDock::_connect_pressed() {
}
void ConnectionsDock::_notification(int p_what) {
- if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
- update_tree();
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_THEME_CHANGED: {
+ search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ } break;
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
+ update_tree();
+ } break;
}
}
@@ -1135,7 +1141,6 @@ ConnectionsDock::ConnectionsDock(EditorNode *p_editor) {
search_box = memnew(LineEdit);
search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
search_box->set_placeholder(TTR("Filter signals"));
- search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
search_box->set_clear_button_enabled(true);
search_box->connect("text_changed", callable_mp(this, &ConnectionsDock::_filter_changed));
vbc->add_child(search_box);
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index 608eab9a9f..d0dfbc7c11 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -170,7 +170,7 @@ void CreateDialog::_update_search() {
root->set_text(0, base_type);
root->set_icon(0, search_options->get_theme_icon(icon_fallback, SNAME("EditorIcons")));
search_options_types[base_type] = root;
- _configure_search_option_item(root, base_type, ClassDB::class_exists(base_type));
+ _configure_search_option_item(root, base_type, ClassDB::class_exists(base_type) ? TypeCategory::CPP_TYPE : TypeCategory::OTHER_TYPE);
const String search_text = search_box->get_text();
bool empty_search = search_text.is_empty();
@@ -185,7 +185,7 @@ void CreateDialog::_update_search() {
// Build the type tree.
for (int i = 0; i < candidates.size(); i++) {
- _add_type(candidates[i], ClassDB::class_exists(candidates[i]));
+ _add_type(candidates[i], ClassDB::class_exists(candidates[i]) ? TypeCategory::CPP_TYPE : TypeCategory::OTHER_TYPE);
}
// Select the best result.
@@ -202,31 +202,80 @@ void CreateDialog::_update_search() {
}
}
-void CreateDialog::_add_type(const String &p_type, bool p_cpp_type) {
+void CreateDialog::_add_type(const String &p_type, const TypeCategory p_type_category) {
if (search_options_types.has(p_type)) {
return;
}
String inherits;
- if (p_cpp_type) {
+
+ TypeCategory inherited_type = TypeCategory::OTHER_TYPE;
+
+ if (p_type_category == TypeCategory::CPP_TYPE) {
inherits = ClassDB::get_parent_class(p_type);
- } else if (ScriptServer::is_global_class(p_type)) {
- inherits = EditorNode::get_editor_data().script_class_get_base(p_type);
+ inherited_type = TypeCategory::CPP_TYPE;
+ } else if (p_type_category == TypeCategory::PATH_TYPE) {
+ ERR_FAIL_COND(!ResourceLoader::exists(p_type, "Script"));
+ Ref<Script> script = ResourceLoader::load(p_type, "Script");
+ ERR_FAIL_COND(script.is_null());
+
+ Ref<Script> base = script->get_base_script();
+ if (base.is_null()) {
+ String extends;
+ script->get_language()->get_global_class_name(script->get_path(), &extends);
+
+ inherits = extends;
+ inherited_type = TypeCategory::CPP_TYPE;
+ } else {
+ inherits = script->get_language()->get_global_class_name(base->get_path());
+ if (inherits.is_empty()) {
+ inherits = base->get_path();
+ inherited_type = TypeCategory::PATH_TYPE;
+ }
+ }
} else {
- inherits = custom_type_parents[p_type];
+ if (ScriptServer::is_global_class(p_type)) {
+ inherits = EditorNode::get_editor_data().script_class_get_base(p_type);
+ if (inherits.is_empty()) {
+ Ref<Script> script = EditorNode::get_editor_data().script_class_load_script(p_type);
+ ERR_FAIL_COND(script.is_null());
+
+ Ref<Script> base = script->get_base_script();
+ if (base.is_null()) {
+ String extends;
+ script->get_language()->get_global_class_name(script->get_path(), &extends);
+
+ inherits = extends;
+ inherited_type = TypeCategory::CPP_TYPE;
+ } else {
+ inherits = base->get_path();
+ inherited_type = TypeCategory::PATH_TYPE;
+ }
+ }
+ } else {
+ inherits = custom_type_parents[p_type];
+ if (ClassDB::class_exists(inherits)) {
+ inherited_type = TypeCategory::CPP_TYPE;
+ }
+ }
}
- _add_type(inherits, p_cpp_type || ClassDB::class_exists(inherits));
+ // Should never happen, but just in case...
+ ERR_FAIL_COND(inherits.is_empty());
+
+ _add_type(inherits, inherited_type);
TreeItem *item = search_options->create_item(search_options_types[inherits]);
search_options_types[p_type] = item;
- _configure_search_option_item(item, p_type, p_cpp_type);
+ _configure_search_option_item(item, p_type, p_type_category);
}
-void CreateDialog::_configure_search_option_item(TreeItem *r_item, const String &p_type, const bool p_cpp_type) {
+void CreateDialog::_configure_search_option_item(TreeItem *r_item, const String &p_type, const TypeCategory p_type_category) {
bool script_type = ScriptServer::is_global_class(p_type);
- if (p_cpp_type) {
+ if (p_type_category == TypeCategory::CPP_TYPE) {
r_item->set_text(0, p_type);
+ } else if (p_type_category == TypeCategory::PATH_TYPE) {
+ r_item->set_text(0, "\"" + p_type + "\"");
} else if (script_type) {
r_item->set_metadata(0, p_type);
r_item->set_text(0, p_type + " (" + ScriptServer::get_global_class_path(p_type).get_file() + ")");
@@ -235,7 +284,9 @@ void CreateDialog::_configure_search_option_item(TreeItem *r_item, const String
r_item->set_text(0, p_type);
}
- bool can_instantiate = (p_cpp_type && ClassDB::can_instantiate(p_type)) || !p_cpp_type;
+ bool can_instantiate = (p_type_category == TypeCategory::CPP_TYPE && ClassDB::can_instantiate(p_type)) ||
+ p_type_category == TypeCategory::OTHER_TYPE;
+
if (!can_instantiate) {
r_item->set_custom_color(0, search_options->get_theme_color(SNAME("disabled_font_color"), SNAME("Editor")));
r_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, "NodeDisabled"));
@@ -259,7 +310,7 @@ void CreateDialog::_configure_search_option_item(TreeItem *r_item, const String
const String &description = DTR(EditorHelp::get_doc_data()->class_list[p_type].brief_description);
r_item->set_tooltip(0, description);
- if (!p_cpp_type && !script_type) {
+ if (p_type_category == TypeCategory::OTHER_TYPE && !script_type) {
Ref<Texture2D> icon = EditorNode::get_editor_data().get_custom_types()[custom_type_parents[p_type]][custom_type_indices[p_type]].icon;
if (icon.is_valid()) {
r_item->set_icon(0, icon);
@@ -367,13 +418,16 @@ void CreateDialog::_sbox_input(const Ref<InputEvent> &p_ie) {
}
}
+void CreateDialog::_update_theme() {
+ search_box->set_right_icon(search_options->get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ favorite->set_icon(search_options->get_theme_icon(SNAME("Favorites"), SNAME("EditorIcons")));
+}
+
void CreateDialog::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
connect("confirmed", callable_mp(this, &CreateDialog::_confirmed));
- search_box->set_right_icon(search_options->get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
- search_box->set_clear_button_enabled(true);
- favorite->set_icon(search_options->get_theme_icon(SNAME("Favorites"), SNAME("EditorIcons")));
+ _update_theme();
} break;
case NOTIFICATION_EXIT_TREE: {
disconnect("confirmed", callable_mp(this, &CreateDialog::_confirmed));
@@ -386,6 +440,9 @@ void CreateDialog::_notification(int p_what) {
EditorSettings::get_singleton()->get_project_metadata("dialog_bounds", "create_new_node", Rect2(get_position(), get_size()));
}
} break;
+ case NOTIFICATION_THEME_CHANGED: {
+ _update_theme();
+ } break;
}
}
@@ -711,6 +768,7 @@ CreateDialog::CreateDialog() {
hsc->add_child(vbc);
search_box = memnew(LineEdit);
+ search_box->set_clear_button_enabled(true);
search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
search_box->connect("text_changed", callable_mp(this, &CreateDialog::_text_changed));
search_box->connect("gui_input", callable_mp(this, &CreateDialog::_sbox_input));
diff --git a/editor/create_dialog.h b/editor/create_dialog.h
index c36730c4f0..f905160df3 100644
--- a/editor/create_dialog.h
+++ b/editor/create_dialog.h
@@ -41,6 +41,12 @@
class CreateDialog : public ConfirmationDialog {
GDCLASS(CreateDialog, ConfirmationDialog);
+ enum TypeCategory {
+ CPP_TYPE,
+ PATH_TYPE,
+ OTHER_TYPE
+ };
+
LineEdit *search_box;
Tree *search_options;
@@ -62,8 +68,8 @@ class CreateDialog : public ConfirmationDialog {
void _update_search();
bool _should_hide_type(const String &p_type) const;
- void _add_type(const String &p_current, bool p_cpp_type);
- void _configure_search_option_item(TreeItem *r_item, const String &p_type, const bool p_cpp_type);
+ void _add_type(const String &p_type, const TypeCategory p_type_category);
+ void _configure_search_option_item(TreeItem *r_item, const String &p_type, const TypeCategory p_type_category);
String _top_result(const Vector<String> p_candidates, const String &p_search_text) const;
float _score_type(const String &p_type, const String &p_search) const;
bool _is_type_preferred(const String &p_type) const;
@@ -95,6 +101,8 @@ class CreateDialog : public ConfirmationDialog {
bool _is_class_disabled_by_feature_profile(const StringName &p_class) const;
void _load_favorites_and_history();
+ void _update_theme();
+
protected:
void _notification(int p_what);
static void _bind_methods();
diff --git a/editor/debugger/editor_debugger_inspector.cpp b/editor/debugger/editor_debugger_inspector.cpp
index ddcd32c16f..38bdbe2870 100644
--- a/editor/debugger/editor_debugger_inspector.cpp
+++ b/editor/debugger/editor_debugger_inspector.cpp
@@ -262,11 +262,18 @@ void EditorDebuggerInspector::add_stack_variable(const Array &p_array) {
variables->prop_values[type + n] = v;
variables->update();
edit(variables);
+
+ // To prevent constantly resizing when using filtering.
+ int size_x = get_size().x;
+ if (size_x > get_custom_minimum_size().x) {
+ set_custom_minimum_size(Size2(size_x, 0));
+ }
}
void EditorDebuggerInspector::clear_stack_variables() {
variables->clear();
variables->update();
+ set_custom_minimum_size(Size2(0, 0));
}
String EditorDebuggerInspector::get_stack_variable(const String &p_var) {
diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp
index 5bc2be60a7..e9d275895f 100644
--- a/editor/debugger/editor_debugger_node.cpp
+++ b/editor/debugger/editor_debugger_node.cpp
@@ -95,6 +95,7 @@ ScriptEditorDebugger *EditorDebuggerNode::_add_debugger() {
node->connect("stopped", callable_mp(this, &EditorDebuggerNode::_debugger_stopped), varray(id));
node->connect("stack_frame_selected", callable_mp(this, &EditorDebuggerNode::_stack_frame_selected), varray(id));
node->connect("error_selected", callable_mp(this, &EditorDebuggerNode::_error_selected), varray(id));
+ node->connect("breakpoint_selected", callable_mp(this, &EditorDebuggerNode::_error_selected), varray(id));
node->connect("clear_execution", callable_mp(this, &EditorDebuggerNode::_clear_execution));
node->connect("breaked", callable_mp(this, &EditorDebuggerNode::_breaked), varray(id));
node->connect("remote_tree_updated", callable_mp(this, &EditorDebuggerNode::_remote_tree_updated), varray(id));
diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp
index b72a20ee2f..4349ffc75b 100644
--- a/editor/debugger/script_editor_debugger.cpp
+++ b/editor/debugger/script_editor_debugger.cpp
@@ -788,8 +788,10 @@ void ScriptEditorDebugger::_notification(int p_what) {
le_clear->connect("pressed", callable_mp(this, &ScriptEditorDebugger::_live_edit_clear));
error_tree->connect("item_selected", callable_mp(this, &ScriptEditorDebugger::_error_selected));
error_tree->connect("item_activated", callable_mp(this, &ScriptEditorDebugger::_error_activated));
+ breakpoints_tree->connect("item_activated", callable_mp(this, &ScriptEditorDebugger::_breakpoint_tree_clicked));
vmem_refresh->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")));
vmem_export->set_icon(get_theme_icon(SNAME("Save"), SNAME("EditorIcons")));
+ search->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
reason->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
@@ -864,6 +866,7 @@ void ScriptEditorDebugger::_notification(int p_what) {
docontinue->set_icon(get_theme_icon(SNAME("DebugContinue"), SNAME("EditorIcons")));
vmem_refresh->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")));
vmem_export->set_icon(get_theme_icon(SNAME("Save"), SNAME("EditorIcons")));
+ search->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
} break;
}
}
@@ -893,6 +896,13 @@ void ScriptEditorDebugger::_clear_breakpoints() {
emit_signal("clear_breakpoints");
}
+void ScriptEditorDebugger::_breakpoint_tree_clicked() {
+ TreeItem *selected = breakpoints_tree->get_selected();
+ if (selected->has_meta("line")) {
+ emit_signal(SNAME("breakpoint_selected"), selected->get_parent()->get_text(0), int(selected->get_meta("line")));
+ }
+}
+
void ScriptEditorDebugger::start(Ref<RemoteDebuggerPeer> p_peer) {
_clear_errors_list();
stop();
@@ -1351,6 +1361,45 @@ void ScriptEditorDebugger::set_breakpoint(const String &p_path, int p_line, bool
msg.push_back(p_line);
msg.push_back(p_enabled);
_put_msg("breakpoint", msg);
+
+ TreeItem *path_item = breakpoints_tree->search_item_text(p_path);
+ if (path_item == nullptr) {
+ if (!p_enabled) {
+ return;
+ }
+ path_item = breakpoints_tree->create_item();
+ path_item->set_text(0, p_path);
+ }
+
+ int idx = 0;
+ TreeItem *breakpoint_item;
+ for (breakpoint_item = path_item->get_first_child(); breakpoint_item; breakpoint_item = breakpoint_item->get_next()) {
+ if ((int)breakpoint_item->get_meta("line") < p_line) {
+ idx++;
+ continue;
+ }
+
+ if ((int)breakpoint_item->get_meta("line") == p_line) {
+ break;
+ }
+ }
+
+ if (breakpoint_item == nullptr) {
+ if (!p_enabled) {
+ return;
+ }
+ breakpoint_item = breakpoints_tree->create_item(path_item, idx);
+ breakpoint_item->set_meta("line", p_line);
+ breakpoint_item->set_text(0, vformat(TTR("Line %d"), p_line));
+ return;
+ }
+
+ if (!p_enabled) {
+ path_item->remove_child(breakpoint_item);
+ if (path_item->get_first_child() == nullptr) {
+ breakpoints_tree->get_root()->remove_child(path_item);
+ }
+ }
}
void ScriptEditorDebugger::reload_scripts() {
@@ -1417,6 +1466,23 @@ void ScriptEditorDebugger::_clear_errors_list() {
clear_button->set_disabled(true);
}
+void ScriptEditorDebugger::_breakpoints_item_rmb_selected(const Vector2 &p_pos) {
+ breakpoints_menu->clear();
+ breakpoints_menu->set_size(Size2(1, 1));
+
+ const TreeItem *selected = breakpoints_tree->get_selected();
+ String file = selected->get_text(0);
+ if (selected->has_meta("line")) {
+ breakpoints_menu->add_icon_item(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TTR("Delete Breakpoint"), ACTION_DELETE_BREAKPOINT);
+ file = selected->get_parent()->get_text(0);
+ }
+ breakpoints_menu->add_icon_item(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TTR("Delete All Breakpoints in: ") + file, ACTION_DELETE_BREAKPOINTS_IN_FILE);
+ breakpoints_menu->add_icon_item(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TTR("Delete All Breakpoints"), ACTION_DELETE_ALL_BREAKPOINTS);
+
+ breakpoints_menu->set_position(breakpoints_tree->get_global_position() + p_pos);
+ breakpoints_menu->popup();
+}
+
// Right click on specific file(s) or folder(s).
void ScriptEditorDebugger::_error_tree_item_rmb_selected(const Vector2 &p_pos) {
item_menu->clear();
@@ -1491,6 +1557,29 @@ void ScriptEditorDebugger::_item_menu_id_pressed(int p_option) {
line_number));
}
} break;
+ case ACTION_DELETE_BREAKPOINT: {
+ const TreeItem *selected = breakpoints_tree->get_selected();
+ _set_breakpoint(selected->get_parent()->get_text(0), selected->get_meta("line"), false);
+ } break;
+ case ACTION_DELETE_BREAKPOINTS_IN_FILE: {
+ TreeItem *file_item = breakpoints_tree->get_selected();
+ if (file_item->has_meta("line")) {
+ file_item = file_item->get_parent();
+ }
+
+ // Store first else we will be removing as we loop.
+ List<int> lines;
+ for (TreeItem *breakpoint_item = file_item->get_first_child(); breakpoint_item; breakpoint_item = breakpoint_item->get_next()) {
+ lines.push_back(breakpoint_item->get_meta("line"));
+ }
+
+ for (const int &line : lines) {
+ _set_breakpoint(file_item->get_text(0), line, false);
+ }
+ } break;
+ case ACTION_DELETE_ALL_BREAKPOINTS: {
+ _clear_breakpoints();
+ } break;
}
}
@@ -1517,6 +1606,7 @@ void ScriptEditorDebugger::_bind_methods() {
ADD_SIGNAL(MethodInfo("stop_requested"));
ADD_SIGNAL(MethodInfo("stack_frame_selected", PropertyInfo(Variant::INT, "frame")));
ADD_SIGNAL(MethodInfo("error_selected", PropertyInfo(Variant::INT, "error")));
+ ADD_SIGNAL(MethodInfo("breakpoint_selected", PropertyInfo("script"), PropertyInfo(Variant::INT, "line")));
ADD_SIGNAL(MethodInfo("set_execution", PropertyInfo("script"), PropertyInfo(Variant::INT, "line")));
ADD_SIGNAL(MethodInfo("clear_execution", PropertyInfo("script")));
ADD_SIGNAL(MethodInfo("breaked", PropertyInfo(Variant::BOOL, "reallydid"), PropertyInfo(Variant::BOOL, "can_debug"), PropertyInfo(Variant::STRING, "reason"), PropertyInfo(Variant::BOOL, "has_stackdump")));
@@ -1644,9 +1734,15 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
docontinue->set_shortcut(ED_GET_SHORTCUT("debugger/continue"));
docontinue->connect("pressed", callable_mp(this, &ScriptEditorDebugger::debug_continue));
+ HSplitContainer *parent_sc = memnew(HSplitContainer);
+ vbc->add_child(parent_sc);
+ parent_sc->set_v_size_flags(SIZE_EXPAND_FILL);
+ parent_sc->set_split_offset(500 * EDSCALE);
+
HSplitContainer *sc = memnew(HSplitContainer);
- vbc->add_child(sc);
sc->set_v_size_flags(SIZE_EXPAND_FILL);
+ sc->set_h_size_flags(SIZE_EXPAND_FILL);
+ parent_sc->add_child(sc);
stack_dump = memnew(Tree);
stack_dump->set_allow_reselect(true);
@@ -1658,15 +1754,47 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
stack_dump->connect("cell_selected", callable_mp(this, &ScriptEditorDebugger::_stack_dump_frame_selected));
sc->add_child(stack_dump);
+ VBoxContainer *inspector_vbox = memnew(VBoxContainer);
+ inspector_vbox->set_h_size_flags(SIZE_EXPAND_FILL);
+ sc->add_child(inspector_vbox);
+
+ HBoxContainer *tools_hb = memnew(HBoxContainer);
+ inspector_vbox->add_child(tools_hb);
+
+ search = memnew(LineEdit);
+ search->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ search->set_placeholder(TTR("Filter stack variables"));
+ search->set_clear_button_enabled(true);
+ tools_hb->add_child(search);
+
inspector = memnew(EditorDebuggerInspector);
inspector->set_h_size_flags(SIZE_EXPAND_FILL);
+ inspector->set_v_size_flags(SIZE_EXPAND_FILL);
inspector->set_enable_capitalize_paths(false);
inspector->set_read_only(true);
inspector->connect("object_selected", callable_mp(this, &ScriptEditorDebugger::_remote_object_selected));
inspector->connect("object_edited", callable_mp(this, &ScriptEditorDebugger::_remote_object_edited));
inspector->connect("object_property_updated", callable_mp(this, &ScriptEditorDebugger::_remote_object_property_updated));
- sc->add_child(inspector);
+ inspector->register_text_enter(search);
+ inspector->set_use_filter(true);
+ inspector_vbox->add_child(inspector);
+
+ breakpoints_tree = memnew(Tree);
+ breakpoints_tree->set_h_size_flags(SIZE_EXPAND_FILL);
+ breakpoints_tree->set_column_titles_visible(true);
+ breakpoints_tree->set_column_title(0, TTR("Breakpoints"));
+ breakpoints_tree->set_allow_reselect(true);
+ breakpoints_tree->set_allow_rmb_select(true);
+ breakpoints_tree->set_hide_root(true);
+ breakpoints_tree->connect("item_rmb_selected", callable_mp(this, &ScriptEditorDebugger::_breakpoints_item_rmb_selected));
+ breakpoints_tree->create_item();
+
+ parent_sc->add_child(breakpoints_tree);
tabs->add_child(dbg);
+
+ breakpoints_menu = memnew(PopupMenu);
+ breakpoints_menu->connect("id_pressed", callable_mp(this, &ScriptEditorDebugger::_item_menu_id_pressed));
+ breakpoints_tree->add_child(breakpoints_menu);
}
{ //errors
diff --git a/editor/debugger/script_editor_debugger.h b/editor/debugger/script_editor_debugger.h
index ff1a852f26..c061e7c61e 100644
--- a/editor/debugger/script_editor_debugger.h
+++ b/editor/debugger/script_editor_debugger.h
@@ -81,6 +81,9 @@ private:
enum Actions {
ACTION_COPY_ERROR,
ACTION_OPEN_SOURCE,
+ ACTION_DELETE_BREAKPOINT,
+ ACTION_DELETE_BREAKPOINTS_IN_FILE,
+ ACTION_DELETE_ALL_BREAKPOINTS,
};
AcceptDialog *msgdialog;
@@ -99,6 +102,9 @@ private:
Button *clear_button;
PopupMenu *item_menu;
+ Tree *breakpoints_tree;
+ PopupMenu *breakpoints_menu;
+
EditorFileDialog *file_dialog;
enum FileDialogPurpose {
SAVE_MONITORS_CSV,
@@ -134,6 +140,7 @@ private:
LineEdit *vmem_total;
Tree *stack_dump;
+ LineEdit *search = nullptr;
EditorDebuggerInspector *inspector;
SceneDebuggerTree *scene_tree;
@@ -197,6 +204,7 @@ private:
void _clear_errors_list();
+ void _breakpoints_item_rmb_selected(const Vector2 &p_pos);
void _error_tree_item_rmb_selected(const Vector2 &p_pos);
void _item_menu_id_pressed(int p_option);
void _tab_changed(int p_tab);
@@ -210,6 +218,8 @@ private:
void _set_breakpoint(const String &p_path, const int &p_line, const bool &p_enabled);
void _clear_breakpoints();
+ void _breakpoint_tree_clicked();
+
protected:
void _notification(int p_what);
static void _bind_methods();
diff --git a/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp
index 1de67149c6..5d4c746785 100644
--- a/editor/editor_asset_installer.cpp
+++ b/editor/editor_asset_installer.cpp
@@ -140,7 +140,6 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) {
extension_guess["jpeg"] = tree->get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons"));
extension_guess["png"] = tree->get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons"));
extension_guess["svg"] = tree->get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons"));
- extension_guess["svgz"] = tree->get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons"));
extension_guess["tga"] = tree->get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons"));
extension_guess["webp"] = tree->get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons"));
diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp
index 0829b9d24f..8e4bbbb99b 100644
--- a/editor/editor_audio_buses.cpp
+++ b/editor/editor_audio_buses.cpp
@@ -324,7 +324,7 @@ float EditorAudioBus::_normalized_volume_to_scaled_db(float normalized) {
/* There are three different formulas for the conversion from normalized
* values to relative decibal values.
* One formula is an exponential graph which intends to counteract
- * the logorithmic nature of human hearing. This is an approximation
+ * the logarithmic nature of human hearing. This is an approximation
* of the behaviour of a 'logarithmic potentiometer' found on most
* musical instruments and also emulated in popular software.
* The other two equations are hand-tuned linear tapers that intend to
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index 014e27ae15..f97973ce5d 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -1501,36 +1501,12 @@ void EditorExport::add_export_preset(const Ref<EditorExportPreset> &p_preset, in
}
String EditorExportPlatform::test_etc2() const {
- // String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name");
- // bool etc_supported = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc");
- // bool etc2_supported = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc2");
- String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name");
- bool etc_supported = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc");
- bool etc2_supported = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc2");
-
- if (driver == "opengl3" && !etc_supported) {
- return TTR("Target platform requires 'ETC' texture compression for OpenGL. Enable 'Import Etc' in Project Settings.");
- } else if (driver == "vulkan" && !etc2_supported) {
- // FIXME: Review if this is true for Vulkan.
- return TTR("Target platform requires 'ETC2' texture compression for Vulkan. Enable 'Import Etc 2' in Project Settings.");
- }
- return String();
-}
+ const bool etc2_supported = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc2");
-String EditorExportPlatform::test_etc2_or_pvrtc() const {
- String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name");
- bool etc2_supported = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc2");
- bool pvrtc_supported = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_pvrtc");
- // String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name");
- // bool etc2_supported = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc2");
- // bool pvrtc_supported = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_pvrtc");
-
- if (driver == "opengl3" && !pvrtc_supported) {
- return TTR("Target platform requires 'PVRTC' texture compression for OpenGL. Enable 'Import Pvrtc' in Project Settings.");
- } else if (driver == "vulkan" && !etc2_supported && !pvrtc_supported) {
- // FIXME: Review if this is true for Vulkan.
- return TTR("Target platform requires 'ETC2' or 'PVRTC' texture compression for Vulkan. Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings.");
+ if (!etc2_supported) {
+ return TTR("Target platform requires 'ETC2' texture compression. Enable 'Import Etc 2' in Project Settings.");
}
+
return String();
}
diff --git a/editor/editor_export.h b/editor/editor_export.h
index 3d46ae1996..796fb12793 100644
--- a/editor/editor_export.h
+++ b/editor/editor_export.h
@@ -269,8 +269,7 @@ public:
virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) { return OK; }
virtual Ref<Texture2D> get_run_icon() const { return get_logo(); }
- String test_etc2() const; //generic test for etc2 since most platforms use it
- String test_etc2_or_pvrtc() const; // test for etc2 or pvrtc support for iOS
+ String test_etc2() const;
virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const = 0;
virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const = 0;
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index dee00b6678..33c6c77e53 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -52,6 +52,15 @@ EditorFileDialog::RegisterFunc EditorFileDialog::unregister_func = nullptr;
void EditorFileDialog::popup_file_dialog() {
popup_centered_clamped(Size2(1050, 700) * EDSCALE, 0.8);
+ _focus_file_text();
+}
+
+void EditorFileDialog::_focus_file_text() {
+ int lp = file->get_text().rfind(".");
+ if (lp != -1) {
+ file->select(0, lp);
+ file->grab_focus();
+ }
}
VBoxContainer *EditorFileDialog::get_vbox() {
@@ -121,6 +130,18 @@ void EditorFileDialog::_notification(int p_what) {
if (!is_visible()) {
set_process_unhandled_input(false);
}
+ } else if (p_what == NOTIFICATION_WM_WINDOW_FOCUS_IN) {
+ // Check if the current directory was removed externally (much less likely to happen while editor window is focused).
+ String previous_dir = get_current_dir();
+ while (!dir_access->dir_exists(get_current_dir())) {
+ _go_up();
+
+ // In case we can't go further up, use some fallback and break.
+ if (get_current_dir() == previous_dir) {
+ _dir_submitted(OS::get_singleton()->get_user_data_dir());
+ break;
+ }
+ }
}
}
@@ -974,11 +995,7 @@ void EditorFileDialog::set_current_file(const String &p_file) {
file->set_text(p_file);
update_dir();
invalidate();
- int lp = p_file.rfind(".");
- if (lp != -1) {
- file->select(0, lp);
- file->grab_focus();
- }
+ _focus_file_text();
if (is_visible()) {
_request_single_thumbnail(get_current_dir().plus_file(get_current_file()));
@@ -1301,7 +1318,7 @@ void EditorFileDialog::_recent_selected(int p_idx) {
}
void EditorFileDialog::_go_up() {
- dir_access->change_dir("..");
+ dir_access->change_dir(get_current_dir().get_base_dir());
update_file_list();
update_dir();
_push_history();
diff --git a/editor/editor_file_dialog.h b/editor/editor_file_dialog.h
index b7abfe0836..16077cbfb9 100644
--- a/editor/editor_file_dialog.h
+++ b/editor/editor_file_dialog.h
@@ -149,6 +149,8 @@ private:
void update_file_list();
void update_filters();
+ void _focus_file_text();
+
void _update_favorites();
void _favorite_pressed();
void _favorite_selected(int p_idx);
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index a0673c8fb7..5beed352a6 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -1604,6 +1604,10 @@ void EditorFileSystem::update_file(const String &p_file) {
_queue_update_script_classes();
}
+Set<String> EditorFileSystem::get_valid_extensions() const {
+ return valid_extensions;
+}
+
Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector<String> &p_files) {
String importer_name;
@@ -1644,7 +1648,7 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector
config->get_section_keys("params", &sk);
for (const String &param : sk) {
Variant value = config->get_value("params", param);
- //override with whathever is in file
+ //override with whatever is in file
source_file_options[p_files[i]][param] = value;
}
}
diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h
index ecc71e7d42..0c1bfbca47 100644
--- a/editor/editor_file_system.h
+++ b/editor/editor_file_system.h
@@ -272,6 +272,7 @@ public:
void scan();
void scan_changes();
void update_file(const String &p_file);
+ Set<String> get_valid_extensions() const;
EditorFileSystemDirectory *get_filesystem_path(const String &p_path);
String get_file_type(const String &p_file) const;
diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp
index 04bfcfac95..db4de3bed0 100644
--- a/editor/editor_log.cpp
+++ b/editor/editor_log.cpp
@@ -84,6 +84,7 @@ void EditorLog::_update_theme() {
copy_button->set_icon(get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")));
collapse_button->set_icon(get_theme_icon(SNAME("CombineLines"), SNAME("EditorIcons")));
show_search_button->set_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
}
void EditorLog::_notification(int p_what) {
@@ -348,7 +349,6 @@ EditorLog::EditorLog() {
search_box = memnew(LineEdit);
search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
search_box->set_placeholder(TTR("Filter messages"));
- search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
search_box->set_clear_button_enabled(true);
search_box->set_visible(true);
search_box->connect("text_changed", callable_mp(this, &EditorLog::_search_changed));
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index a8cb2e791c..5d868777e7 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -2861,11 +2861,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
DisplayServer::get_singleton()->window_set_mode(DisplayServer::get_singleton()->window_get_mode() == DisplayServer::WINDOW_MODE_FULLSCREEN ? DisplayServer::WINDOW_MODE_WINDOWED : DisplayServer::WINDOW_MODE_FULLSCREEN);
} break;
- case SETTINGS_TOGGLE_CONSOLE: {
- bool was_visible = DisplayServer::get_singleton()->is_console_visible();
- DisplayServer::get_singleton()->console_set_visible(!was_visible);
- EditorSettings::get_singleton()->set_setting("interface/editor/hide_console_window", was_visible);
- } break;
case EDITOR_SCREENSHOT: {
screenshot_timer->start();
} break;
@@ -6039,8 +6034,10 @@ EditorNode::EditorNode() {
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/inspector/default_color_picker_shape", PROPERTY_HINT_ENUM, "HSV Rectangle,HSV Rectangle Wheel,VHS Circle", PROPERTY_USAGE_DEFAULT));
EDITOR_DEF("run/auto_save/save_before_running", true);
EDITOR_DEF("interface/editors/sub_editor_panning_scheme", 0);
+ EDITOR_DEF("interface/editors/animation_editors_panning_scheme", 1);
// Should be in sync with ControlScheme in ViewPanner.
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/editors/sub_editor_panning_scheme", PROPERTY_HINT_ENUM, "Scroll Zooms,Scroll Pans", PROPERTY_USAGE_DEFAULT));
+ EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/editors/animation_editors_panning_scheme", PROPERTY_HINT_ENUM, "Scroll Zooms,Scroll Pans", PROPERTY_USAGE_DEFAULT));
const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false);
for (const String &E : textfile_ext) {
@@ -6512,11 +6509,6 @@ EditorNode::EditorNode() {
ED_SHORTCUT_OVERRIDE("editor/fullscreen_mode", "macos", KeyModifierMask::CMD | KeyModifierMask::CTRL | Key::F);
p->add_shortcut(ED_GET_SHORTCUT("editor/fullscreen_mode"), SETTINGS_TOGGLE_FULLSCREEN);
-#if defined(WINDOWS_ENABLED) && defined(WINDOWS_SUBSYSTEM_CONSOLE)
- // The console can only be toggled if the application was built for the console subsystem,
- // not the GUI subsystem.
- p->add_item(TTR("Toggle System Console"), SETTINGS_TOGGLE_CONSOLE);
-#endif
p->add_separator();
if (OS::get_singleton()->get_data_path() == OS::get_singleton()->get_config_path()) {
diff --git a/editor/editor_node.h b/editor/editor_node.h
index af7223ffb4..e315f1f4b3 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -188,7 +188,6 @@ private:
SETTINGS_MANAGE_FEATURE_PROFILES,
SETTINGS_INSTALL_ANDROID_BUILD_TEMPLATE,
SETTINGS_PICK_MAIN_SCENE,
- SETTINGS_TOGGLE_CONSOLE,
SETTINGS_TOGGLE_FULLSCREEN,
SETTINGS_HELP,
SCENE_TAB_CLOSE,
diff --git a/editor/editor_paths.cpp b/editor/editor_paths.cpp
index a4481cd1eb..d4e40db406 100644
--- a/editor/editor_paths.cpp
+++ b/editor/editor_paths.cpp
@@ -91,6 +91,11 @@ EditorPaths::EditorPaths() {
// Self-contained mode if a `._sc_` or `_sc_` file is present in executable dir.
String exe_path = OS::get_singleton()->get_executable_path().get_base_dir();
+
+ // On macOS, look outside .app bundle, since .app bundle is read-only.
+ if (OS::get_singleton()->has_feature("macos") && exe_path.ends_with("MacOS") && exe_path.plus_file("..").simplify_path().ends_with("Contents")) {
+ exe_path = exe_path.plus_file("../../..").simplify_path();
+ }
{
DirAccessRef d = DirAccess::create_for_path(exe_path);
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index bb0a2ed7c1..b662eb8b1c 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -428,7 +428,6 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("interface/editor/separate_distraction_mode", false);
_initial_set("interface/editor/automatically_open_screenshots", true);
EDITOR_SETTING_USAGE(Variant::BOOL, PROPERTY_HINT_NONE, "interface/editor/single_window_mode", false, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)
- _initial_set("interface/editor/hide_console_window", false);
_initial_set("interface/editor/mouse_extra_buttons_navigate_history", true);
_initial_set("interface/editor/save_each_scene_on_quit", true); // Regression
#ifdef DEV_ENABLED
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index a8a1dc37ab..5b7ea65b04 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -30,7 +30,9 @@
#include "editor_themes.h"
+#include "core/error/error_macros.h"
#include "core/io/resource_loader.h"
+#include "core/variant/dictionary.h"
#include "editor_fonts.h"
#include "editor_icons.gen.h"
#include "editor_scale.h"
@@ -95,6 +97,7 @@ static Ref<Texture2D> flip_icon(Ref<Texture2D> p_texture, bool p_flip_y = false,
Ref<ImageTexture> texture(memnew(ImageTexture));
Ref<Image> img = p_texture->get_image();
+ ERR_FAIL_NULL_V(img, Ref<Texture2D>());
img = img->duplicate();
if (p_flip_y) {
@@ -109,7 +112,7 @@ static Ref<Texture2D> flip_icon(Ref<Texture2D> p_texture, bool p_flip_y = false,
}
#ifdef MODULE_SVG_ENABLED
-static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, float p_scale = EDSCALE, float p_saturation = 1.0) {
+static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, float p_scale = EDSCALE, float p_saturation = 1.0, Dictionary p_convert_colors = Dictionary()) {
Ref<ImageTexture> icon = memnew(ImageTexture);
Ref<Image> img = memnew(Image);
@@ -117,8 +120,9 @@ static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color,
// Generating upsampled icons is slower, and the benefit is hardly visible
// with integer editor scales.
const bool upsample = !Math::is_equal_approx(Math::round(p_scale), p_scale);
- ImageLoaderSVG::create_image_from_string(img, editor_icons_sources[p_index], p_scale, upsample, p_convert_color);
-
+ ImageLoaderSVG img_loader;
+ img_loader.set_replace_colors(p_convert_colors);
+ img_loader.create_image_from_string(img, editor_icons_sources[p_index], p_scale, upsample, p_convert_color);
if (p_saturation != 1.0) {
img->adjust_bcs(1.0, 1.0, p_saturation);
}
@@ -135,8 +139,10 @@ static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color,
void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = true, int p_thumb_size = 32, bool p_only_thumbs = false, float p_icon_saturation = 1.0) {
#ifdef MODULE_SVG_ENABLED
// The default icon theme is designed to be used for a dark theme.
- // This dictionary stores color codes to convert to other colors
+ // This dictionary stores Color values to convert to other colors
// for better readability on a light theme.
+ // Godot Color values are used to avoid the ambiguity of strings
+ // (where "#ffffff", "fff", and "white" are all equivalent).
Dictionary dark_icon_color_dictionary;
// The names of the icons to never convert, even if one of their colors
@@ -243,8 +249,6 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
dark_icon_color_dictionary[Color::html("#45ff8b")] = success_color;
dark_icon_color_dictionary[Color::html("#dbab09")] = warning_color;
- ImageLoaderSVG::set_convert_colors(&dark_icon_color_dictionary);
-
// Generate icons.
if (!p_only_thumbs) {
for (int i = 0; i < editor_icons_count; i++) {
@@ -255,7 +259,7 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
}
const int is_exception = exceptions.has(editor_icons_names[i]);
- const Ref<ImageTexture> icon = editor_generate_icon(i, !is_exception, EDSCALE, saturation);
+ const Ref<ImageTexture> icon = editor_generate_icon(i, !is_exception, EDSCALE, saturation, dark_icon_color_dictionary);
p_theme->set_icon(editor_icons_names[i], "EditorIcons", icon);
}
@@ -269,7 +273,7 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
for (int i = 0; i < editor_bg_thumbs_count; i++) {
const int index = editor_bg_thumbs_indices[i];
const int is_exception = exceptions.has(editor_icons_names[index]);
- const Ref<ImageTexture> icon = editor_generate_icon(index, !p_dark_theme && !is_exception, scale, force_filter);
+ const Ref<ImageTexture> icon = editor_generate_icon(index, !p_dark_theme && !is_exception, scale, force_filter, dark_icon_color_dictionary);
p_theme->set_icon(editor_icons_names[index], "EditorIcons", icon);
}
@@ -278,13 +282,11 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
for (int i = 0; i < editor_md_thumbs_count; i++) {
const int index = editor_md_thumbs_indices[i];
const bool is_exception = exceptions.has(editor_icons_names[index]);
- const Ref<ImageTexture> icon = editor_generate_icon(index, !p_dark_theme && !is_exception, scale, force_filter);
+ const Ref<ImageTexture> icon = editor_generate_icon(index, !p_dark_theme && !is_exception, scale, force_filter, dark_icon_color_dictionary);
p_theme->set_icon(editor_icons_names[index], "EditorIcons", icon);
}
}
-
- ImageLoaderSVG::set_convert_colors(nullptr);
#else
WARN_PRINT("SVG support disabled, editor icons won't be rendered.");
#endif
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index 0253307d5a..d71861e72d 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -1472,12 +1472,18 @@ void FileSystemDock::_folder_removed(String p_folder) {
void FileSystemDock::_rename_operation_confirm() {
String new_name = rename_dialog_text->get_text().strip_edges();
+ String old_name = tree->get_selected()->get_text(0);
if (new_name.length() == 0) {
EditorNode::get_singleton()->show_warning(TTR("No name provided."));
return;
} else if (new_name.find("/") != -1 || new_name.find("\\") != -1 || new_name.find(":") != -1) {
EditorNode::get_singleton()->show_warning(TTR("Name contains invalid characters."));
return;
+ } else if (to_rename.is_file && old_name.get_extension() != new_name.get_extension()) {
+ if (!EditorFileSystem::get_singleton()->get_valid_extensions().find(new_name.get_extension())) {
+ EditorNode::get_singleton()->show_warning(TTR("This file extension is not recognized by the editor.\nIf you want to rename it anyway, use your operating system's file manager.\nAfter renaming to an unknown extension, the file won't be shown in the editor anymore."));
+ return;
+ }
}
String old_path = to_rename.path.ends_with("/") ? to_rename.path.substr(0, to_rename.path.length() - 1) : to_rename.path;
diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp
index c65d4e9e3b..ff24339f9f 100644
--- a/editor/groups_editor.cpp
+++ b/editor/groups_editor.cpp
@@ -370,7 +370,8 @@ void GroupDialog::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_TRANSLATION_CHANGED:
case Control::NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
- case NOTIFICATION_ENTER_TREE: {
+ case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_THEME_CHANGED: {
if (is_layout_rtl()) {
add_button->set_icon(groups->get_theme_icon(SNAME("Back"), SNAME("EditorIcons")));
remove_button->set_icon(groups->get_theme_icon(SNAME("Forward"), SNAME("EditorIcons")));
diff --git a/editor/icons/SnapGrid.svg b/editor/icons/SnapGrid.svg
index e3aea78162..6960d4d13d 100644
--- a/editor/icons/SnapGrid.svg
+++ b/editor/icons/SnapGrid.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 0v3h-3v2h3v4h-3v2h3v3h2v-9h9v-2h-3v-3h-2v3h-4v-3zm4 13v2h2v-2zm6 0v2h2v-2z" fill="#e0e0e0"/><path d="m11 7a4 4 0 0 0 -4 4v2h2v-2a2 2 0 0 1 2-2 2 2 0 0 1 2 2v2h2v-2a4 4 0 0 0 -4-4z" fill="#fff" fill-opacity=".68627"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 0v2h-2v1h2v4h-2v1h2v4h-2v1h2v2h1v-2h3v-1h-3v-4h4l1-1v-4h4v3h1v-3h2v-1h-2v-2h-1v2h-4v-2h-1v2h-4v-2zm1 3h4v4h-4zm4 10v2h2v-2zm6 0v2h2v-2z" fill="#e0e0e0"/><path d="m11 7a4 4 0 0 0 -4 4v2h2v-2a2 2 0 0 1 2-2 2 2 0 0 1 2 2v2h2v-2a4 4 0 0 0 -4-4z" fill="#fff" fill-opacity=".68627"/></svg>
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index 22b2bd1ed4..c1ae5be0bb 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -471,7 +471,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ImporterMesh> &p
bool local_xform_mirror = p_local_xform.basis.determinant() < 0;
if (p_morph_data) {
- //add morphie target
+ //add morph target
ERR_FAIL_COND_V(!p_morph_data->targets.has("MORPH_TARGET"), ERR_INVALID_DATA);
String mt = p_morph_data->targets["MORPH_TARGET"];
ERR_FAIL_COND_V(!p_morph_data->sources.has(mt), ERR_INVALID_DATA);
diff --git a/editor/import/resource_importer_bmfont.cpp b/editor/import/resource_importer_bmfont.cpp
index fa560e8eb1..8a655fbc0c 100644
--- a/editor/import/resource_importer_bmfont.cpp
+++ b/editor/import/resource_importer_bmfont.cpp
@@ -30,7 +30,6 @@
#include "resource_importer_bmfont.h"
-#include "core/io/image_loader.h"
#include "core/io/resource_saver.h"
String ResourceImporterBMFont::get_importer_name() const {
@@ -64,749 +63,14 @@ void ResourceImporterBMFont::get_import_options(const String &p_path, List<Impor
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress"), true));
}
-void _convert_packed_8bit(Ref<FontData> &r_font, Ref<Image> &p_source, int p_page, int p_sz) {
- int w = p_source->get_width();
- int h = p_source->get_height();
-
- PackedByteArray imgdata = p_source->get_data();
- const uint8_t *r = imgdata.ptr();
-
- PackedByteArray imgdata_r;
- imgdata_r.resize(w * h * 2);
- uint8_t *wr = imgdata_r.ptrw();
-
- PackedByteArray imgdata_g;
- imgdata_g.resize(w * h * 2);
- uint8_t *wg = imgdata_g.ptrw();
-
- PackedByteArray imgdata_b;
- imgdata_b.resize(w * h * 2);
- uint8_t *wb = imgdata_b.ptrw();
-
- PackedByteArray imgdata_a;
- imgdata_a.resize(w * h * 2);
- uint8_t *wa = imgdata_a.ptrw();
-
- for (int i = 0; i < h; i++) {
- for (int j = 0; j < w; j++) {
- int ofs_src = (i * w + j) * 4;
- int ofs_dst = (i * w + j) * 2;
- wr[ofs_dst + 0] = 255;
- wr[ofs_dst + 1] = r[ofs_src + 0];
- wg[ofs_dst + 0] = 255;
- wg[ofs_dst + 1] = r[ofs_src + 1];
- wb[ofs_dst + 0] = 255;
- wb[ofs_dst + 1] = r[ofs_src + 2];
- wa[ofs_dst + 0] = 255;
- wa[ofs_dst + 1] = r[ofs_src + 3];
- }
- }
- Ref<Image> img_r = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_r));
- r_font->set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 0, img_r);
- Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g));
- r_font->set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 1, img_g);
- Ref<Image> img_b = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_b));
- r_font->set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 2, img_b);
- Ref<Image> img_a = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_a));
- r_font->set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 3, img_a);
-}
-
-void _convert_packed_4bit(Ref<FontData> &r_font, Ref<Image> &p_source, int p_page, int p_sz) {
- int w = p_source->get_width();
- int h = p_source->get_height();
-
- PackedByteArray imgdata = p_source->get_data();
- const uint8_t *r = imgdata.ptr();
-
- PackedByteArray imgdata_r;
- imgdata_r.resize(w * h * 2);
- uint8_t *wr = imgdata_r.ptrw();
-
- PackedByteArray imgdata_g;
- imgdata_g.resize(w * h * 2);
- uint8_t *wg = imgdata_g.ptrw();
-
- PackedByteArray imgdata_b;
- imgdata_b.resize(w * h * 2);
- uint8_t *wb = imgdata_b.ptrw();
-
- PackedByteArray imgdata_a;
- imgdata_a.resize(w * h * 2);
- uint8_t *wa = imgdata_a.ptrw();
-
- PackedByteArray imgdata_ro;
- imgdata_ro.resize(w * h * 2);
- uint8_t *wro = imgdata_ro.ptrw();
-
- PackedByteArray imgdata_go;
- imgdata_go.resize(w * h * 2);
- uint8_t *wgo = imgdata_go.ptrw();
-
- PackedByteArray imgdata_bo;
- imgdata_bo.resize(w * h * 2);
- uint8_t *wbo = imgdata_bo.ptrw();
-
- PackedByteArray imgdata_ao;
- imgdata_ao.resize(w * h * 2);
- uint8_t *wao = imgdata_ao.ptrw();
-
- for (int i = 0; i < h; i++) {
- for (int j = 0; j < w; j++) {
- int ofs_src = (i * w + j) * 4;
- int ofs_dst = (i * w + j) * 2;
- wr[ofs_dst + 0] = 255;
- wro[ofs_dst + 0] = 255;
- if (r[ofs_src + 0] > 0x0F) {
- wr[ofs_dst + 1] = (r[ofs_src + 0] - 0x0F) * 2;
- wro[ofs_dst + 1] = 0;
- } else {
- wr[ofs_dst + 1] = 0;
- wro[ofs_dst + 1] = r[ofs_src + 0] * 2;
- }
- wg[ofs_dst + 0] = 255;
- wgo[ofs_dst + 0] = 255;
- if (r[ofs_src + 1] > 0x0F) {
- wg[ofs_dst + 1] = (r[ofs_src + 1] - 0x0F) * 2;
- wgo[ofs_dst + 1] = 0;
- } else {
- wg[ofs_dst + 1] = 0;
- wgo[ofs_dst + 1] = r[ofs_src + 1] * 2;
- }
- wb[ofs_dst + 0] = 255;
- wbo[ofs_dst + 0] = 255;
- if (r[ofs_src + 2] > 0x0F) {
- wb[ofs_dst + 1] = (r[ofs_src + 2] - 0x0F) * 2;
- wbo[ofs_dst + 1] = 0;
- } else {
- wb[ofs_dst + 1] = 0;
- wbo[ofs_dst + 1] = r[ofs_src + 2] * 2;
- }
- wa[ofs_dst + 0] = 255;
- wao[ofs_dst + 0] = 255;
- if (r[ofs_src + 3] > 0x0F) {
- wa[ofs_dst + 1] = (r[ofs_src + 3] - 0x0F) * 2;
- wao[ofs_dst + 1] = 0;
- } else {
- wa[ofs_dst + 1] = 0;
- wao[ofs_dst + 1] = r[ofs_src + 3] * 2;
- }
- }
- }
- Ref<Image> img_r = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_r));
- r_font->set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 0, img_r);
- Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g));
- r_font->set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 1, img_g);
- Ref<Image> img_b = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_b));
- r_font->set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 2, img_b);
- Ref<Image> img_a = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_a));
- r_font->set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 3, img_a);
-
- Ref<Image> img_ro = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_ro));
- r_font->set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 0, img_ro);
- Ref<Image> img_go = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_go));
- r_font->set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 1, img_go);
- Ref<Image> img_bo = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_bo));
- r_font->set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 2, img_bo);
- Ref<Image> img_ao = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_ao));
- r_font->set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 3, img_ao);
-}
-
-void _convert_rgba_4bit(Ref<FontData> &r_font, Ref<Image> &p_source, int p_page, int p_sz) {
- int w = p_source->get_width();
- int h = p_source->get_height();
-
- PackedByteArray imgdata = p_source->get_data();
- const uint8_t *r = imgdata.ptr();
-
- PackedByteArray imgdata_g;
- imgdata_g.resize(w * h * 4);
- uint8_t *wg = imgdata_g.ptrw();
-
- PackedByteArray imgdata_o;
- imgdata_o.resize(w * h * 4);
- uint8_t *wo = imgdata_o.ptrw();
-
- for (int i = 0; i < h; i++) {
- for (int j = 0; j < w; j++) {
- int ofs = (i * w + j) * 4;
-
- if (r[ofs + 0] > 0x7F) {
- wg[ofs + 0] = r[ofs + 0];
- wo[ofs + 0] = 0;
- } else {
- wg[ofs + 0] = 0;
- wo[ofs + 0] = r[ofs + 0] * 2;
- }
- if (r[ofs + 1] > 0x7F) {
- wg[ofs + 1] = r[ofs + 1];
- wo[ofs + 1] = 0;
- } else {
- wg[ofs + 1] = 0;
- wo[ofs + 1] = r[ofs + 1] * 2;
- }
- if (r[ofs + 2] > 0x7F) {
- wg[ofs + 2] = r[ofs + 2];
- wo[ofs + 2] = 0;
- } else {
- wg[ofs + 2] = 0;
- wo[ofs + 2] = r[ofs + 2] * 2;
- }
- if (r[ofs + 3] > 0x7F) {
- wg[ofs + 3] = r[ofs + 3];
- wo[ofs + 3] = 0;
- } else {
- wg[ofs + 3] = 0;
- wo[ofs + 3] = r[ofs + 3] * 2;
- }
- }
- }
- Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_RGBA8, imgdata_g));
- r_font->set_texture_image(0, Vector2i(p_sz, 0), p_page, img_g);
-
- Ref<Image> img_o = memnew(Image(w, h, 0, Image::FORMAT_RGBA8, imgdata_o));
- r_font->set_texture_image(0, Vector2i(p_sz, 1), p_page, img_o);
-}
-
-void _convert_mono_8bit(Ref<FontData> &r_font, Ref<Image> &p_source, int p_page, int p_ch, int p_sz, int p_ol) {
- int w = p_source->get_width();
- int h = p_source->get_height();
-
- PackedByteArray imgdata = p_source->get_data();
- const uint8_t *r = imgdata.ptr();
-
- int size = 4;
- if (p_source->get_format() == Image::FORMAT_L8) {
- size = 1;
- p_ch = 0;
- }
-
- PackedByteArray imgdata_g;
- imgdata_g.resize(w * h * 2);
- uint8_t *wg = imgdata_g.ptrw();
-
- for (int i = 0; i < h; i++) {
- for (int j = 0; j < w; j++) {
- int ofs_src = (i * w + j) * size;
- int ofs_dst = (i * w + j) * 2;
- wg[ofs_dst + 0] = 255;
- wg[ofs_dst + 1] = r[ofs_src + p_ch];
- }
- }
- Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g));
- r_font->set_texture_image(0, Vector2i(p_sz, p_ol), p_page, img_g);
-}
-
-void _convert_mono_4bit(Ref<FontData> &r_font, Ref<Image> &p_source, int p_page, int p_ch, int p_sz, int p_ol) {
- int w = p_source->get_width();
- int h = p_source->get_height();
-
- PackedByteArray imgdata = p_source->get_data();
- const uint8_t *r = imgdata.ptr();
-
- int size = 4;
- if (p_source->get_format() == Image::FORMAT_L8) {
- size = 1;
- p_ch = 0;
- }
-
- PackedByteArray imgdata_g;
- imgdata_g.resize(w * h * 2);
- uint8_t *wg = imgdata_g.ptrw();
-
- PackedByteArray imgdata_o;
- imgdata_o.resize(w * h * 2);
- uint8_t *wo = imgdata_o.ptrw();
-
- for (int i = 0; i < h; i++) {
- for (int j = 0; j < w; j++) {
- int ofs_src = (i * w + j) * size;
- int ofs_dst = (i * w + j) * 2;
- wg[ofs_dst + 0] = 255;
- wo[ofs_dst + 0] = 255;
- if (r[ofs_src + p_ch] > 0x7F) {
- wg[ofs_dst + 1] = r[ofs_src + p_ch];
- wo[ofs_dst + 1] = 0;
- } else {
- wg[ofs_dst + 1] = 0;
- wo[ofs_dst + 1] = r[ofs_src + p_ch] * 2;
- }
- }
- }
- Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g));
- r_font->set_texture_image(0, Vector2i(p_sz, 0), p_page, img_g);
-
- Ref<Image> img_o = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_o));
- r_font->set_texture_image(0, Vector2i(p_sz, p_ol), p_page, img_o);
-}
-
Error ResourceImporterBMFont::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
print_verbose("Importing BMFont font from: " + p_source_file);
Ref<FontData> font;
font.instantiate();
- font->set_antialiased(false);
- font->set_multichannel_signed_distance_field(false);
- font->set_force_autohinter(false);
- font->set_hinting(TextServer::HINTING_NONE);
- font->set_oversampling(1.0f);
-
- FileAccessRef f = FileAccess::open(p_source_file, FileAccess::READ);
- if (f == nullptr) {
- ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Cannot open font from file ") + "\"" + p_source_file + "\".");
- }
-
- int base_size = 16;
- int height = 0;
- int ascent = 0;
- int outline = 0;
- uint32_t st_flags = 0;
- String font_name;
-
- bool packed = false;
- uint8_t ch[4] = { 0, 0, 0, 0 }; // RGBA
- int first_gl_ch = -1;
- int first_ol_ch = -1;
- int first_cm_ch = -1;
-
- unsigned char magic[4];
- f->get_buffer((unsigned char *)&magic, 4);
- if (magic[0] == 'B' && magic[1] == 'M' && magic[2] == 'F') {
- // Binary BMFont file.
- ERR_FAIL_COND_V_MSG(magic[3] != 3, ERR_CANT_CREATE, vformat(TTR("Version %d of BMFont is not supported."), (int)magic[3]));
-
- uint8_t block_type = f->get_8();
- uint32_t block_size = f->get_32();
- while (!f->eof_reached()) {
- uint64_t off = f->get_position();
- switch (block_type) {
- case 1: /* info */ {
- ERR_FAIL_COND_V_MSG(block_size < 15, ERR_CANT_CREATE, TTR("Invalid BMFont info block size."));
- base_size = f->get_16();
- uint8_t flags = f->get_8();
- ERR_FAIL_COND_V_MSG(flags & 0x02, ERR_CANT_CREATE, TTR("Non-unicode version of BMFont is not supported."));
- if (flags & (1 << 3)) {
- st_flags |= TextServer::FONT_BOLD;
- }
- if (flags & (1 << 2)) {
- st_flags |= TextServer::FONT_ITALIC;
- }
- f->get_8(); // non-unicode charset, skip
- f->get_16(); // stretch_h, skip
- f->get_8(); // aa, skip
- f->get_32(); // padding, skip
- f->get_16(); // spacing, skip
- outline = f->get_8();
- // font name
- PackedByteArray name_data;
- name_data.resize(block_size - 14);
- f->get_buffer(name_data.ptrw(), block_size - 14);
- font_name = String::utf8((const char *)name_data.ptr(), block_size - 14);
- font->set_fixed_size(base_size);
- } break;
- case 2: /* common */ {
- ERR_FAIL_COND_V_MSG(block_size != 15, ERR_CANT_CREATE, TTR("Invalid BMFont common block size."));
- height = f->get_16();
- ascent = f->get_16();
- f->get_32(); // scale, skip
- f->get_16(); // pages, skip
- uint8_t flags = f->get_8();
- packed = (flags & 0x01);
- ch[3] = f->get_8();
- ch[0] = f->get_8();
- ch[1] = f->get_8();
- ch[2] = f->get_8();
- for (int i = 0; i < 4; i++) {
- if (ch[i] == 0 && first_gl_ch == -1) {
- first_gl_ch = i;
- }
- if (ch[i] == 1 && first_ol_ch == -1) {
- first_ol_ch = i;
- }
- if (ch[i] == 2 && first_cm_ch == -1) {
- first_cm_ch = i;
- }
- }
- } break;
- case 3: /* pages */ {
- int page = 0;
- CharString cs;
- char32_t c = f->get_8();
- while (!f->eof_reached() && f->get_position() <= off + block_size) {
- if (c == '\0') {
- String base_dir = p_source_file.get_base_dir();
- String file = base_dir.plus_file(String::utf8(cs.ptr(), cs.length()));
- if (RenderingServer::get_singleton() != nullptr) {
- Ref<Image> img;
- img.instantiate();
- Error err = ImageLoader::load_image(file, img);
- ERR_FAIL_COND_V_MSG(err != OK, ERR_FILE_CANT_READ, TTR("Can't load font texture: ") + "\"" + file + "\".");
-
- if (packed) {
- if (ch[3] == 0) { // 4 x 8 bit monochrome, no outline
- outline = 0;
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_packed_8bit(font, img, page, base_size);
- } else if ((ch[3] == 2) && (outline > 0)) { // 4 x 4 bit monochrome, gl + outline
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_packed_4bit(font, img, page, base_size);
- } else {
- ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Unsupported BMFont texture format."));
- }
- } else {
- if ((ch[0] == 0) && (ch[1] == 0) && (ch[2] == 0) && (ch[3] == 0)) { // RGBA8 color, no outline
- outline = 0;
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- font->set_texture_image(0, Vector2i(base_size, 0), page, img);
- } else if ((ch[0] == 2) && (ch[1] == 2) && (ch[2] == 2) && (ch[3] == 2) && (outline > 0)) { // RGBA4 color, gl + outline
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_rgba_4bit(font, img, page, base_size);
- } else if ((first_gl_ch >= 0) && (first_ol_ch >= 0) && (outline > 0)) { // 1 x 8 bit monochrome, gl + outline
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_mono_8bit(font, img, page, first_gl_ch, base_size, 0);
- _convert_mono_8bit(font, img, page, first_ol_ch, base_size, 1);
- } else if ((first_cm_ch >= 0) && (outline > 0)) { // 1 x 4 bit monochrome, gl + outline
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_mono_4bit(font, img, page, first_cm_ch, base_size, 1);
- } else if (first_gl_ch >= 0) { // 1 x 8 bit monochrome, no outline
- outline = 0;
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_mono_8bit(font, img, page, first_gl_ch, base_size, 0);
- } else {
- ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Unsupported BMFont texture format."));
- }
- }
- }
- page++;
- cs = "";
- } else {
- cs += c;
- }
- c = f->get_8();
- }
- } break;
- case 4: /* chars */ {
- int char_count = block_size / 20;
- for (int i = 0; i < char_count; i++) {
- Vector2 advance;
- Vector2 size;
- Vector2 offset;
- Rect2 uv_rect;
-
- char32_t idx = f->get_32();
- uv_rect.position.x = (int16_t)f->get_16();
- uv_rect.position.y = (int16_t)f->get_16();
- uv_rect.size.width = (int16_t)f->get_16();
- size.width = uv_rect.size.width;
- uv_rect.size.height = (int16_t)f->get_16();
- size.height = uv_rect.size.height;
- offset.x = (int16_t)f->get_16();
- offset.y = (int16_t)f->get_16() - ascent;
- advance.x = (int16_t)f->get_16();
- if (advance.x < 0) {
- advance.x = size.width + 1;
- }
-
- int texture_idx = f->get_8();
- uint8_t channel = f->get_8();
-
- ERR_FAIL_COND_V_MSG(!packed && channel != 15, ERR_CANT_CREATE, TTR("Invalid glyph channel."));
- int ch_off = 0;
- switch (channel) {
- case 1:
- ch_off = 2;
- break; // B
- case 2:
- ch_off = 1;
- break; // G
- case 4:
- ch_off = 0;
- break; // R
- case 8:
- ch_off = 3;
- break; // A
- default:
- ch_off = 0;
- break;
- }
- font->set_glyph_advance(0, base_size, idx, advance);
- font->set_glyph_offset(0, Vector2i(base_size, 0), idx, offset);
- font->set_glyph_size(0, Vector2i(base_size, 0), idx, size);
- font->set_glyph_uv_rect(0, Vector2i(base_size, 0), idx, uv_rect);
- font->set_glyph_texture_idx(0, Vector2i(base_size, 0), idx, texture_idx * (packed ? 4 : 1) + ch_off);
- if (outline > 0) {
- font->set_glyph_offset(0, Vector2i(base_size, 1), idx, offset);
- font->set_glyph_size(0, Vector2i(base_size, 1), idx, size);
- font->set_glyph_uv_rect(0, Vector2i(base_size, 1), idx, uv_rect);
- font->set_glyph_texture_idx(0, Vector2i(base_size, 1), idx, texture_idx * (packed ? 4 : 1) + ch_off);
- }
- }
- } break;
- case 5: /* kerning */ {
- int pair_count = block_size / 10;
- for (int i = 0; i < pair_count; i++) {
- Vector2i kpk;
- kpk.x = f->get_32();
- kpk.y = f->get_32();
- font->set_kerning(0, base_size, kpk, Vector2((int16_t)f->get_16(), 0));
- }
- } break;
- default: {
- ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Invalid BMFont block type."));
- } break;
- }
- f->seek(off + block_size);
- block_type = f->get_8();
- block_size = f->get_32();
- }
-
- } else {
- // Text BMFont file.
- f->seek(0);
- while (true) {
- String line = f->get_line();
-
- int delimiter = line.find(" ");
- String type = line.substr(0, delimiter);
- int pos = delimiter + 1;
- Map<String, String> keys;
-
- while (pos < line.size() && line[pos] == ' ') {
- pos++;
- }
-
- while (pos < line.size()) {
- int eq = line.find("=", pos);
- if (eq == -1) {
- break;
- }
- String key = line.substr(pos, eq - pos);
- int end = -1;
- String value;
- if (line[eq + 1] == '"') {
- end = line.find("\"", eq + 2);
- if (end == -1) {
- break;
- }
- value = line.substr(eq + 2, end - 1 - eq - 1);
- pos = end + 1;
- } else {
- end = line.find(" ", eq + 1);
- if (end == -1) {
- end = line.size();
- }
- value = line.substr(eq + 1, end - eq);
- pos = end;
- }
-
- while (pos < line.size() && line[pos] == ' ') {
- pos++;
- }
-
- keys[key] = value;
- }
-
- if (type == "info") {
- if (keys.has("size")) {
- base_size = keys["size"].to_int();
- font->set_fixed_size(base_size);
- }
- if (keys.has("outline")) {
- outline = keys["outline"].to_int();
- }
- if (keys.has("bold")) {
- if (keys["bold"].to_int()) {
- st_flags |= TextServer::FONT_BOLD;
- }
- }
- if (keys.has("italic")) {
- if (keys["italic"].to_int()) {
- st_flags |= TextServer::FONT_ITALIC;
- }
- }
- if (keys.has("face")) {
- font_name = keys["face"];
- }
- ERR_FAIL_COND_V_MSG((!keys.has("unicode") || keys["unicode"].to_int() != 1), ERR_CANT_CREATE, TTR("Non-unicode version of BMFont is not supported."));
- } else if (type == "common") {
- if (keys.has("lineHeight")) {
- height = keys["lineHeight"].to_int();
- }
- if (keys.has("base")) {
- ascent = keys["base"].to_int();
- }
- if (keys.has("packed")) {
- packed = (keys["packed"].to_int() == 1);
- }
- if (keys.has("alphaChnl")) {
- ch[3] = keys["alphaChnl"].to_int();
- }
- if (keys.has("redChnl")) {
- ch[0] = keys["redChnl"].to_int();
- }
- if (keys.has("greenChnl")) {
- ch[1] = keys["greenChnl"].to_int();
- }
- if (keys.has("blueChnl")) {
- ch[2] = keys["blueChnl"].to_int();
- }
- for (int i = 0; i < 4; i++) {
- if (ch[i] == 0 && first_gl_ch == -1) {
- first_gl_ch = i;
- }
- if (ch[i] == 1 && first_ol_ch == -1) {
- first_ol_ch = i;
- }
- if (ch[i] == 2 && first_cm_ch == -1) {
- first_cm_ch = i;
- }
- }
- } else if (type == "page") {
- int page = 0;
- if (keys.has("id")) {
- page = keys["id"].to_int();
- }
- if (keys.has("file")) {
- String base_dir = p_source_file.get_base_dir();
- String file = base_dir.plus_file(keys["file"]);
- if (RenderingServer::get_singleton() != nullptr) {
- Ref<Image> img;
- img.instantiate();
- Error err = ImageLoader::load_image(file, img);
- ERR_FAIL_COND_V_MSG(err != OK, ERR_FILE_CANT_READ, TTR("Can't load font texture: ") + "\"" + file + "\".");
- if (packed) {
- if (ch[3] == 0) { // 4 x 8 bit monochrome, no outline
- outline = 0;
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_packed_8bit(font, img, page, base_size);
- } else if ((ch[3] == 2) && (outline > 0)) { // 4 x 4 bit monochrome, gl + outline
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_packed_4bit(font, img, page, base_size);
- } else {
- ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Unsupported BMFont texture format."));
- }
- } else {
- if ((ch[0] == 0) && (ch[1] == 0) && (ch[2] == 0) && (ch[3] == 0)) { // RGBA8 color, no outline
- outline = 0;
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- font->set_texture_image(0, Vector2i(base_size, 0), page, img);
- } else if ((ch[0] == 2) && (ch[1] == 2) && (ch[2] == 2) && (ch[3] == 2) && (outline > 0)) { // RGBA4 color, gl + outline
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_rgba_4bit(font, img, page, base_size);
- } else if ((first_gl_ch >= 0) && (first_ol_ch >= 0) && (outline > 0)) { // 1 x 8 bit monochrome, gl + outline
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_mono_8bit(font, img, page, first_gl_ch, base_size, 0);
- _convert_mono_8bit(font, img, page, first_ol_ch, base_size, 1);
- } else if ((first_cm_ch >= 0) && (outline > 0)) { // 1 x 4 bit monochrome, gl + outline
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_mono_4bit(font, img, page, first_cm_ch, base_size, 1);
- } else if (first_gl_ch >= 0) { // 1 x 8 bit monochrome, no outline
- outline = 0;
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_mono_8bit(font, img, page, first_gl_ch, base_size, 0);
- } else {
- ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Unsupported BMFont texture format."));
- }
- }
- }
- }
- } else if (type == "char") {
- char32_t idx = 0;
- Vector2 advance;
- Vector2 size;
- Vector2 offset;
- Rect2 uv_rect;
- int texture_idx = -1;
- uint8_t channel = 15;
-
- if (keys.has("id")) {
- idx = keys["id"].to_int();
- }
- if (keys.has("x")) {
- uv_rect.position.x = keys["x"].to_int();
- }
- if (keys.has("y")) {
- uv_rect.position.y = keys["y"].to_int();
- }
- if (keys.has("width")) {
- uv_rect.size.width = keys["width"].to_int();
- size.width = keys["width"].to_int();
- }
- if (keys.has("height")) {
- uv_rect.size.height = keys["height"].to_int();
- size.height = keys["height"].to_int();
- }
- if (keys.has("xoffset")) {
- offset.x = keys["xoffset"].to_int();
- }
- if (keys.has("yoffset")) {
- offset.y = keys["yoffset"].to_int() - ascent;
- }
- if (keys.has("page")) {
- texture_idx = keys["page"].to_int();
- }
- if (keys.has("xadvance")) {
- advance.x = keys["xadvance"].to_int();
- }
- if (advance.x < 0) {
- advance.x = size.width + 1;
- }
- if (keys.has("chnl")) {
- channel = keys["chnl"].to_int();
- }
-
- ERR_FAIL_COND_V_MSG(!packed && channel != 15, ERR_CANT_CREATE, TTR("Invalid glyph channel."));
- int ch_off = 0;
- switch (channel) {
- case 1:
- ch_off = 2;
- break; // B
- case 2:
- ch_off = 1;
- break; // G
- case 4:
- ch_off = 0;
- break; // R
- case 8:
- ch_off = 3;
- break; // A
- default:
- ch_off = 0;
- break;
- }
- font->set_glyph_advance(0, base_size, idx, advance);
- font->set_glyph_offset(0, Vector2i(base_size, 0), idx, offset);
- font->set_glyph_size(0, Vector2i(base_size, 0), idx, size);
- font->set_glyph_uv_rect(0, Vector2i(base_size, 0), idx, uv_rect);
- font->set_glyph_texture_idx(0, Vector2i(base_size, 0), idx, texture_idx * (packed ? 4 : 1) + ch_off);
- if (outline > 0) {
- font->set_glyph_offset(0, Vector2i(base_size, 1), idx, offset);
- font->set_glyph_size(0, Vector2i(base_size, 1), idx, size);
- font->set_glyph_uv_rect(0, Vector2i(base_size, 1), idx, uv_rect);
- font->set_glyph_texture_idx(0, Vector2i(base_size, 1), idx, texture_idx * (packed ? 4 : 1) + ch_off);
- }
- } else if (type == "kerning") {
- Vector2i kpk;
- if (keys.has("first")) {
- kpk.x = keys["first"].to_int();
- }
- if (keys.has("second")) {
- kpk.y = keys["second"].to_int();
- }
- if (keys.has("amount")) {
- font->set_kerning(0, base_size, kpk, Vector2(keys["amount"].to_int(), 0));
- }
- }
-
- if (f->eof_reached()) {
- break;
- }
- }
- }
- font->set_font_name(font_name);
- font->set_font_style(st_flags);
- font->set_ascent(0, base_size, ascent);
- font->set_descent(0, base_size, height - ascent);
+ Error err = font->load_bitmap_font(p_source_file);
+ ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot load font to file \"" + p_source_file + "\".");
int flg = ResourceSaver::SaverFlags::FLAG_BUNDLE_RESOURCES | ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS;
if ((bool)p_options["compress"]) {
@@ -814,7 +78,7 @@ Error ResourceImporterBMFont::import(const String &p_source_file, const String &
}
print_verbose("Saving to: " + p_save_path + ".fontdata");
- Error err = ResourceSaver::save(p_save_path + ".fontdata", font, flg);
+ err = ResourceSaver::save(p_save_path + ".fontdata", font, flg);
ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot save font to file \"" + p_save_path + ".res\".");
print_verbose("Done saving to: " + p_save_path + ".fontdata");
return OK;
diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp
index 5876d6df0b..7ca61e83e7 100644
--- a/editor/import/resource_importer_layered_texture.cpp
+++ b/editor/import/resource_importer_layered_texture.cpp
@@ -450,12 +450,6 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const
formats_imported.push_back("etc2");
}
- if (ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_pvrtc")) {
- _save_tex(slices, p_save_path + ".etc2." + extension, compress_mode, lossy, Image::COMPRESS_ETC2, csource, used_channels, mipmaps, true);
- r_platform_variants->push_back("pvrtc");
- formats_imported.push_back("pvrtc");
- }
-
if (!ok_on_pc) {
EditorNode::add_io_error("Warning, no suitable PC VRAM compression enabled in Project Settings. This texture will not display correctly on PC.");
}
@@ -481,7 +475,6 @@ const char *ResourceImporterLayeredTexture::compression_formats[] = {
"s3tc",
"etc",
"etc2",
- "pvrtc",
nullptr
};
String ResourceImporterLayeredTexture::get_import_settings_string() const {
diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp
index 59550a3ee3..f21012258c 100644
--- a/editor/import/resource_importer_texture.cpp
+++ b/editor/import/resource_importer_texture.cpp
@@ -211,14 +211,17 @@ void ResourceImporterTexture::get_import_options(const String &p_path, List<Impo
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "mipmaps/generate"), (p_preset == PRESET_3D ? true : false)));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "mipmaps/limit", PROPERTY_HINT_RANGE, "-1,256"), -1));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "roughness/mode", PROPERTY_HINT_ENUM, "Detect,Disabled,Red,Green,Blue,Alpha,Gray"), 0));
- r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "roughness/src_normal", PROPERTY_HINT_FILE, "*.bmp,*.dds,*.exr,*.jpeg,*.jpg,*.hdr,*.png,*.svg,*.svgz,*.tga,*.webp"), ""));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "roughness/src_normal", PROPERTY_HINT_FILE, "*.bmp,*.dds,*.exr,*.jpeg,*.jpg,*.hdr,*.png,*.svg,*.tga,*.webp"), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/fix_alpha_border"), p_preset != PRESET_3D));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/premult_alpha"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/normal_map_invert_y"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/HDR_as_SRGB"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "process/size_limit", PROPERTY_HINT_RANGE, "0,4096,1"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "detect_3d/compress_to", PROPERTY_HINT_ENUM, "Disabled,VRAM Compressed,Basis Universal"), (p_preset == PRESET_DETECT) ? 1 : 0));
- r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "svg/scale", PROPERTY_HINT_RANGE, "0.001,100,0.001"), 1.0));
+
+ if (p_path.get_extension() == "svg") {
+ r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "svg/scale", PROPERTY_HINT_RANGE, "0.001,100,0.001"), 1.0));
+ }
}
void ResourceImporterTexture::save_to_stex_format(FileAccess *f, const Ref<Image> &p_image, CompressMode p_compress_mode, Image::UsedChannels p_channels, Image::CompressMode p_compress_format, float p_lossy_quality) {
@@ -408,11 +411,14 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
int size_limit = p_options["process/size_limit"];
bool hdr_as_srgb = p_options["process/HDR_as_SRGB"];
int normal = p_options["compress/normal_map"];
- float scale = p_options["svg/scale"];
int hdr_compression = p_options["compress/hdr_compression"];
int bptc_ldr = p_options["compress/bptc_ldr"];
int roughness = p_options["roughness/mode"];
String normal_map = p_options["roughness/src_normal"];
+ float scale = 1.0;
+ if (p_options.has("svg/scale")) {
+ scale = p_options["svg/scale"];
+ }
Ref<Image> normal_image;
Image::RoughnessChannel roughness_channel = Image::ROUGHNESS_CHANNEL_R;
@@ -556,12 +562,6 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
formats_imported.push_back("etc");
}
- if (ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_pvrtc")) {
- _save_stex(image, p_save_path + ".pvrtc.stex", compress_mode, lossy, Image::COMPRESS_PVRTC1_4, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel);
- r_platform_variants->push_back("pvrtc");
- formats_imported.push_back("pvrtc");
- }
-
if (!ok_on_pc) {
EditorNode::add_io_error("Warning, no suitable PC VRAM compression enabled in Project Settings. This texture will not display correctly on PC.");
}
@@ -586,7 +586,6 @@ const char *ResourceImporterTexture::compression_formats[] = {
"s3tc",
"etc",
"etc2",
- "pvrtc",
nullptr
};
String ResourceImporterTexture::get_import_settings_string() const {
diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp
index ccb287e433..f56e868286 100644
--- a/editor/inspector_dock.cpp
+++ b/editor/inspector_dock.cpp
@@ -406,6 +406,7 @@ Container *InspectorDock::get_addon_area() {
void InspectorDock::_notification(int p_what) {
switch (p_what) {
+ case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_TRANSLATION_CHANGED:
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
@@ -415,6 +416,7 @@ void InspectorDock::_notification(int p_what) {
resource_load_button->set_icon(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")));
resource_save_button->set_icon(get_theme_icon(SNAME("Save"), SNAME("EditorIcons")));
resource_extra_button->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
+ open_docs_button->set_icon(get_theme_icon(SNAME("HelpSearch"), SNAME("EditorIcons")));
PopupMenu *resource_extra_popup = resource_extra_button->get_popup();
resource_extra_popup->set_item_icon(resource_extra_popup->get_item_index(RESOURCE_EDIT_CLIPBOARD), get_theme_icon(SNAME("ActionPaste"), SNAME("EditorIcons")));
@@ -430,6 +432,7 @@ void InspectorDock::_notification(int p_what) {
history_menu->set_icon(get_theme_icon(SNAME("History"), SNAME("EditorIcons")));
object_menu->set_icon(get_theme_icon(SNAME("Tools"), SNAME("EditorIcons")));
+ search->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
warning->set_icon(get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons")));
warning->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor")));
} break;
@@ -562,7 +565,6 @@ void InspectorDock::update_keying() {
InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) {
set_name("Inspector");
- set_theme(p_editor->get_gui_base()->get_theme());
editor = p_editor;
editor_data = &p_editor_data;
@@ -573,7 +575,6 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) {
resource_new_button = memnew(Button);
resource_new_button->set_flat(true);
resource_new_button->set_tooltip(TTR("Create a new resource in memory and edit it."));
- resource_new_button->set_icon(get_theme_icon(SNAME("New"), SNAME("EditorIcons")));
general_options_hb->add_child(resource_new_button);
resource_new_button->connect("pressed", callable_mp(this, &InspectorDock::_new_resource));
resource_new_button->set_focus_mode(Control::FOCUS_NONE);
@@ -581,14 +582,12 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) {
resource_load_button = memnew(Button);
resource_load_button->set_flat(true);
resource_load_button->set_tooltip(TTR("Load an existing resource from disk and edit it."));
- resource_load_button->set_icon(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")));
general_options_hb->add_child(resource_load_button);
resource_load_button->connect("pressed", callable_mp(this, &InspectorDock::_open_resource_selector));
resource_load_button->set_focus_mode(Control::FOCUS_NONE);
resource_save_button = memnew(MenuButton);
resource_save_button->set_tooltip(TTR("Save the currently edited resource."));
- resource_save_button->set_icon(get_theme_icon(SNAME("Save"), SNAME("EditorIcons")));
general_options_hb->add_child(resource_save_button);
resource_save_button->get_popup()->add_item(TTR("Save"), RESOURCE_SAVE);
resource_save_button->get_popup()->add_item(TTR("Save As..."), RESOURCE_SAVE_AS);
@@ -597,7 +596,6 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) {
resource_save_button->set_disabled(true);
resource_extra_button = memnew(MenuButton);
- resource_extra_button->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
resource_extra_button->set_tooltip(TTR("Extra resource options."));
general_options_hb->add_child(resource_extra_button);
resource_extra_button->connect("about_to_popup", callable_mp(this, &InspectorDock::_prepare_resource_extra_popup));
@@ -614,11 +612,6 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) {
backward_button = memnew(Button);
backward_button->set_flat(true);
general_options_hb->add_child(backward_button);
- if (is_layout_rtl()) {
- backward_button->set_icon(get_theme_icon(SNAME("Forward"), SNAME("EditorIcons")));
- } else {
- backward_button->set_icon(get_theme_icon(SNAME("Back"), SNAME("EditorIcons")));
- }
backward_button->set_tooltip(TTR("Go to the previous edited object in history."));
backward_button->set_disabled(true);
backward_button->connect("pressed", callable_mp(this, &InspectorDock::_edit_back));
@@ -626,18 +619,12 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) {
forward_button = memnew(Button);
forward_button->set_flat(true);
general_options_hb->add_child(forward_button);
- if (is_layout_rtl()) {
- forward_button->set_icon(get_theme_icon(SNAME("Back"), SNAME("EditorIcons")));
- } else {
- forward_button->set_icon(get_theme_icon(SNAME("Forward"), SNAME("EditorIcons")));
- }
forward_button->set_tooltip(TTR("Go to the next edited object in history."));
forward_button->set_disabled(true);
forward_button->connect("pressed", callable_mp(this, &InspectorDock::_edit_forward));
history_menu = memnew(MenuButton);
history_menu->set_tooltip(TTR("History of recently edited objects."));
- history_menu->set_icon(get_theme_icon(SNAME("History"), SNAME("EditorIcons")));
general_options_hb->add_child(history_menu);
history_menu->connect("about_to_popup", callable_mp(this, &InspectorDock::_prepare_history));
history_menu->get_popup()->connect("id_pressed", callable_mp(this, &InspectorDock::_select_history));
@@ -652,7 +639,6 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) {
open_docs_button->set_flat(true);
open_docs_button->set_disabled(true);
open_docs_button->set_tooltip(TTR("Open documentation for this object."));
- open_docs_button->set_icon(get_theme_icon(SNAME("HelpSearch"), SNAME("EditorIcons")));
open_docs_button->set_shortcut(ED_SHORTCUT("property_editor/open_help", TTR("Open Documentation")));
subresource_hb->add_child(open_docs_button);
open_docs_button->connect("pressed", callable_mp(this, &InspectorDock::_menu_option), varray(OBJECT_REQUEST_HELP));
@@ -668,13 +654,11 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) {
search = memnew(LineEdit);
search->set_h_size_flags(Control::SIZE_EXPAND_FILL);
search->set_placeholder(TTR("Filter properties"));
- search->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
search->set_clear_button_enabled(true);
property_tools_hb->add_child(search);
object_menu = memnew(MenuButton);
object_menu->set_shortcut_context(this);
- object_menu->set_icon(get_theme_icon(SNAME("Tools"), SNAME("EditorIcons")));
property_tools_hb->add_child(object_menu);
object_menu->set_tooltip(TTR("Manage object properties."));
object_menu->get_popup()->connect("id_pressed", callable_mp(this, &InspectorDock::_menu_option));
@@ -682,8 +666,6 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) {
warning = memnew(Button);
add_child(warning);
warning->set_text(TTR("Changes may be lost!"));
- warning->set_icon(get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons")));
- warning->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor")));
warning->set_clip_text(true);
warning->hide();
warning->connect("pressed", callable_mp(this, &InspectorDock::_warning_pressed));
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp
index 9ebdede4e9..71db40a829 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp
@@ -103,7 +103,7 @@ void AnimationNodeBlendTreeEditor::_property_changed(const StringName &p_propert
}
void AnimationNodeBlendTreeEditor::_update_graph() {
- if (updating) {
+ if (updating || blend_tree.is_null()) {
return;
}
@@ -732,6 +732,10 @@ void AnimationNodeBlendTreeEditor::_removed_from_graph() {
}
void AnimationNodeBlendTreeEditor::_notification(int p_what) {
+ if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
+ graph->set_panning_scheme((GraphEdit::PanningScheme)EDITOR_GET("interface/editors/sub_editor_panning_scheme").operator int());
+ }
+
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
error_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index 4ce9f40a5e..d7c0ba7540 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -967,16 +967,7 @@ void AnimationPlayerEditor::_animation_duplicate() {
return;
}
- Ref<Animation> new_anim = memnew(Animation);
- List<PropertyInfo> plist;
- anim->get_property_list(&plist);
- for (const PropertyInfo &E : plist) {
- if (E.usage & PROPERTY_USAGE_STORAGE) {
- new_anim->set(E.name, anim->get(E.name));
- }
- }
- new_anim->set_path("");
-
+ Ref<Animation> new_anim = _animation_clone(anim);
String new_name = current;
while (player->has_animation(new_name)) {
new_name = new_name + " (copy)";
@@ -1000,6 +991,44 @@ void AnimationPlayerEditor::_animation_duplicate() {
}
}
+Ref<Animation> AnimationPlayerEditor::_animation_clone(Ref<Animation> p_anim) {
+ Ref<Animation> new_anim = memnew(Animation);
+ List<PropertyInfo> plist;
+ p_anim->get_property_list(&plist);
+
+ for (const PropertyInfo &E : plist) {
+ if (E.usage & PROPERTY_USAGE_STORAGE) {
+ new_anim->set(E.name, p_anim->get(E.name));
+ }
+ }
+ new_anim->set_path("");
+
+ return new_anim;
+}
+
+void AnimationPlayerEditor::_animation_paste(Ref<Animation> p_anim) {
+ String name = p_anim->get_name();
+ if (name.is_empty()) {
+ name = TTR("Pasted Animation");
+ }
+
+ int idx = 1;
+ String base = name;
+ while (player->has_animation(name)) {
+ idx++;
+ name = base + " " + itos(idx);
+ }
+
+ undo_redo->create_action(TTR("Paste Animation"));
+ undo_redo->add_do_method(player, "add_animation", name, p_anim);
+ undo_redo->add_undo_method(player, "remove_animation", name);
+ undo_redo->add_do_method(this, "_animation_player_changed", player);
+ undo_redo->add_undo_method(this, "_animation_player_changed", player);
+ undo_redo->commit_action();
+
+ _select_anim_by_name(name);
+}
+
void AnimationPlayerEditor::_seek_value_changed(float p_value, bool p_set, bool p_timeline_only) {
if (updating || !player || player->is_playing()) {
return;
@@ -1135,31 +1164,22 @@ void AnimationPlayerEditor::_animation_tool_menu(int p_option) {
case TOOL_PASTE_ANIM: {
Ref<Animation> anim2 = EditorSettings::get_singleton()->get_resource_clipboard();
if (!anim2.is_valid()) {
- error_dialog->set_text(TTR("No animation resource on clipboard!"));
+ error_dialog->set_text(TTR("No animation resource in clipboard!"));
error_dialog->popup_centered();
return;
}
-
- String name = anim2->get_name();
- if (name.is_empty()) {
- name = TTR("Pasted Animation");
- }
-
- int idx = 1;
- String base = name;
- while (player->has_animation(name)) {
- idx++;
- name = base + " " + itos(idx);
+ Ref<Animation> new_anim = _animation_clone(anim2);
+ _animation_paste(new_anim);
+ } break;
+ case TOOL_PASTE_ANIM_REF: {
+ Ref<Animation> anim2 = EditorSettings::get_singleton()->get_resource_clipboard();
+ if (!anim2.is_valid()) {
+ error_dialog->set_text(TTR("No animation resource in clipboard!"));
+ error_dialog->popup_centered();
+ return;
}
- undo_redo->create_action(TTR("Paste Animation"));
- undo_redo->add_do_method(player, "add_animation", name, anim2);
- undo_redo->add_undo_method(player, "remove_animation", name);
- undo_redo->add_do_method(this, "_animation_player_changed", player);
- undo_redo->add_undo_method(this, "_animation_player_changed", player);
- undo_redo->commit_action();
-
- _select_anim_by_name(name);
+ _animation_paste(anim2);
} break;
case TOOL_EDIT_RESOURCE: {
if (!animation->get_item_count()) {
@@ -1587,6 +1607,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay
tool_anim->get_popup()->add_separator();
tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/copy_animation", TTR("Copy")), TOOL_COPY_ANIM);
tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/paste_animation", TTR("Paste")), TOOL_PASTE_ANIM);
+ tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/paste_animation_as_reference", TTR("Paste As Reference")), TOOL_PASTE_ANIM_REF);
tool_anim->get_popup()->add_separator();
tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/duplicate_animation", TTR("Duplicate")), TOOL_DUPLICATE_ANIM);
tool_anim->get_popup()->add_separator();
diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h
index 4e7ea46c1d..626d31f439 100644
--- a/editor/plugins/animation_player_editor_plugin.h
+++ b/editor/plugins/animation_player_editor_plugin.h
@@ -60,6 +60,7 @@ class AnimationPlayerEditor : public VBoxContainer {
TOOL_REMOVE_ANIM,
TOOL_COPY_ANIM,
TOOL_PASTE_ANIM,
+ TOOL_PASTE_ANIM_REF,
TOOL_EDIT_RESOURCE
};
@@ -183,6 +184,8 @@ class AnimationPlayerEditor : public VBoxContainer {
void _animation_blend();
void _animation_edit();
void _animation_duplicate();
+ Ref<Animation> _animation_clone(const Ref<Animation> p_anim);
+ void _animation_paste(const Ref<Animation> p_anim);
void _animation_resource_edit();
void _scale_changed(const String &p_scale);
void _save_animation(String p_file);
diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp
index 49bef4acd5..31ef13a2eb 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -193,7 +193,8 @@ void EditorAssetLibraryItemDescription::set_image(int p_type, int p_index, const
void EditorAssetLibraryItemDescription::_notification(int p_what) {
switch (p_what) {
- case NOTIFICATION_ENTER_TREE: {
+ case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_THEME_CHANGED: {
previews_bg->add_theme_style_override("panel", previews->get_theme_stylebox(SNAME("normal"), SNAME("TextEdit")));
} break;
}
@@ -397,9 +398,9 @@ void EditorAssetLibraryItemDownload::configure(const String &p_title, int p_asse
void EditorAssetLibraryItemDownload::_notification(int p_what) {
switch (p_what) {
- // FIXME: The editor crashes if 'NOTICATION_THEME_CHANGED' is used.
- case NOTIFICATION_ENTER_TREE: {
- add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("TabContainer")));
+ case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_THEME_CHANGED: {
+ panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("TabContainer")));
dismiss->set_normal_texture(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
} break;
case NOTIFICATION_PROCESS: {
@@ -492,8 +493,11 @@ void EditorAssetLibraryItemDownload::_bind_methods() {
}
EditorAssetLibraryItemDownload::EditorAssetLibraryItemDownload() {
+ panel = memnew(PanelContainer);
+ add_child(panel);
+
HBoxContainer *hb = memnew(HBoxContainer);
- add_child(hb);
+ panel->add_child(hb);
icon = memnew(TextureRect);
hb->add_child(icon);
@@ -541,16 +545,16 @@ EditorAssetLibraryItemDownload::EditorAssetLibraryItemDownload() {
set_custom_minimum_size(Size2(310, 0) * EDSCALE);
download = memnew(HTTPRequest);
- add_child(download);
+ panel->add_child(download);
download->connect("request_completed", callable_mp(this, &EditorAssetLibraryItemDownload::_http_download_completed));
setup_http_request(download);
download_error = memnew(AcceptDialog);
- add_child(download_error);
+ panel->add_child(download_error);
download_error->set_title(TTR("Download Error"));
asset_installer = memnew(EditorAssetInstaller);
- add_child(asset_installer);
+ panel->add_child(asset_installer);
asset_installer->connect("confirmed", callable_mp(this, &EditorAssetLibraryItemDownload::_close));
prev_status = -1;
@@ -562,11 +566,15 @@ EditorAssetLibraryItemDownload::EditorAssetLibraryItemDownload() {
void EditorAssetLibrary::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY: {
+ error_label->raise();
+ } break;
+ case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_THEME_CHANGED: {
error_tr->set_texture(get_theme_icon(SNAME("Error"), SNAME("EditorIcons")));
filter->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
- filter->set_clear_button_enabled(true);
-
- error_label->raise();
+ library_scroll_bg->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
+ downloads_scroll->add_theme_style_override("bg", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
+ error_label->add_theme_color_override("color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
if (is_visible()) {
@@ -596,14 +604,6 @@ void EditorAssetLibrary::_notification(int p_what) {
}
} break;
- case NOTIFICATION_THEME_CHANGED: {
- library_scroll_bg->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
- downloads_scroll->add_theme_style_override("bg", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
- error_tr->set_texture(get_theme_icon(SNAME("Error"), SNAME("EditorIcons")));
- filter->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
- filter->set_clear_button_enabled(true);
- } break;
-
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
_update_repository_options();
} break;
@@ -1354,6 +1354,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
} else {
filter->set_placeholder(TTR("Search assets (excluding templates, projects, and demos)"));
}
+ filter->set_clear_button_enabled(true);
search_hb->add_child(filter);
filter->set_h_size_flags(Control::SIZE_EXPAND_FILL);
filter->connect("text_changed", callable_mp(this, &EditorAssetLibrary::_search_text_changed));
@@ -1495,7 +1496,6 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
error_hb = memnew(HBoxContainer);
library_main->add_child(error_hb);
error_label = memnew(Label);
- error_label->add_theme_color_override("color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
error_hb->add_child(error_label);
error_tr = memnew(TextureRect);
error_tr->set_v_size_flags(Control::SIZE_SHRINK_CENTER);
diff --git a/editor/plugins/asset_library_editor_plugin.h b/editor/plugins/asset_library_editor_plugin.h
index d797608c24..8d6c0eb76e 100644
--- a/editor/plugins/asset_library_editor_plugin.h
+++ b/editor/plugins/asset_library_editor_plugin.h
@@ -126,9 +126,10 @@ public:
EditorAssetLibraryItemDescription();
};
-class EditorAssetLibraryItemDownload : public PanelContainer {
- GDCLASS(EditorAssetLibraryItemDownload, PanelContainer);
+class EditorAssetLibraryItemDownload : public Control {
+ GDCLASS(EditorAssetLibraryItemDownload, Control);
+ PanelContainer *panel;
TextureRect *icon;
Label *title;
ProgressBar *progress;
diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp
index e272b96778..c6d1d99c08 100644
--- a/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/polygon_2d_editor_plugin.cpp
@@ -38,6 +38,8 @@
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#include "scene/2d/skeleton_2d.h"
+#include "scene/gui/scroll_container.h"
+#include "scene/gui/view_panner.h"
Node2D *Polygon2DEditor::_get_node() const {
return node;
@@ -63,9 +65,8 @@ int Polygon2DEditor::_get_polygon_count() const {
void Polygon2DEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
- case NOTIFICATION_THEME_CHANGED: {
- uv_edit_draw->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
- bone_scroll->add_theme_style_override("bg", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
+ uv_panner->set_control_scheme((ViewPanner::ControlScheme)EDITOR_GET("interface/editors/sub_editor_panning_scheme").operator int());
} break;
case NOTIFICATION_READY: {
button_uv->set_icon(get_theme_icon(SNAME("Uv"), SNAME("EditorIcons")));
@@ -88,6 +89,11 @@ void Polygon2DEditor::_notification(int p_what) {
uv_vscroll->set_anchors_and_offsets_preset(PRESET_RIGHT_WIDE);
uv_hscroll->set_anchors_and_offsets_preset(PRESET_BOTTOM_WIDE);
+ [[fallthrough]];
+ }
+ case NOTIFICATION_THEME_CHANGED: {
+ uv_edit_draw->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
+ bone_scroll->add_theme_style_override("bg", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
if (!is_visible()) {
@@ -440,6 +446,11 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
return;
}
+ if (uv_panner->gui_input(p_input)) {
+ accept_event();
+ return;
+ }
+
Transform2D mtx;
mtx.elements[2] = -uv_draw_ofs;
mtx.scale_basis(Vector2(uv_draw_zoom, uv_draw_zoom));
@@ -767,23 +778,13 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
}
uv_edit_draw->update();
-
- } else if (mb->get_button_index() == MouseButton::WHEEL_UP && mb->is_pressed()) {
- uv_zoom->set_value(uv_zoom->get_value() / (1 - (0.1 * mb->get_factor())));
- } else if (mb->get_button_index() == MouseButton::WHEEL_DOWN && mb->is_pressed()) {
- uv_zoom->set_value(uv_zoom->get_value() * (1 - (0.1 * mb->get_factor())));
}
}
Ref<InputEventMouseMotion> mm = p_input;
if (mm.is_valid()) {
- if ((mm->get_button_mask() & MouseButton::MASK_MIDDLE) != MouseButton::NONE || Input::get_singleton()->is_key_pressed(Key::SPACE)) {
- Vector2 drag = mm->get_relative();
- uv_hscroll->set_value(uv_hscroll->get_value() - drag.x);
- uv_vscroll->set_value(uv_vscroll->get_value() - drag.y);
-
- } else if (uv_drag) {
+ if (uv_drag) {
Vector2 uv_drag_to = mm->get_position();
uv_drag_to = snap_point(uv_drag_to); // FIXME: Only works correctly with 'UV_MODE_EDIT_POINT', it's imprecise with the rest.
Vector2 drag = mtx.affine_inverse().xform(uv_drag_to) - mtx.affine_inverse().xform(uv_drag_from);
@@ -925,6 +926,23 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
}
}
+void Polygon2DEditor::_uv_scroll_callback(Vector2 p_scroll_vec) {
+ _uv_pan_callback(-p_scroll_vec * 32);
+}
+
+void Polygon2DEditor::_uv_pan_callback(Vector2 p_scroll_vec) {
+ uv_hscroll->set_value(uv_hscroll->get_value() - p_scroll_vec.x);
+ uv_vscroll->set_value(uv_vscroll->get_value() - p_scroll_vec.y);
+}
+
+void Polygon2DEditor::_uv_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin) {
+ if (p_scroll_vec.y < 0) {
+ uv_zoom->set_value(uv_zoom->get_value() / (1 - (0.1 * Math::abs(p_scroll_vec.y))));
+ } else {
+ uv_zoom->set_value(uv_zoom->get_value() * (1 - (0.1 * Math::abs(p_scroll_vec.y))));
+ }
+}
+
void Polygon2DEditor::_uv_scroll_changed(real_t) {
if (updating_uv_scroll) {
return;
@@ -1262,6 +1280,10 @@ Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) :
uv_edit_mode[2]->connect("pressed", callable_mp(this, &Polygon2DEditor::_uv_edit_mode_select), varray(2));
uv_edit_mode[3]->connect("pressed", callable_mp(this, &Polygon2DEditor::_uv_edit_mode_select), varray(3));
+ uv_panner.instantiate();
+ uv_panner->set_callbacks(callable_mp(this, &Polygon2DEditor::_uv_scroll_callback), callable_mp(this, &Polygon2DEditor::_uv_pan_callback), callable_mp(this, &Polygon2DEditor::_uv_zoom_callback));
+ uv_panner->set_disable_rmb(true);
+
uv_mode_hb->add_child(memnew(VSeparator));
uv_main_vb->add_child(uv_mode_hb);
diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h
index a04179dcad..959c230d7b 100644
--- a/editor/plugins/polygon_2d_editor_plugin.h
+++ b/editor/plugins/polygon_2d_editor_plugin.h
@@ -32,7 +32,9 @@
#define POLYGON_2D_EDITOR_PLUGIN_H
#include "editor/plugins/abstract_polygon_2d_editor.h"
-#include "scene/gui/scroll_container.h"
+
+class ViewPanner;
+class ScrollContainer;
class Polygon2DEditor : public AbstractPolygon2DEditor {
GDCLASS(Polygon2DEditor, AbstractPolygon2DEditor);
@@ -78,6 +80,11 @@ class Polygon2DEditor : public AbstractPolygon2DEditor {
MenuButton *uv_menu;
TextureRect *uv_icon_zoom;
+ Ref<ViewPanner> uv_panner;
+ void _uv_scroll_callback(Vector2 p_scroll_vec);
+ void _uv_pan_callback(Vector2 p_scroll_vec);
+ void _uv_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin);
+
VBoxContainer *bone_scroll_main_vb;
ScrollContainer *bone_scroll;
VBoxContainer *bone_scroll_vb;
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 03ed0e0ef2..f1e5e7612b 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -1771,6 +1771,7 @@ struct _ScriptEditorItemData {
String name;
String sort_key;
Ref<Texture2D> icon;
+ bool tool = false;
int index = 0;
String tooltip;
bool used = false;
@@ -1894,6 +1895,7 @@ void ScriptEditor::_update_script_colors() {
int hist_size = EditorSettings::get_singleton()->get("text_editor/script_list/script_temperature_history_size");
Color hot_color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ hot_color.set_s(hot_color.get_s() * 0.9);
Color cold_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
for (int i = 0; i < script_list->get_item_count(); i++) {
@@ -1953,6 +1955,7 @@ void ScriptEditor::_update_script_names() {
se->set_meta("_edit_res_path", path);
}
String name = se->get_name();
+ Ref<Script> scr = se->get_edited_resource();
_ScriptEditorItemData sd;
sd.icon = icon;
@@ -1962,6 +1965,9 @@ void ScriptEditor::_update_script_names() {
sd.used = used.has(se->get_edited_resource());
sd.category = 0;
sd.ref = se;
+ if (scr.is_valid()) {
+ sd.tool = scr->is_tool();
+ }
switch (sort_by) {
case SORT_BY_NAME: {
@@ -2081,8 +2087,14 @@ void ScriptEditor::_update_script_names() {
}
}
+ Color tool_color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ tool_color.set_s(tool_color.get_s() * 1.5);
for (int i = 0; i < sedata_filtered.size(); i++) {
script_list->add_item(sedata_filtered[i].name, sedata_filtered[i].icon);
+ if (sedata_filtered[i].tool) {
+ script_list->set_item_icon_modulate(script_list->get_item_count() - 1, tool_color);
+ }
+
int index = script_list->get_item_count() - 1;
script_list->set_item_tooltip(index, sedata_filtered[i].tooltip);
script_list->set_item_metadata(index, sedata_filtered[i].index); /* Saving as metadata the script's index in the tab container and not the filtered one */
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 97a882c383..ab094f4dc6 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -392,8 +392,17 @@ String ScriptTextEditor::get_name() {
}
Ref<Texture2D> ScriptTextEditor::get_theme_icon() {
- if (get_parent_control() && get_parent_control()->has_theme_icon(script->get_class(), "EditorIcons")) {
- return get_parent_control()->get_theme_icon(script->get_class(), "EditorIcons");
+ if (get_parent_control()) {
+ String icon_name = script->get_class();
+ if (script->is_built_in()) {
+ icon_name += "Internal";
+ }
+
+ if (get_parent_control()->has_theme_icon(icon_name, "EditorIcons")) {
+ return get_parent_control()->get_theme_icon(icon_name, "EditorIcons");
+ } else if (get_parent_control()->has_theme_icon(script->get_class(), "EditorIcons")) {
+ return get_parent_control()->get_theme_icon(script->get_class(), "EditorIcons");
+ }
}
return Ref<Texture2D>();
diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp
index 2da4f80751..3350cec912 100644
--- a/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -222,28 +222,14 @@ void SpriteFramesEditor::_sheet_add_frames() {
int fc = frames->get_frame_count(edited_anim);
- Point2 src_origin;
- Rect2 src_region(Point2(), texture_size);
-
- AtlasTexture *src_atlas = Object::cast_to<AtlasTexture>(*split_sheet_preview->get_texture());
- if (src_atlas && src_atlas->get_atlas().is_valid()) {
- src_origin = src_atlas->get_region().position - src_atlas->get_margin().position;
- src_region = src_atlas->get_region();
- }
-
for (Set<int>::Element *E = frames_selected.front(); E; E = E->next()) {
int idx = E->get();
Point2 frame_coords(idx % frame_count_x, idx / frame_count_x);
- Rect2 frame(frame_coords * frame_size + src_origin, frame_size);
- Rect2 region = frame.intersection(src_region);
- Rect2 margin(region == Rect2() ? Point2() : region.position - frame.position, frame.size - region.size);
-
Ref<AtlasTexture> at;
at.instantiate();
at->set_atlas(split_sheet_preview->get_texture());
- at->set_region(region);
- at->set_margin(margin);
+ at->set_region(Rect2(frame_coords * frame_size, frame_size));
undo_redo->add_do_method(frames, "add_frame", edited_anim, at, -1);
undo_redo->add_undo_method(frames, "remove_frame", edited_anim, fc);
diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp
index 1b28e84ca2..d5c2051f31 100644
--- a/editor/plugins/tiles/tile_data_editors.cpp
+++ b/editor/plugins/tiles/tile_data_editors.cpp
@@ -1148,6 +1148,7 @@ void TileDataDefaultEditor::setup_property_editor(Variant::Type p_type, String p
property_editor->set_label(p_label);
}
property_editor->connect("property_changed", callable_mp(this, &TileDataDefaultEditor::_property_value_changed).unbind(1));
+ property_editor->set_tooltip(p_property);
property_editor->update_property();
add_child(property_editor);
}
@@ -1356,6 +1357,7 @@ void TileDataCollisionEditor::_polygons_changed() {
one_way_property_editor->set_label(one_way_property);
one_way_property_editor->connect("property_changed", callable_mp(this, &TileDataCollisionEditor::_property_value_changed).unbind(1));
one_way_property_editor->connect("selected", callable_mp(this, &TileDataCollisionEditor::_property_selected));
+ one_way_property_editor->set_tooltip(one_way_property_editor->get_edited_property());
one_way_property_editor->update_property();
add_child(one_way_property_editor);
property_editors[one_way_property] = one_way_property_editor;
@@ -1367,6 +1369,7 @@ void TileDataCollisionEditor::_polygons_changed() {
one_way_margin_property_editor->set_label(one_way_margin_property);
one_way_margin_property_editor->connect("property_changed", callable_mp(this, &TileDataCollisionEditor::_property_value_changed).unbind(1));
one_way_margin_property_editor->connect("selected", callable_mp(this, &TileDataCollisionEditor::_property_selected));
+ one_way_margin_property_editor->set_tooltip(one_way_margin_property_editor->get_edited_property());
one_way_margin_property_editor->update_property();
add_child(one_way_margin_property_editor);
property_editors[one_way_margin_property] = one_way_margin_property_editor;
@@ -1527,6 +1530,7 @@ TileDataCollisionEditor::TileDataCollisionEditor() {
linear_velocity_editor->set_label("linear_velocity");
linear_velocity_editor->connect("property_changed", callable_mp(this, &TileDataCollisionEditor::_property_value_changed).unbind(1));
linear_velocity_editor->connect("selected", callable_mp(this, &TileDataCollisionEditor::_property_selected));
+ linear_velocity_editor->set_tooltip(linear_velocity_editor->get_edited_property());
linear_velocity_editor->update_property();
add_child(linear_velocity_editor);
property_editors["linear_velocity"] = linear_velocity_editor;
@@ -1536,6 +1540,7 @@ TileDataCollisionEditor::TileDataCollisionEditor() {
angular_velocity_editor->set_label("angular_velocity");
angular_velocity_editor->connect("property_changed", callable_mp(this, &TileDataCollisionEditor::_property_value_changed).unbind(1));
angular_velocity_editor->connect("selected", callable_mp(this, &TileDataCollisionEditor::_property_selected));
+ angular_velocity_editor->set_tooltip(angular_velocity_editor->get_edited_property());
angular_velocity_editor->update_property();
add_child(angular_velocity_editor);
property_editors["angular_velocity"] = angular_velocity_editor;
@@ -2505,6 +2510,7 @@ TileDataTerrainsEditor::TileDataTerrainsEditor() {
terrain_set_property_editor->set_object_and_property(dummy_object, "terrain_set");
terrain_set_property_editor->set_label("Terrain Set");
terrain_set_property_editor->connect("property_changed", callable_mp(this, &TileDataTerrainsEditor::_property_value_changed).unbind(1));
+ terrain_set_property_editor->set_tooltip(terrain_set_property_editor->get_edited_property());
add_child(terrain_set_property_editor);
terrain_property_editor = memnew(EditorPropertyEnum);
diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp
index f99fcb3675..cdde22f5bc 100644
--- a/editor/plugins/tiles/tiles_editor_plugin.cpp
+++ b/editor/plugins/tiles/tiles_editor_plugin.cpp
@@ -113,7 +113,7 @@ void TilesEditorPlugin::_thread() {
tile_map->set_scale(scale);
tile_map->set_position(-(scale * encompassing_rect.get_center()) + thumbnail_size2 / 2);
- // Add the viewport at the lasst moment to avoid rendering too early.
+ // Add the viewport at the last moment to avoid rendering too early.
EditorNode::get_singleton()->add_child(viewport);
RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast<TilesEditorPlugin *>(this), &TilesEditorPlugin::_preview_frame_started), Vector<Variant>(), Object::CONNECT_ONESHOT);
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index 1bf6243bcc..bcc597d595 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -215,7 +215,6 @@ void ProjectSettingsEditor::_add_feature_overrides() {
presets.insert("s3tc");
presets.insert("etc");
presets.insert("etc2");
- presets.insert("pvrtc");
presets.insert("debug");
presets.insert("release");
presets.insert("editor");
@@ -467,6 +466,14 @@ void ProjectSettingsEditor::_update_action_map_editor() {
action_map->update_action_list(actions);
}
+void ProjectSettingsEditor::_update_theme() {
+ search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ restart_close_button->set_icon(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
+ restart_container->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
+ restart_icon->set_texture(get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons")));
+ restart_label->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+}
+
void ProjectSettingsEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_VISIBILITY_CHANGED: {
@@ -476,21 +483,12 @@ void ProjectSettingsEditor::_notification(int p_what) {
} break;
case NOTIFICATION_ENTER_TREE: {
inspector->edit(ps);
-
- search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
- search_box->set_clear_button_enabled(true);
-
- restart_close_button->set_icon(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
- restart_container->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
- restart_icon->set_texture(get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons")));
- restart_label->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor")));
-
_update_action_map_editor();
+ _update_theme();
} break;
- case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
- search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
- search_box->set_clear_button_enabled(true);
- } break;
+ case NOTIFICATION_THEME_CHANGED:
+ _update_theme();
+ break;
}
}
@@ -524,6 +522,7 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
search_box = memnew(LineEdit);
search_box->set_placeholder(TTR("Filter Settings"));
+ search_box->set_clear_button_enabled(true);
search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
search_bar->add_child(search_box);
diff --git a/editor/project_settings_editor.h b/editor/project_settings_editor.h
index 26af73c54e..a8eed0093f 100644
--- a/editor/project_settings_editor.h
+++ b/editor/project_settings_editor.h
@@ -99,6 +99,7 @@ class ProjectSettingsEditor : public AcceptDialog {
void _action_renamed(const String &p_old_name, const String &p_new_name);
void _action_reordered(const String &p_action_name, const String &p_relative_to, bool p_before);
void _update_action_map_editor();
+ void _update_theme();
protected:
void _notification(int p_what);
diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp
index 0e34d200f2..20845b0e9d 100644
--- a/editor/rename_dialog.cpp
+++ b/editor/rename_dialog.cpp
@@ -527,7 +527,7 @@ String RenameDialog::_postprocess(const String &subject) {
// To Lowercase
result = result.to_lower();
} else if (case_id == 2) {
- // To Upercase
+ // To Uppercase
result = result.to_upper();
}
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index c1ceba27b3..dc95b73569 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -1256,6 +1256,10 @@ void SceneTreeDialog::popup_scenetree_dialog() {
popup_centered_clamped(Size2(350, 700) * EDSCALE);
}
+void SceneTreeDialog::_update_theme() {
+ filter->set_right_icon(tree->get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+}
+
void SceneTreeDialog::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_VISIBILITY_CHANGED: {
@@ -1265,8 +1269,10 @@ void SceneTreeDialog::_notification(int p_what) {
} break;
case NOTIFICATION_ENTER_TREE: {
connect("confirmed", callable_mp(this, &SceneTreeDialog::_select));
- filter->set_right_icon(tree->get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
- filter->set_clear_button_enabled(true);
+ _update_theme();
+ } break;
+ case NOTIFICATION_THEME_CHANGED: {
+ _update_theme();
} break;
case NOTIFICATION_EXIT_TREE: {
disconnect("confirmed", callable_mp(this, &SceneTreeDialog::_select));
@@ -1303,6 +1309,7 @@ SceneTreeDialog::SceneTreeDialog() {
filter = memnew(LineEdit);
filter->set_h_size_flags(Control::SIZE_EXPAND_FILL);
filter->set_placeholder(TTR("Filter nodes"));
+ filter->set_clear_button_enabled(true);
filter->add_theme_constant_override("minimum_character_width", 0);
filter->connect("text_changed", callable_mp(this, &SceneTreeDialog::_filter_changed));
vbc->add_child(filter);
diff --git a/editor/scene_tree_editor.h b/editor/scene_tree_editor.h
index 7fb1451934..39fe64b828 100644
--- a/editor/scene_tree_editor.h
+++ b/editor/scene_tree_editor.h
@@ -174,6 +174,7 @@ class SceneTreeDialog : public ConfirmationDialog {
void _select();
void _cancel();
void _filter_changed(const String &p_filter);
+ void _update_theme();
protected:
void _notification(int p_what);