diff options
Diffstat (limited to 'editor')
32 files changed, 158 insertions, 87 deletions
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 3ea970a0f0..9888013ce6 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -657,7 +657,7 @@ FindReplaceBar::FindReplaceBar() { // be handled too late if they weren't handled here. void CodeTextEditor::_input(const Ref<InputEvent> &event) { const Ref<InputEventKey> key_event = event; - if (!key_event.is_valid() || !key_event->is_pressed()) { + if (!key_event.is_valid() || !key_event->is_pressed() || !text_editor->has_focus()) { return; } diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index 62b5911ac1..6507956d07 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -984,7 +984,7 @@ void ConnectionsDock::update_tree() { while (F && descr == String()) { for (int i = 0; i < F->get().signals.size(); i++) { if (F->get().signals[i].name == signal_name.operator String()) { - descr = DTR(F->get().signals[i].description.strip_edges()); + descr = DTR(F->get().signals[i].description); break; } } diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index 75fff03297..e4a853dbd7 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -53,13 +53,15 @@ void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode, const St if (f) { TreeItem *root = recent->create_item(); + String icon_fallback = search_options->has_theme_icon(base_type, "EditorIcons") ? base_type : "Object"; + while (!f->eof_reached()) { String l = f->get_line().strip_edges(); String name = l.split(" ")[0]; if ((ClassDB::class_exists(name) || ScriptServer::is_global_class(name)) && !_is_class_disabled_by_feature_profile(name)) { TreeItem *ti = recent->create_item(root); ti->set_text(0, l); - ti->set_icon(0, EditorNode::get_singleton()->get_class_icon(l, base_type)); + ti->set_icon(0, EditorNode::get_singleton()->get_class_icon(name, icon_fallback)); } } @@ -248,7 +250,8 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p const String &description = DTR(EditorHelp::get_doc_data()->class_list[p_type].brief_description); item->set_tooltip(0, description); - item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, base_type)); + String icon_fallback = search_options->has_theme_icon(base_type, "EditorIcons") ? base_type : "Object"; + item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, icon_fallback)); p_types[p_type] = item; } @@ -305,9 +308,8 @@ void CreateDialog::_update_search() { EditorData &ed = EditorNode::get_editor_data(); root->set_text(0, base_type); - if (search_options->has_theme_icon(base_type, "EditorIcons")) { - root->set_icon(0, search_options->get_theme_icon(base_type, "EditorIcons")); - } + String base_icon = search_options->has_theme_icon(base_type, "EditorIcons") ? base_type : "Object"; + root->set_icon(0, search_options->get_theme_icon(base_icon, "EditorIcons")); TreeItem *to_select = search_box->get_text() == base_type ? root : nullptr; @@ -393,9 +395,7 @@ void CreateDialog::_update_search() { TreeItem *item = search_options->create_item(ti); item->set_metadata(0, type); item->set_text(0, ct[i].name); - if (ct[i].icon.is_valid()) { - item->set_icon(0, ct[i].icon); - } + item->set_icon(0, ct[i].icon.is_valid() ? ct[i].icon : search_options->get_theme_icon(base_icon, "EditorIcons")); if (!to_select || ct[i].name == search_box->get_text()) { to_select = item; @@ -598,16 +598,21 @@ void CreateDialog::_save_favorite_list() { void CreateDialog::_update_favorite_list() { favorites->clear(); + TreeItem *root = favorites->create_item(); + + String icon_fallback = search_options->has_theme_icon(base_type, "EditorIcons") ? base_type : "Object"; + for (int i = 0; i < favorite_list.size(); i++) { String l = favorite_list[i]; String name = l.split(" ")[0]; if (!((ClassDB::class_exists(name) || ScriptServer::is_global_class(name)) && !_is_class_disabled_by_feature_profile(name))) { continue; } + TreeItem *ti = favorites->create_item(root); ti->set_text(0, l); - ti->set_icon(0, EditorNode::get_singleton()->get_class_icon(l, base_type)); + ti->set_icon(0, EditorNode::get_singleton()->get_class_icon(name, icon_fallback)); } emit_signal("favorites_updated"); } diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp index 200ae7045f..da0ff9f18f 100644 --- a/editor/editor_autoload_settings.cpp +++ b/editor/editor_autoload_settings.cpp @@ -674,18 +674,18 @@ bool EditorAutoloadSettings::autoload_add(const String &p_name, const String &p_ String error; if (!_autoload_name_is_valid(name, &error)) { - EditorNode::get_singleton()->show_warning(error); + EditorNode::get_singleton()->show_warning(TTR("Can't add autoload:") + "\n" + error); return false; } const String &path = p_path; if (!FileAccess::exists(path)) { - EditorNode::get_singleton()->show_warning(TTR("Invalid path.") + "\n" + TTR("File does not exist.")); + EditorNode::get_singleton()->show_warning(TTR("Can't add autoload:") + "\n" + TTR(vformat("%s is an invalid path. File does not exist.", path))); return false; } if (!path.begins_with("res://")) { - EditorNode::get_singleton()->show_warning(TTR("Invalid path.") + "\n" + TTR("Not in resource path.")); + EditorNode::get_singleton()->show_warning(TTR("Can't add autoload:") + "\n" + TTR(vformat("%s is an invalid path. Not in resource path (res://).", path))); return false; } @@ -912,4 +912,4 @@ void EditorAutoloadSettings::_set_autoload_add_path(const String &p_text) { void EditorAutoloadSettings::_browse_autoload_add_path() { file_dialog->popup_centered_ratio(); -}
\ No newline at end of file +} diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 1b423f69b7..a8ded44323 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -1583,9 +1583,9 @@ void EditorInspector::update_tree() { DocData *dd = EditorHelp::get_doc_data(); Map<String, DocData::ClassDoc>::Element *E = dd->class_list.find(type2); if (E) { - descr = E->get().brief_description; + descr = DTR(E->get().brief_description); } - class_descr_cache[type2] = DTR(descr); + class_descr_cache[type2] = descr; } category->set_tooltip(p.name + "::" + (class_descr_cache[type2] == "" ? "" : class_descr_cache[type2])); @@ -1755,7 +1755,7 @@ void EditorInspector::update_tree() { while (F && descr == String()) { for (int i = 0; i < F->get().properties.size(); i++) { if (F->get().properties[i].name == propname.operator String()) { - descr = DTR(F->get().properties[i].description.strip_edges()); + descr = DTR(F->get().properties[i].description); break; } } @@ -1765,7 +1765,7 @@ void EditorInspector::update_tree() { // Likely a theme property. for (int i = 0; i < F->get().theme_properties.size(); i++) { if (F->get().theme_properties[i].name == slices[1]) { - descr = DTR(F->get().theme_properties[i].description.strip_edges()); + descr = DTR(F->get().theme_properties[i].description); break; } } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 8b7014fabe..14a03c5377 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -4782,7 +4782,7 @@ void EditorNode::set_distraction_free_mode(bool p_enter) { } } -bool EditorNode::get_distraction_free_mode() const { +bool EditorNode::is_distraction_free_mode_enabled() const { return distraction_free->is_pressed(); } @@ -6568,6 +6568,7 @@ EditorNode::EditorNode() { gui_base->add_child(load_error_dialog); execute_outputs = memnew(RichTextLabel); + execute_outputs->set_selection_enabled(true); execute_output_dialog = memnew(AcceptDialog); execute_output_dialog->add_child(execute_outputs); execute_output_dialog->set_title(""); diff --git a/editor/editor_node.h b/editor/editor_node.h index dfe3d91c07..7c9cf44d6c 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -693,7 +693,7 @@ public: bool get_docks_visible() const; void set_distraction_free_mode(bool p_enter); - bool get_distraction_free_mode() const; + bool is_distraction_free_mode_enabled() const; void add_control_to_dock(DockSlot p_slot, Control *p_control); void remove_control_from_dock(Control *p_control); diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index 2365090f03..6d93e92555 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -270,6 +270,10 @@ void EditorInterface::set_distraction_free_mode(bool p_enter) { EditorNode::get_singleton()->set_distraction_free_mode(p_enter); } +bool EditorInterface::is_distraction_free_mode_enabled() const { + return EditorNode::get_singleton()->is_distraction_free_mode_enabled(); +} + EditorInterface *EditorInterface::singleton = nullptr; void EditorInterface::_bind_methods() { @@ -302,6 +306,9 @@ void EditorInterface::_bind_methods() { ClassDB::bind_method(D_METHOD("set_main_screen_editor", "name"), &EditorInterface::set_main_screen_editor); ClassDB::bind_method(D_METHOD("set_distraction_free_mode", "enter"), &EditorInterface::set_distraction_free_mode); + ClassDB::bind_method(D_METHOD("is_distraction_free_mode_enabled"), &EditorInterface::is_distraction_free_mode_enabled); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distraction_free_mode"), "set_distraction_free_mode", "is_distraction_free_mode_enabled"); } EditorInterface::EditorInterface() { diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h index 2792c8bf19..aac36bfdfd 100644 --- a/editor/editor_plugin.h +++ b/editor/editor_plugin.h @@ -105,6 +105,7 @@ public: void set_main_screen_editor(const String &p_name); void set_distraction_free_mode(bool p_enter); + bool is_distraction_free_mode_enabled() const; EditorInterface(); }; diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp index 1f39a12c25..b57ea3745d 100644 --- a/editor/import/resource_importer_layered_texture.cpp +++ b/editor/import/resource_importer_layered_texture.cpp @@ -134,7 +134,7 @@ String ResourceImporterLayeredTexture::get_preset_name(int p_idx) const { } void ResourceImporterLayeredTexture::get_import_options(List<ImportOption> *r_options, int p_preset) const { - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Lossless,Lossy,Video RAM,Uncompressed,Basis Universal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Lossless (PNG),Lossy (WebP),Video RAM (S3TC/ETC/BPTC),Uncompressed,Basis Universal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1)); r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "compress/lossy_quality", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.7)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/hdr_compression", PROPERTY_HINT_ENUM, "Disabled,Opaque Only,Always"), 1)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/bptc_ldr", PROPERTY_HINT_ENUM, "Disabled,Enabled,RGBA Only"), 0)); diff --git a/editor/import/resource_importer_texture_atlas.cpp b/editor/import/resource_importer_texture_atlas.cpp index 0818655c4c..2423553d22 100644 --- a/editor/import/resource_importer_texture_atlas.cpp +++ b/editor/import/resource_importer_texture_atlas.cpp @@ -33,6 +33,7 @@ #include "atlas_import_failed.xpm" #include "core/io/image_loader.h" #include "core/io/resource_saver.h" +#include "core/math/geometry_2d.h" #include "core/os/file_access.h" #include "editor/editor_atlas_packer.h" #include "scene/resources/mesh.h" @@ -129,7 +130,8 @@ static void _plot_triangle(Vector2 *vertices, const Vector2 &p_offset, bool p_tr 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++) { + int max_y = MIN(y[2], height - p_offset.y - 1); + for (int yi = y[0]; yi <= max_y; yi++) { if (yi >= 0) { for (int xi = (xf > 0 ? int(xf) : 0); xi <= (xt < width ? xt : width - 1); xi++) { int px = xi, py = yi; @@ -247,7 +249,7 @@ Error ResourceImporterTextureAtlas::import_group_file(const String &p_group_file chart.vertices = polygons[j]; chart.can_transpose = true; - Vector<int> poly = Geometry::triangulate_polygon(polygons[j]); + Vector<int> poly = Geometry2D::triangulate_polygon(polygons[j]); for (int i = 0; i < poly.size(); i += 3) { EditorAtlasPacker::Chart::Face f; f.vertex[0] = poly[i + 0]; diff --git a/editor/node_3d_editor_gizmos.cpp b/editor/node_3d_editor_gizmos.cpp index 0eb4e6036a..2ddcf3d877 100644 --- a/editor/node_3d_editor_gizmos.cpp +++ b/editor/node_3d_editor_gizmos.cpp @@ -30,7 +30,8 @@ #include "node_3d_editor_gizmos.h" -#include "core/math/geometry.h" +#include "core/math/geometry_2d.h" +#include "core/math/geometry_3d.h" #include "core/math/quick_hull.h" #include "scene/3d/audio_stream_player_3d.h" #include "scene/3d/baked_lightmap.h" @@ -482,7 +483,7 @@ bool EditorNode3DGizmo::intersect_frustum(const Camera3D *p_camera, const Vector transformed_frustum.push_back(it.xform(p_frustum[i])); } - Vector<Vector3> convex_points = Geometry::compute_convex_mesh_points(p_frustum.ptr(), p_frustum.size()); + Vector<Vector3> convex_points = Geometry3D::compute_convex_mesh_points(p_frustum.ptr(), p_frustum.size()); if (collision_mesh->inside_convex_shape(transformed_frustum.ptr(), transformed_frustum.size(), convex_points.ptr(), convex_points.size(), mesh_scale)) { return true; } @@ -616,7 +617,7 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point, s[0] = p_camera->unproject_position(a); s[1] = p_camera->unproject_position(b); - Vector2 p = Geometry::get_closest_point_to_segment_2d(p_point, s); + Vector2 p = Geometry2D::get_closest_point_to_segment(p_point, s); float pd = p.distance_to(p_point); @@ -831,7 +832,7 @@ static float _find_closest_angle_to_half_pi_arc(const Vector3 &p_from, const Vec Vector3 n = Vector3(Math::cos(an), 0, -Math::sin(an)) * p_arc_radius; Vector3 ra, rb; - Geometry::get_closest_points_between_segments(p, n, p_from, p_to, ra, rb); + Geometry3D::get_closest_points_between_segments(p, n, p_from, p_to, ra, rb); float d = ra.distance_to(rb); if (d < min_d) { @@ -857,7 +858,7 @@ void Light3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camer if (p_idx == 0) { if (Object::cast_to<SpotLight3D>(light)) { Vector3 ra, rb; - Geometry::get_closest_points_between_segments(Vector3(), Vector3(0, 0, -4096), s[0], s[1], ra, rb); + Geometry3D::get_closest_points_between_segments(Vector3(), Vector3(0, 0, -4096), s[0], s[1], ra, rb); float d = -ra.z; if (Node3DEditor::get_singleton()->is_snap_enabled()) { @@ -1100,7 +1101,7 @@ void AudioStreamPlayer3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int Vector3 to(Math::sin(an), 0, -Math::cos(an)); Vector3 r1, r2; - Geometry::get_closest_points_between_segments(from, to, ray_from, ray_to, r1, r2); + Geometry3D::get_closest_points_between_segments(from, to, ray_from, ray_to, r1, r2); float d = r1.distance_to(r2); if (d < closest_dist) { closest_dist = d; @@ -1238,7 +1239,7 @@ void Camera3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Came camera->set("fov", CLAMP(a * 2.0, 1, 179)); } else { Vector3 ra, rb; - Geometry::get_closest_points_between_segments(Vector3(0, 0, -1), Vector3(4096, 0, -1), s[0], s[1], ra, rb); + Geometry3D::get_closest_points_between_segments(Vector3(0, 0, -1), Vector3(4096, 0, -1), s[0], s[1], ra, rb); float d = ra.x * 2.0; if (Node3DEditor::get_singleton()->is_snap_enabled()) { d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap()); @@ -2169,7 +2170,7 @@ void VisibilityNotifier3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int if (move) { Vector3 ra, rb; - Geometry::get_closest_points_between_segments(ofs - axis * 4096, ofs + axis * 4096, sg[0], sg[1], ra, rb); + Geometry3D::get_closest_points_between_segments(ofs - axis * 4096, ofs + axis * 4096, sg[0], sg[1], ra, rb); float d = ra[p_idx]; if (Node3DEditor::get_singleton()->is_snap_enabled()) { @@ -2181,7 +2182,7 @@ void VisibilityNotifier3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int } else { Vector3 ra, rb; - Geometry::get_closest_points_between_segments(ofs, ofs + axis * 4096, sg[0], sg[1], ra, rb); + Geometry3D::get_closest_points_between_segments(ofs, ofs + axis * 4096, sg[0], sg[1], ra, rb); float d = ra[p_idx] - ofs[p_idx]; if (Node3DEditor::get_singleton()->is_snap_enabled()) { @@ -2360,7 +2361,7 @@ void GPUParticles3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx if (move) { Vector3 ra, rb; - Geometry::get_closest_points_between_segments(ofs - axis * 4096, ofs + axis * 4096, sg[0], sg[1], ra, rb); + Geometry3D::get_closest_points_between_segments(ofs - axis * 4096, ofs + axis * 4096, sg[0], sg[1], ra, rb); float d = ra[p_idx]; if (Node3DEditor::get_singleton()->is_snap_enabled()) { @@ -2372,7 +2373,7 @@ void GPUParticles3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx } else { Vector3 ra, rb; - Geometry::get_closest_points_between_segments(ofs, ofs + axis * 4096, sg[0], sg[1], ra, rb); + Geometry3D::get_closest_points_between_segments(ofs, ofs + axis * 4096, sg[0], sg[1], ra, rb); float d = ra[p_idx] - ofs[p_idx]; if (Node3DEditor::get_singleton()->is_snap_enabled()) { @@ -2523,7 +2524,7 @@ void ReflectionProbeGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_id axis[p_idx] = 1.0; Vector3 ra, rb; - Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb); + Geometry3D::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb); float d = ra[p_idx]; if (Node3DEditor::get_singleton()->is_snap_enabled()) { d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap()); @@ -2550,7 +2551,7 @@ void ReflectionProbeGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_id axis[p_idx] = 1.0; Vector3 ra, rb; - Geometry::get_closest_points_between_segments(origin - axis * 16384, origin + axis * 16384, sg[0], sg[1], ra, rb); + Geometry3D::get_closest_points_between_segments(origin - axis * 16384, origin + axis * 16384, sg[0], sg[1], ra, rb); // Adjust the actual position to account for the gizmo handle position float d = ra[p_idx] + 0.25; if (Node3DEditor::get_singleton()->is_snap_enabled()) { @@ -2701,7 +2702,7 @@ void DecalGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3 axis[p_idx] = 1.0; Vector3 ra, rb; - Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb); + Geometry3D::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb); float d = ra[p_idx]; if (Node3DEditor::get_singleton()->is_snap_enabled()) { d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap()); @@ -2842,7 +2843,7 @@ void GIProbeGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camer axis[p_idx] = 1.0; Vector3 ra, rb; - Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb); + Geometry3D::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb); float d = ra[p_idx]; if (Node3DEditor::get_singleton()->is_snap_enabled()) { d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap()); @@ -3354,7 +3355,7 @@ void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_i if (Object::cast_to<SphereShape3D>(*s)) { Ref<SphereShape3D> ss = s; Vector3 ra, rb; - Geometry::get_closest_points_between_segments(Vector3(), Vector3(4096, 0, 0), sg[0], sg[1], ra, rb); + Geometry3D::get_closest_points_between_segments(Vector3(), Vector3(4096, 0, 0), sg[0], sg[1], ra, rb); float d = ra.x; if (Node3DEditor::get_singleton()->is_snap_enabled()) { d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap()); @@ -3370,7 +3371,7 @@ void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_i if (Object::cast_to<RayShape3D>(*s)) { Ref<RayShape3D> rs = s; Vector3 ra, rb; - Geometry::get_closest_points_between_segments(Vector3(), Vector3(0, 0, 4096), sg[0], sg[1], ra, rb); + Geometry3D::get_closest_points_between_segments(Vector3(), Vector3(0, 0, 4096), sg[0], sg[1], ra, rb); float d = ra.z; if (Node3DEditor::get_singleton()->is_snap_enabled()) { d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap()); @@ -3388,7 +3389,7 @@ void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_i axis[p_idx] = 1.0; Ref<BoxShape3D> bs = s; Vector3 ra, rb; - Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); + Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); float d = ra[p_idx]; if (Node3DEditor::get_singleton()->is_snap_enabled()) { d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap()); @@ -3408,7 +3409,7 @@ void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_i axis[p_idx == 0 ? 0 : 2] = 1.0; Ref<CapsuleShape3D> cs2 = s; Vector3 ra, rb; - Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); + Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); float d = axis.dot(ra); if (p_idx == 1) { d -= cs2->get_radius(); @@ -3434,7 +3435,7 @@ void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_i axis[p_idx == 0 ? 0 : 1] = 1.0; Ref<CylinderShape3D> cs2 = s; Vector3 ra, rb; - Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); + Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); float d = axis.dot(ra); if (Node3DEditor::get_singleton()->is_snap_enabled()) { d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap()); @@ -3802,7 +3803,7 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { if (points.size() > 3) { Vector<Vector3> varr = Variant(points); - Geometry::MeshData md; + Geometry3D::MeshData md; Error err = QuickHull::build(varr, md); if (err == OK) { Vector<Vector3> points2; diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp index 1abba45f9e..b905c8db12 100644 --- a/editor/plugins/abstract_polygon_2d_editor.cpp +++ b/editor/plugins/abstract_polygon_2d_editor.cpp @@ -31,6 +31,7 @@ #include "abstract_polygon_2d_editor.h" #include "canvas_item_editor_plugin.h" +#include "core/math/geometry_2d.h" #include "core/os/keyboard.h" #include "editor/editor_scale.h" @@ -671,7 +672,7 @@ AbstractPolygon2DEditor::PosVertex AbstractPolygon2DEditor::closest_edge_point(c Vector2 segment[2] = { xform.xform(points[i] + offset), xform.xform(points[(i + 1) % n_points] + offset) }; - Vector2 cp = Geometry::get_closest_point_to_segment_2d(p_pos, segment); + Vector2 cp = Geometry2D::get_closest_point_to_segment(p_pos, segment); if (cp.distance_squared_to(segment[0]) < eps2 || cp.distance_squared_to(segment[1]) < eps2) { continue; //not valid to reuse point diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp index df67482dfb..a7d5c2207b 100644 --- a/editor/plugins/animation_blend_space_2d_editor.cpp +++ b/editor/plugins/animation_blend_space_2d_editor.cpp @@ -32,7 +32,7 @@ #include "core/input/input.h" #include "core/io/resource_loader.h" -#include "core/math/delaunay_2d.h" +#include "core/math/geometry_2d.h" #include "core/os/keyboard.h" #include "core/project_settings.h" #include "editor/editor_scale.h" @@ -165,7 +165,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven triangle.push_back(points[idx]); } - if (Geometry::is_point_in_triangle(mb->get_position(), triangle[0], triangle[1], triangle[2])) { + if (Geometry2D::is_point_in_triangle(mb->get_position(), triangle[0], triangle[1], triangle[2])) { selected_triangle = i; _update_tool_erase(); return; diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index 652754a146..a435b1c482 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -32,7 +32,7 @@ #include "core/input/input.h" #include "core/io/resource_loader.h" -#include "core/math/delaunay_2d.h" +#include "core/math/geometry_2d.h" #include "core/os/keyboard.h" #include "core/project_settings.h" #include "editor/editor_scale.h" @@ -191,7 +191,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv transition_lines[i].from, transition_lines[i].to }; - Vector2 cpoint = Geometry::get_closest_point_to_segment_2d(mb->get_position(), s); + Vector2 cpoint = Geometry2D::get_closest_point_to_segment(mb->get_position(), s); float d = cpoint.distance_to(mb->get_position()); if (d > transition_lines[i].width) { continue; diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index b62dfd13c8..59366a239f 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -31,6 +31,7 @@ #include "canvas_item_editor_plugin.h" #include "core/input/input.h" +#include "core/math/geometry_2d.h" #include "core/os/keyboard.h" #include "core/print_string.h" #include "core/project_settings.h" @@ -86,7 +87,6 @@ public: GridContainer *child_container; set_title(TTR("Configure Snap")); - get_ok()->set_text(TTR("Close")); container = memnew(VBoxContainer); add_child(container); @@ -672,7 +672,7 @@ void CanvasItemEditor::_get_bones_at_pos(const Point2 &p_pos, Vector<_SelectResu } // Check if the point is inside the Polygon2D - if (Geometry::is_point_in_polygon(screen_pos, bone_shape)) { + if (Geometry2D::is_point_in_polygon(screen_pos, bone_shape)) { // Check if the item is already in the list bool duplicate = false; for (int i = 0; i < r_items.size(); i++) { diff --git a/editor/plugins/collision_polygon_3d_editor_plugin.cpp b/editor/plugins/collision_polygon_3d_editor_plugin.cpp index c61d410d38..d9d9cf6a87 100644 --- a/editor/plugins/collision_polygon_3d_editor_plugin.cpp +++ b/editor/plugins/collision_polygon_3d_editor_plugin.cpp @@ -32,6 +32,7 @@ #include "canvas_item_editor_plugin.h" #include "core/input/input.h" +#include "core/math/geometry_2d.h" #include "core/os/file_access.h" #include "core/os/keyboard.h" #include "editor/editor_settings.h" @@ -196,7 +197,7 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con p_camera->unproject_position(gt.xform(Vector3(poly[(i + 1) % poly.size()].x, poly[(i + 1) % poly.size()].y, depth))) }; - Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint, points); + Vector2 cp = Geometry2D::get_closest_point_to_segment(gpoint, points); if (cp.distance_squared_to(points[0]) < CMP_EPSILON2 || cp.distance_squared_to(points[1]) < CMP_EPSILON2) { continue; //not valid to reuse point } diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp index 0f381c06b4..596629f8e8 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.cpp +++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp @@ -36,6 +36,7 @@ #include "scene/resources/concave_polygon_shape_2d.h" #include "scene/resources/convex_polygon_shape_2d.h" #include "scene/resources/line_shape_2d.h" +#include "scene/resources/ray_shape_2d.h" #include "scene/resources/rectangle_shape_2d.h" #include "scene/resources/segment_shape_2d.h" diff --git a/editor/plugins/debugger_editor_plugin.cpp b/editor/plugins/debugger_editor_plugin.cpp index 0ca479555d..0a4d173923 100644 --- a/editor/plugins/debugger_editor_plugin.cpp +++ b/editor/plugins/debugger_editor_plugin.cpp @@ -68,13 +68,10 @@ DebuggerEditorPlugin::DebuggerEditorPlugin(EditorNode *p_editor, MenuButton *p_d p->add_check_shortcut(ED_SHORTCUT("editor/visible_navigation", TTR("Visible Navigation")), RUN_DEBUG_NAVIGATION); p->set_item_tooltip(p->get_item_count() - 1, TTR("Navigation meshes and polygons will be visible on the running game if this option is turned on.")); p->add_separator(); - //those are now on by default, since they are harmless p->add_check_shortcut(ED_SHORTCUT("editor/sync_scene_changes", TTR("Sync Scene Changes")), RUN_LIVE_DEBUG); p->set_item_tooltip(p->get_item_count() - 1, TTR("When this option is turned on, any changes made to the scene in the editor will be replicated in the running game.\nWhen used remotely on a device, this is more efficient with network filesystem.")); - p->set_item_checked(p->get_item_count() - 1, true); p->add_check_shortcut(ED_SHORTCUT("editor/sync_script_changes", TTR("Sync Script Changes")), RUN_RELOAD_SCRIPTS); p->set_item_tooltip(p->get_item_count() - 1, TTR("When this option is turned on, any script that is saved will be reloaded on the running game.\nWhen used remotely on a device, this is more efficient with network filesystem.")); - p->set_item_checked(p->get_item_count() - 1, true); // Multi-instance, start/stop instances_menu = memnew(PopupMenu); @@ -174,8 +171,8 @@ void DebuggerEditorPlugin::_update_debug_options() { bool check_file_server = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_file_server", false); bool check_debug_collisions = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_collisons", false); bool check_debug_navigation = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_navigation", false); - bool check_live_debug = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_live_debug", false); - bool check_reload_scripts = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_reload_scripts", false); + bool check_live_debug = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_live_debug", true); + bool check_reload_scripts = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_reload_scripts", true); int instances = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_instances", 1); if (check_deploy_remote) { diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 8466ee86e5..f59b4171b4 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -832,7 +832,7 @@ bool Node3DEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_high Vector3 r; - if (Geometry::segment_intersects_sphere(ray_pos, ray_pos + ray * MAX_Z, grabber_pos, grabber_radius, &r)) { + if (Geometry3D::segment_intersects_sphere(ray_pos, ray_pos + ray * MAX_Z, grabber_pos, grabber_radius, &r)) { float d = r.distance_to(ray_pos); if (d < col_d) { col_d = d; @@ -929,7 +929,7 @@ bool Node3DEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_high Vector3 r; - if (Geometry::segment_intersects_sphere(ray_pos, ray_pos + ray * MAX_Z, grabber_pos, grabber_radius, &r)) { + if (Geometry3D::segment_intersects_sphere(ray_pos, ray_pos + ray * MAX_Z, grabber_pos, grabber_radius, &r)) { float d = r.distance_to(ray_pos); if (d < col_d) { col_d = d; diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp index a44fe69ff6..25cffa3d6c 100644 --- a/editor/plugins/path_3d_editor_plugin.cpp +++ b/editor/plugins/path_3d_editor_plugin.cpp @@ -30,6 +30,8 @@ #include "path_3d_editor_plugin.h" +#include "core/math/geometry_2d.h" +#include "core/math/geometry_3d.h" #include "core/os/keyboard.h" #include "node_3d_editor_plugin.h" #include "scene/resources/curve.h" @@ -344,7 +346,7 @@ bool Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref Vector2 s[2]; s[0] = p_camera->unproject_position(from); s[1] = p_camera->unproject_position(to); - Vector2 inters = Geometry::get_closest_point_to_segment_2d(mbpos, s); + Vector2 inters = Geometry2D::get_closest_point_to_segment(mbpos, s); float d = inters.distance_to(mbpos); if (d < 10 && d < closest_d) { @@ -354,7 +356,7 @@ bool Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref Vector3 ray_dir = p_camera->project_ray_normal(mbpos); Vector3 ra, rb; - Geometry::get_closest_points_between_segments(ray_from, ray_from + ray_dir * 4096, from, to, ra, rb); + Geometry3D::get_closest_points_between_segments(ray_from, ray_from + ray_dir * 4096, from, to, ra, rb); closest_seg_point = it.xform(rb); } diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index 7ee695b9fe..1f98c0139b 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -32,6 +32,7 @@ #include "canvas_item_editor_plugin.h" #include "core/input/input.h" +#include "core/math/geometry_2d.h" #include "core/os/file_access.h" #include "core/os/keyboard.h" #include "editor/editor_scale.h" @@ -693,7 +694,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { polys.write[j] = mtx.xform(points_prev[idx]); } - if (Geometry::is_point_in_polygon(Vector2(mb->get_position().x, mb->get_position().y), polys)) { + if (Geometry2D::is_point_in_polygon(Vector2(mb->get_position().x, mb->get_position().y), polys)) { erase_index = i; break; } diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index e7f8a56e5e..4b79d8c344 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -609,6 +609,18 @@ void ScriptTextEditor::_validate_script() { for (List<ScriptLanguage::Warning>::Element *E = warnings.front(); E; E = E->next()) { ScriptLanguage::Warning w = E->get(); + Dictionary ignore_meta; + ignore_meta["line"] = w.line; + ignore_meta["code"] = w.string_code.to_lower(); + warnings_panel->push_cell(); + warnings_panel->push_meta(ignore_meta); + warnings_panel->push_color( + warnings_panel->get_theme_color("accent_color", "Editor").lerp(warnings_panel->get_theme_color("mono_color", "Editor"), 0.5)); + warnings_panel->add_text(TTR("[Ignore]")); + warnings_panel->pop(); // Color. + warnings_panel->pop(); // Meta ignore. + warnings_panel->pop(); // Cell. + warnings_panel->push_cell(); warnings_panel->push_meta(w.line - 1); warnings_panel->push_color(warnings_panel->get_theme_color("warning_color", "Editor")); @@ -621,15 +633,6 @@ void ScriptTextEditor::_validate_script() { warnings_panel->push_cell(); warnings_panel->add_text(w.message); warnings_panel->pop(); // Cell. - - Dictionary ignore_meta; - ignore_meta["line"] = w.line; - ignore_meta["code"] = w.string_code.to_lower(); - warnings_panel->push_cell(); - warnings_panel->push_meta(ignore_meta); - warnings_panel->add_text(TTR("(ignore)")); - warnings_panel->pop(); // Meta ignore. - warnings_panel->pop(); // Cell. } warnings_panel->pop(); // Table. @@ -1747,6 +1750,8 @@ ScriptTextEditor::ScriptTextEditor() { warnings_panel = memnew(RichTextLabel); editor_box->add_child(warnings_panel); + warnings_panel->add_theme_font_override( + "normal_font", EditorNode::get_singleton()->get_gui_base()->get_theme_font("main", "EditorFonts")); warnings_panel->set_custom_minimum_size(Size2(0, 100 * EDSCALE)); warnings_panel->set_h_size_flags(SIZE_EXPAND_FILL); warnings_panel->set_meta_underline(true); diff --git a/editor/plugins/sprite_2d_editor_plugin.cpp b/editor/plugins/sprite_2d_editor_plugin.cpp index b21586a6b0..f5fafb68a5 100644 --- a/editor/plugins/sprite_2d_editor_plugin.cpp +++ b/editor/plugins/sprite_2d_editor_plugin.cpp @@ -31,6 +31,7 @@ #include "sprite_2d_editor_plugin.h" #include "canvas_item_editor_plugin.h" +#include "core/math/geometry_2d.h" #include "editor/editor_scale.h" #include "scene/2d/collision_polygon_2d.h" #include "scene/2d/light_occluder_2d.h" @@ -233,7 +234,7 @@ void Sprite2DEditor::_update_mesh_data() { computed_vertices.push_back(vtx); } - Vector<int> poly = Geometry::triangulate_polygon(lines[j]); + Vector<int> poly = Geometry2D::triangulate_polygon(lines[j]); for (int i = 0; i < poly.size(); i += 3) { for (int k = 0; k < 3; k++) { diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index 6c037f94a0..3281a59c1c 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -194,6 +194,21 @@ void TileMapEditor::_palette_multi_selected(int index, bool selected) { _update_palette(); } +void TileMapEditor::_palette_input(const Ref<InputEvent> &p_event) { + const Ref<InputEventMouseButton> mb = p_event; + + // Zoom in/out using Ctrl + mouse wheel. + if (mb.is_valid() && mb->is_pressed() && mb->get_command()) { + if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_UP) { + size_slider->set_value(size_slider->get_value() + 0.2); + } + + if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_DOWN) { + size_slider->set_value(size_slider->get_value() - 0.2); + } + } +} + void TileMapEditor::_canvas_mouse_enter() { mouse_over = true; CanvasItemEditor::get_singleton()->update_viewport(); @@ -1913,6 +1928,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { palette->add_theme_constant_override("vseparation", 8 * EDSCALE); palette->connect("item_selected", callable_mp(this, &TileMapEditor::_palette_selected)); palette->connect("multi_selected", callable_mp(this, &TileMapEditor::_palette_multi_selected)); + palette->connect("gui_input", callable_mp(this, &TileMapEditor::_palette_input)); palette_container->add_child(palette); // Add message for when no texture is selected. diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h index 5f82d7bfb8..e25e2d2add 100644 --- a/editor/plugins/tile_map_editor_plugin.h +++ b/editor/plugins/tile_map_editor_plugin.h @@ -182,6 +182,7 @@ class TileMapEditor : public VBoxContainer { void _menu_option(int p_option); void _palette_selected(int index); void _palette_multi_selected(int index, bool selected); + void _palette_input(const Ref<InputEvent> &p_event); Dictionary _create_cell_dictionary(int tile, bool flip_x, bool flip_y, bool transpose, Vector2 autotile_coord); void _start_undo(const String &p_action); diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index 644facd5bd..b3d4b391d3 100644 --- a/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp @@ -569,6 +569,7 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) { scroll = memnew(ScrollContainer); main_vb->add_child(scroll); scroll->set_v_size_flags(SIZE_EXPAND_FILL); + scroll->connect("gui_input", callable_mp(this, &TileSetEditor::_on_scroll_container_input)); scroll->set_clip_contents(true); empty_message = memnew(Label); @@ -1198,6 +1199,27 @@ bool TileSetEditor::is_within_grabbing_distance_of_first_point(const Vector2 &p_ return distance < p_grab_threshold; } +void TileSetEditor::_on_scroll_container_input(const Ref<InputEvent> &p_event) { + const Ref<InputEventMouseButton> mb = p_event; + + if (mb.is_valid()) { + // Zoom in/out using Ctrl + mouse wheel. This is done on the ScrollContainer + // to allow performing this action anywhere, even if the cursor isn't + // hovering the texture in the workspace. + if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed() && mb->get_control()) { + print_line("zooming in"); + _zoom_in(); + // Don't scroll up after zooming in. + accept_event(); + } else if (mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed() && mb->get_control()) { + print_line("zooming out"); + _zoom_out(); + // Don't scroll down after zooming out. + accept_event(); + } + } +} + void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { if (tileset.is_null() || !get_current_texture().is_valid()) { return; @@ -1214,8 +1236,8 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { } current_tile_region.position += WORKSPACE_MARGIN; - Ref<InputEventMouseButton> mb = p_ie; - Ref<InputEventMouseMotion> mm = p_ie; + const Ref<InputEventMouseButton> mb = p_ie; + const Ref<InputEventMouseMotion> mm = p_ie; if (mb.is_valid()) { if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && !creating_shape) { @@ -1239,13 +1261,6 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { delete tiles; } } - - // Mouse Wheel Event - if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed() && mb->get_control()) { - _zoom_in(); - } else if (mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed() && mb->get_control()) { - _zoom_out(); - } } // Drag Middle Mouse if (mm.is_valid()) { diff --git a/editor/plugins/tile_set_editor_plugin.h b/editor/plugins/tile_set_editor_plugin.h index 827325cfd7..2955dda244 100644 --- a/editor/plugins/tile_set_editor_plugin.h +++ b/editor/plugins/tile_set_editor_plugin.h @@ -200,6 +200,7 @@ private: void _on_workspace_overlay_draw(); void _on_workspace_draw(); void _on_workspace_process(); + void _on_scroll_container_input(const Ref<InputEvent> &p_event); void _on_workspace_input(const Ref<InputEvent> &p_ie); void _on_tool_clicked(int p_tool); void _on_priority_changed(float val); diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index dc5ff6a5eb..499f7d4017 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -916,6 +916,8 @@ public: icon = nullptr; icon_needs_reload = true; hover = false; + + set_focus_mode(FocusMode::FOCUS_ALL); } void set_is_favorite(bool fav) { @@ -1739,6 +1741,10 @@ void ProjectList::_panel_input(const Ref<InputEvent> &p_ev, Node *p_hb) { select_project(clicked_index); } + if (_selected_project_keys.has(clicked_project.project_key)) { + clicked_project.control->grab_focus(); + } + emit_signal(SIGNAL_SELECTION_CHANGED); if (!mb->get_control() && mb->is_doubleclick()) { diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp index 6888ebdc71..c6c93fae83 100644 --- a/editor/property_selector.cpp +++ b/editor/property_selector.cpp @@ -357,7 +357,7 @@ void PropertySelector::_item_selected() { if (E) { for (int i = 0; i < E->get().properties.size(); i++) { if (E->get().properties[i].name == name) { - text = E->get().properties[i].description; + text = DTR(E->get().properties[i].description); } } } @@ -372,7 +372,7 @@ void PropertySelector::_item_selected() { if (E) { for (int i = 0; i < E->get().methods.size(); i++) { if (E->get().methods[i].name == name) { - text = E->get().methods[i].description; + text = DTR(E->get().methods[i].description); } } } diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index a81a2ff4e9..c37d32b26b 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -2557,6 +2557,11 @@ void SceneTreeDock::_focus_node() { } void SceneTreeDock::attach_script_to_selected(bool p_extend) { + if (ScriptServer::get_language_count() == 0) { + EditorNode::get_singleton()->show_warning(TTR("Cannot attach a script: there are no languages registered.\nThis is probably because this editor was built with all language modules disabled.")); + return; + } + if (!profile_allow_script_editing) { return; } diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index 04fbfdff9d..ae5229b628 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -783,7 +783,7 @@ ScriptCreateDialog::ScriptCreateDialog() { gc->add_child(memnew(Label(TTR("Language:")))); gc->add_child(language_menu); - default_language = 0; + default_language = -1; for (int i = 0; i < ScriptServer::get_language_count(); i++) { String lang = ScriptServer::get_language(i)->get_name(); language_menu->add_item(lang); @@ -791,8 +791,9 @@ ScriptCreateDialog::ScriptCreateDialog() { default_language = i; } } - - language_menu->select(default_language); + if (default_language >= 0) { + language_menu->select(default_language); + } current_language = default_language; language_menu->connect("item_selected", callable_mp(this, &ScriptCreateDialog::_lang_changed)); |