summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/code_editor.cpp2
-rw-r--r--editor/debugger/editor_profiler.cpp196
-rw-r--r--editor/debugger/editor_profiler.h6
-rw-r--r--editor/editor_help_search.cpp27
-rw-r--r--editor/editor_help_search.h1
-rw-r--r--editor/editor_node.cpp2
-rw-r--r--editor/editor_plugin.cpp5
-rw-r--r--editor/editor_plugin.h1
-rw-r--r--editor/editor_properties.cpp3
-rw-r--r--editor/editor_themes.cpp1
-rw-r--r--editor/icons/PickerCursor.svg1
-rw-r--r--editor/import/resource_importer_scene.cpp2
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp9
-rw-r--r--editor/plugins/mesh_library_editor_plugin.cpp2
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp34
-rw-r--r--editor/plugins/node_3d_editor_plugin.h2
-rw-r--r--editor/plugins/script_text_editor.cpp3
-rw-r--r--editor/plugins/shader_editor_plugin.cpp4
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp2
-rw-r--r--editor/project_manager.cpp19
-rw-r--r--editor/property_editor.cpp3
-rw-r--r--editor/scene_tree_dock.cpp1
-rw-r--r--editor/scene_tree_editor.cpp6
-rw-r--r--editor/settings_config_dialog.cpp3
25 files changed, 155 insertions, 182 deletions
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index ac8bef817b..6ed2cb9d9c 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -142,7 +142,7 @@ bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col)
bool found = text_editor->search(text, p_flags, p_from_line, p_from_col, line, col);
if (found) {
- if (!preserve_cursor) {
+ if (!preserve_cursor && !is_selection_only()) {
text_editor->unfold_line(line);
text_editor->cursor_set_line(line, false);
text_editor->cursor_set_column(col + text.length(), false);
diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp
index c4290b7cca..6befee090b 100644
--- a/editor/debugger/editor_profiler.cpp
+++ b/editor/debugger/editor_profiler.cpp
@@ -43,28 +43,34 @@ void EditorProfiler::_make_metric_ptrs(Metric &m) {
}
}
+EditorProfiler::Metric EditorProfiler::_get_frame_metric(int index) {
+ return frame_metrics[(frame_metrics.size() + last_metric - (total_metrics - 1) + index) % frame_metrics.size()];
+}
+
void EditorProfiler::add_frame_metric(const Metric &p_metric, bool p_final) {
++last_metric;
if (last_metric >= frame_metrics.size()) {
last_metric = 0;
}
+ total_metrics++;
+ if (total_metrics > frame_metrics.size()) {
+ total_metrics = frame_metrics.size();
+ }
+
frame_metrics.write[last_metric] = p_metric;
_make_metric_ptrs(frame_metrics.write[last_metric]);
updating_frame = true;
- cursor_metric_edit->set_max(frame_metrics[last_metric].frame_number);
- cursor_metric_edit->set_min(MAX(frame_metrics[last_metric].frame_number - frame_metrics.size(), 0));
+ clear_button->set_disabled(false);
+ cursor_metric_edit->set_editable(true);
+ cursor_metric_edit->set_max(p_metric.frame_number);
+ cursor_metric_edit->set_min(_get_frame_metric(0).frame_number);
if (!seeking) {
- cursor_metric_edit->set_value(frame_metrics[last_metric].frame_number);
- if (hover_metric != -1) {
- hover_metric++;
- if (hover_metric >= frame_metrics.size()) {
- hover_metric = 0;
- }
- }
+ cursor_metric_edit->set_value(p_metric.frame_number);
}
+
updating_frame = false;
if (frame_delay->is_stopped()) {
@@ -83,6 +89,7 @@ void EditorProfiler::clear() {
metric_size = CLAMP(metric_size, 60, 1024);
frame_metrics.clear();
frame_metrics.resize(metric_size);
+ total_metrics = 0;
last_metric = -1;
variables->clear();
plot_sigs.clear();
@@ -93,6 +100,7 @@ void EditorProfiler::clear() {
cursor_metric_edit->set_min(0);
cursor_metric_edit->set_max(100); // Doesn't make much sense, but we can't have min == max. Doesn't hurt.
cursor_metric_edit->set_value(0);
+ cursor_metric_edit->set_editable(false);
updating_frame = false;
hover_metric = -1;
seeking = false;
@@ -187,11 +195,8 @@ void EditorProfiler::_update_plot() {
const bool use_self = display_time->get_selected() == DISPLAY_SELF_TIME;
float highest = 0;
- for (int i = 0; i < frame_metrics.size(); i++) {
- const Metric &m = frame_metrics[i];
- if (!m.valid) {
- continue;
- }
+ for (int i = 0; i < total_metrics; i++) {
+ const Metric &m = _get_frame_metric(i);
for (Set<StringName>::Element *E = plot_sigs.front(); E; E = E->next()) {
const Map<StringName, Metric::Category *>::Element *F = m.category_ptrs.find(E->get());
@@ -220,78 +225,43 @@ void EditorProfiler::_update_plot() {
int *column = columnv.ptrw();
- Map<StringName, int> plot_prev;
- //Map<StringName,int> plot_max;
+ Map<StringName, int> prev_plots;
- for (int i = 0; i < w; i++) {
+ for (int i = 0; i < total_metrics * w / frame_metrics.size() - 1; i++) {
for (int j = 0; j < h * 4; j++) {
column[j] = 0;
}
int current = i * frame_metrics.size() / w;
- int next = (i + 1) * frame_metrics.size() / w;
- if (next > frame_metrics.size()) {
- next = frame_metrics.size();
- }
- if (next == current) {
- next = current + 1; //just because for loop must work
- }
for (Set<StringName>::Element *E = plot_sigs.front(); E; E = E->next()) {
- int plot_pos = -1;
+ const Metric &m = _get_frame_metric(current);
- for (int j = current; j < next; j++) {
- //wrap
- int idx = last_metric + 1 + j;
- while (idx >= frame_metrics.size()) {
- idx -= frame_metrics.size();
- }
-
- //get
- const Metric &m = frame_metrics[idx];
- if (!m.valid) {
- continue; //skip because invalid
- }
+ float value = 0;
- float value = 0;
-
- const Map<StringName, Metric::Category *>::Element *F = m.category_ptrs.find(E->get());
- if (F) {
- value = F->get()->total_time;
- }
+ const Map<StringName, Metric::Category *>::Element *F = m.category_ptrs.find(E->get());
+ if (F) {
+ value = F->get()->total_time;
+ }
- const Map<StringName, Metric::Category::Item *>::Element *G = m.item_ptrs.find(E->get());
- if (G) {
- if (use_self) {
- value = G->get()->self;
- } else {
- value = G->get()->total;
- }
+ const Map<StringName, Metric::Category::Item *>::Element *G = m.item_ptrs.find(E->get());
+ if (G) {
+ if (use_self) {
+ value = G->get()->self;
+ } else {
+ value = G->get()->total;
}
-
- plot_pos = MAX(CLAMP(int(value * h / highest), 0, h - 1), plot_pos);
}
+ int plot_pos = CLAMP(int(value * h / highest), 0, h - 1);
+
int prev_plot = plot_pos;
- Map<StringName, int>::Element *H = plot_prev.find(E->get());
+ Map<StringName, int>::Element *H = prev_plots.find(E->get());
if (H) {
prev_plot = H->get();
H->get() = plot_pos;
} else {
- plot_prev[E->get()] = plot_pos;
- }
-
- if (plot_pos == -1 && prev_plot == -1) {
- //don't bother drawing
- continue;
- }
-
- if (prev_plot != -1 && plot_pos == -1) {
- plot_pos = prev_plot;
- }
-
- if (prev_plot == -1 && plot_pos != -1) {
- prev_plot = plot_pos;
+ prev_plots[E->get()] = plot_pos;
}
plot_pos = h - plot_pos - 1;
@@ -352,15 +322,13 @@ void EditorProfiler::_update_plot() {
}
void EditorProfiler::_update_frame() {
- int cursor_metric = _get_cursor_index();
-
- ERR_FAIL_INDEX(cursor_metric, frame_metrics.size());
+ int cursor_metric = cursor_metric_edit->get_value() - _get_frame_metric(0).frame_number;
updating_frame = true;
variables->clear();
TreeItem *root = variables->create_item();
- const Metric &m = frame_metrics[cursor_metric];
+ const Metric &m = _get_frame_metric(cursor_metric);
int dtime = display_time->get_selected();
@@ -410,6 +378,7 @@ void EditorProfiler::_activate_pressed() {
if (activate->is_pressed()) {
activate->set_icon(get_theme_icon("Stop", "EditorIcons"));
activate->set_text(TTR("Stop"));
+ _clear_pressed();
} else {
activate->set_icon(get_theme_icon("Play", "EditorIcons"));
activate->set_text(TTR("Start"));
@@ -418,6 +387,7 @@ void EditorProfiler::_activate_pressed() {
}
void EditorProfiler::_clear_pressed() {
+ clear_button->set_disabled(true);
clear();
_update_plot();
}
@@ -430,30 +400,16 @@ void EditorProfiler::_notification(int p_what) {
}
void EditorProfiler::_graph_tex_draw() {
- if (last_metric < 0) {
+ if (total_metrics == 0) {
return;
}
if (seeking) {
- int max_frames = frame_metrics.size();
- int frame = cursor_metric_edit->get_value() - (frame_metrics[last_metric].frame_number - max_frames + 1);
- if (frame < 0) {
- frame = 0;
- }
-
- int cur_x = frame * graph->get_size().x / max_frames;
-
+ int frame = cursor_metric_edit->get_value() - _get_frame_metric(0).frame_number;
+ int cur_x = (2 * frame + 1) * graph->get_size().x / (2 * frame_metrics.size()) + 1;
graph->draw_line(Vector2(cur_x, 0), Vector2(cur_x, graph->get_size().y), Color(1, 1, 1, 0.8));
}
-
- if (hover_metric != -1 && frame_metrics[hover_metric].valid) {
- int max_frames = frame_metrics.size();
- int frame = frame_metrics[hover_metric].frame_number - (frame_metrics[last_metric].frame_number - max_frames + 1);
- if (frame < 0) {
- frame = 0;
- }
-
- int cur_x = frame * graph->get_size().x / max_frames;
-
+ if (hover_metric > -1 && hover_metric < total_metrics) {
+ int cur_x = (2 * hover_metric + 1) * graph->get_size().x / (2 * frame_metrics.size()) + 1;
graph->draw_line(Vector2(cur_x, 0), Vector2(cur_x, graph->get_size().y), Color(1, 1, 1, 0.4));
}
}
@@ -484,10 +440,10 @@ void EditorProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) {
if (
(mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_LEFT && mb->is_pressed()) ||
(mm.is_valid())) {
- int x = me->get_position().x;
+ int x = me->get_position().x - 1;
x = x * frame_metrics.size() / graph->get_size().width;
- bool show_hover = x >= 0 && x < frame_metrics.size();
+ hover_metric = x;
if (x < 0) {
x = 0;
@@ -497,41 +453,11 @@ void EditorProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) {
x = frame_metrics.size() - 1;
}
- int metric = frame_metrics.size() - x - 1;
- metric = last_metric - metric;
- while (metric < 0) {
- metric += frame_metrics.size();
- }
-
- if (show_hover) {
- hover_metric = metric;
-
- } else {
- hover_metric = -1;
- }
-
if (mb.is_valid() || mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) {
- //cursor_metric=x;
updating_frame = true;
- //metric may be invalid, so look for closest metric that is valid, this makes snap feel better
- bool valid = false;
- for (int i = 0; i < frame_metrics.size(); i++) {
- if (frame_metrics[metric].valid) {
- valid = true;
- break;
- }
-
- metric++;
- if (metric >= frame_metrics.size()) {
- metric = 0;
- }
- }
-
- if (valid) {
- cursor_metric_edit->set_value(frame_metrics[metric].frame_number);
- }
-
+ if (x < total_metrics)
+ cursor_metric_edit->set_value(_get_frame_metric(x).frame_number);
updating_frame = false;
if (activate->is_pressed()) {
@@ -552,24 +478,6 @@ void EditorProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) {
}
}
-int EditorProfiler::_get_cursor_index() const {
- if (last_metric < 0) {
- return 0;
- }
- if (!frame_metrics[last_metric].valid) {
- return 0;
- }
-
- int diff = (frame_metrics[last_metric].frame_number - cursor_metric_edit->get_value());
-
- int idx = last_metric - diff;
- while (idx < 0) {
- idx += frame_metrics.size();
- }
-
- return idx;
-}
-
void EditorProfiler::disable_seeking() {
seeking = false;
graph->update();
@@ -659,6 +567,7 @@ EditorProfiler::EditorProfiler() {
clear_button = memnew(Button);
clear_button->set_text(TTR("Clear"));
clear_button->connect("pressed", callable_mp(this, &EditorProfiler::_clear_pressed));
+ clear_button->set_disabled(true);
hb->add_child(clear_button);
hb->add_child(memnew(Label(TTR("Measure:"))));
@@ -687,6 +596,8 @@ EditorProfiler::EditorProfiler() {
cursor_metric_edit = memnew(SpinBox);
cursor_metric_edit->set_h_size_flags(SIZE_FILL);
+ cursor_metric_edit->set_value(0);
+ cursor_metric_edit->set_editable(false);
hb->add_child(cursor_metric_edit);
cursor_metric_edit->connect("value_changed", callable_mp(this, &EditorProfiler::_cursor_metric_changed));
@@ -726,6 +637,7 @@ EditorProfiler::EditorProfiler() {
int metric_size = CLAMP(int(EDITOR_DEF("debugger/profiler_frame_history_size", 600)), 60, 1024);
frame_metrics.resize(metric_size);
+ total_metrics = 0;
last_metric = -1;
hover_metric = -1;
diff --git a/editor/debugger/editor_profiler.h b/editor/debugger/editor_profiler.h
index e16bde41f6..8880824b87 100644
--- a/editor/debugger/editor_profiler.h
+++ b/editor/debugger/editor_profiler.h
@@ -106,13 +106,13 @@ private:
SpinBox *cursor_metric_edit;
Vector<Metric> frame_metrics;
+ int total_metrics;
int last_metric;
int max_functions;
bool updating_frame;
- //int cursor_metric;
int hover_metric;
float graph_height;
@@ -139,14 +139,14 @@ private:
void _graph_tex_draw();
void _graph_tex_input(const Ref<InputEvent> &p_ev);
- int _get_cursor_index() const;
-
Color _get_color_from_signature(const StringName &p_signature) const;
void _cursor_metric_changed(double);
void _combo_changed(int);
+ Metric _get_frame_metric(int index);
+
protected:
void _notification(int p_what);
static void _bind_methods();
diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp
index a1ff87fe2e..23226ffa9b 100644
--- a/editor/editor_help_search.cpp
+++ b/editor/editor_help_search.cpp
@@ -123,7 +123,7 @@ void EditorHelpSearch::_notification(int p_what) {
if (search->work()) {
// Search done.
- // Only point to the perfect match if it's a new search, and not just reopening a old one.
+ // Only point to the match if it's a new search, and not just reopening a old one.
if (!old_search) {
results_tree->ensure_cursor_is_visible();
} else {
@@ -310,6 +310,7 @@ bool EditorHelpSearch::Runner::_phase_match_classes_init() {
iterator_doc = EditorHelp::get_doc_data()->class_list.front();
matches.clear();
matched_item = nullptr;
+ match_highest_score = 0;
return true;
}
@@ -460,16 +461,20 @@ bool EditorHelpSearch::Runner::_match_string(const String &p_term, const String
}
void EditorHelpSearch::Runner::_match_item(TreeItem *p_item, const String &p_text) {
- if (!matched_item) {
- if (search_flags & SEARCH_CASE_SENSITIVE) {
- if (p_text.casecmp_to(term) == 0) {
- matched_item = p_item;
- }
- } else {
- if (p_text.nocasecmp_to(term) == 0) {
- matched_item = p_item;
- }
- }
+ float inverse_length = 1.f / float(p_text.length());
+
+ // Favor types where search term is a substring close to the start of the type.
+ float w = 0.5f;
+ int pos = p_text.findn(term);
+ float score = (pos > -1) ? 1.0f - w * MIN(1, 3 * pos * inverse_length) : MAX(0.f, .9f - w);
+
+ // Favor shorter items: they resemble the search term more.
+ w = 0.1f;
+ score *= (1 - w) + w * (term.length() * inverse_length);
+
+ if (match_highest_score == 0 || score > match_highest_score) {
+ matched_item = p_item;
+ match_highest_score = score;
}
}
diff --git a/editor/editor_help_search.h b/editor/editor_help_search.h
index 0e236d523d..350a02315f 100644
--- a/editor/editor_help_search.h
+++ b/editor/editor_help_search.h
@@ -124,6 +124,7 @@ class EditorHelpSearch::Runner : public Reference {
TreeItem *root_item = nullptr;
Map<String, TreeItem *> class_items;
TreeItem *matched_item = nullptr;
+ float match_highest_score = 0;
bool _is_class_disabled_by_feature_profile(const StringName &p_class);
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 9ca46cfcc0..055baeb81e 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -5892,6 +5892,8 @@ EditorNode::EditorNode() {
EDITOR_DEF("interface/inspector/resources_to_open_in_new_inspector", "Script,MeshLibrary,TileSet");
EDITOR_DEF("interface/inspector/default_color_picker_mode", 0);
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/inspector/default_color_picker_mode", PROPERTY_HINT_ENUM, "RGB,HSV,RAW", PROPERTY_USAGE_DEFAULT));
+ EDITOR_DEF("interface/inspector/default_color_picker_shape", (int32_t)ColorPicker::SHAPE_VHS_CIRCLE);
+ 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);
theme_base = memnew(Control);
diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp
index 064271fce8..eabcbacd9a 100644
--- a/editor/editor_plugin.cpp
+++ b/editor/editor_plugin.cpp
@@ -160,6 +160,10 @@ void EditorInterface::edit_resource(const Ref<Resource> &p_resource) {
EditorNode::get_singleton()->edit_resource(p_resource);
}
+void EditorInterface::edit_node(Node *p_node) {
+ EditorNode::get_singleton()->edit_node(p_node);
+}
+
void EditorInterface::open_scene_from_path(const String &scene_path) {
if (EditorNode::get_singleton()->is_changing_scene()) {
return;
@@ -312,6 +316,7 @@ void EditorInterface::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_base_control"), &EditorInterface::get_base_control);
ClassDB::bind_method(D_METHOD("get_editor_scale"), &EditorInterface::get_editor_scale);
ClassDB::bind_method(D_METHOD("edit_resource", "resource"), &EditorInterface::edit_resource);
+ ClassDB::bind_method(D_METHOD("edit_node", "node"), &EditorInterface::edit_node);
ClassDB::bind_method(D_METHOD("open_scene_from_path", "scene_filepath"), &EditorInterface::open_scene_from_path);
ClassDB::bind_method(D_METHOD("reload_scene_from_path", "scene_filepath"), &EditorInterface::reload_scene_from_path);
ClassDB::bind_method(D_METHOD("play_main_scene"), &EditorInterface::play_main_scene);
diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h
index b0713c641b..67b163eabf 100644
--- a/editor/editor_plugin.h
+++ b/editor/editor_plugin.h
@@ -71,6 +71,7 @@ public:
Control *get_editor_main_control();
void edit_resource(const Ref<Resource> &p_resource);
+ void edit_node(Node *p_node);
void open_scene_from_path(const String &scene_path);
void reload_scene_from_path(const String &scene_path);
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index fa44239e32..4ea993af5b 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -2190,6 +2190,9 @@ void EditorPropertyColor::_picker_created() {
} else if (default_color_mode == 2) {
picker->get_picker()->set_raw_mode(true);
}
+
+ int picker_shape = EDITOR_GET("interface/inspector/default_color_picker_shape");
+ picker->get_picker()->set_picker_shape((ColorPicker::PickerShapeType)picker_shape);
}
void EditorPropertyColor::_picker_opening() {
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 35cf330714..4c5c3af765 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -1282,6 +1282,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("preset_bg", "ColorPicker", theme->get_icon("GuiMiniCheckerboard", "EditorIcons"));
theme->set_icon("overbright_indicator", "ColorPicker", theme->get_icon("OverbrightIndicator", "EditorIcons"));
theme->set_icon("bar_arrow", "ColorPicker", theme->get_icon("ColorPickerBarArrow", "EditorIcons"));
+ theme->set_icon("picker_cursor", "ColorPicker", theme->get_icon("PickerCursor", "EditorIcons"));
theme->set_icon("bg", "ColorPickerButton", theme->get_icon("GuiMiniCheckerboard", "EditorIcons"));
diff --git a/editor/icons/PickerCursor.svg b/editor/icons/PickerCursor.svg
new file mode 100644
index 0000000000..88ee3f55ce
--- /dev/null
+++ b/editor/icons/PickerCursor.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0 -6-6zm0 1a5 5 0 0 1 5 5 5 5 0 0 1 -5 5 5 5 0 0 1 -5-5 5 5 0 0 1 5-5z" fill="#fff"/><path d="m8 3a5 5 0 0 0 -5 5 5 5 0 0 0 5 5 5 5 0 0 0 5-5 5 5 0 0 0 -5-5zm-.0605469 1a4 4 0 0 1 .0605469 0 4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 3.9394531-4z"/></svg>
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index 9041b815ca..4bb56beaeb 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -1241,7 +1241,7 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m
if (mesh.is_valid()) {
mesh_node->set_mesh(mesh);
for (int i = 0; i < mesh->get_surface_count(); i++) {
- mesh_node->set_surface_material(i, src_mesh_node->get_surface_material(i));
+ mesh_node->set_surface_override_material(i, src_mesh_node->get_surface_material(i));
}
}
}
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index b678197037..f1c9cb120d 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -804,11 +804,15 @@ void CanvasItemEditor::_find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_n
bool CanvasItemEditor::_select_click_on_item(CanvasItem *item, Point2 p_click_pos, bool p_append) {
bool still_selected = true;
- if (p_append) {
+ if (p_append && !editor_selection->get_selected_node_list().is_empty()) {
if (editor_selection->is_selected(item)) {
// Already in the selection, remove it from the selected nodes
editor_selection->remove_node(item);
still_selected = false;
+
+ if (editor_selection->get_selected_node_list().size() == 1) {
+ editor->push_item(editor_selection->get_selected_node_list()[0]);
+ }
} else {
// Add the item to the selection
editor_selection->add_node(item);
@@ -2589,6 +2593,9 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
}
_find_canvas_items_in_rect(Rect2(bsfrom, bsto - bsfrom), scene, &selitems);
+ if (selitems.size() == 1 && editor_selection->get_selected_node_list().is_empty()) {
+ editor->push_item(selitems[0]);
+ }
for (List<CanvasItem *>::Element *E = selitems.front(); E; E = E->next()) {
editor_selection->add_node(E->get());
}
diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp
index f8932cd534..6f1f243444 100644
--- a/editor/plugins/mesh_library_editor_plugin.cpp
+++ b/editor/plugins/mesh_library_editor_plugin.cpp
@@ -93,7 +93,7 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library,
mesh = mesh->duplicate();
for (int j = 0; j < mesh->get_surface_count(); ++j) {
- Ref<Material> mat = mi->get_surface_material(j);
+ Ref<Material> mat = mi->get_surface_override_material(j);
if (mat.is_valid()) {
mesh->surface_set_material(j, mat);
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index cbe0133034..3df092bc13 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -1279,7 +1279,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
clicked = ObjectID();
clicked_includes_current = false;
- if ((spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT && b->get_control()) || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE) {
+ if ((spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT && b->get_command()) || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE) {
/* HANDLE ROTATION */
if (get_selected_count() == 0) {
break; //bye
@@ -2215,6 +2215,12 @@ void Node3DEditorViewport::scale_cursor_distance(real_t scale) {
cursor.distance = CLAMP(cursor.distance * scale, min_distance, max_distance);
}
+ if (cursor.distance == max_distance || cursor.distance == min_distance) {
+ zoom_failed_attempts_count++;
+ } else {
+ zoom_failed_attempts_count = 0;
+ }
+
zoom_indicator_delay = ZOOM_FREELOOK_INDICATOR_DELAY_S;
surface->update();
}
@@ -2396,6 +2402,7 @@ void Node3DEditorViewport::_notification(int p_what) {
zoom_indicator_delay -= delta;
if (zoom_indicator_delay <= 0) {
surface->update();
+ zoom_limit_label->hide();
}
}
@@ -2535,6 +2542,8 @@ void Node3DEditorViewport::_notification(int p_what) {
cpu_time += cpu_time_history[i];
}
cpu_time /= FRAME_TIME_HISTORY;
+ // Prevent unrealistically low values.
+ cpu_time = MAX(0.01, cpu_time);
gpu_time_history[gpu_time_history_index] = RS::get_singleton()->viewport_get_measured_render_time_gpu(viewport->get_viewport_rid());
gpu_time_history_index = (gpu_time_history_index + 1) % FRAME_TIME_HISTORY;
@@ -2543,16 +2552,19 @@ void Node3DEditorViewport::_notification(int p_what) {
gpu_time += gpu_time_history[i];
}
gpu_time /= FRAME_TIME_HISTORY;
+ // Prevent division by zero for the FPS counter (and unrealistically low values).
+ // This limits the reported FPS to 100000.
+ gpu_time = MAX(0.01, gpu_time);
// Color labels depending on performance level ("good" = green, "OK" = yellow, "bad" = red).
// Middle point is at 15 ms.
- cpu_time_label->set_text(vformat(TTR("CPU Time: %s ms"), String::num(cpu_time, 1)));
+ cpu_time_label->set_text(vformat(TTR("CPU Time: %s ms"), rtos(cpu_time).pad_decimals(1)));
cpu_time_label->add_theme_color_override(
"font_color",
frame_time_gradient->get_color_at_offset(
Math::range_lerp(cpu_time, 0, 30, 0, 1)));
- gpu_time_label->set_text(vformat(TTR("GPU Time: %s ms"), String::num(gpu_time, 1)));
+ gpu_time_label->set_text(vformat(TTR("GPU Time: %s ms"), rtos(gpu_time).pad_decimals(1)));
// Middle point is at 15 ms.
gpu_time_label->add_theme_color_override(
"font_color",
@@ -2770,6 +2782,7 @@ void Node3DEditorViewport::_draw() {
} else {
// Show zoom
+ zoom_limit_label->set_visible(zoom_failed_attempts_count > 15);
real_t min_distance = MAX(camera->get_near() * 4, ZOOM_FREELOOK_MIN);
real_t max_distance = MIN(camera->get_far() / 4, ZOOM_FREELOOK_MAX);
@@ -3647,9 +3660,9 @@ Vector3 Node3DEditorViewport::_get_instance_position(const Point2 &p_pos) const
AABB Node3DEditorViewport::_calculate_spatial_bounds(const Node3D *p_parent, bool p_exclude_top_level_transform) {
AABB bounds;
- const MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(p_parent);
- if (mesh_instance) {
- bounds = mesh_instance->get_aabb();
+ const VisualInstance3D *visual_instance = Object::cast_to<VisualInstance3D>(p_parent);
+ if (visual_instance) {
+ bounds = visual_instance->get_aabb();
}
for (int i = 0; i < p_parent->get_child_count(); i++) {
@@ -4132,6 +4145,15 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito
locked_label->set_text(TTR("View Rotation Locked"));
locked_label->hide();
+ zoom_limit_label = memnew(Label);
+ zoom_limit_label->set_anchors_and_offsets_preset(LayoutPreset::PRESET_BOTTOM_LEFT);
+ zoom_limit_label->set_offset(Side::SIDE_TOP, -28 * EDSCALE);
+ zoom_limit_label->set_text(TTR("To zoom further, change the camera's clipping planes (View -> Settings...)"));
+ zoom_limit_label->set_name("ZoomLimitMessageLabel");
+ zoom_limit_label->add_theme_color_override("font_color", Color(1, 1, 1, 1));
+ zoom_limit_label->hide();
+ surface->add_child(zoom_limit_label);
+
frame_time_gradient = memnew(Gradient);
// The color is set when the theme changes.
frame_time_gradient->add_point(0.5, Color());
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index ff4a941b06..70329f90c7 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -295,6 +295,7 @@ private:
Label *info_label;
Label *cinema_label;
Label *locked_label;
+ Label *zoom_limit_label;
VBoxContainer *top_right_vbox;
ViewportRotationControl *rotation_control;
@@ -418,6 +419,7 @@ private:
void scale_freelook_speed(real_t scale);
real_t zoom_indicator_delay;
+ int zoom_failed_attempts_count = 0;
RID move_gizmo_instance[3], move_plane_gizmo_instance[3], rotate_gizmo_instance[4], scale_gizmo_instance[3], scale_plane_gizmo_instance[3];
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 3534809891..c982207224 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -1721,6 +1721,9 @@ void ScriptTextEditor::_enable_code_editor() {
color_picker->set_raw_mode(true);
}
+ int picker_shape = EDITOR_GET("interface/inspector/default_color_picker_shape");
+ color_picker->set_picker_shape((ColorPicker::PickerShapeType)picker_shape);
+
quick_open = memnew(ScriptEditorQuickOpen);
quick_open->connect("goto_line", callable_mp(this, &ScriptTextEditor::_goto_line));
add_child(quick_open);
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 8f8a4b3054..ed3b746678 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -205,7 +205,7 @@ void ShaderTextEditor::_code_complete_script(const String &p_code, List<ScriptCo
ShaderLanguage sl;
String calltip;
- sl.complete(p_code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type, r_options, calltip);
+ sl.complete(p_code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderLanguage::VaryingFunctionNames(), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type, r_options, calltip);
get_text_editor()->set_code_hint(calltip);
}
@@ -219,7 +219,7 @@ void ShaderTextEditor::_validate_script() {
ShaderLanguage sl;
- Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type);
+ Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderLanguage::VaryingFunctionNames(), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type);
if (err != OK) {
String error_text = "error(" + itos(sl.get_error_line()) + "): " + sl.get_error_text();
diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp
index ad60984ad1..404ef62eca 100644
--- a/editor/plugins/skeleton_3d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_3d_editor_plugin.cpp
@@ -515,6 +515,8 @@ void Skeleton3DEditor::_joint_tree_selection_changed() {
rest_editor->set_target(bone_path + "rest");
custom_pose_editor->set_target(bone_path + "custom_pose");
+ _update_properties();
+
pose_editor->set_visible(true);
rest_editor->set_visible(true);
custom_pose_editor->set_visible(true);
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index b2fa9c540e..e5b8dfd464 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -3398,7 +3398,7 @@ void VisualShaderEditor::_update_preview() {
ShaderLanguage sl;
- Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type);
+ Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderLanguage::VaryingFunctionNames(), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type);
for (int i = 0; i < preview_text->get_line_count(); i++) {
preview_text->set_line_as_marked(i, false);
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index d3def86bd1..1e79bb81d1 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -296,7 +296,7 @@ private:
String sp = _test_path();
if (sp != "") {
// If the project name is empty or default, infer the project name from the selected folder name
- if (project_name->get_text() == "" || project_name->get_text() == TTR("New Game Project")) {
+ if (project_name->get_text().strip_edges() == "" || project_name->get_text().strip_edges() == TTR("New Game Project")) {
sp = sp.replace("\\", "/");
int lidx = sp.rfind("/");
@@ -380,16 +380,17 @@ private:
}
void _create_folder() {
- if (project_name->get_text() == "" || created_folder_path != "" || project_name->get_text().ends_with(".") || project_name->get_text().ends_with(" ")) {
- set_message(TTR("Invalid Project Name."), MESSAGE_WARNING);
+ const String project_name_no_edges = project_name->get_text().strip_edges();
+ if (project_name_no_edges == "" || created_folder_path != "" || project_name_no_edges.ends_with(".")) {
+ set_message(TTR("Invalid project name."), MESSAGE_WARNING);
return;
}
DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
if (d->change_dir(project_path->get_text()) == OK) {
- if (!d->dir_exists(project_name->get_text())) {
- if (d->make_dir(project_name->get_text()) == OK) {
- d->change_dir(project_name->get_text());
+ if (!d->dir_exists(project_name_no_edges)) {
+ if (d->make_dir(project_name_no_edges) == OK) {
+ d->change_dir(project_name_no_edges);
String dir_str = d->get_current_dir();
project_path->set_text(dir_str);
_path_text_changed(dir_str);
@@ -415,7 +416,7 @@ private:
_test_path();
- if (p_text == "") {
+ if (p_text.strip_edges() == "") {
set_message(TTR("It would be a good idea to name your project."), MESSAGE_ERROR);
}
}
@@ -442,7 +443,7 @@ private:
set_message(vformat(TTR("Couldn't load project.godot in project path (error %d). It may be missing or corrupted."), err), MESSAGE_ERROR);
} else {
ProjectSettings::CustomMap edited_settings;
- edited_settings["application/config/name"] = project_name->get_text();
+ edited_settings["application/config/name"] = project_name->get_text().strip_edges();
if (current->save_custom(dir2.plus_file("project.godot"), edited_settings, Vector<String>(), true) != OK) {
set_message(TTR("Couldn't edit project.godot in project path."), MESSAGE_ERROR);
@@ -483,7 +484,7 @@ private:
initial_settings["rendering/textures/vram_compression/import_etc2"] = false;
initial_settings["rendering/textures/vram_compression/import_etc"] = true;
}
- initial_settings["application/config/name"] = project_name->get_text();
+ initial_settings["application/config/name"] = project_name->get_text().strip_edges();
initial_settings["application/config/icon"] = "res://icon.png";
initial_settings["rendering/environment/defaults/default_environment"] = "res://default_env.tres";
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index 0a4f432e4a..1a010b9168 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -832,6 +832,9 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
} else if (default_color_mode == 2) {
color_picker->set_raw_mode(true);
}
+
+ int picker_shape = EDITOR_GET("interface/inspector/default_color_picker_shape");
+ color_picker->set_picker_shape((ColorPicker::PickerShapeType)picker_shape);
}
color_picker->show();
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index c62e9cbe5f..5e6ebc22a3 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -3095,6 +3095,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
edit_remote->set_h_size_flags(SIZE_EXPAND_FILL);
edit_remote->set_text(TTR("Remote"));
edit_remote->set_toggle_mode(true);
+ edit_remote->set_tooltip(TTR("If selected, the Remote scene tree dock will cause the project to stutter every time it updates.\nSwitch back to the Local scene tree dock to improve performance."));
edit_remote->connect("pressed", callable_mp(this, &SceneTreeDock::_remote_tree_selected));
edit_local = memnew(Button);
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index b5e9aec854..ec37fa53b3 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -120,7 +120,7 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i
}
undo_redo->commit_action();
} else if (p_id == BUTTON_WARNING) {
- String config_err = n->get_configuration_warning();
+ String config_err = n->get_configuration_warnings_as_string();
if (config_err == String()) {
return;
}
@@ -252,9 +252,9 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll
if (can_rename) { //should be can edit..
- String warning = p_node->get_configuration_warning();
+ String warning = p_node->get_configuration_warnings_as_string();
if (!warning.is_empty()) {
- item->add_button(0, get_theme_icon("NodeWarning", "EditorIcons"), BUTTON_WARNING, false, TTR("Node configuration warning:") + "\n" + p_node->get_configuration_warning());
+ item->add_button(0, get_theme_icon("NodeWarning", "EditorIcons"), BUTTON_WARNING, false, TTR("Node configuration warning:") + "\n" + warning);
}
int num_connections = p_node->get_persistent_signal_connection_count();
diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp
index 3be2136a20..81af4996ed 100644
--- a/editor/settings_config_dialog.cpp
+++ b/editor/settings_config_dialog.cpp
@@ -393,9 +393,10 @@ void EditorSettingsDialog::_shortcut_button_pressed(Object *p_item, int p_column
TreeItem *ti = Object::cast_to<TreeItem>(p_item);
ERR_FAIL_COND(!ti);
+ button_idx = p_idx;
+
if (ti->get_metadata(0) == "Common") {
// Editing a Built-in action, which can have multiple bindings.
- button_idx = p_idx;
editing_action = true;
current_action = ti->get_text(0);