summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/create_dialog.cpp22
-rw-r--r--editor/doc_tools.cpp3
-rw-r--r--editor/editor_atlas_packer.cpp62
-rw-r--r--editor/editor_atlas_packer.h2
-rw-r--r--editor/editor_settings_dialog.cpp5
-rw-r--r--editor/editor_translation.cpp6
-rw-r--r--editor/import/dynamic_font_import_settings.cpp4
-rw-r--r--editor/import/editor_import_collada.cpp2
-rw-r--r--editor/import/resource_importer_scene.cpp16
-rw-r--r--editor/import/resource_importer_texture_atlas.cpp9
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp42
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h1
-rw-r--r--editor/plugins/control_editor_plugin.cpp8
-rw-r--r--editor/plugins/node_3d_editor_gizmos.cpp5
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp79
-rw-r--r--editor/plugins/node_3d_editor_plugin.h5
-rw-r--r--editor/plugins/script_editor_plugin.cpp2
-rw-r--r--editor/plugins/tiles/tile_map_editor.cpp9
-rw-r--r--editor/plugins/tiles/tile_set_atlas_source_editor.cpp2
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp4
-rw-r--r--editor/script_create_dialog.cpp82
-rw-r--r--editor/script_create_dialog.h1
22 files changed, 206 insertions, 165 deletions
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index 081f0ac868..7e59fc31c4 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -235,19 +235,19 @@ void CreateDialog::_add_type(const String &p_type, const TypeCategory p_type_cat
}
} else {
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> 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);
+ 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 = 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;
}
diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp
index 250182b8fc..a9d18e9dcc 100644
--- a/editor/doc_tools.cpp
+++ b/editor/doc_tools.cpp
@@ -1468,7 +1468,8 @@ Error DocTools::save_classes(const String &p_default_path, const Map<String, Str
Error DocTools::load_compressed(const uint8_t *p_data, int p_compressed_size, int p_uncompressed_size) {
Vector<uint8_t> data;
data.resize(p_uncompressed_size);
- Compression::decompress(data.ptrw(), p_uncompressed_size, p_data, p_compressed_size, Compression::MODE_DEFLATE);
+ int ret = Compression::decompress(data.ptrw(), p_uncompressed_size, p_data, p_compressed_size, Compression::MODE_DEFLATE);
+ ERR_FAIL_COND_V_MSG(ret == -1, ERR_FILE_CORRUPT, "Compressed file is corrupt.");
class_list.clear();
Ref<XMLParser> parser = memnew(XMLParser);
diff --git a/editor/editor_atlas_packer.cpp b/editor/editor_atlas_packer.cpp
index aad32968de..9c6bcd769a 100644
--- a/editor/editor_atlas_packer.cpp
+++ b/editor/editor_atlas_packer.cpp
@@ -30,60 +30,10 @@
#include "editor_atlas_packer.h"
+#include "core/math/geometry_2d.h"
#include "core/math/vector2.h"
#include "core/math/vector2i.h"
-void EditorAtlasPacker::_plot_triangle(Ref<BitMap> p_bitmap, Vector2i *vertices) {
- int width = p_bitmap->get_size().width;
- int height = p_bitmap->get_size().height;
- int x[3];
- int y[3];
-
- for (int j = 0; j < 3; j++) {
- x[j] = vertices[j].x;
- y[j] = vertices[j].y;
- }
-
- // sort the points vertically
- if (y[1] > y[2]) {
- SWAP(x[1], x[2]);
- SWAP(y[1], y[2]);
- }
- if (y[0] > y[1]) {
- SWAP(x[0], x[1]);
- SWAP(y[0], y[1]);
- }
- if (y[1] > y[2]) {
- SWAP(x[1], x[2]);
- SWAP(y[1], y[2]);
- }
-
- double dx_far = double(x[2] - x[0]) / (y[2] - y[0] + 1);
- double dx_upper = double(x[1] - x[0]) / (y[1] - y[0] + 1);
- double dx_low = double(x[2] - x[1]) / (y[2] - y[1] + 1);
- double xf = x[0];
- double xt = x[0] + dx_upper; // if y[0] == y[1], special case
- for (int yi = y[0]; yi <= (y[2] > height - 1 ? height - 1 : y[2]); yi++) {
- if (yi >= 0) {
- for (int xi = (xf > 0 ? int(xf) : 0); xi <= (xt < width ? xt : width - 1); xi++) {
- //pixels[int(x + y * width)] = color;
-
- p_bitmap->set_bit(Point2(xi, yi), true);
- }
-
- for (int xi = (xf < width ? int(xf) : width - 1); xi >= (xt > 0 ? xt : 0); xi--) {
- p_bitmap->set_bit(Point2(xi, yi), true);
- }
- }
- xf += dx_far;
- if (yi < y[1]) {
- xt += dx_upper;
- } else {
- xt += dx_low;
- }
- }
-}
-
void EditorAtlasPacker::chart_pack(Vector<Chart> &charts, int &r_width, int &r_height, int p_atlas_max_size, int p_cell_resolution) {
int divide_by = MIN(64, p_cell_resolution);
Vector<PlottedBitmap> bitmaps;
@@ -122,10 +72,18 @@ void EditorAtlasPacker::chart_pack(Vector<Chart> &charts, int &r_width, int &r_h
Vector2 vtx = chart.vertices[chart.faces[j].vertex[k]];
vtx -= aabb.position;
vtx /= divide_by;
+ vtx.x = MIN(vtx.x, w - 1);
+ vtx.y = MIN(vtx.y, h - 1);
v[k] = vtx;
}
- _plot_triangle(src_bitmap, v);
+ for (int k = 0; k < 3; k++) {
+ int l = k == 0 ? 2 : k - 1;
+ Vector<Point2i> points = Geometry2D::bresenham_line(v[k], v[l]);
+ for (Point2i point : points) {
+ src_bitmap->set_bit(point, true);
+ }
+ }
}
//src_bitmap->convert_to_image()->save_png("bitmap" + itos(i) + ".png");
diff --git a/editor/editor_atlas_packer.h b/editor/editor_atlas_packer.h
index 169a6bead8..7b7692011f 100644
--- a/editor/editor_atlas_packer.h
+++ b/editor/editor_atlas_packer.h
@@ -67,8 +67,6 @@ private:
}
};
- static void _plot_triangle(Ref<BitMap> p_bitmap, Vector2i *vertices);
-
public:
static void chart_pack(Vector<Chart> &charts, int &r_width, int &r_height, int p_atlas_max_size = 2048, int p_cell_resolution = 4);
};
diff --git a/editor/editor_settings_dialog.cpp b/editor/editor_settings_dialog.cpp
index 6a5ab91ba0..18324f9971 100644
--- a/editor/editor_settings_dialog.cpp
+++ b/editor/editor_settings_dialog.cpp
@@ -369,6 +369,11 @@ void EditorSettingsDialog::_update_shortcuts() {
Array events; // Need to get the list of events into an array so it can be set as metadata on the item.
Vector<String> event_strings;
+ // Skip non-builtin actions.
+ if (!InputMap::get_singleton()->get_builtins_with_feature_overrides_applied().has(action_name)) {
+ continue;
+ }
+
List<Ref<InputEvent>> all_default_events = InputMap::get_singleton()->get_builtins_with_feature_overrides_applied().find(action_name).value();
List<Ref<InputEventKey>> key_default_events;
// Remove all non-key events from the defaults. Only check keys, since we are in the editor.
diff --git a/editor/editor_translation.cpp b/editor/editor_translation.cpp
index 98248f3a87..f64adcf0a1 100644
--- a/editor/editor_translation.cpp
+++ b/editor/editor_translation.cpp
@@ -56,7 +56,8 @@ void load_editor_translations(const String &p_locale) {
if (etl->lang == p_locale) {
Vector<uint8_t> data;
data.resize(etl->uncomp_size);
- Compression::decompress(data.ptrw(), etl->uncomp_size, etl->data, etl->comp_size, Compression::MODE_DEFLATE);
+ int ret = Compression::decompress(data.ptrw(), etl->uncomp_size, etl->data, etl->comp_size, Compression::MODE_DEFLATE);
+ ERR_FAIL_COND_MSG(ret == -1, "Compressed file is corrupt.");
FileAccessMemory *fa = memnew(FileAccessMemory);
fa->open_custom(data.ptr(), data.size());
@@ -80,7 +81,8 @@ void load_doc_translations(const String &p_locale) {
if (dtl->lang == p_locale) {
Vector<uint8_t> data;
data.resize(dtl->uncomp_size);
- Compression::decompress(data.ptrw(), dtl->uncomp_size, dtl->data, dtl->comp_size, Compression::MODE_DEFLATE);
+ int ret = Compression::decompress(data.ptrw(), dtl->uncomp_size, dtl->data, dtl->comp_size, Compression::MODE_DEFLATE);
+ ERR_FAIL_COND_MSG(ret == -1, "Compressed file is corrupt.");
FileAccessMemory *fa = memnew(FileAccessMemory);
fa->open_custom(data.ptr(), data.size());
diff --git a/editor/import/dynamic_font_import_settings.cpp b/editor/import/dynamic_font_import_settings.cpp
index 8486d170a7..ebfb0b32fb 100644
--- a/editor/import/dynamic_font_import_settings.cpp
+++ b/editor/import/dynamic_font_import_settings.cpp
@@ -560,7 +560,7 @@ void DynamicFontImportSettings::_variation_changed(const String &p_edited_proper
void DynamicFontImportSettings::_variations_validate() {
String warn;
if (!vars_list_root->get_first_child()) {
- warn = TTR("Warinig: There are no configurations specified, no glyphs will be pre-rendered.");
+ warn = TTR("Warning: There are no configurations specified, no glyphs will be pre-rendered.");
}
for (TreeItem *vars_item_a = vars_list_root->get_first_child(); vars_item_a; vars_item_a = vars_item_a->get_next()) {
Ref<DynamicFontImportSettingsData> import_variation_data_a = vars_item_a->get_metadata(0);
@@ -575,7 +575,7 @@ void DynamicFontImportSettings::_variations_validate() {
match = match && (import_variation_data_b->settings[E->key()] == E->get());
}
if (match) {
- warn = TTR("Warinig: Multiple configurations have identical settings. Duplicates will be ignored.");
+ warn = TTR("Warning: Multiple configurations have identical settings. Duplicates will be ignored.");
break;
}
}
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index c1ae5be0bb..3b5a82b2c3 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -1535,7 +1535,7 @@ void ColladaImport::create_animation(int p_clip, bool p_import_value_tracks) {
bool has_rotation = false;
bool has_scale = false;
- for (int i = 0; cn->xform_list.size(); i++) {
+ for (int i = 0; i < cn->xform_list.size(); i++) {
switch (cn->xform_list[i].op) {
case Collada::Node::XForm::OP_ROTATE: {
has_rotation = true;
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index 3eb12353b5..e7c605aaf0 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -1649,14 +1649,6 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m
}
}
- if (generate_lods) {
- src_mesh_node->get_mesh()->generate_lods(merge_angle, split_angle);
- }
-
- if (create_shadow_meshes) {
- src_mesh_node->get_mesh()->create_shadow_mesh();
- }
-
if (bake_lightmaps) {
Transform3D xf;
Node3D *n = src_mesh_node;
@@ -1689,6 +1681,14 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m
}
}
+ if (generate_lods) {
+ src_mesh_node->get_mesh()->generate_lods(merge_angle, split_angle);
+ }
+
+ if (create_shadow_meshes) {
+ src_mesh_node->get_mesh()->create_shadow_mesh();
+ }
+
if (!save_to_file.is_empty()) {
Ref<Mesh> existing = Ref<Resource>(ResourceCache::get(save_to_file));
if (existing.is_valid()) {
diff --git a/editor/import/resource_importer_texture_atlas.cpp b/editor/import/resource_importer_texture_atlas.cpp
index d2a9fe2538..cd481e009e 100644
--- a/editor/import/resource_importer_texture_atlas.cpp
+++ b/editor/import/resource_importer_texture_atlas.cpp
@@ -75,6 +75,7 @@ void ResourceImporterTextureAtlas::get_import_options(const String &p_path, List
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "atlas_file", PROPERTY_HINT_SAVE_FILE, "*.png"), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "import_mode", PROPERTY_HINT_ENUM, "Region,Mesh2D"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "crop_to_region"), false));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "trim_alpha_border_from_region"), true));
}
String ResourceImporterTextureAtlas::get_option_group_file() const {
@@ -210,14 +211,18 @@ Error ResourceImporterTextureAtlas::import_group_file(const String &p_group_file
pack_data.is_cropped = options["crop_to_region"];
int mode = options["import_mode"];
+ bool trim_alpha_border_from_region = options["trim_alpha_border_from_region"];
if (mode == IMPORT_MODE_REGION) {
pack_data.is_mesh = false;
EditorAtlasPacker::Chart chart;
- //clip a region from the image
- Rect2 used_rect = image->get_used_rect();
+ Rect2 used_rect = Rect2(Vector2(), image->get_size());
+ if (trim_alpha_border_from_region) {
+ // Clip a region from the image.
+ used_rect = image->get_used_rect();
+ }
pack_data.region = used_rect;
chart.vertices.push_back(used_rect.position);
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 76558eb946..e43d1feb08 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -1163,25 +1163,25 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bo
if (k.is_valid()) {
if (k->is_pressed()) {
if (ED_GET_SHORTCUT("canvas_item_editor/zoom_3.125_percent")->matches_event(p_event)) {
- _update_zoom((1.0 / 32.0) * MAX(1, EDSCALE));
+ _shortcut_zoom_set(1.0 / 32.0);
} else if (ED_GET_SHORTCUT("canvas_item_editor/zoom_6.25_percent")->matches_event(p_event)) {
- _update_zoom((1.0 / 16.0) * MAX(1, EDSCALE));
+ _shortcut_zoom_set(1.0 / 16.0);
} else if (ED_GET_SHORTCUT("canvas_item_editor/zoom_12.5_percent")->matches_event(p_event)) {
- _update_zoom((1.0 / 8.0) * MAX(1, EDSCALE));
+ _shortcut_zoom_set(1.0 / 8.0);
} else if (ED_GET_SHORTCUT("canvas_item_editor/zoom_25_percent")->matches_event(p_event)) {
- _update_zoom((1.0 / 4.0) * MAX(1, EDSCALE));
+ _shortcut_zoom_set(1.0 / 4.0);
} else if (ED_GET_SHORTCUT("canvas_item_editor/zoom_50_percent")->matches_event(p_event)) {
- _update_zoom((1.0 / 2.0) * MAX(1, EDSCALE));
+ _shortcut_zoom_set(1.0 / 2.0);
} else if (ED_GET_SHORTCUT("canvas_item_editor/zoom_100_percent")->matches_event(p_event)) {
- _update_zoom(1.0 * MAX(1, EDSCALE));
+ _shortcut_zoom_set(1.0);
} else if (ED_GET_SHORTCUT("canvas_item_editor/zoom_200_percent")->matches_event(p_event)) {
- _update_zoom(2.0 * MAX(1, EDSCALE));
+ _shortcut_zoom_set(2.0);
} else if (ED_GET_SHORTCUT("canvas_item_editor/zoom_400_percent")->matches_event(p_event)) {
- _update_zoom(4.0 * MAX(1, EDSCALE));
+ _shortcut_zoom_set(4.0);
} else if (ED_GET_SHORTCUT("canvas_item_editor/zoom_800_percent")->matches_event(p_event)) {
- _update_zoom(8.0 * MAX(1, EDSCALE));
+ _shortcut_zoom_set(8.0);
} else if (ED_GET_SHORTCUT("canvas_item_editor/zoom_1600_percent")->matches_event(p_event)) {
- _update_zoom(16.0 * MAX(1, EDSCALE));
+ _shortcut_zoom_set(16.0);
}
}
}
@@ -3510,7 +3510,7 @@ void CanvasItemEditor::_draw_invisible_nodes_positions(Node *p_node, const Trans
return;
}
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node);
- if (canvas_item && !canvas_item->is_visible()) {
+ if (canvas_item && !canvas_item->is_visible_in_tree()) {
return;
}
@@ -4010,6 +4010,10 @@ void CanvasItemEditor::_update_zoom(real_t p_zoom) {
_zoom_on_position(p_zoom, viewport_scrollable->get_size() / 2.0);
}
+void CanvasItemEditor::_shortcut_zoom_set(real_t p_zoom) {
+ _zoom_on_position(p_zoom * MAX(1, EDSCALE), viewport->get_local_mouse_position());
+}
+
void CanvasItemEditor::_button_toggle_smart_snap(bool p_status) {
smart_snap_active = p_status;
viewport->update();
@@ -5500,16 +5504,18 @@ bool CanvasItemEditorViewport::_create_instance(Node *parent, String &path, cons
editor_data->get_undo_redo().add_do_method(ed, "live_debug_instance_node", edited_scene->get_path_to(parent), path, new_name);
editor_data->get_undo_redo().add_undo_method(ed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(parent)) + "/" + new_name));
- CanvasItem *parent_ci = Object::cast_to<CanvasItem>(parent);
- if (parent_ci) {
+ CanvasItem *instance_ci = Object::cast_to<CanvasItem>(instantiated_scene);
+ if (instance_ci) {
Vector2 target_pos = canvas_item_editor->get_canvas_transform().affine_inverse().xform(p_point);
target_pos = canvas_item_editor->snap_point(target_pos);
- target_pos = parent_ci->get_global_transform_with_canvas().affine_inverse().xform(target_pos);
- // Preserve instance position of the original scene.
- CanvasItem *instance_ci = Object::cast_to<CanvasItem>(instantiated_scene);
- if (instance_ci) {
- target_pos += instance_ci->_edit_get_position();
+
+ CanvasItem *parent_ci = Object::cast_to<CanvasItem>(parent);
+ if (parent_ci) {
+ target_pos = parent_ci->get_global_transform_with_canvas().affine_inverse().xform(target_pos);
}
+ // Preserve instance position of the original scene.
+ target_pos += instance_ci->_edit_get_position();
+
editor_data->get_undo_redo().add_do_method(instantiated_scene, "set_position", target_pos);
}
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index 57760475a1..e7c265ee02 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -470,6 +470,7 @@ private:
VBoxContainer *controls_vb;
EditorZoomWidget *zoom_widget;
void _update_zoom(real_t p_zoom);
+ void _shortcut_zoom_set(real_t p_zoom);
void _zoom_on_position(real_t p_zoom, Point2 p_position = Point2());
void _button_toggle_smart_snap(bool p_status);
void _button_toggle_grid_snap(bool p_status);
diff --git a/editor/plugins/control_editor_plugin.cpp b/editor/plugins/control_editor_plugin.cpp
index e6f267673c..7b85fea1e9 100644
--- a/editor/plugins/control_editor_plugin.cpp
+++ b/editor/plugins/control_editor_plugin.cpp
@@ -358,8 +358,12 @@ void EditorPropertySizeFlags::setup(const Vector<String> &p_options, bool p_vert
Control *gui_base = EditorNode::get_singleton()->get_gui_base();
String wide_preset_icon = SNAME("ControlAlignHCenterWide");
+ String begin_preset_icon = SNAME("ControlAlignCenterLeft");
+ String end_preset_icon = SNAME("ControlAlignCenterRight");
if (vertical) {
wide_preset_icon = SNAME("ControlAlignVCenterWide");
+ begin_preset_icon = SNAME("ControlAlignCenterTop");
+ end_preset_icon = SNAME("ControlAlignCenterBottom");
}
flag_presets->clear();
@@ -367,12 +371,12 @@ void EditorPropertySizeFlags::setup(const Vector<String> &p_options, bool p_vert
flag_presets->add_icon_item(gui_base->get_theme_icon(wide_preset_icon, SNAME("EditorIcons")), TTR("Fill"), SIZE_FLAGS_PRESET_FILL);
}
// Shrink Begin is the same as no flags at all, as such it cannot be disabled.
- flag_presets->add_icon_item(gui_base->get_theme_icon(SNAME("ControlAlignCenterLeft"), SNAME("EditorIcons")), TTR("Shrink Begin"), SIZE_FLAGS_PRESET_SHRINK_BEGIN);
+ flag_presets->add_icon_item(gui_base->get_theme_icon(begin_preset_icon, SNAME("EditorIcons")), TTR("Shrink Begin"), SIZE_FLAGS_PRESET_SHRINK_BEGIN);
if (flags.has(SIZE_SHRINK_CENTER)) {
flag_presets->add_icon_item(gui_base->get_theme_icon(SNAME("ControlAlignCenter"), SNAME("EditorIcons")), TTR("Shrink Center"), SIZE_FLAGS_PRESET_SHRINK_CENTER);
}
if (flags.has(SIZE_SHRINK_END)) {
- flag_presets->add_icon_item(gui_base->get_theme_icon(SNAME("ControlAlignCenterRight"), SNAME("EditorIcons")), TTR("Shrink End"), SIZE_FLAGS_PRESET_SHRINK_END);
+ flag_presets->add_icon_item(gui_base->get_theme_icon(end_preset_icon, SNAME("EditorIcons")), TTR("Shrink End"), SIZE_FLAGS_PRESET_SHRINK_END);
}
flag_presets->add_separator();
flag_presets->add_item(TTR("Custom"), SIZE_FLAGS_PRESET_CUSTOM);
diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp
index 46b33f62fe..23f3087553 100644
--- a/editor/plugins/node_3d_editor_gizmos.cpp
+++ b/editor/plugins/node_3d_editor_gizmos.cpp
@@ -3669,13 +3669,8 @@ void VoxelGIGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
continue;
}
- Vector2 dir;
- dir[j] = 1.0;
- Vector2 ta, tb;
int j_n1 = (j + 1) % 3;
int j_n2 = (j + 2) % 3;
- ta[j_n1] = 1.0;
- tb[j_n2] = 1.0;
for (int k = 0; k < 4; k++) {
Vector3 from = aabb.position, to = aabb.position;
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 3d3738ad47..002c879cdc 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -32,6 +32,7 @@
#include "core/config/project_settings.h"
#include "core/input/input.h"
+#include "core/input/input_map.h"
#include "core/math/camera_matrix.h"
#include "core/math/math_funcs.h"
#include "core/os/keyboard.h"
@@ -2291,26 +2292,6 @@ Point2i Node3DEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMouse
return relative;
}
-static bool is_shortcut_pressed(const String &p_path) {
- Ref<Shortcut> shortcut = ED_GET_SHORTCUT(p_path);
- if (shortcut.is_null()) {
- return false;
- }
-
- const Array shortcuts = shortcut->get_events();
- Ref<InputEventKey> k;
- if (shortcuts.size() > 0) {
- k = shortcuts.front();
- }
-
- if (k.is_null()) {
- return false;
- }
- const Input &input = *Input::get_singleton();
- Key keycode = k->get_keycode();
- return input.is_key_pressed(keycode);
-}
-
void Node3DEditorViewport::_update_freelook(real_t delta) {
if (!is_freelook_active()) {
return;
@@ -2340,31 +2321,34 @@ void Node3DEditorViewport::_update_freelook(real_t delta) {
Vector3 direction;
- if (is_shortcut_pressed("spatial_editor/freelook_left")) {
+ // Use actions from the inputmap, as this is the only way to reliably detect input in this method.
+ // See #54469 for more discussion and explanation.
+ Input *inp = Input::get_singleton();
+ if (inp->is_action_pressed("spatial_editor/freelook_left")) {
direction -= right;
}
- if (is_shortcut_pressed("spatial_editor/freelook_right")) {
+ if (inp->is_action_pressed("spatial_editor/freelook_right")) {
direction += right;
}
- if (is_shortcut_pressed("spatial_editor/freelook_forward")) {
+ if (inp->is_action_pressed("spatial_editor/freelook_forward")) {
direction += forward;
}
- if (is_shortcut_pressed("spatial_editor/freelook_backwards")) {
+ if (inp->is_action_pressed("spatial_editor/freelook_backwards")) {
direction -= forward;
}
- if (is_shortcut_pressed("spatial_editor/freelook_up")) {
+ if (inp->is_action_pressed("spatial_editor/freelook_up")) {
direction += up;
}
- if (is_shortcut_pressed("spatial_editor/freelook_down")) {
+ if (inp->is_action_pressed("spatial_editor/freelook_down")) {
direction -= up;
}
real_t speed = freelook_speed;
- if (is_shortcut_pressed("spatial_editor/freelook_speed_modifier")) {
+ if (inp->is_action_pressed("spatial_editor/freelook_speed_modifier")) {
speed *= 3.0;
}
- if (is_shortcut_pressed("spatial_editor/freelook_slow_modifier")) {
+ if (inp->is_action_pressed("spatial_editor/freelook_slow_modifier")) {
speed *= 0.333333;
}
@@ -4427,6 +4411,28 @@ void Node3DEditorViewport::finish_transform() {
surface->update();
}
+// Register a shortcut and also add it as an input action with the same events.
+void Node3DEditorViewport::register_shortcut_action(const String &p_path, const String &p_name, Key p_keycode) {
+ Ref<Shortcut> sc = ED_SHORTCUT(p_path, p_name, p_keycode);
+ shortcut_changed_callback(sc, p_path);
+ // Connect to the change event on the shortcut so the input binding can be updated.
+ sc->connect("changed", callable_mp(this, &Node3DEditorViewport::shortcut_changed_callback), varray(sc, p_path));
+}
+
+// Update the action in the InputMap to the provided shortcut events.
+void Node3DEditorViewport::shortcut_changed_callback(const Ref<Shortcut> p_shortcut, const String &p_shortcut_path) {
+ InputMap *im = InputMap::get_singleton();
+ if (im->has_action(p_shortcut_path)) {
+ im->action_erase_events(p_shortcut_path);
+ } else {
+ im->add_action(p_shortcut_path);
+ }
+
+ for (int i = 0; i < p_shortcut->get_events().size(); i++) {
+ im->action_add_event(p_shortcut_path, p_shortcut->get_events()[i]);
+ }
+}
+
Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p_index) {
cpu_time_history_index = 0;
gpu_time_history_index = 0;
@@ -4586,14 +4592,15 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p
view_menu->get_popup()->set_item_tooltip(shadeless_idx, unsupported_tooltip);
}
- ED_SHORTCUT("spatial_editor/freelook_left", TTR("Freelook Left"), Key::A);
- ED_SHORTCUT("spatial_editor/freelook_right", TTR("Freelook Right"), Key::D);
- ED_SHORTCUT("spatial_editor/freelook_forward", TTR("Freelook Forward"), Key::W);
- ED_SHORTCUT("spatial_editor/freelook_backwards", TTR("Freelook Backwards"), Key::S);
- ED_SHORTCUT("spatial_editor/freelook_up", TTR("Freelook Up"), Key::E);
- ED_SHORTCUT("spatial_editor/freelook_down", TTR("Freelook Down"), Key::Q);
- ED_SHORTCUT("spatial_editor/freelook_speed_modifier", TTR("Freelook Speed Modifier"), Key::SHIFT);
- ED_SHORTCUT("spatial_editor/freelook_slow_modifier", TTR("Freelook Slow Modifier"), Key::ALT);
+ register_shortcut_action("spatial_editor/freelook_left", TTR("Freelook Left"), Key::A);
+ register_shortcut_action("spatial_editor/freelook_right", TTR("Freelook Right"), Key::D);
+ register_shortcut_action("spatial_editor/freelook_forward", TTR("Freelook Forward"), Key::W);
+ register_shortcut_action("spatial_editor/freelook_backwards", TTR("Freelook Backwards"), Key::S);
+ register_shortcut_action("spatial_editor/freelook_up", TTR("Freelook Up"), Key::E);
+ register_shortcut_action("spatial_editor/freelook_down", TTR("Freelook Down"), Key::Q);
+ register_shortcut_action("spatial_editor/freelook_speed_modifier", TTR("Freelook Speed Modifier"), Key::SHIFT);
+ register_shortcut_action("spatial_editor/freelook_slow_modifier", TTR("Freelook Slow Modifier"), Key::ALT);
+
ED_SHORTCUT("spatial_editor/lock_transform_x", TTR("Lock Transformation to X axis"), Key::X);
ED_SHORTCUT("spatial_editor/lock_transform_y", TTR("Lock Transformation to Y axis"), Key::Y);
ED_SHORTCUT("spatial_editor/lock_transform_z", TTR("Lock Transformation to Z axis"), Key::Z);
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index 9e92a1e9b3..5c0bfab34e 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -378,7 +378,7 @@ private:
Node3DEditor *spatial_editor;
Camera3D *previewing;
- Camera3D *preview;
+ Camera3D *preview = nullptr;
bool previewing_cinema;
bool _is_node_locked(const Node *p_node);
@@ -415,6 +415,9 @@ private:
void update_transform(Point2 p_mousepos, bool p_shift);
void finish_transform();
+ void register_shortcut_action(const String &p_path, const String &p_name, Key p_keycode);
+ void shortcut_changed_callback(const Ref<Shortcut> p_shortcut, const String &p_shortcut_path);
+
protected:
void _notification(int p_what);
static void _bind_methods();
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index bd4064708b..30c2b12519 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -762,7 +762,7 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) {
if (p_save && file.is_valid()) {
// Do not try to save internal scripts, but prompt to save in-memory
// scripts which are not saved to disk yet (have empty path).
- if (file->is_built_in()) {
+ if (!file->is_built_in()) {
save_current_script();
}
}
diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp
index 95cd5683a6..4a0fc0b29f 100644
--- a/editor/plugins/tiles/tile_map_editor.cpp
+++ b/editor/plugins/tiles/tile_map_editor.cpp
@@ -1347,7 +1347,12 @@ void TileMapEditorTilesPlugin::_stop_dragging() {
}
if (picked_source >= 0) {
- sources_list->set_current(picked_source);
+ for (int i = 0; i < sources_list->get_item_count(); i++) {
+ if (int(sources_list->get_item_metadata(i)) == picked_source) {
+ sources_list->set_current(i);
+ break;
+ }
+ }
sources_list->ensure_current_is_visible();
TilesEditorPlugin::get_singleton()->set_sources_lists_current(picked_source);
}
@@ -4019,7 +4024,7 @@ TileMapEditor::TileMapEditor() {
// Layer selector.
layers_selection_popup = memnew(PopupMenu);
layers_selection_popup->connect("id_pressed", callable_mp(this, &TileMapEditor::_layers_selection_id_pressed));
- layers_selection_popup->set_close_on_parent_focus(false);
+ layers_selection_popup->set_flag(Window::FLAG_POPUP, false);
layers_selection_button = memnew(Button);
layers_selection_button->set_toggle_mode(true);
diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
index ade591cde6..0c78a0f1c0 100644
--- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
+++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
@@ -108,7 +108,7 @@ void TileSetAtlasSourceEditor::TileSetAtlasSourceProxyObject::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_id", "id"), &TileSetAtlasSourceEditor::TileSetAtlasSourceProxyObject::set_id);
ClassDB::bind_method(D_METHOD("get_id"), &TileSetAtlasSourceEditor::TileSetAtlasSourceProxyObject::get_id);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "id"), "set_id", "get_id");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "id", PROPERTY_HINT_RANGE, "0," + itos(INT_MAX) + ",1"), "set_id", "get_id");
ADD_SIGNAL(MethodInfo("changed", PropertyInfo(Variant::STRING, "what")));
}
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 446ad12104..a821faf6b3 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -4458,8 +4458,8 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("ColorOp", "Color", "Common", "VisualShaderNodeColorOp", TTR("Color operator."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Grayscale", "Color", "Functions", "VisualShaderNodeColorFunc", TTR("Grayscale function."), { VisualShaderNodeColorFunc::FUNC_GRAYSCALE }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
- add_options.push_back(AddOption("HSV2RGB", "Color", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts HSV vector to RGB equivalent."), { VisualShaderNodeVectorFunc::FUNC_HSV2RGB }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
- add_options.push_back(AddOption("RGB2HSV", "Color", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts RGB vector to HSV equivalent."), { VisualShaderNodeVectorFunc::FUNC_RGB2HSV }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
+ add_options.push_back(AddOption("HSV2RGB", "Color", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts HSV vector to RGB equivalent."), { VisualShaderNodeVectorFunc::FUNC_HSV2RGB, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
+ add_options.push_back(AddOption("RGB2HSV", "Color", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts RGB vector to HSV equivalent."), { VisualShaderNodeVectorFunc::FUNC_RGB2HSV, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Sepia", "Color", "Functions", "VisualShaderNodeColorFunc", TTR("Sepia function."), { VisualShaderNodeColorFunc::FUNC_SEPIA }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Burn", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Burn operator."), { VisualShaderNodeColorOp::OP_BURN }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index 4a6c014942..bf43e11cdb 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -37,9 +37,73 @@
#include "editor/create_dialog.h"
#include "editor/editor_file_dialog.h"
#include "editor/editor_file_system.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+static String _get_parent_class_of_script(String p_path) {
+ if (!ResourceLoader::exists(p_path, "Script")) {
+ return "Object"; // A script eventually inherits from Object.
+ }
+
+ Ref<Script> script = ResourceLoader::load(p_path, "Script");
+ ERR_FAIL_COND_V(script.is_null(), "Object");
+
+ String class_name;
+ Ref<Script> base = script->get_base_script();
+
+ // Inherits from a built-in class.
+ if (base.is_null()) {
+ script->get_language()->get_global_class_name(script->get_path(), &class_name);
+ return class_name;
+ }
+
+ // Inherits from a script that has class_name.
+ class_name = script->get_language()->get_global_class_name(base->get_path());
+ if (!class_name.is_empty()) {
+ return class_name;
+ }
+
+ // Inherits from a plain script.
+ return _get_parent_class_of_script(base->get_path());
+}
+
+static Vector<String> _get_hierarchy(String p_class_name) {
+ Vector<String> hierarchy;
+
+ String class_name = p_class_name;
+ while (true) {
+ // A registered class.
+ if (ClassDB::class_exists(class_name)) {
+ hierarchy.push_back(class_name);
+
+ class_name = ClassDB::get_parent_class(class_name);
+ continue;
+ }
+
+ // A class defined in script with class_name.
+ if (ScriptServer::is_global_class(class_name)) {
+ hierarchy.push_back(class_name);
+
+ Ref<Script> script = EditorNode::get_editor_data().script_class_load_script(class_name);
+ ERR_BREAK(script.is_null());
+ class_name = _get_parent_class_of_script(script->get_path());
+ continue;
+ }
+
+ break;
+ }
+
+ if (hierarchy.is_empty()) {
+ if (p_class_name.is_valid_identifier()) {
+ hierarchy.push_back(p_class_name);
+ }
+ hierarchy.push_back("Object");
+ }
+
+ return hierarchy;
+}
+
void ScriptCreateDialog::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
@@ -353,18 +417,6 @@ void ScriptCreateDialog::_load_exist() {
hide();
}
-Vector<String> ScriptCreateDialog::get_hierarchy(String p_object) const {
- Vector<String> hierarchy;
- hierarchy.append(p_object);
-
- String parent_class = ClassDB::get_parent_class(p_object);
- while (parent_class.is_valid_identifier()) {
- hierarchy.append(parent_class);
- parent_class = ClassDB::get_parent_class(parent_class);
- }
- return hierarchy;
-}
-
void ScriptCreateDialog::_language_changed(int l) {
language = ScriptServer::get_language(l);
@@ -553,14 +605,14 @@ void ScriptCreateDialog::_update_template_menu() {
}
String inherits_base_type = parent_name->get_text();
- // If it inherits from a script, select Object instead.
+ // If it inherits from a script, get its parent class first.
if (inherits_base_type[0] == '"') {
- inherits_base_type = "Object";
+ inherits_base_type = _get_parent_class_of_script(inherits_base_type.unquote());
}
// Get all ancestor node for selected base node.
// There templates will also fit the base node.
- Vector<String> hierarchy = get_hierarchy(inherits_base_type);
+ Vector<String> hierarchy = _get_hierarchy(inherits_base_type);
int last_used_template = -1;
int preselected_template = -1;
int previous_ancestor_level = -1;
diff --git a/editor/script_create_dialog.h b/editor/script_create_dialog.h
index aea9649abc..5c0f51812f 100644
--- a/editor/script_create_dialog.h
+++ b/editor/script_create_dialog.h
@@ -115,7 +115,6 @@ class ScriptCreateDialog : public ConfirmationDialog {
virtual void ok_pressed() override;
void _create_new();
void _load_exist();
- Vector<String> get_hierarchy(String p_object) const;
void _msg_script_valid(bool valid, const String &p_msg = String());
void _msg_path_valid(bool valid, const String &p_msg = String());
void _update_template_menu();