diff options
Diffstat (limited to 'editor')
66 files changed, 1765 insertions, 442 deletions
diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp index 17b03fd479..22adf4f267 100644 --- a/editor/animation_bezier_editor.cpp +++ b/editor/animation_bezier_editor.cpp @@ -32,6 +32,7 @@ #include "editor/editor_node.h" #include "editor_scale.h" +#include "scene/resources/text_line.h" float AnimationBezierTrackEdit::_bezier_h_to_pixel(float p_h) { float h = p_h; @@ -247,6 +248,7 @@ void AnimationBezierTrackEdit::_notification(int p_what) { } Ref<Font> font = get_theme_font("font", "Label"); + int font_size = get_theme_font_size("font_size", "Label"); Color color = get_theme_color("font_color", "Label"); int hsep = get_theme_constant("hseparation", "ItemList"); int vsep = get_theme_constant("vseparation", "ItemList"); @@ -286,26 +288,27 @@ void AnimationBezierTrackEdit::_notification(int p_what) { String text; - int h = font->get_height(); - if (node) { int ofs = 0; Ref<Texture2D> icon = EditorNode::get_singleton()->get_object_icon(node, "Node"); - h = MAX(h, icon->get_height()); + text = node->get_name(); + ofs += hsep; + ofs += icon->get_width(); + + TextLine text_buf = TextLine(text, font, font_size); + text_buf.set_width(limit - ofs - hsep); + + int h = MAX(text_buf.get_size().y, icon->get_height()); draw_texture(icon, Point2(ofs, vofs + int(h - icon->get_height()) / 2)); margin = icon->get_width(); - text = node->get_name(); - ofs += hsep; - ofs += icon->get_width(); - - Vector2 string_pos = Point2(ofs, vofs + (h - font->get_height()) / 2 + font->get_ascent()); + Vector2 string_pos = Point2(ofs, vofs + (h - text_buf.get_size().y) / 2 + text_buf.get_line_ascent()); string_pos = string_pos.floor(); - draw_string(font, string_pos, text, color, limit - ofs - hsep); + text_buf.draw(get_canvas_item(), string_pos, color); vofs += h + vsep; } @@ -327,7 +330,10 @@ void AnimationBezierTrackEdit::_notification(int p_what) { path = path.replace_first(base_path, ""); Color cc = color; - Rect2 rect = Rect2(margin, vofs, limit - margin - hsep, font->get_height() + vsep); + TextLine text_buf = TextLine(path, font, font_size); + text_buf.set_width(limit - margin - hsep); + + Rect2 rect = Rect2(margin, vofs, limit - margin - hsep, text_buf.get_size().y + vsep); if (i != track) { cc.a *= 0.7; uint32_t hash = path.hash(); @@ -338,7 +344,7 @@ void AnimationBezierTrackEdit::_notification(int p_what) { Color subcolor; subcolor.set_hsv(h, 0.2, 0.8); subcolor.a = 0.5; - draw_rect(Rect2(0, vofs + font->get_height() * 0.1, margin - hsep, font->get_height() * 0.8), subcolor); + draw_rect(Rect2(0, vofs + text_buf.get_size().y * 0.1, margin - hsep, text_buf.get_size().y * 0.8), subcolor); subtrack_colors[i] = subcolor; subtracks[i] = rect; @@ -347,15 +353,17 @@ void AnimationBezierTrackEdit::_notification(int p_what) { ac.a = 0.5; draw_rect(rect, ac); } - draw_string(font, Point2(margin, vofs + font->get_ascent()), path, cc, limit - margin - hsep); - vofs += font->get_height() + vsep; + Vector2 string_pos = Point2(margin, vofs + text_buf.get_line_ascent()); + text_buf.draw(get_canvas_item(), string_pos, cc); + + vofs += text_buf.get_size().y + vsep; } Color accent = get_theme_color("accent_color", "Editor"); { //guides - float min_left_scale = font->get_height() + vsep; + float min_left_scale = font->get_height(font_size) + vsep; float scale = (min_left_scale * 2) * v_zoom; float step = Math::pow(10.0, Math::round(Math::log(scale / 5.0) / Math::log(10.0))) * 5.0; @@ -367,7 +375,7 @@ void AnimationBezierTrackEdit::_notification(int p_what) { bool first = true; int prev_iv = 0; - for (int i = font->get_height(); i < get_size().height; i++) { + for (int i = font->get_height(font_size); i < get_size().height; i++) { float ofs = get_size().height / 2 - i; ofs *= v_zoom; ofs += v_scroll; @@ -382,7 +390,7 @@ void AnimationBezierTrackEdit::_notification(int p_what) { draw_line(Point2(limit, i), Point2(right_limit, i), lc); Color c = color; c.a *= 0.5; - draw_string(font, Point2(limit + 8, i - 2), rtos(Math::stepify((iv + 1) * scale, step)), c); + draw_string(font, Point2(limit + 8, i - 2), TS->format_number(rtos(Math::stepify((iv + 1) * scale, step))), HALIGN_LEFT, -1, font_size, c); } first = false; @@ -453,8 +461,8 @@ void AnimationBezierTrackEdit::_notification(int p_what) { ep.point_rect.size = bezier_icon->get_size(); if (selection.has(i)) { draw_texture(selected_icon, ep.point_rect.position); - draw_string(font, ep.point_rect.position + Vector2(8, -font->get_height() - 4), TTR("Time:") + " " + rtos(Math::stepify(offset, 0.001)), accent); - draw_string(font, ep.point_rect.position + Vector2(8, -8), TTR("Value:") + " " + rtos(Math::stepify(value, 0.001)), accent); + draw_string(font, ep.point_rect.position + Vector2(8, -font->get_height(font_size) - 4), TTR("Time:") + " " + TS->format_number(rtos(Math::stepify(offset, 0.001))), HALIGN_LEFT, -1, font_size, accent); + draw_string(font, ep.point_rect.position + Vector2(8, -8), TTR("Value:") + " " + TS->format_number(rtos(Math::stepify(value, 0.001))), HALIGN_LEFT, -1, font_size, accent); } else { draw_texture(bezier_icon, ep.point_rect.position); } diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 6f30d5a492..d4d4c7d809 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -1397,6 +1397,7 @@ void AnimationTimelineEdit::_notification(int p_what) { } Ref<Font> font = get_theme_font("font", "Label"); + int font_size = get_theme_font_size("font_size", "Label"); Color color = get_theme_color("font_color", "Label"); int zoomw = key_range; @@ -1488,10 +1489,10 @@ void AnimationTimelineEdit::_notification(int p_what) { int decimals = 2; bool step_found = false; - const int period_width = font->get_char_size('.').width; - int max_digit_width = font->get_char_size('0').width; + const int period_width = font->get_char_size('.', 0, font_size).width; + int max_digit_width = font->get_char_size('0', 0, font_size).width; for (int i = 1; i <= 9; i++) { - const int digit_width = font->get_char_size('0' + i).width; + const int digit_width = font->get_char_size('0' + i, 0, font_size).width; max_digit_width = MAX(digit_width, max_digit_width); } const int max_sc = int(Math::ceil(zoomw / scale)); @@ -1538,8 +1539,8 @@ void AnimationTimelineEdit::_notification(int p_what) { if (frame != prev_frame && i >= prev_frame_ofs) { draw_line(Point2(get_name_limit() + i, 0), Point2(get_name_limit() + i, h), linecolor, Math::round(EDSCALE)); - draw_string(font, Point2(get_name_limit() + i + 3 * EDSCALE, (h - font->get_height()) / 2 + font->get_ascent()).floor(), itos(frame), sub ? color_time_dec : color_time_sec, zoomw - i); - prev_frame_ofs = i + font->get_string_size(itos(frame)).x + 5 * EDSCALE; + draw_string(font, Point2(get_name_limit() + i + 3 * EDSCALE, (h - font->get_height(font_size)) / 2 + font->get_ascent(font_size)).floor(), itos(frame), HALIGN_LEFT, zoomw - i, font_size, sub ? color_time_dec : color_time_sec); + prev_frame_ofs = i + font->get_string_size(itos(frame), font_size).x + 5 * EDSCALE; } } } @@ -1556,7 +1557,7 @@ void AnimationTimelineEdit::_notification(int p_what) { if ((sc / step) != (prev_sc / step) || (prev_sc < 0 && sc >= 0)) { int scd = sc < 0 ? prev_sc : sc; draw_line(Point2(get_name_limit() + i, 0), Point2(get_name_limit() + i, h), linecolor, Math::round(EDSCALE)); - draw_string(font, Point2(get_name_limit() + i + 3, (h - font->get_height()) / 2 + font->get_ascent()).floor(), String::num((scd - (scd % step)) / double(SC_ADJ), decimals), sub ? color_time_dec : color_time_sec, zoomw - i); + draw_string(font, Point2(get_name_limit() + i + 3, (h - font->get_height(font_size)) / 2 + font->get_ascent(font_size)).floor(), String::num((scd - (scd % step)) / double(SC_ADJ), decimals), HALIGN_LEFT, zoomw - i, font_size, sub ? color_time_dec : color_time_sec); } } } @@ -1583,7 +1584,8 @@ void AnimationTimelineEdit::set_animation(const Ref<Animation> &p_animation) { Size2 AnimationTimelineEdit::get_minimum_size() const { Size2 ms = add_track->get_minimum_size(); Ref<Font> font = get_theme_font("font", "Label"); - ms.height = MAX(ms.height, font->get_height()); + int font_size = get_theme_font_size("font_size", "Label"); + ms.height = MAX(ms.height, font->get_height(font_size)); ms.width = get_buttons_width() + add_track->get_minimum_size().width + get_theme_icon("Hsize", "EditorIcons")->get_width() + 2; return ms; } @@ -1798,6 +1800,8 @@ AnimationTimelineEdit::AnimationTimelineEdit() { panning_timeline = false; dragging_timeline = false; dragging_hsize = false; + + set_layout_direction(Control::LAYOUT_DIRECTION_LTR); } //////////////////////////////////// @@ -1819,6 +1823,7 @@ void AnimationTrackEdit::_notification(int p_what) { } Ref<Font> font = get_theme_font("font", "Label"); + int font_size = get_theme_font_size("font_size", "Label"); Color color = get_theme_color("font_color", "Label"); Ref<Texture2D> type_icons[6] = { get_theme_icon("KeyValue", "EditorIcons"), @@ -1890,9 +1895,9 @@ void AnimationTrackEdit::_notification(int p_what) { path_rect = Rect2(ofs, 0, limit - ofs - hsep, get_size().height); - Vector2 string_pos = Point2(ofs, (get_size().height - font->get_height()) / 2 + font->get_ascent()); + Vector2 string_pos = Point2(ofs, (get_size().height - font->get_height(font_size)) / 2 + font->get_ascent(font_size)); string_pos = string_pos.floor(); - draw_string(font, string_pos, text, text_color, limit - ofs - hsep); + draw_string(font, string_pos, text, HALIGN_LEFT, limit - ofs - hsep, font_size, text_color); draw_line(Point2(limit, 0), Point2(limit, get_size().height), linecolor, Math::round(EDSCALE)); } @@ -2173,6 +2178,7 @@ void AnimationTrackEdit::draw_key(int p_index, float p_pixels_sec, int p_x, bool if (animation->track_get_type(track) == Animation::TYPE_METHOD) { Ref<Font> font = get_theme_font("font", "Label"); + int font_size = get_theme_font_size("font_size", "Label"); Color color = get_theme_color("font_color", "Label"); color.a = 0.5; @@ -2197,7 +2203,7 @@ void AnimationTrackEdit::draw_key(int p_index, float p_pixels_sec, int p_x, bool int limit = MAX(0, p_clip_right - p_x - icon_to_draw->get_width()); if (limit > 0) { - draw_string(font, Vector2(p_x + icon_to_draw->get_width(), int(get_size().height - font->get_height()) / 2 + font->get_ascent()), text, color, limit); + draw_string(font, Vector2(p_x + icon_to_draw->get_width(), int(get_size().height - font->get_height(font_size)) / 2 + font->get_ascent(font_size)), text, HALIGN_LEFT, limit, font_size, color); } } @@ -2302,9 +2308,10 @@ NodePath AnimationTrackEdit::get_path() const { Size2 AnimationTrackEdit::get_minimum_size() const { Ref<Texture2D> texture = get_theme_icon("Object", "EditorIcons"); Ref<Font> font = get_theme_font("font", "Label"); + int font_size = get_theme_font_size("font_size", "Label"); int separation = get_theme_constant("vseparation", "ItemList"); - int max_h = MAX(texture->get_height(), font->get_height()); + int max_h = MAX(texture->get_height(), font->get_height(font_size)); max_h = MAX(max_h, get_key_height()); return Vector2(1, max_h + separation); @@ -3036,6 +3043,7 @@ AnimationTrackEdit *AnimationTrackEditPlugin::create_animation_track_edit(Object void AnimationTrackEditGroup::_notification(int p_what) { if (p_what == NOTIFICATION_DRAW) { Ref<Font> font = get_theme_font("font", "Label"); + int font_size = get_theme_font_size("font_size", "Label"); int separation = get_theme_constant("hseparation", "ItemList"); Color color = get_theme_color("font_color", "Label"); @@ -3059,7 +3067,7 @@ void AnimationTrackEditGroup::_notification(int p_what) { int ofs = 0; draw_texture(icon, Point2(ofs, int(get_size().height - icon->get_height()) / 2)); ofs += separation + icon->get_width(); - draw_string(font, Point2(ofs, int(get_size().height - font->get_height()) / 2 + font->get_ascent()), node_name, color, timeline->get_name_limit() - ofs); + draw_string(font, Point2(ofs, int(get_size().height - font->get_height(font_size)) / 2 + font->get_ascent(font_size)), node_name, HALIGN_LEFT, timeline->get_name_limit() - ofs, font_size, color); int px = (-timeline->get_value() + timeline->get_play_position()) * timeline->get_zoom_scale() + timeline->get_name_limit(); @@ -3080,9 +3088,10 @@ void AnimationTrackEditGroup::set_type_and_name(const Ref<Texture2D> &p_type, co Size2 AnimationTrackEditGroup::get_minimum_size() const { Ref<Font> font = get_theme_font("font", "Label"); + int font_size = get_theme_font_size("font_size", "Label"); int separation = get_theme_constant("vseparation", "ItemList"); - return Vector2(0, MAX(font->get_height(), icon->get_height()) + separation); + return Vector2(0, MAX(font->get_height(font_size), icon->get_height()) + separation); } void AnimationTrackEditGroup::set_timeline(AnimationTimelineEdit *p_timeline) { diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp index 9fc67000f9..4d96289343 100644 --- a/editor/animation_track_editor_plugins.cpp +++ b/editor/animation_track_editor_plugins.cpp @@ -37,6 +37,7 @@ #include "scene/2d/sprite_2d.h" #include "scene/3d/sprite_3d.h" #include "scene/animation/animation_player.h" +#include "scene/resources/text_line.h" #include "servers/audio/audio_stream.h" /// BOOL /// @@ -80,12 +81,14 @@ void AnimationTrackEditBool::draw_key(int p_index, float p_pixels_sec, int p_x, int AnimationTrackEditColor::get_key_height() const { Ref<Font> font = get_theme_font("font", "Label"); - return font->get_height() * 0.8; + int font_size = get_theme_font_size("font_size", "Label"); + return font->get_height(font_size) * 0.8; } Rect2 AnimationTrackEditColor::get_key_rect(int p_index, float p_pixels_sec) { Ref<Font> font = get_theme_font("font", "Label"); - int fh = font->get_height() * 0.8; + int font_size = get_theme_font_size("font_size", "Label"); + int fh = font->get_height(font_size) * 0.8; return Rect2(-fh / 2, 0, fh, get_size().height); } @@ -95,7 +98,8 @@ bool AnimationTrackEditColor::is_key_selectable_by_distance() const { void AnimationTrackEditColor::draw_key_link(int p_index, float p_pixels_sec, int p_x, int p_next_x, int p_clip_left, int p_clip_right) { Ref<Font> font = get_theme_font("font", "Label"); - int fh = (font->get_height() * 0.8); + int font_size = get_theme_font_size("font_size", "Label"); + int fh = (font->get_height(font_size) * 0.8); int x_from = p_x + fh / 2 - 1; int x_to = p_next_x - fh / 2 + 1; @@ -144,7 +148,8 @@ void AnimationTrackEditColor::draw_key(int p_index, float p_pixels_sec, int p_x, Color color = get_animation()->track_get_key_value(get_track(), p_index); Ref<Font> font = get_theme_font("font", "Label"); - int fh = font->get_height() * 0.8; + int font_size = get_theme_font_size("font_size", "Label"); + int fh = font->get_height(font_size) * 0.8; Rect2 rect(Vector2(p_x - fh / 2, int(get_size().height - fh) / 2), Size2(fh, fh)); @@ -182,7 +187,8 @@ int AnimationTrackEditAudio::get_key_height() const { } Ref<Font> font = get_theme_font("font", "Label"); - return int(font->get_height() * 1.5); + int font_size = get_theme_font_size("font_size", "Label"); + return int(font->get_height(font_size) * 1.5); } Rect2 AnimationTrackEditAudio::get_key_rect(int p_index, float p_pixels_sec) { @@ -214,7 +220,8 @@ Rect2 AnimationTrackEditAudio::get_key_rect(int p_index, float p_pixels_sec) { return Rect2(0, 0, len * p_pixels_sec, get_size().height); } else { Ref<Font> font = get_theme_font("font", "Label"); - int fh = font->get_height() * 0.8; + int font_size = get_theme_font_size("font_size", "Label"); + int fh = font->get_height(font_size) * 0.8; return Rect2(0, 0, fh, get_size().height); } } @@ -277,7 +284,8 @@ void AnimationTrackEditAudio::draw_key(int p_index, float p_pixels_sec, int p_x, } Ref<Font> font = get_theme_font("font", "Label"); - float fh = int(font->get_height() * 1.5); + int font_size = get_theme_font_size("font_size", "Label"); + float fh = int(font->get_height(font_size) * 1.5); Rect2 rect = Rect2(from_x, (get_size().height - fh) / 2, to_x - from_x, fh); draw_rect(rect, Color(0.25, 0.25, 0.25)); @@ -307,7 +315,8 @@ void AnimationTrackEditAudio::draw_key(int p_index, float p_pixels_sec, int p_x, } } else { Ref<Font> font = get_theme_font("font", "Label"); - int fh = font->get_height() * 0.8; + int font_size = get_theme_font_size("font_size", "Label"); + int fh = font->get_height(font_size) * 0.8; Rect2 rect(Vector2(p_x, int(get_size().height - fh) / 2), Size2(fh, fh)); Color color = get_theme_color("font_color", "Label"); @@ -339,7 +348,8 @@ int AnimationTrackEditSpriteFrame::get_key_height() const { } Ref<Font> font = get_theme_font("font", "Label"); - return int(font->get_height() * 2); + int font_size = get_theme_font_size("font_size", "Label"); + return int(font->get_height(font_size) * 2); } Rect2 AnimationTrackEditSpriteFrame::get_key_rect(int p_index, float p_pixels_sec) { @@ -406,7 +416,8 @@ Rect2 AnimationTrackEditSpriteFrame::get_key_rect(int p_index, float p_pixels_se size = size.floor(); Ref<Font> font = get_theme_font("font", "Label"); - int height = int(font->get_height() * 2); + int font_size = get_theme_font_size("font_size", "Label"); + int height = int(font->get_height(font_size) * 2); int width = height * size.width / size.height; return Rect2(0, 0, width, get_size().height); @@ -496,7 +507,8 @@ void AnimationTrackEditSpriteFrame::draw_key(int p_index, float p_pixels_sec, in } Ref<Font> font = get_theme_font("font", "Label"); - int height = int(font->get_height() * 2); + int font_size = get_theme_font_size("font_size", "Label"); + int height = int(font->get_height(font_size) * 2); int width = height * region.size.width / region.size.height; @@ -539,7 +551,8 @@ int AnimationTrackEditSubAnim::get_key_height() const { } Ref<Font> font = get_theme_font("font", "Label"); - return int(font->get_height() * 1.5); + int font_size = get_theme_font_size("font_size", "Label"); + return int(font->get_height(font_size) * 1.5); } Rect2 AnimationTrackEditSubAnim::get_key_rect(int p_index, float p_pixels_sec) { @@ -567,7 +580,8 @@ Rect2 AnimationTrackEditSubAnim::get_key_rect(int p_index, float p_pixels_sec) { return Rect2(0, 0, len * p_pixels_sec, get_size().height); } else { Ref<Font> font = get_theme_font("font", "Label"); - int fh = font->get_height() * 0.8; + int font_size = get_theme_font_size("font_size", "Label"); + int fh = font->get_height(font_size) * 0.8; return Rect2(0, 0, fh, get_size().height); } } @@ -621,7 +635,8 @@ void AnimationTrackEditSubAnim::draw_key(int p_index, float p_pixels_sec, int p_ } Ref<Font> font = get_theme_font("font", "Label"); - int fh = font->get_height() * 1.5; + int font_size = get_theme_font_size("font_size", "Label"); + int fh = font->get_height(font_size) * 1.5; Rect2 rect(from_x, int(get_size().height - fh) / 2, to_x - from_x, fh); @@ -664,7 +679,7 @@ void AnimationTrackEditSubAnim::draw_key(int p_index, float p_pixels_sec, int p_ int limit = to_x - from_x - 4; if (limit > 0) { - draw_string(font, Point2(from_x + 2, int(get_size().height - font->get_height()) / 2 + font->get_ascent()), anim, color); + draw_string(font, Point2(from_x + 2, int(get_size().height - font->get_height(font_size)) / 2 + font->get_ascent(font_size)), anim, HALIGN_LEFT, -1, font_size, color); } if (p_selected) { @@ -673,7 +688,8 @@ void AnimationTrackEditSubAnim::draw_key(int p_index, float p_pixels_sec, int p_ } } else { Ref<Font> font = get_theme_font("font", "Label"); - int fh = font->get_height() * 0.8; + int font_size = get_theme_font_size("font_size", "Label"); + int fh = font->get_height(font_size) * 0.8; Rect2 rect(Vector2(p_x, int(get_size().height - fh) / 2), Size2(fh, fh)); Color color = get_theme_color("font_color", "Label"); @@ -771,7 +787,8 @@ void AnimationTrackEditTypeAudio::_preview_changed(ObjectID p_which) { int AnimationTrackEditTypeAudio::get_key_height() const { Ref<Font> font = get_theme_font("font", "Label"); - return int(font->get_height() * 1.5); + int font_size = get_theme_font_size("font_size", "Label"); + return int(font->get_height(font_size) * 1.5); } Rect2 AnimationTrackEditTypeAudio::get_key_rect(int p_index, float p_pixels_sec) { @@ -835,7 +852,8 @@ void AnimationTrackEditTypeAudio::draw_key(int p_index, float p_pixels_sec, int } Ref<Font> font = get_theme_font("font", "Label"); - float fh = int(font->get_height() * 1.5); + int font_size = get_theme_font_size("font_size", "Label"); + float fh = int(font->get_height(font_size) * 1.5); float len = stream->get_length(); @@ -1104,7 +1122,8 @@ int AnimationTrackEditTypeAnimation::get_key_height() const { } Ref<Font> font = get_theme_font("font", "Label"); - return int(font->get_height() * 1.5); + int font_size = get_theme_font_size("font_size", "Label"); + return int(font->get_height(font_size) * 1.5); } Rect2 AnimationTrackEditTypeAnimation::get_key_rect(int p_index, float p_pixels_sec) { @@ -1132,7 +1151,8 @@ Rect2 AnimationTrackEditTypeAnimation::get_key_rect(int p_index, float p_pixels_ return Rect2(0, 0, len * p_pixels_sec, get_size().height); } else { Ref<Font> font = get_theme_font("font", "Label"); - int fh = font->get_height() * 0.8; + int font_size = get_theme_font_size("font_size", "Label"); + int fh = font->get_height(font_size) * 0.8; return Rect2(0, 0, fh, get_size().height); } } @@ -1186,7 +1206,8 @@ void AnimationTrackEditTypeAnimation::draw_key(int p_index, float p_pixels_sec, } Ref<Font> font = get_theme_font("font", "Label"); - int fh = font->get_height() * 1.5; + int font_size = get_theme_font_size("font_size", "Label"); + int fh = font->get_height(font_size) * 1.5; Rect2 rect(from_x, int(get_size().height - fh) / 2, to_x - from_x, fh); @@ -1229,7 +1250,7 @@ void AnimationTrackEditTypeAnimation::draw_key(int p_index, float p_pixels_sec, int limit = to_x - from_x - 4; if (limit > 0) { - draw_string(font, Point2(from_x + 2, int(get_size().height - font->get_height()) / 2 + font->get_ascent()), anim, color); + draw_string(font, Point2(from_x + 2, int(get_size().height - font->get_height(font_size)) / 2 + font->get_ascent(font_size)), anim, HALIGN_LEFT, -1, font_size, color); } if (p_selected) { @@ -1238,7 +1259,8 @@ void AnimationTrackEditTypeAnimation::draw_key(int p_index, float p_pixels_sec, } } else { Ref<Font> font = get_theme_font("font", "Label"); - int fh = font->get_height() * 0.8; + int font_size = get_theme_font_size("font_size", "Label"); + int fh = font->get_height(font_size) * 0.8; Rect2 rect(Vector2(p_x, int(get_size().height - fh) / 2), Size2(fh, fh)); Color color = get_theme_color("font_color", "Label"); diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 3182bca0eb..c4a8b310ec 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -38,7 +38,7 @@ #include "editor_settings.h" #include "scene/gui/margin_container.h" #include "scene/gui/separator.h" -#include "scene/resources/dynamic_font.h" +#include "scene/resources/font.h" void GotoLineDialog::popup_find_line(CodeEdit *p_edit) { text_editor = p_edit; @@ -731,6 +731,7 @@ void CodeTextEditor::_text_editor_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMagnifyGesture> magnify_gesture = p_event; if (magnify_gesture.is_valid()) { + /* Ref<DynamicFont> font = text_editor->get_theme_font("font"); if (font.is_valid()) { @@ -742,6 +743,8 @@ void CodeTextEditor::_text_editor_gui_input(const Ref<InputEvent> &p_event) { _add_font_size((int)font_size - font->get_size()); } + */ + //TODO move size to draw functions return; } @@ -764,27 +767,15 @@ void CodeTextEditor::_text_editor_gui_input(const Ref<InputEvent> &p_event) { void CodeTextEditor::_zoom_in() { font_resize_val += MAX(EDSCALE, 1.0f); - _zoom_changed(); } void CodeTextEditor::_zoom_out() { font_resize_val -= MAX(EDSCALE, 1.0f); - _zoom_changed(); -} - -void CodeTextEditor::_zoom_changed() { - if (font_resize_timer->get_time_left() == 0) { - font_resize_timer->start(); - } } void CodeTextEditor::_reset_zoom() { - Ref<DynamicFont> font = text_editor->get_theme_font("font"); // Reset source font size to default. - - if (font.is_valid()) { - EditorSettings::get_singleton()->set("interface/editor/code_font_size", 14); - font->set_size(14); - } + font_resize_val = 1.0f; + //TODO MOVE size to draw functions } void CodeTextEditor::_line_col_changed() { @@ -893,29 +884,6 @@ Ref<Texture2D> CodeTextEditor::_get_completion_icon(const ScriptCodeCompletionOp return tex; } -void CodeTextEditor::_font_resize_timeout() { - if (_add_font_size(font_resize_val)) { - font_resize_val = 0; - } -} - -bool CodeTextEditor::_add_font_size(int p_delta) { - Ref<DynamicFont> font = text_editor->get_theme_font("font"); - - if (font.is_valid()) { - int new_size = CLAMP(font->get_size() + p_delta, 8 * EDSCALE, 96 * EDSCALE); - - if (new_size != font->get_size()) { - EditorSettings::get_singleton()->set("interface/editor/code_font_size", new_size / EDSCALE); - font->set_size(new_size); - } - - return true; - } else { - return false; - } -} - void CodeTextEditor::update_editor_settings() { completion_font_color = EDITOR_GET("text_editor/highlighting/completion_font_color"); completion_string_color = EDITOR_GET("text_editor/highlighting/string_color"); @@ -1486,17 +1454,22 @@ void CodeTextEditor::goto_error() { void CodeTextEditor::_update_font() { text_editor->add_theme_font_override("font", get_theme_font("source", "EditorFonts")); + text_editor->add_theme_font_size_override("font_size", get_theme_font_size("source_size", "EditorFonts")); error->add_theme_font_override("font", get_theme_font("status_source", "EditorFonts")); + error->add_theme_font_size_override("font_size", get_theme_font_size("status_source_size", "EditorFonts")); error->add_theme_color_override("font_color", get_theme_color("error_color", "Editor")); Ref<Font> status_bar_font = get_theme_font("status_source", "EditorFonts"); + int status_bar_font_size = get_theme_font_size("status_source_size", "EditorFonts"); error->add_theme_font_override("font", status_bar_font); + error->add_theme_font_size_override("font_size", status_bar_font_size); int count = status_bar->get_child_count(); for (int i = 0; i < count; i++) { Control *n = Object::cast_to<Control>(status_bar->get_child(i)); if (n) { n->add_theme_font_override("font", status_bar_font); + n->add_theme_font_size_override("font_size", status_bar_font_size); } } } @@ -1547,7 +1520,11 @@ void CodeTextEditor::_set_show_warnings_panel(bool p_show) { } void CodeTextEditor::_toggle_scripts_pressed() { - toggle_scripts_button->set_icon(ScriptEditor::get_singleton()->toggle_scripts_panel() ? get_theme_icon("Back", "EditorIcons") : get_theme_icon("Forward", "EditorIcons")); + if (is_layout_rtl()) { + toggle_scripts_button->set_icon(ScriptEditor::get_singleton()->toggle_scripts_panel() ? get_theme_icon("Back", "EditorIcons") : get_theme_icon("Forward", "EditorIcons")); + } else { + toggle_scripts_button->set_icon(ScriptEditor::get_singleton()->toggle_scripts_panel() ? get_theme_icon("Forward", "EditorIcons") : get_theme_icon("Back", "EditorIcons")); + } } void CodeTextEditor::_error_pressed(const Ref<InputEvent> &p_event) { @@ -1668,7 +1645,11 @@ void CodeTextEditor::show_toggle_scripts_button() { } void CodeTextEditor::update_toggle_scripts_button() { - toggle_scripts_button->set_icon(ScriptEditor::get_singleton()->is_scripts_panel_toggled() ? get_theme_icon("Back", "EditorIcons") : get_theme_icon("Forward", "EditorIcons")); + if (is_layout_rtl()) { + toggle_scripts_button->set_icon(ScriptEditor::get_singleton()->is_scripts_panel_toggled() ? get_theme_icon("Back", "EditorIcons") : get_theme_icon("Forward", "EditorIcons")); + } else { + toggle_scripts_button->set_icon(ScriptEditor::get_singleton()->is_scripts_panel_toggled() ? get_theme_icon("Forward", "EditorIcons") : get_theme_icon("Back", "EditorIcons")); + } toggle_scripts_button->set_tooltip(TTR("Toggle Scripts Panel") + " (" + ED_GET_SHORTCUT("script_editor/toggle_scripts_panel")->get_as_text() + ")"); } @@ -1750,6 +1731,7 @@ CodeTextEditor::CodeTextEditor() { warning_count_label->set_tooltip(TTR("Warnings")); warning_count_label->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color("warning_color", "Editor")); warning_count_label->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font("status_source", "EditorFonts")); + warning_count_label->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size("status_source_size", "EditorFonts")); warning_count_label->connect("gui_input", callable_mp(this, &CodeTextEditor::_warning_label_gui_input)); is_warnings_panel_opened = false; @@ -1760,6 +1742,7 @@ CodeTextEditor::CodeTextEditor() { status_bar->add_child(line_and_col_txt); line_and_col_txt->set_v_size_flags(SIZE_EXPAND | SIZE_SHRINK_CENTER); line_and_col_txt->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font("status_source", "EditorFonts")); + line_and_col_txt->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size("status_source_size", "EditorFonts")); line_and_col_txt->set_tooltip(TTR("Line and column numbers.")); line_and_col_txt->set_mouse_filter(MOUSE_FILTER_STOP); @@ -1781,11 +1764,6 @@ CodeTextEditor::CodeTextEditor() { font_resize_val = 0; font_size = EditorSettings::get_singleton()->get("interface/editor/code_font_size"); - font_resize_timer = memnew(Timer); - add_child(font_resize_timer); - font_resize_timer->set_one_shot(true); - font_resize_timer->set_wait_time(0.07); - font_resize_timer->connect("timeout", callable_mp(this, &CodeTextEditor::_font_resize_timeout)); EditorSettings::get_singleton()->connect("settings_changed", callable_mp(this, &CodeTextEditor::_on_settings_change)); } diff --git a/editor/code_editor.h b/editor/code_editor.h index b38170cbf5..d8f89d440e 100644 --- a/editor/code_editor.h +++ b/editor/code_editor.h @@ -151,7 +151,6 @@ class CodeTextEditor : public VBoxContainer { Timer *idle; Timer *code_complete_timer; - Timer *font_resize_timer; int font_resize_val; real_t font_size; @@ -164,14 +163,11 @@ class CodeTextEditor : public VBoxContainer { void _update_font(); void _complete_request(); Ref<Texture2D> _get_completion_icon(const ScriptCodeCompletionOption &p_option); - void _font_resize_timeout(); - bool _add_font_size(int p_delta); void _input(const Ref<InputEvent> &event); void _text_editor_gui_input(const Ref<InputEvent> &p_event); void _zoom_in(); void _zoom_out(); - void _zoom_changed(); void _reset_zoom(); Color completion_font_color; diff --git a/editor/debugger/editor_performance_profiler.cpp b/editor/debugger/editor_performance_profiler.cpp index 47fe282758..44c5f83e9a 100644 --- a/editor/debugger/editor_performance_profiler.cpp +++ b/editor/debugger/editor_performance_profiler.cpp @@ -82,10 +82,10 @@ String EditorPerformanceProfiler::_create_label(float p_value, Performance::Moni return String::humanize_size(p_value); } case Performance::MONITOR_TYPE_TIME: { - return rtos(p_value * 1000).pad_decimals(2) + " ms"; + return TS->format_number(rtos(p_value * 1000).pad_decimals(2)) + " " + RTR("ms"); } default: { - return rtos(p_value); + return TS->format_number(rtos(p_value)); } } } @@ -111,6 +111,7 @@ void EditorPerformanceProfiler::_monitor_draw() { Ref<StyleBox> graph_style_box = get_theme_stylebox("normal", "TextEdit"); Ref<Font> graph_font = get_theme_font("font", "TextEdit"); + int font_size = get_theme_font_size("font_size", "TextEdit"); int columns = int(Math::ceil(Math::sqrt(float(active.size())))); int rows = int(Math::ceil(float(active.size()) / float(columns))); @@ -131,19 +132,19 @@ void EditorPerformanceProfiler::_monitor_draw() { rect.size -= graph_style_box->get_minimum_size(); Color draw_color = get_theme_color("accent_color", "Editor"); draw_color.set_hsv(Math::fmod(hue_shift * float(current.frame_index), 0.9f), draw_color.get_s() * 0.9f, draw_color.get_v() * value_multiplier, 0.6f); - monitor_draw->draw_string(graph_font, rect.position + Point2(0, graph_font->get_ascent()), current.item->get_text(0), draw_color, rect.size.x); + monitor_draw->draw_string(graph_font, rect.position + Point2(0, graph_font->get_ascent(font_size)), current.item->get_text(0), HALIGN_LEFT, rect.size.x, font_size, draw_color); draw_color.a = 0.9f; - float value_position = rect.size.width - graph_font->get_string_size(current.item->get_text(1)).width; + float value_position = rect.size.width - graph_font->get_string_size(current.item->get_text(1), font_size).width; if (value_position < 0) { value_position = 0; } - monitor_draw->draw_string(graph_font, rect.position + Point2(value_position, graph_font->get_ascent()), current.item->get_text(1), draw_color, rect.size.x); + monitor_draw->draw_string(graph_font, rect.position + Point2(value_position, graph_font->get_ascent(font_size)), current.item->get_text(1), HALIGN_LEFT, rect.size.x, font_size, draw_color); - rect.position.y += graph_font->get_height(); - rect.size.height -= graph_font->get_height(); + rect.position.y += graph_font->get_height(font_size); + rect.size.height -= graph_font->get_height(font_size); - int line_count = rect.size.height / (graph_font->get_height() * 2); + int line_count = rect.size.height / (graph_font->get_height(font_size) * 2); if (line_count > 5) { line_count = 5; } @@ -151,12 +152,12 @@ void EditorPerformanceProfiler::_monitor_draw() { Color horizontal_line_color; horizontal_line_color.set_hsv(draw_color.get_h(), draw_color.get_s() * 0.5f, draw_color.get_v() * 0.5f, 0.3f); monitor_draw->draw_line(rect.position, rect.position + Vector2(rect.size.width, 0), horizontal_line_color, Math::round(EDSCALE)); - monitor_draw->draw_string(graph_font, rect.position + Vector2(0, graph_font->get_ascent()), _create_label(current.max, current.type), horizontal_line_color, rect.size.width); + monitor_draw->draw_string(graph_font, rect.position + Vector2(0, graph_font->get_ascent(font_size)), _create_label(current.max, current.type), HALIGN_LEFT, rect.size.width, font_size, horizontal_line_color); for (int j = 0; j < line_count; j++) { Vector2 y_offset = Vector2(0, rect.size.height * (1.0f - float(j) / float(line_count))); monitor_draw->draw_line(rect.position + y_offset, rect.position + Vector2(rect.size.width, 0) + y_offset, horizontal_line_color, Math::round(EDSCALE)); - monitor_draw->draw_string(graph_font, rect.position - Vector2(0, graph_font->get_descent()) + y_offset, _create_label(current.max * float(j) / float(line_count), current.type), horizontal_line_color, rect.size.width); + monitor_draw->draw_string(graph_font, rect.position - Vector2(0, graph_font->get_descent(font_size)) + y_offset, _create_label(current.max * float(j) / float(line_count), current.type), HALIGN_LEFT, rect.size.width, font_size, horizontal_line_color); } } @@ -182,7 +183,7 @@ void EditorPerformanceProfiler::_monitor_draw() { monitor_draw->draw_line(rect.position + Point2(from, 0), rect.position + Point2(from, rect.size.y), line_color, Math::round(EDSCALE)); String label = _create_label(e->get(), current.type); - Size2 size = graph_font->get_string_size(label); + Size2 size = graph_font->get_string_size(label, font_size); Vector2 text_top_left_position = Vector2(from, h2) - (size + Vector2(MARKER_MARGIN, MARKER_MARGIN)); if (text_top_left_position.x < 0) { text_top_left_position.x = from + MARKER_MARGIN; @@ -190,7 +191,7 @@ void EditorPerformanceProfiler::_monitor_draw() { if (text_top_left_position.y < 0) { text_top_left_position.y = h2 + MARKER_MARGIN; } - monitor_draw->draw_string(graph_font, rect.position + text_top_left_position + Point2(0, graph_font->get_ascent()), label, line_color, rect.size.x); + monitor_draw->draw_string(graph_font, rect.position + text_top_left_position + Point2(0, graph_font->get_ascent(font_size)), label, HALIGN_LEFT, rect.size.x, font_size, line_color); } prev = h2; e = e->next(); diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp index 8bd21fff5c..930aca6e5a 100644 --- a/editor/debugger/editor_profiler.cpp +++ b/editor/debugger/editor_profiler.cpp @@ -103,19 +103,19 @@ static String _get_percent_txt(float p_value, float p_total) { p_total = 0.00001; } - return String::num((p_value / p_total) * 100, 1) + "%"; + return TS->format_number(String::num((p_value / p_total) * 100, 1)) + TS->percent_sign(); } String EditorProfiler::_get_time_as_text(const Metric &m, float p_time, int p_calls) { const int dmode = display_mode->get_selected(); if (dmode == DISPLAY_FRAME_TIME) { - return rtos(p_time * 1000).pad_decimals(2) + " ms"; + return TS->format_number(rtos(p_time * 1000).pad_decimals(2)) + " " + RTR("ms"); } else if (dmode == DISPLAY_AVERAGE_TIME) { if (p_calls == 0) { - return "0.00 ms"; + return TS->format_number("0.00") + " " + RTR("ms"); } else { - return rtos((p_time / p_calls) * 1000).pad_decimals(2) + " ms"; + return TS->format_number(rtos((p_time / p_calls) * 1000).pad_decimals(2)) + " " + RTR("ms"); } } else if (dmode == DISPLAY_FRAME_PERCENT) { return _get_percent_txt(p_time, m.frame_time); @@ -423,7 +423,7 @@ void EditorProfiler::_clear_pressed() { } void EditorProfiler::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_LAYOUT_DIRECTION_CHANGED || p_what == NOTIFICATION_TRANSLATION_CHANGED) { activate->set_icon(get_theme_icon("Play", "EditorIcons")); clear_button->set_icon(get_theme_icon("Clear", "EditorIcons")); } diff --git a/editor/debugger/editor_visual_profiler.cpp b/editor/debugger/editor_visual_profiler.cpp index baeb06794a..d7a09d6b0c 100644 --- a/editor/debugger/editor_visual_profiler.cpp +++ b/editor/debugger/editor_visual_profiler.cpp @@ -114,9 +114,9 @@ String EditorVisualProfiler::_get_time_as_text(float p_time) { int dmode = display_mode->get_selected(); if (dmode == DISPLAY_FRAME_TIME) { - return rtos(p_time) + "ms"; + return TS->format_number(rtos(p_time)) + " " + RTR("ms"); } else if (dmode == DISPLAY_FRAME_PERCENT) { - return String::num(p_time * 100 / graph_limit, 2) + "%"; + return TS->format_number(String::num(p_time * 100 / graph_limit, 2)) + " " + TS->percent_sign(); } return "err"; @@ -423,8 +423,12 @@ void EditorVisualProfiler::_clear_pressed() { } void EditorVisualProfiler::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE) { - activate->set_icon(get_theme_icon("Play", "EditorIcons")); + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_LAYOUT_DIRECTION_CHANGED || p_what == NOTIFICATION_TRANSLATION_CHANGED) { + if (is_layout_rtl()) { + activate->set_icon(get_theme_icon("PlayBackwards", "EditorIcons")); + } else { + activate->set_icon(get_theme_icon("Play", "EditorIcons")); + } clear_button->set_icon(get_theme_icon("Clear", "EditorIcons")); } } @@ -434,6 +438,7 @@ void EditorVisualProfiler::_graph_tex_draw() { return; } Ref<Font> font = get_theme_font("font", "Label"); + int font_size = get_theme_font_size("font_size", "Label"); if (seeking) { int max_frames = frame_metrics.size(); int frame = cursor_metric_edit->get_value() - (frame_metrics[last_metric].frame_number - max_frames + 1); @@ -457,7 +462,7 @@ void EditorVisualProfiler::_graph_tex_draw() { graph->draw_line(Vector2(0, frame_y), Vector2(half_width, frame_y), Color(1, 1, 1, 0.3)); String limit_str = String::num(graph_limit, 2); - graph->draw_string(font, Vector2(half_width - font->get_string_size(limit_str).x - 2, frame_y - 2), limit_str, Color(1, 1, 1, 0.6)); + graph->draw_string(font, Vector2(half_width - font->get_string_size(limit_str, font_size).x - 2, frame_y - 2), limit_str, HALIGN_LEFT, -1, font_size, Color(1, 1, 1, 0.6)); } if (graph_height_gpu > 0) { @@ -468,11 +473,11 @@ void EditorVisualProfiler::_graph_tex_draw() { graph->draw_line(Vector2(half_width, frame_y), Vector2(graph->get_size().x, frame_y), Color(1, 1, 1, 0.3)); String limit_str = String::num(graph_limit, 2); - graph->draw_string(font, Vector2(half_width * 2 - font->get_string_size(limit_str).x - 2, frame_y - 2), limit_str, Color(1, 1, 1, 0.6)); + graph->draw_string(font, Vector2(half_width * 2 - font->get_string_size(limit_str, font_size).x - 2, frame_y - 2), limit_str, HALIGN_LEFT, -1, font_size, Color(1, 1, 1, 0.6)); } - graph->draw_string(font, Vector2(font->get_string_size("X").x, font->get_ascent() + 2), "CPU:", Color(1, 1, 1, 0.8)); - graph->draw_string(font, Vector2(font->get_string_size("X").x + graph->get_size().width / 2, font->get_ascent() + 2), "GPU:", Color(1, 1, 1, 0.8)); + graph->draw_string(font, Vector2(font->get_string_size("X", font_size).x, font->get_ascent(font_size) + 2), "CPU:", HALIGN_LEFT, -1, font_size, Color(1, 1, 1, 0.8)); + graph->draw_string(font, Vector2(font->get_string_size("X", font_size).x + graph->get_size().width / 2, font->get_ascent(font_size) + 2), "GPU:", HALIGN_LEFT, -1, font_size, Color(1, 1, 1, 0.8)); /* if (hover_metric != -1 && frame_metrics[hover_metric].valid) { diff --git a/editor/doc_data.cpp b/editor/doc_data.cpp index 8504d61d2f..165a5c8546 100644 --- a/editor/doc_data.cpp +++ b/editor/doc_data.cpp @@ -523,6 +523,14 @@ void DocData::generate(bool p_basic_types) { c.theme_properties.push_back(pd); } l.clear(); + Theme::get_default()->get_font_size_list(cname, &l); + for (List<StringName>::Element *E = l.front(); E; E = E->next()) { + PropertyDoc pd; + pd.name = E->get(); + pd.type = "int"; + c.theme_properties.push_back(pd); + } + l.clear(); Theme::get_default()->get_stylebox_list(cname, &l); for (List<StringName>::Element *E = l.front(); E; E = E->next()) { PropertyDoc pd; diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp index cbde7d593a..95802a0b9c 100644 --- a/editor/editor_about.cpp +++ b/editor/editor_about.cpp @@ -40,9 +40,12 @@ void EditorAbout::_theme_changed() { Control *base = EditorNode::get_singleton()->get_gui_base(); Ref<Font> font = base->get_theme_font("source", "EditorFonts"); + int font_size = base->get_theme_font_size("source_size", "EditorFonts"); _tpl_text->add_theme_font_override("normal_font", font); + _tpl_text->add_theme_font_size_override("normal_font_size", font_size); _tpl_text->add_theme_constant_override("line_separation", 6 * EDSCALE); _license_text->add_theme_font_override("normal_font", font); + _license_text->add_theme_font_size_override("normal_font_size", font_size); _license_text->add_theme_constant_override("line_separation", 6 * EDSCALE); _logo->set_texture(base->get_theme_icon("Logo", "EditorIcons")); } @@ -213,7 +216,7 @@ EditorAbout::EditorAbout() { for (int component_index = 0; component_index < COPYRIGHT_INFO_COUNT; component_index++) { const ComponentCopyright &component = COPYRIGHT_INFO[component_index]; TreeItem *ti = _tpl_tree->create_item(tpl_ti_tp); - String component_name = component.name; + String component_name = String::utf8(component.name); ti->set_text(0, component_name); String text = component_name + "\n"; long_text += "- " + component_name + "\n"; @@ -221,7 +224,7 @@ EditorAbout::EditorAbout() { const ComponentCopyrightPart &part = component.parts[part_index]; text += "\n Files:"; for (int file_num = 0; file_num < part.file_count; file_num++) { - text += "\n " + String(part.files[file_num]); + text += "\n " + String::utf8(part.files[file_num]); } String copyright; for (int copyright_index = 0; copyright_index < part.copyright_count; copyright_index++) { @@ -229,7 +232,7 @@ EditorAbout::EditorAbout() { } text += copyright; long_text += copyright; - String license = "\n License: " + String(part.license) + "\n"; + String license = "\n License: " + String::utf8(part.license) + "\n"; text += license; long_text += license + "\n"; } @@ -237,10 +240,10 @@ EditorAbout::EditorAbout() { } for (int i = 0; i < LICENSE_COUNT; i++) { TreeItem *ti = _tpl_tree->create_item(tpl_ti_lc); - String licensename = String(LICENSE_NAMES[i]); + String licensename = String::utf8(LICENSE_NAMES[i]); ti->set_text(0, licensename); long_text += "- " + licensename + "\n\n"; - String licensebody = String(LICENSE_BODIES[i]); + String licensebody = String::utf8(LICENSE_BODIES[i]); ti->set_metadata(0, licensebody); long_text += " " + licensebody.replace("\n", "\n ") + "\n\n"; } diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index a3deb95130..6dc0fffd92 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -1379,14 +1379,15 @@ void EditorAudioMeterNotches::add_notch(float p_normalized_offset, float p_db_va Size2 EditorAudioMeterNotches::get_minimum_size() const { Ref<Font> font = get_theme_font("font", "Label"); - float font_height = font->get_height(); + int font_size = get_theme_font_size("font_size", "Label"); + float font_height = font->get_height(font_size); float width = 0; float height = top_padding + btm_padding; for (int i = 0; i < notches.size(); i++) { if (notches[i].render_db_value) { - width = MAX(width, font->get_string_size(String::num(Math::abs(notches[i].db_value)) + "dB").x); + width = MAX(width, font->get_string_size(String::num(Math::abs(notches[i].db_value)) + "dB", font_size).x); height += font_height; } } @@ -1413,7 +1414,8 @@ void EditorAudioMeterNotches::_notification(int p_what) { void EditorAudioMeterNotches::_draw_audio_notches() { Ref<Font> font = get_theme_font("font", "Label"); - float font_height = font->get_height(); + int font_size = get_theme_font_size("font_size", "Label"); + float font_height = font->get_height(font_size); for (int i = 0; i < notches.size(); i++) { AudioNotch n = notches[i]; @@ -1427,6 +1429,7 @@ void EditorAudioMeterNotches::_draw_audio_notches() { Vector2(line_length + label_space, (1.0f - n.relative_position) * (get_size().y - btm_padding - top_padding) + (font_height / 4) + top_padding), String::num(Math::abs(n.db_value)) + "dB", + HALIGN_LEFT, -1, font_size, notch_color); } } diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index 69edefd75c..f7cb5428ce 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -398,7 +398,11 @@ Error EditorExportPlatform::_save_zip_file(void *p_userdata, const String &p_pat Ref<ImageTexture> EditorExportPlatform::get_option_icon(int p_index) const { Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme(); ERR_FAIL_COND_V(theme.is_null(), Ref<ImageTexture>()); - return theme->get_icon("Play", "EditorIcons"); + if (EditorNode::get_singleton()->get_viewport()->is_layout_rtl()) { + return theme->get_icon("PlayBackwards", "EditorIcons"); + } else { + return theme->get_icon("Play", "EditorIcons"); + } } String EditorExportPlatform::find_export_template(String template_file_name, String *err) const { @@ -972,6 +976,15 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & p_func(p_udata, splash, array, idx, total, enc_in_filters, enc_ex_filters, key); } + // Store text server data if exists. + if (TS->has_feature(TextServer::FEATURE_USE_SUPPORT_DATA)) { + String ts_data = "res://" + TS->get_support_data_filename(); + if (FileAccess::exists(ts_data)) { + Vector<uint8_t> array = FileAccess::get_file_as_array(ts_data); + p_func(p_udata, ts_data, array, idx, total, enc_in_filters, enc_ex_filters, key); + } + } + String config_file = "project.binary"; String engine_cfb = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp" + config_file); ProjectSettings::get_singleton()->save_custom(engine_cfb, custom_map, custom_list); diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index e3923a48c5..ffdd7c7fa8 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -59,12 +59,17 @@ VBoxContainer *EditorFileDialog::get_vbox() { } void EditorFileDialog::_notification(int p_what) { - if (p_what == NOTIFICATION_READY || p_what == NOTIFICATION_THEME_CHANGED) { + if (p_what == NOTIFICATION_READY || p_what == NOTIFICATION_THEME_CHANGED || p_what == Control::NOTIFICATION_LAYOUT_DIRECTION_CHANGED || p_what == NOTIFICATION_TRANSLATION_CHANGED) { // Update icons. mode_thumbnails->set_icon(item_list->get_theme_icon("FileThumbnail", "EditorIcons")); mode_list->set_icon(item_list->get_theme_icon("FileList", "EditorIcons")); - dir_prev->set_icon(item_list->get_theme_icon("Back", "EditorIcons")); - dir_next->set_icon(item_list->get_theme_icon("Forward", "EditorIcons")); + if (is_layout_rtl()) { + dir_prev->set_icon(item_list->get_theme_icon("Forward", "EditorIcons")); + dir_next->set_icon(item_list->get_theme_icon("Back", "EditorIcons")); + } else { + dir_prev->set_icon(item_list->get_theme_icon("Back", "EditorIcons")); + dir_next->set_icon(item_list->get_theme_icon("Forward", "EditorIcons")); + } dir_up->set_icon(item_list->get_theme_icon("ArrowUp", "EditorIcons")); refresh->set_icon(item_list->get_theme_icon("Reload", "EditorIcons")); favorite->set_icon(item_list->get_theme_icon("Favorites", "EditorIcons")); @@ -97,8 +102,13 @@ void EditorFileDialog::_notification(int p_what) { // Update icons. mode_thumbnails->set_icon(item_list->get_theme_icon("FileThumbnail", "EditorIcons")); mode_list->set_icon(item_list->get_theme_icon("FileList", "EditorIcons")); - dir_prev->set_icon(item_list->get_theme_icon("Back", "EditorIcons")); - dir_next->set_icon(item_list->get_theme_icon("Forward", "EditorIcons")); + if (is_layout_rtl()) { + dir_prev->set_icon(item_list->get_theme_icon("Forward", "EditorIcons")); + dir_next->set_icon(item_list->get_theme_icon("Back", "EditorIcons")); + } else { + dir_prev->set_icon(item_list->get_theme_icon("Back", "EditorIcons")); + dir_next->set_icon(item_list->get_theme_icon("Forward", "EditorIcons")); + } dir_up->set_icon(item_list->get_theme_icon("ArrowUp", "EditorIcons")); refresh->set_icon(item_list->get_theme_icon("Reload", "EditorIcons")); favorite->set_icon(item_list->get_theme_icon("Favorites", "EditorIcons")); @@ -1486,6 +1496,7 @@ EditorFileDialog::EditorFileDialog() { pathhb->add_child(drives_container); dir = memnew(LineEdit); + dir->set_structured_text_bidi_override(Control::STRUCTURED_TEXT_FILE); pathhb->add_child(dir); dir->set_h_size_flags(Control::SIZE_EXPAND_FILL); @@ -1624,6 +1635,7 @@ EditorFileDialog::EditorFileDialog() { file_box = memnew(HBoxContainer); file_box->add_child(memnew(Label(TTR("File:")))); file = memnew(LineEdit); + file->set_structured_text_bidi_override(Control::STRUCTURED_TEXT_FILE); file->set_stretch_ratio(4); file->set_h_size_flags(Control::SIZE_EXPAND_FILL); file_box->add_child(file); @@ -1662,6 +1674,7 @@ EditorFileDialog::EditorFileDialog() { makedialog->add_child(makevb); makedirname = memnew(LineEdit); + makedirname->set_structured_text_bidi_override(Control::STRUCTURED_TEXT_FILE); makevb->add_margin_child(TTR("Name:"), makedirname); add_child(makedialog); makedialog->register_text_enter(makedirname); diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp index 100c76c32b..f5bb4921d4 100644 --- a/editor/editor_fonts.cpp +++ b/editor/editor_fonts.cpp @@ -35,57 +35,61 @@ #include "editor_scale.h" #include "editor_settings.h" #include "scene/resources/default_theme/default_theme.h" -#include "scene/resources/dynamic_font.h" - -#define MAKE_FALLBACKS(m_name) \ - m_name->add_fallback(FontArabic); \ - m_name->add_fallback(FontHebrew); \ - m_name->add_fallback(FontThai); \ - m_name->add_fallback(FontHindi); \ - m_name->add_fallback(FontJapanese); \ - m_name->add_fallback(FontFallback); +#include "scene/resources/font.h" + +#define MAKE_FALLBACKS(m_name) \ + m_name->add_data(FontArabic); \ + m_name->add_data(FontBengali); \ + m_name->add_data(FontGeorgian); \ + m_name->add_data(FontMalayalam); \ + m_name->add_data(FontOriya); \ + m_name->add_data(FontSinhala); \ + m_name->add_data(FontTamil); \ + m_name->add_data(FontTelugu); \ + m_name->add_data(FontHebrew); \ + m_name->add_data(FontThai); \ + m_name->add_data(FontHindi); \ + m_name->add_data(FontJapanese); \ + m_name->add_data(FontFallback); // the custom spacings might only work with Noto Sans -#define MAKE_DEFAULT_FONT(m_name, m_size) \ - Ref<DynamicFont> m_name; \ - m_name.instance(); \ - m_name->set_size(m_size); \ - if (CustomFont.is_valid()) { \ - m_name->set_font_data(CustomFont); \ - m_name->add_fallback(DefaultFont); \ - } else { \ - m_name->set_font_data(DefaultFont); \ - } \ - m_name->set_spacing(DynamicFont::SPACING_TOP, -EDSCALE); \ - m_name->set_spacing(DynamicFont::SPACING_BOTTOM, -EDSCALE); \ +#define MAKE_DEFAULT_FONT(m_name) \ + Ref<Font> m_name; \ + m_name.instance(); \ + if (CustomFont.is_valid()) { \ + m_name->add_data(CustomFont); \ + m_name->add_data(DefaultFont); \ + } else { \ + m_name->add_data(DefaultFont); \ + } \ + m_name->set_spacing(Font::SPACING_TOP, -EDSCALE); \ + m_name->set_spacing(Font::SPACING_BOTTOM, -EDSCALE); \ MAKE_FALLBACKS(m_name); -#define MAKE_BOLD_FONT(m_name, m_size) \ - Ref<DynamicFont> m_name; \ - m_name.instance(); \ - m_name->set_size(m_size); \ - if (CustomFontBold.is_valid()) { \ - m_name->set_font_data(CustomFontBold); \ - m_name->add_fallback(DefaultFontBold); \ - } else { \ - m_name->set_font_data(DefaultFontBold); \ - } \ - m_name->set_spacing(DynamicFont::SPACING_TOP, -EDSCALE); \ - m_name->set_spacing(DynamicFont::SPACING_BOTTOM, -EDSCALE); \ +#define MAKE_BOLD_FONT(m_name) \ + Ref<Font> m_name; \ + m_name.instance(); \ + if (CustomFontBold.is_valid()) { \ + m_name->add_data(CustomFontBold); \ + m_name->add_data(DefaultFontBold); \ + } else { \ + m_name->add_data(DefaultFontBold); \ + } \ + m_name->set_spacing(Font::SPACING_TOP, -EDSCALE); \ + m_name->set_spacing(Font::SPACING_BOTTOM, -EDSCALE); \ MAKE_FALLBACKS(m_name); -#define MAKE_SOURCE_FONT(m_name, m_size) \ - Ref<DynamicFont> m_name; \ - m_name.instance(); \ - m_name->set_size(m_size); \ - if (CustomFontSource.is_valid()) { \ - m_name->set_font_data(CustomFontSource); \ - m_name->add_fallback(dfmono); \ - } else { \ - m_name->set_font_data(dfmono); \ - } \ - m_name->set_spacing(DynamicFont::SPACING_TOP, -EDSCALE); \ - m_name->set_spacing(DynamicFont::SPACING_BOTTOM, -EDSCALE); \ +#define MAKE_SOURCE_FONT(m_name) \ + Ref<Font> m_name; \ + m_name.instance(); \ + if (CustomFontSource.is_valid()) { \ + m_name->add_data(CustomFontSource); \ + m_name->add_data(dfmono); \ + } else { \ + m_name->add_data(dfmono); \ + } \ + m_name->set_spacing(Font::SPACING_TOP, -EDSCALE); \ + m_name->set_spacing(Font::SPACING_BOTTOM, -EDSCALE); \ MAKE_FALLBACKS(m_name); void editor_register_fonts(Ref<Theme> p_theme) { @@ -96,7 +100,7 @@ void editor_register_fonts(Ref<Theme> p_theme) { bool font_antialiased = (bool)EditorSettings::get_singleton()->get("interface/editor/font_antialiased"); int font_hinting_setting = (int)EditorSettings::get_singleton()->get("interface/editor/font_hinting"); - DynamicFontData::Hinting font_hinting; + TextServer::Hinting font_hinting; switch (font_hinting_setting) { case 0: // The "Auto" setting uses the setting that best matches the OS' font rendering: @@ -104,29 +108,31 @@ void editor_register_fonts(Ref<Theme> p_theme) { // - Windows uses ClearType, which is in between "Light" and "Normal" hinting. // - Linux has configurable font hinting, but most distributions including Ubuntu default to "Light". #ifdef OSX_ENABLED - font_hinting = DynamicFontData::HINTING_NONE; + font_hinting = TextServer::HINTING_NONE; #else - font_hinting = DynamicFontData::HINTING_LIGHT; + font_hinting = TextServer::HINTING_LIGHT; #endif break; case 1: - font_hinting = DynamicFontData::HINTING_NONE; + font_hinting = TextServer::HINTING_NONE; break; case 2: - font_hinting = DynamicFontData::HINTING_LIGHT; + font_hinting = TextServer::HINTING_LIGHT; break; default: - font_hinting = DynamicFontData::HINTING_NORMAL; + font_hinting = TextServer::HINTING_NORMAL; break; } + int default_font_size = int(EDITOR_GET("interface/editor/main_font_size")) * EDSCALE; + String custom_font_path = EditorSettings::get_singleton()->get("interface/editor/main_font"); - Ref<DynamicFontData> CustomFont; + Ref<FontData> CustomFont; if (custom_font_path.length() > 0 && dir->file_exists(custom_font_path)) { CustomFont.instance(); + CustomFont->load_resource(custom_font_path, default_font_size); CustomFont->set_antialiased(font_antialiased); CustomFont->set_hinting(font_hinting); - CustomFont->set_font_path(custom_font_path); CustomFont->set_force_autohinter(true); //just looks better..i think? } else { EditorSettings::get_singleton()->set_manually("interface/editor/main_font", ""); @@ -135,12 +141,12 @@ void editor_register_fonts(Ref<Theme> p_theme) { /* Custom Bold font */ String custom_font_path_bold = EditorSettings::get_singleton()->get("interface/editor/main_font_bold"); - Ref<DynamicFontData> CustomFontBold; + Ref<FontData> CustomFontBold; if (custom_font_path_bold.length() > 0 && dir->file_exists(custom_font_path_bold)) { CustomFontBold.instance(); + CustomFontBold->load_resource(custom_font_path_bold, default_font_size); CustomFontBold->set_antialiased(font_antialiased); CustomFontBold->set_hinting(font_hinting); - CustomFontBold->set_font_path(custom_font_path_bold); CustomFontBold->set_force_autohinter(true); //just looks better..i think? } else { EditorSettings::get_singleton()->set_manually("interface/editor/main_font_bold", ""); @@ -149,12 +155,12 @@ void editor_register_fonts(Ref<Theme> p_theme) { /* Custom source code font */ String custom_font_path_source = EditorSettings::get_singleton()->get("interface/editor/code_font"); - Ref<DynamicFontData> CustomFontSource; + Ref<FontData> CustomFontSource; if (custom_font_path_source.length() > 0 && dir->file_exists(custom_font_path_source)) { CustomFontSource.instance(); + CustomFontSource->load_resource(custom_font_path_source, default_font_size); CustomFontSource->set_antialiased(font_antialiased); CustomFontSource->set_hinting(font_hinting); - CustomFontSource->set_font_path(custom_font_path_source); } else { EditorSettings::get_singleton()->set_manually("interface/editor/code_font", ""); } @@ -163,115 +169,167 @@ void editor_register_fonts(Ref<Theme> p_theme) { /* Droid Sans */ - Ref<DynamicFontData> DefaultFont; + Ref<FontData> DefaultFont; DefaultFont.instance(); + DefaultFont->load_memory(_font_NotoSansUI_Regular, _font_NotoSansUI_Regular_size, "ttf", default_font_size); DefaultFont->set_antialiased(font_antialiased); DefaultFont->set_hinting(font_hinting); - DefaultFont->set_font_ptr(_font_NotoSansUI_Regular, _font_NotoSansUI_Regular_size); DefaultFont->set_force_autohinter(true); //just looks better..i think? - Ref<DynamicFontData> DefaultFontBold; + Ref<FontData> DefaultFontBold; DefaultFontBold.instance(); + DefaultFontBold->load_memory(_font_NotoSansUI_Bold, _font_NotoSansUI_Bold_size, "ttf", default_font_size); DefaultFontBold->set_antialiased(font_antialiased); DefaultFontBold->set_hinting(font_hinting); - DefaultFontBold->set_font_ptr(_font_NotoSansUI_Bold, _font_NotoSansUI_Bold_size); DefaultFontBold->set_force_autohinter(true); // just looks better..i think? - Ref<DynamicFontData> FontFallback; + Ref<FontData> FontFallback; FontFallback.instance(); + FontFallback->load_memory(_font_DroidSansFallback, _font_DroidSansFallback_size, "ttf", default_font_size); FontFallback->set_antialiased(font_antialiased); FontFallback->set_hinting(font_hinting); - FontFallback->set_font_ptr(_font_DroidSansFallback, _font_DroidSansFallback_size); FontFallback->set_force_autohinter(true); //just looks better..i think? - Ref<DynamicFontData> FontJapanese; + Ref<FontData> FontJapanese; FontJapanese.instance(); + FontJapanese->load_memory(_font_DroidSansJapanese, _font_DroidSansJapanese_size, "ttf", default_font_size); FontJapanese->set_antialiased(font_antialiased); FontJapanese->set_hinting(font_hinting); - FontJapanese->set_font_ptr(_font_DroidSansJapanese, _font_DroidSansJapanese_size); FontJapanese->set_force_autohinter(true); //just looks better..i think? - Ref<DynamicFontData> FontArabic; + Ref<FontData> FontArabic; FontArabic.instance(); + FontArabic->load_memory(_font_NotoNaskhArabicUI_Regular, _font_NotoNaskhArabicUI_Regular_size, "ttf", default_font_size); FontArabic->set_antialiased(font_antialiased); FontArabic->set_hinting(font_hinting); - FontArabic->set_font_ptr(_font_NotoNaskhArabicUI_Regular, _font_NotoNaskhArabicUI_Regular_size); FontArabic->set_force_autohinter(true); //just looks better..i think? - Ref<DynamicFontData> FontHebrew; + Ref<FontData> FontBengali; + FontBengali.instance(); + FontBengali->load_memory(_font_NotoSansBengali_Regular, _font_NotoSansBengali_Regular_size, "ttf", default_font_size); + FontBengali->set_antialiased(font_antialiased); + FontBengali->set_hinting(font_hinting); + FontBengali->set_force_autohinter(true); //just looks better..i think? + + Ref<FontData> FontGeorgian; + FontGeorgian.instance(); + FontGeorgian->load_memory(_font_NotoSansGeorgian_Regular, _font_NotoSansGeorgian_Regular_size, "ttf", default_font_size); + FontGeorgian->set_antialiased(font_antialiased); + FontGeorgian->set_hinting(font_hinting); + FontGeorgian->set_force_autohinter(true); //just looks better..i think? + + Ref<FontData> FontHebrew; FontHebrew.instance(); + FontHebrew->load_memory(_font_NotoSansHebrew_Regular, _font_NotoSansHebrew_Regular_size, "ttf", default_font_size); FontHebrew->set_antialiased(font_antialiased); FontHebrew->set_hinting(font_hinting); - FontHebrew->set_font_ptr(_font_NotoSansHebrew_Regular, _font_NotoSansHebrew_Regular_size); FontHebrew->set_force_autohinter(true); //just looks better..i think? - Ref<DynamicFontData> FontThai; + Ref<FontData> FontMalayalam; + FontMalayalam.instance(); + FontMalayalam->load_memory(_font_NotoSansMalayalamUI_Regular, _font_NotoSansMalayalamUI_Regular_size, "ttf", default_font_size); + FontMalayalam->set_antialiased(font_antialiased); + FontMalayalam->set_hinting(font_hinting); + FontMalayalam->set_force_autohinter(true); //just looks better..i think? + + Ref<FontData> FontOriya; + FontOriya.instance(); + FontOriya->load_memory(_font_NotoSansOriyaUI_Regular, _font_NotoSansOriyaUI_Regular_size, "ttf", default_font_size); + FontOriya->set_antialiased(font_antialiased); + FontOriya->set_hinting(font_hinting); + FontOriya->set_force_autohinter(true); //just looks better..i think? + + Ref<FontData> FontSinhala; + FontSinhala.instance(); + FontSinhala->load_memory(_font_NotoSansSinhalaUI_Regular, _font_NotoSansSinhalaUI_Regular_size, "ttf", default_font_size); + FontSinhala->set_antialiased(font_antialiased); + FontSinhala->set_hinting(font_hinting); + FontSinhala->set_force_autohinter(true); //just looks better..i think? + + Ref<FontData> FontTamil; + FontTamil.instance(); + FontTamil->load_memory(_font_NotoSansTamilUI_Regular, _font_NotoSansTamilUI_Regular_size, "ttf", default_font_size); + FontTamil->set_antialiased(font_antialiased); + FontTamil->set_hinting(font_hinting); + FontTamil->set_force_autohinter(true); //just looks better..i think? + + Ref<FontData> FontTelugu; + FontTelugu.instance(); + FontTelugu->load_memory(_font_NotoSansTeluguUI_Regular, _font_NotoSansTeluguUI_Regular_size, "ttf", default_font_size); + FontTelugu->set_antialiased(font_antialiased); + FontTelugu->set_hinting(font_hinting); + FontTelugu->set_force_autohinter(true); //just looks better..i think? + + Ref<FontData> FontThai; FontThai.instance(); + FontThai->load_memory(_font_NotoSansThaiUI_Regular, _font_NotoSansThaiUI_Regular_size, "ttf", default_font_size); FontThai->set_antialiased(font_antialiased); FontThai->set_hinting(font_hinting); - FontThai->set_font_ptr(_font_NotoSansThaiUI_Regular, _font_NotoSansThaiUI_Regular_size); FontThai->set_force_autohinter(true); //just looks better..i think? - Ref<DynamicFontData> FontHindi; + Ref<FontData> FontHindi; FontHindi.instance(); + FontHindi->load_memory(_font_NotoSansDevanagariUI_Regular, _font_NotoSansDevanagariUI_Regular_size, "ttf", default_font_size); FontHindi->set_antialiased(font_antialiased); FontHindi->set_hinting(font_hinting); - FontHindi->set_font_ptr(_font_NotoSansDevanagariUI_Regular, _font_NotoSansDevanagariUI_Regular_size); FontHindi->set_force_autohinter(true); //just looks better..i think? /* Hack */ - Ref<DynamicFontData> dfmono; + Ref<FontData> dfmono; dfmono.instance(); + dfmono->load_memory(_font_Hack_Regular, _font_Hack_Regular_size, "ttf", default_font_size); dfmono->set_antialiased(font_antialiased); dfmono->set_hinting(font_hinting); - dfmono->set_font_ptr(_font_Hack_Regular, _font_Hack_Regular_size); - - int default_font_size = int(EDITOR_GET("interface/editor/main_font_size")) * EDSCALE; // Default font - MAKE_DEFAULT_FONT(df, default_font_size); - p_theme->set_default_font(df); // Default theme font + MAKE_DEFAULT_FONT(df); + p_theme->set_default_theme_font(df); // Default theme font + p_theme->set_default_theme_font_size(default_font_size); + + p_theme->set_font_size("main_size", "EditorFonts", default_font_size); p_theme->set_font("main", "EditorFonts", df); // Bold font - MAKE_BOLD_FONT(df_bold, default_font_size); + MAKE_BOLD_FONT(df_bold); + p_theme->set_font_size("bold_size", "EditorFonts", default_font_size); p_theme->set_font("bold", "EditorFonts", df_bold); // Title font - MAKE_BOLD_FONT(df_title, default_font_size + 2 * EDSCALE); - p_theme->set_font("title", "EditorFonts", df_title); + p_theme->set_font_size("title_size", "EditorFonts", default_font_size + 2 * EDSCALE); + p_theme->set_font("title", "EditorFonts", df_bold); // Documentation fonts - MAKE_DEFAULT_FONT(df_doc, int(EDITOR_GET("text_editor/help/help_font_size")) * EDSCALE); - MAKE_BOLD_FONT(df_doc_bold, int(EDITOR_GET("text_editor/help/help_font_size")) * EDSCALE); - MAKE_BOLD_FONT(df_doc_title, int(EDITOR_GET("text_editor/help/help_title_font_size")) * EDSCALE); - MAKE_SOURCE_FONT(df_doc_code, int(EDITOR_GET("text_editor/help/help_source_font_size")) * EDSCALE); - MAKE_SOURCE_FONT(df_doc_kbd, (int(EDITOR_GET("text_editor/help/help_source_font_size")) - 1) * EDSCALE); - p_theme->set_font("doc", "EditorFonts", df_doc); - p_theme->set_font("doc_bold", "EditorFonts", df_doc_bold); - p_theme->set_font("doc_title", "EditorFonts", df_doc_title); - p_theme->set_font("doc_source", "EditorFonts", df_doc_code); - p_theme->set_font("doc_keyboard", "EditorFonts", df_doc_kbd); + MAKE_SOURCE_FONT(df_code); + p_theme->set_font_size("doc_size", "EditorFonts", int(EDITOR_GET("text_editor/help/help_font_size")) * EDSCALE); + p_theme->set_font("doc", "EditorFonts", df); + p_theme->set_font_size("doc_bold_size", "EditorFonts", int(EDITOR_GET("text_editor/help/help_font_size")) * EDSCALE); + p_theme->set_font("doc_bold", "EditorFonts", df_bold); + p_theme->set_font_size("doc_title_size", "EditorFonts", int(EDITOR_GET("text_editor/help/help_title_font_size")) * EDSCALE); + p_theme->set_font("doc_title", "EditorFonts", df_bold); + p_theme->set_font_size("doc_source_size", "EditorFonts", int(EDITOR_GET("text_editor/help/help_source_font_size")) * EDSCALE); + p_theme->set_font("doc_source", "EditorFonts", df_code); + p_theme->set_font_size("doc_keyboard_size", "EditorFonts", (int(EDITOR_GET("text_editor/help/help_source_font_size")) - 1) * EDSCALE); + p_theme->set_font("doc_keyboard", "EditorFonts", df_code); // Ruler font - MAKE_DEFAULT_FONT(df_rulers, 8 * EDSCALE); - p_theme->set_font("rulers", "EditorFonts", df_rulers); + p_theme->set_font_size("rulers_size", "EditorFonts", 8 * EDSCALE); + p_theme->set_font("rulers", "EditorFonts", df); // Rotation widget font - MAKE_DEFAULT_FONT(df_rotation_control, 14 * EDSCALE); - p_theme->set_font("rotation_control", "EditorFonts", df_rotation_control); + p_theme->set_font_size("rotation_control_size", "EditorFonts", 14 * EDSCALE); + p_theme->set_font("rotation_control", "EditorFonts", df); // Code font - MAKE_SOURCE_FONT(df_code, int(EDITOR_GET("interface/editor/code_font_size")) * EDSCALE); + p_theme->set_font_size("source_size", "EditorFonts", int(EDITOR_GET("interface/editor/code_font_size")) * EDSCALE); p_theme->set_font("source", "EditorFonts", df_code); - MAKE_SOURCE_FONT(df_expression, (int(EDITOR_GET("interface/editor/code_font_size")) - 1) * EDSCALE); - p_theme->set_font("expression", "EditorFonts", df_expression); + p_theme->set_font_size("expression_size", "EditorFonts", (int(EDITOR_GET("interface/editor/code_font_size")) - 1) * EDSCALE); + p_theme->set_font("expression", "EditorFonts", df_code); - MAKE_SOURCE_FONT(df_output_code, int(EDITOR_GET("run/output/font_size")) * EDSCALE); - p_theme->set_font("output_source", "EditorFonts", df_output_code); + p_theme->set_font_size("output_source_size", "EditorFonts", int(EDITOR_GET("run/output/font_size")) * EDSCALE); + p_theme->set_font("output_source", "EditorFonts", df_code); - MAKE_SOURCE_FONT(df_text_editor_status_code, default_font_size); - p_theme->set_font("status_source", "EditorFonts", df_text_editor_status_code); + p_theme->set_font_size("status_source_size", "EditorFonts", default_font_size); + p_theme->set_font("status_source", "EditorFonts", df_code); } diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 30aebd2b1f..72bd2b57eb 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -168,7 +168,8 @@ void EditorHelp::_class_desc_resized() { // Add extra horizontal margins for better readability. // The margins increase as the width of the editor help container increases. Ref<Font> doc_code_font = get_theme_font("doc_source", "EditorFonts"); - real_t char_width = doc_code_font->get_char_size('x').width; + int font_size = get_theme_font_size("doc_source_size", "EditorFonts"); + real_t char_width = doc_code_font->get_char_size('x', 0, font_size).width; const int display_margin = MAX(30 * EDSCALE, get_parent_anchorable_rect().size.width - char_width * 120 * EDSCALE) * 0.5; Ref<StyleBox> class_desc_stylebox = EditorNode::get_singleton()->get_theme_base()->get_theme_stylebox("normal", "RichTextLabel")->duplicate(); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 371100652f..0c419168c0 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -41,7 +41,8 @@ Size2 EditorProperty::get_minimum_size() const { Size2 ms; Ref<Font> font = get_theme_font("font", "Tree"); - ms.height = font->get_height(); + int font_size = get_theme_font_size("font_size", "Tree"); + ms.height = font->get_height(font_size); for (int i = 0; i < get_child_count(); i++) { Control *c = Object::cast_to<Control>(get_child(i)); @@ -108,7 +109,8 @@ void EditorProperty::_notification(int p_what) { { int child_room = size.width * (1.0 - split_ratio); Ref<Font> font = get_theme_font("font", "Tree"); - int height = font->get_height(); + int font_size = get_theme_font_size("font_size", "Tree"); + int height = font->get_height(font_size); bool no_children = true; //compute room needed @@ -135,7 +137,11 @@ void EditorProperty::_notification(int p_what) { rect = Rect2(size.width - 1, 0, 1, height); } else { text_size = MAX(0, size.width - (child_room + 4 * EDSCALE)); - rect = Rect2(size.width - child_room, 0, child_room, height); + if (is_layout_rtl()) { + rect = Rect2(1, 0, child_room, height); + } else { + rect = Rect2(size.width - child_room, 0, child_room, height); + } } if (bottom_editor) { @@ -154,6 +160,9 @@ void EditorProperty::_notification(int p_what) { } rect.size.x -= key->get_width() + get_theme_constant("hseparator", "Tree"); + if (is_layout_rtl()) { + rect.position.x += key->get_width() + get_theme_constant("hseparator", "Tree"); + } if (no_children) { text_size -= key->get_width() + 4 * EDSCALE; @@ -167,6 +176,10 @@ void EditorProperty::_notification(int p_what) { rect.size.x -= close->get_width() + get_theme_constant("hseparator", "Tree"); + if (is_layout_rtl()) { + rect.position.x += close->get_width() + get_theme_constant("hseparator", "Tree"); + } + if (no_children) { text_size -= close->get_width() + 4 * EDSCALE; } @@ -200,7 +213,9 @@ void EditorProperty::_notification(int p_what) { if (p_what == NOTIFICATION_DRAW) { Ref<Font> font = get_theme_font("font", "Tree"); + int font_size = get_theme_font_size("font_size", "Tree"); Color dark_color = get_theme_color("dark_color_2", "Editor"); + bool rtl = is_layout_rtl(); Size2 size = get_size(); if (bottom_editor) { @@ -249,7 +264,11 @@ void EditorProperty::_notification(int p_what) { color2.b *= 1.2; } check_rect = Rect2(ofs, ((size.height - checkbox->get_height()) / 2), checkbox->get_width(), checkbox->get_height()); - draw_texture(checkbox, check_rect.position, color2); + if (rtl) { + draw_texture(checkbox, Vector2(size.width - check_rect.position.x - checkbox->get_width(), check_rect.position.y), color2); + } else { + draw_texture(checkbox, check_rect.position, color2); + } ofs += get_theme_constant("hseparator", "Tree") + checkbox->get_width() + get_theme_constant("hseparation", "CheckBox"); text_limit -= ofs; } else { @@ -267,14 +286,21 @@ void EditorProperty::_notification(int p_what) { color2.g *= 1.2; color2.b *= 1.2; } - - draw_texture(reload_icon, revert_rect.position, color2); + if (rtl) { + draw_texture(reload_icon, Vector2(size.width - revert_rect.position.x - reload_icon->get_width(), revert_rect.position.y), color2); + } else { + draw_texture(reload_icon, revert_rect.position, color2); + } } else { revert_rect = Rect2(); } - int v_ofs = (size.height - font->get_height()) / 2; - draw_string(font, Point2(ofs, v_ofs + font->get_ascent()), label, color, text_limit); + int v_ofs = (size.height - font->get_height(font_size)) / 2; + if (rtl) { + draw_string(font, Point2(size.width - ofs - text_limit, v_ofs + font->get_ascent(font_size)), label, HALIGN_RIGHT, text_limit, font_size, color); + } else { + draw_string(font, Point2(ofs, v_ofs + font->get_ascent(font_size)), label, HALIGN_LEFT, text_limit, font_size, color); + } if (keying) { Ref<Texture2D> key; @@ -294,7 +320,12 @@ void EditorProperty::_notification(int p_what) { color2.b *= 1.2; } keying_rect = Rect2(ofs, ((size.height - key->get_height()) / 2), key->get_width(), key->get_height()); - draw_texture(key, keying_rect.position, color2); + if (rtl) { + draw_texture(key, Vector2(size.width - keying_rect.position.x - key->get_width(), keying_rect.position.y), color2); + } else { + draw_texture(key, keying_rect.position, color2); + } + } else { keying_rect = Rect2(); } @@ -313,7 +344,11 @@ void EditorProperty::_notification(int p_what) { color2.b *= 1.2; } delete_rect = Rect2(ofs, ((size.height - close->get_height()) / 2), close->get_width(), close->get_height()); - draw_texture(close, delete_rect.position, color2); + if (rtl) { + draw_texture(close, Vector2(size.width - delete_rect.position.x - close->get_width(), delete_rect.position.y), color2); + } else { + draw_texture(close, delete_rect.position, color2); + } } else { delete_rect = Rect2(); } @@ -648,27 +683,31 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouse> me = p_event; if (me.is_valid()) { + Vector2 mpos = me->get_position(); + if (is_layout_rtl()) { + mpos.x = get_size().x - mpos.x; + } bool button_left = me->get_button_mask() & BUTTON_MASK_LEFT; - bool new_keying_hover = keying_rect.has_point(me->get_position()) && !button_left; + bool new_keying_hover = keying_rect.has_point(mpos) && !button_left; if (new_keying_hover != keying_hover) { keying_hover = new_keying_hover; update(); } - bool new_delete_hover = delete_rect.has_point(me->get_position()) && !button_left; + bool new_delete_hover = delete_rect.has_point(mpos) && !button_left; if (new_delete_hover != delete_hover) { delete_hover = new_delete_hover; update(); } - bool new_revert_hover = revert_rect.has_point(me->get_position()) && !button_left; + bool new_revert_hover = revert_rect.has_point(mpos) && !button_left; if (new_revert_hover != revert_hover) { revert_hover = new_revert_hover; update(); } - bool new_check_hover = check_rect.has_point(me->get_position()) && !button_left; + bool new_check_hover = check_rect.has_point(mpos) && !button_left; if (new_check_hover != check_hover) { check_hover = new_check_hover; update(); @@ -678,13 +717,18 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + Vector2 mpos = mb->get_position(); + if (is_layout_rtl()) { + mpos.x = get_size().x - mpos.x; + } + if (!selected && selectable) { selected = true; emit_signal("selected", property, -1); update(); } - if (keying_rect.has_point(mb->get_position())) { + if (keying_rect.has_point(mpos)) { emit_signal("property_keyed", property, use_keying_next()); if (use_keying_next()) { @@ -704,11 +748,11 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) { call_deferred("update_property"); } } - if (delete_rect.has_point(mb->get_position())) { + if (delete_rect.has_point(mpos)) { emit_signal("property_deleted", property); } - if (revert_rect.has_point(mb->get_position())) { + if (revert_rect.has_point(mpos)) { Variant vorig; Node *node = Object::cast_to<Node>(object); @@ -744,7 +788,7 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) { return; } } - if (check_rect.has_point(mb->get_position())) { + if (check_rect.has_point(mpos)) { checked = !checked; update(); emit_signal("property_checked", property, checked); @@ -1024,10 +1068,11 @@ void EditorInspectorCategory::_notification(int p_what) { if (p_what == NOTIFICATION_DRAW) { draw_rect(Rect2(Vector2(), get_size()), bg_color); Ref<Font> font = get_theme_font("font", "Tree"); + int font_size = get_theme_font_size("font_size", "Tree"); int hs = get_theme_constant("hseparation", "Tree"); - int w = font->get_string_size(label).width; + int w = font->get_string_size(label, font_size).width; if (icon.is_valid()) { w += hs + icon->get_width(); } @@ -1040,7 +1085,7 @@ void EditorInspectorCategory::_notification(int p_what) { } Color color = get_theme_color("font_color", "Tree"); - draw_string(font, Point2(ofs, font->get_ascent() + (get_size().height - font->get_height()) / 2).floor(), label, color, get_size().width); + draw_string(font, Point2(ofs, font->get_ascent(font_size) + (get_size().height - font->get_height(font_size)) / 2).floor(), label, HALIGN_LEFT, get_size().width, font_size, color); } } @@ -1069,10 +1114,11 @@ Control *EditorInspectorCategory::make_custom_tooltip(const String &p_text) cons Size2 EditorInspectorCategory::get_minimum_size() const { Ref<Font> font = get_theme_font("font", "Tree"); + int font_size = get_theme_font_size("font_size", "Tree"); Size2 ms; ms.width = 1; - ms.height = font->get_height(); + ms.height = font->get_height(font_size); if (icon.is_valid()) { ms.height = MAX(icon->get_height(), ms.height); } @@ -1105,19 +1151,24 @@ void EditorInspectorSection::_test_unfold() { void EditorInspectorSection::_notification(int p_what) { if (p_what == NOTIFICATION_SORT_CHILDREN) { Ref<Font> font = get_theme_font("font", "Tree"); + int font_size = get_theme_font_size("font_size", "Tree"); Ref<Texture2D> arrow; if (foldable) { if (object->editor_is_section_unfolded(section)) { arrow = get_theme_icon("arrow", "Tree"); } else { - arrow = get_theme_icon("arrow_collapsed", "Tree"); + if (is_layout_rtl()) { + arrow = get_theme_icon("arrow_collapsed_mirrored", "Tree"); + } else { + arrow = get_theme_icon("arrow_collapsed", "Tree"); + } } } Size2 size = get_size(); Point2 offset; - offset.y = font->get_height(); + offset.y = font->get_height(font_size); if (arrow.is_valid()) { offset.y = MAX(offset.y, arrow->get_height()); } @@ -1148,18 +1199,20 @@ void EditorInspectorSection::_notification(int p_what) { if (p_what == NOTIFICATION_DRAW) { Ref<Texture2D> arrow; + bool rtl = is_layout_rtl(); if (foldable) { - if (object->editor_is_section_unfolded(section)) { - arrow = get_theme_icon("arrow", "Tree"); + if (rtl) { + arrow = get_theme_icon("arrow_collapsed_mirrored", "Tree"); } else { arrow = get_theme_icon("arrow_collapsed", "Tree"); } } Ref<Font> font = get_theme_font("font", "Tree"); + int font_size = get_theme_font_size("font_size", "Tree"); - int h = font->get_height(); + int h = font->get_height(font_size); if (arrow.is_valid()) { h = MAX(h, arrow->get_height()); } @@ -1169,10 +1222,15 @@ void EditorInspectorSection::_notification(int p_what) { const int arrow_margin = 3; Color color = get_theme_color("font_color", "Tree"); - draw_string(font, Point2(Math::round((16 + arrow_margin) * EDSCALE), font->get_ascent() + (h - font->get_height()) / 2).floor(), label, color, get_size().width); + float text_width = get_size().width - Math::round((16 + arrow_margin) * EDSCALE); + draw_string(font, Point2(rtl ? 0 : Math::round((16 + arrow_margin) * EDSCALE), font->get_ascent(font_size) + (h - font->get_height(font_size)) / 2).floor(), label, rtl ? HALIGN_RIGHT : HALIGN_LEFT, text_width, font_size, color); if (arrow.is_valid()) { - draw_texture(arrow, Point2(Math::round(arrow_margin * EDSCALE), (h - arrow->get_height()) / 2).floor()); + if (rtl) { + draw_texture(arrow, Point2(get_size().width - arrow->get_width() - Math::round(arrow_margin * EDSCALE), (h - arrow->get_height()) / 2).floor()); + } else { + draw_texture(arrow, Point2(Math::round(arrow_margin * EDSCALE), (h - arrow->get_height()) / 2).floor()); + } } if (dropping && !vbox->is_visible_in_tree()) { @@ -1237,7 +1295,8 @@ Size2 EditorInspectorSection::get_minimum_size() const { } Ref<Font> font = get_theme_font("font", "Tree"); - ms.height += font->get_height() + get_theme_constant("vseparation", "Tree"); + int font_size = get_theme_font_size("font_size", "Tree"); + ms.height += font->get_height(font_size) + get_theme_constant("vseparation", "Tree"); ms.width += get_theme_constant("inspector_margin", "Editor"); return ms; @@ -1273,7 +1332,8 @@ void EditorInspectorSection::_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { Ref<Font> font = get_theme_font("font", "Tree"); - if (mb->get_position().y > font->get_height()) { //clicked outside + int font_size = get_theme_font_size("font_size", "Tree"); + if (mb->get_position().y > font->get_height(font_size)) { //clicked outside return; } diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index 36b80a7dd4..10b1013486 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -69,13 +69,13 @@ private: Rect2 bottom_child_rect; Rect2 keying_rect; - bool keying_hover; + bool keying_hover = false; Rect2 revert_rect; - bool revert_hover; + bool revert_hover = false; Rect2 check_rect; - bool check_hover; + bool check_hover = false; Rect2 delete_rect; - bool delete_hover; + bool delete_hover = false; bool can_revert; diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp index 6fbafc7ff3..9c713f748e 100644 --- a/editor/editor_log.cpp +++ b/editor/editor_log.cpp @@ -35,7 +35,7 @@ #include "editor_node.h" #include "editor_scale.h" #include "scene/gui/center_container.h" -#include "scene/resources/dynamic_font.h" +#include "scene/resources/font.h" void EditorLog::_error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, ErrorHandlerType p_type) { EditorLog *self = (EditorLog *)p_self; @@ -61,12 +61,14 @@ void EditorLog::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { //button->set_icon(get_icon("Console","EditorIcons")); log->add_theme_font_override("normal_font", get_theme_font("output_source", "EditorFonts")); + log->add_theme_font_size_override("normal_font_size", get_theme_font_size("output_source_size", "EditorFonts")); log->add_theme_color_override("selection_color", get_theme_color("accent_color", "Editor") * Color(1, 1, 1, 0.4)); } else if (p_what == NOTIFICATION_THEME_CHANGED) { - Ref<DynamicFont> df_output_code = get_theme_font("output_source", "EditorFonts"); + Ref<Font> df_output_code = get_theme_font("output_source", "EditorFonts"); if (df_output_code.is_valid()) { if (log != nullptr) { log->add_theme_font_override("normal_font", get_theme_font("output_source", "EditorFonts")); + log->add_theme_font_size_override("normal_font_size", get_theme_font_size("output_source_size", "EditorFonts")); log->add_theme_color_override("selection_color", get_theme_color("accent_color", "Editor") * Color(1, 1, 1, 0.4)); } } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 9fcb5fff35..ff8f089c26 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -125,6 +125,7 @@ #include "editor/plugins/debugger_editor_plugin.h" #include "editor/plugins/editor_debugger_plugin.h" #include "editor/plugins/editor_preview_plugins.h" +#include "editor/plugins/font_editor_plugin.h" #include "editor/plugins/gi_probe_editor_plugin.h" #include "editor/plugins/gpu_particles_2d_editor_plugin.h" #include "editor/plugins/gpu_particles_3d_editor_plugin.h" @@ -140,6 +141,7 @@ #include "editor/plugins/multimesh_editor_plugin.h" #include "editor/plugins/navigation_polygon_editor_plugin.h" #include "editor/plugins/node_3d_editor_plugin.h" +#include "editor/plugins/ot_features_plugin.h" #include "editor/plugins/packed_scene_translation_parser_plugin.h" #include "editor/plugins/path_2d_editor_plugin.h" #include "editor/plugins/path_3d_editor_plugin.h" @@ -336,7 +338,11 @@ void EditorNode::_update_scene_tabs() { if (scene_tabs->get_offset_buttons_visible()) { // move add button to fixed position on the tabbar if (scene_tab_add->get_parent() == scene_tabs) { - scene_tab_add->set_position(Point2(0, 0)); + if (scene_tabs->is_layout_rtl()) { + scene_tab_add->set_position(Point2(tabbar_container->get_size().x - scene_tab_add->get_size().x, 0)); + } else { + scene_tab_add->set_position(Point2(0, 0)); + } scene_tabs->remove_child(scene_tab_add); tabbar_container->add_child(scene_tab_add); tabbar_container->move_child(scene_tab_add, 1); @@ -351,7 +357,11 @@ void EditorNode::_update_scene_tabs() { if (scene_tabs->get_tab_count() != 0) { last_tab = scene_tabs->get_tab_rect(scene_tabs->get_tab_count() - 1); } - scene_tab_add->set_position(Point2(last_tab.get_position().x + last_tab.get_size().x + 3, last_tab.get_position().y)); + if (scene_tabs->is_layout_rtl()) { + scene_tab_add->set_position(Point2(last_tab.get_position().x - scene_tab_add->get_size().x - 3, last_tab.get_position().y)); + } else { + scene_tab_add->set_position(Point2(last_tab.get_position().x + last_tab.get_size().x + 3, last_tab.get_position().y)); + } } } @@ -647,8 +657,13 @@ void EditorNode::_notification(int p_what) { bottom_panel_raise->set_icon(gui_base->get_theme_icon("ExpandBottomDock", "EditorIcons")); // clear_button->set_icon(gui_base->get_icon("Close", "EditorIcons")); don't have access to that node. needs to become a class property - dock_tab_move_left->set_icon(theme->get_icon("Back", "EditorIcons")); - dock_tab_move_right->set_icon(theme->get_icon("Forward", "EditorIcons")); + if (gui_base->is_layout_rtl()) { + dock_tab_move_left->set_icon(theme->get_icon("Forward", "EditorIcons")); + dock_tab_move_right->set_icon(theme->get_icon("Back", "EditorIcons")); + } else { + dock_tab_move_left->set_icon(theme->get_icon("Back", "EditorIcons")); + dock_tab_move_right->set_icon(theme->get_icon("Forward", "EditorIcons")); + } PopupMenu *p = help_menu->get_popup(); p->set_item_icon(p->get_item_index(HELP_SEARCH), gui_base->get_theme_icon("HelpSearch", "EditorIcons")); @@ -5878,7 +5893,11 @@ EditorNode::EditorNode() { HBoxContainer *dock_hb = memnew(HBoxContainer); dock_tab_move_left = memnew(Button); dock_tab_move_left->set_flat(true); - dock_tab_move_left->set_icon(theme->get_icon("Back", "EditorIcons")); + if (gui_base->is_layout_rtl()) { + dock_tab_move_left->set_icon(theme->get_icon("Forward", "EditorIcons")); + } else { + dock_tab_move_left->set_icon(theme->get_icon("Back", "EditorIcons")); + } dock_tab_move_left->set_focus_mode(Control::FOCUS_NONE); dock_tab_move_left->connect("pressed", callable_mp(this, &EditorNode::_dock_move_left)); dock_hb->add_child(dock_tab_move_left); @@ -5891,7 +5910,11 @@ EditorNode::EditorNode() { dock_tab_move_right = memnew(Button); dock_tab_move_right->set_flat(true); - dock_tab_move_right->set_icon(theme->get_icon("Forward", "EditorIcons")); + if (gui_base->is_layout_rtl()) { + dock_tab_move_right->set_icon(theme->get_icon("Forward", "EditorIcons")); + } else { + dock_tab_move_right->set_icon(theme->get_icon("Back", "EditorIcons")); + } dock_tab_move_right->set_focus_mode(Control::FOCUS_NONE); dock_tab_move_right->connect("pressed", callable_mp(this, &EditorNode::_dock_move_right)); @@ -6349,6 +6372,7 @@ EditorNode::EditorNode() { video_driver->set_focus_mode(Control::FOCUS_NONE); video_driver->connect("item_selected", callable_mp(this, &EditorNode::_video_driver_selected)); video_driver->add_theme_font_override("font", gui_base->get_theme_font("bold", "EditorFonts")); + video_driver->add_theme_font_size_override("font_size", gui_base->get_theme_font_size("bold_size", "EditorFonts")); // TODO re-enable when GLES2 is ported video_driver->set_disabled(true); right_menu_hb->add_child(video_driver); @@ -6648,6 +6672,8 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(GradientEditorPlugin(this))); add_editor_plugin(memnew(CollisionShape2DEditorPlugin(this))); add_editor_plugin(memnew(CurveEditorPlugin(this))); + add_editor_plugin(memnew(FontEditorPlugin(this))); + add_editor_plugin(memnew(OpenTypeFeaturesEditorPlugin(this))); add_editor_plugin(memnew(TextureEditorPlugin(this))); add_editor_plugin(memnew(TextureLayeredEditorPlugin(this))); add_editor_plugin(memnew(Texture3DEditorPlugin(this))); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 1443302f3f..2c4e403a81 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -36,7 +36,7 @@ #include "editor_properties_array_dict.h" #include "editor_scale.h" #include "scene/main/window.h" -#include "scene/resources/dynamic_font.h" +#include "scene/resources/font.h" ///////////////////// NULL ///////////////////////// @@ -146,7 +146,8 @@ void EditorPropertyMultilineText::_notification(int p_what) { Ref<Texture2D> df = get_theme_icon("DistractionFree", "EditorIcons"); open_big_text->set_icon(df); Ref<Font> font = get_theme_font("font", "Label"); - text->set_custom_minimum_size(Vector2(0, font->get_height() * 6)); + int font_size = get_theme_font_size("font_size", "Label"); + text->set_custom_minimum_size(Vector2(0, font->get_height(font_size) * 6)); } break; } @@ -290,6 +291,7 @@ EditorPropertyPath::EditorPropertyPath() { HBoxContainer *path_hb = memnew(HBoxContainer); add_child(path_hb); path = memnew(LineEdit); + path->set_structured_text_bidi_override(Control::STRUCTURED_TEXT_FILE); path_hb->add_child(path); path->connect("text_entered", callable_mp(this, &EditorPropertyPath::_path_selected)); path->connect("focus_exited", callable_mp(this, &EditorPropertyPath::_path_focus_exited)); @@ -587,7 +589,8 @@ public: virtual Size2 get_minimum_size() const override { Ref<Font> font = get_theme_font("font", "Label"); - return Vector2(0, font->get_height() * 2); + int font_size = get_theme_font_size("font_size", "Label"); + return Vector2(0, font->get_height(font_size) * 2); } virtual String get_tooltip(const Point2 &p_pos) const override { @@ -985,6 +988,7 @@ void EditorPropertyEasing::_draw_easing() { const float exp = get_edited_object()->get(get_edited_property()); const Ref<Font> f = get_theme_font("font", "Label"); + int font_size = get_theme_font_size("font_size", "Label"); const Color font_color = get_theme_color("font_color", "Label"); Color line_color; if (dragging) { @@ -1022,7 +1026,7 @@ void EditorPropertyEasing::_draw_easing() { } else { decimals = 1; } - f->draw(ci, Point2(10, 10 + f->get_ascent()), rtos(exp).pad_decimals(decimals), font_color); + f->draw_string(ci, Point2(10, 10 + f->get_ascent(font_size)), TS->format_number(rtos(exp).pad_decimals(decimals)), HALIGN_LEFT, -1, font_size, font_color); } void EditorPropertyEasing::update_property() { @@ -1039,7 +1043,7 @@ void EditorPropertyEasing::_set_preset(int p_preset) { void EditorPropertyEasing::_setup_spin() { setting = true; spin->setup_and_show(); - spin->get_line_edit()->set_text(rtos(get_edited_object()->get(get_edited_property()))); + spin->get_line_edit()->set_text(TS->format_number(rtos(get_edited_object()->get(get_edited_property())))); setting = false; spin->show(); } @@ -1088,7 +1092,7 @@ void EditorPropertyEasing::_notification(int p_what) { preset->add_icon_item(get_theme_icon("CurveInOut", "EditorIcons"), "In-Out", EASING_IN_OUT); preset->add_icon_item(get_theme_icon("CurveOutIn", "EditorIcons"), "Out-In", EASING_OUT_IN); } - easing_draw->set_custom_minimum_size(Size2(0, get_theme_font("font", "Label")->get_height() * 2)); + easing_draw->set_custom_minimum_size(Size2(0, get_theme_font("font", "Label")->get_height(get_theme_font_size("font_size", "Label")) * 2)); } break; } } @@ -3016,7 +3020,7 @@ bool EditorPropertyResource::_is_drop_valid(const Dictionary &p_drag_data) const } else if (at == "ShaderMaterial") { allowed_types.append("Shader"); } else if (at == "Font") { - allowed_types.append("DynamicFontData"); + allowed_types.append("FontData"); } } @@ -3115,9 +3119,9 @@ void EditorPropertyResource::drop_data_fw(const Point2 &p_point, const Variant & break; } - if (at == "Font" && ClassDB::is_parent_class(res->get_class(), "DynamicFontData")) { - Ref<DynamicFont> font = memnew(DynamicFont); - font->set_font_data(res); + if (at == "Font" && ClassDB::is_parent_class(res->get_class(), "FontData")) { + Ref<Font> font = memnew(Font); + font->add_data(res); res = font; break; } diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 2cf0bed7d0..0ea112d48c 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -262,13 +262,30 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { String host_lang = OS::get_singleton()->get_locale(); host_lang = TranslationServer::standardize_locale(host_lang); - // Some locales are not properly supported currently in Godot due to lack of font shaping - // (e.g. Arabic or Hindi), so even though we have work in progress translations for them, - // we skip them as they don't render properly. (GH-28577) - const Vector<String> locales_to_skip = String("ar,bn,fa,he,hi,ml,si,ta,te,ur").split(","); + // Skip locales if Text server lack required features. + Vector<String> locales_to_skip; + if (!TS->has_feature(TextServer::FEATURE_BIDI_LAYOUT) || !TS->has_feature(TextServer::FEATURE_SHAPING)) { + locales_to_skip.push_back("ar"); // Arabic + locales_to_skip.push_back("fa"); // Persian + locales_to_skip.push_back("ur"); // Urdu + } + if (!TS->has_feature(TextServer::FEATURE_BIDI_LAYOUT)) { + locales_to_skip.push_back("he"); // Hebrew + } + if (!TS->has_feature(TextServer::FEATURE_SHAPING)) { + locales_to_skip.push_back("bn"); // Bengali + locales_to_skip.push_back("hi"); // Hindi + locales_to_skip.push_back("ml"); // Malayalam + locales_to_skip.push_back("si"); // Sinhala + locales_to_skip.push_back("ta"); // Tamil + locales_to_skip.push_back("te"); // Telugu + } - String best; + if (!locales_to_skip.empty()) { + WARN_PRINT("Some locales are not properly supported by selected Text Server and are disabled."); + } + String best; EditorTranslationList *etl = _editor_translations; while (etl->data) { @@ -316,6 +333,9 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { hints["interface/editor/main_font_size"] = PropertyInfo(Variant::INT, "interface/editor/main_font_size", PROPERTY_HINT_RANGE, "8,48,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); _initial_set("interface/editor/code_font_size", 14); hints["interface/editor/code_font_size"] = PropertyInfo(Variant::INT, "interface/editor/code_font_size", PROPERTY_HINT_RANGE, "8,48,1", PROPERTY_USAGE_DEFAULT); + _initial_set("interface/editor/code_font_contextual_ligatures", 0); + hints["interface/editor/code_font_contextual_ligatures"] = PropertyInfo(Variant::INT, "interface/editor/code_font_contextual_ligatures", PROPERTY_HINT_ENUM, "Default,Disable contextual alternates (coding ligatures),Use custom OpenType feature set", PROPERTY_USAGE_DEFAULT); + _initial_set("interface/editor/code_font_custom_opentype_features", ""); _initial_set("interface/editor/font_antialiased", true); _initial_set("interface/editor/font_hinting", 0); hints["interface/editor/font_hinting"] = PropertyInfo(Variant::INT, "interface/editor/font_hinting", PROPERTY_HINT_ENUM, "Auto,None,Light,Normal", PROPERTY_USAGE_DEFAULT); diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp index efc966c6c4..d72510d40d 100644 --- a/editor/editor_spin_slider.cpp +++ b/editor/editor_spin_slider.cpp @@ -37,13 +37,13 @@ String EditorSpinSlider::get_tooltip(const Point2 &p_pos) const { if (grabber->is_visible()) { - return rtos(get_value()) + "\n\n" + TTR("Hold Ctrl to round to integers. Hold Shift for more precise changes."); + return TS->format_number(rtos(get_value())) + "\n\n" + TTR("Hold Ctrl to round to integers. Hold Shift for more precise changes."); } - return rtos(get_value()); + return TS->format_number(rtos(get_value())); } String EditorSpinSlider::get_text_value() const { - return String::num(get_value(), Math::range_step_decimals(get_step())); + return TS->format_number(String::num(get_value(), Math::range_step_decimals(get_step()))); } void EditorSpinSlider::_gui_input(const Ref<InputEvent> &p_event) { @@ -214,10 +214,11 @@ void EditorSpinSlider::_notification(int p_what) { draw_style_box(sb, Rect2(Vector2(), get_size())); } Ref<Font> font = get_theme_font("font", "LineEdit"); + int font_size = get_theme_font_size("font_size", "LineEdit"); int sep_base = 4 * EDSCALE; int sep = sep_base + sb->get_offset().x; //make it have the same margin on both sides, looks better - int string_width = font->get_string_size(label).width; + int string_width = font->get_string_size(label, font_size).width; int number_width = get_size().width - sb->get_minimum_size().width - string_width - sep; Ref<Texture2D> updown = get_theme_icon("updown", "SpinBox"); @@ -228,7 +229,7 @@ void EditorSpinSlider::_notification(int p_what) { String numstr = get_text_value(); - int vofs = (get_size().height - font->get_height()) / 2 + font->get_ascent(); + int vofs = (get_size().height - font->get_height(font_size)) / 2 + font->get_ascent(font_size); Color fc = get_theme_color("font_color", "LineEdit"); Color lc; @@ -248,9 +249,9 @@ void EditorSpinSlider::_notification(int p_what) { draw_style_box(focus, Rect2(Vector2(), get_size())); } - draw_string(font, Vector2(Math::round(sb->get_offset().x), vofs), label, lc * Color(1, 1, 1, 0.5)); + draw_string(font, Vector2(Math::round(sb->get_offset().x), vofs), label, HALIGN_LEFT, -1, font_size, lc * Color(1, 1, 1, 0.5)); - draw_string(font, Vector2(Math::round(sb->get_offset().x + string_width + sep), vofs), numstr, fc, number_width); + draw_string(font, Vector2(Math::round(sb->get_offset().x + string_width + sep), vofs), numstr, HALIGN_LEFT, number_width, font_size, fc); if (get_step() == 1) { Ref<Texture2D> updown2 = get_theme_icon("updown", "SpinBox"); @@ -330,9 +331,10 @@ void EditorSpinSlider::_notification(int p_what) { Size2 EditorSpinSlider::get_minimum_size() const { Ref<StyleBox> sb = get_theme_stylebox("normal", "LineEdit"); Ref<Font> font = get_theme_font("font", "LineEdit"); + int font_size = get_theme_font_size("font_size", "LineEdit"); Size2 ms = sb->get_minimum_size(); - ms.height += font->get_height(); + ms.height += font->get_height(font_size); return ms; } @@ -360,7 +362,7 @@ void EditorSpinSlider::_evaluate_input_text() { // This prevents using functions like `pow()`, but using functions // in EditorSpinSlider is a barely known (and barely used) feature. // Instead, we'd rather support German/French keyboard layouts out of the box. - const String text = value_input->get_text().replace(",", "."); + const String text = TS->parse_number(value_input->get_text().replace(",", ".")); Ref<Expression> expr; expr.instance(); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 768e5bccbc..88976ed332 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -600,12 +600,18 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("icon_color_pressed", "Button", icon_color_pressed); // OptionButton + theme->set_stylebox("focus", "OptionButton", style_widget_focus); + theme->set_stylebox("normal", "OptionButton", style_widget); theme->set_stylebox("hover", "OptionButton", style_widget_hover); theme->set_stylebox("pressed", "OptionButton", style_widget_pressed); - theme->set_stylebox("focus", "OptionButton", style_widget_focus); theme->set_stylebox("disabled", "OptionButton", style_widget_disabled); + theme->set_stylebox("normal_mirrored", "OptionButton", style_widget); + theme->set_stylebox("hover_mirrored", "OptionButton", style_widget_hover); + theme->set_stylebox("pressed_mirrored", "OptionButton", style_widget_pressed); + theme->set_stylebox("disabled_mirrored", "OptionButton", style_widget_disabled); + theme->set_color("font_color", "OptionButton", font_color); theme->set_color("font_color_hover", "OptionButton", font_color_hl); theme->set_color("font_color_pressed", "OptionButton", accent_color); @@ -627,6 +633,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("off", "CheckButton", theme->get_icon("GuiToggleOff", "EditorIcons")); theme->set_icon("off_disabled", "CheckButton", theme->get_icon("GuiToggleOffDisabled", "EditorIcons")); + theme->set_icon("on_mirrored", "CheckButton", theme->get_icon("GuiToggleOnMirrored", "EditorIcons")); + theme->set_icon("on_disabled_mirrored", "CheckButton", theme->get_icon("GuiToggleOnDisabledMirrored", "EditorIcons")); + theme->set_icon("off_mirrored", "CheckButton", theme->get_icon("GuiToggleOffMirrored", "EditorIcons")); + theme->set_icon("off_disabled_mirrored", "CheckButton", theme->get_icon("GuiToggleOffDisabledMirrored", "EditorIcons")); + theme->set_color("font_color", "CheckButton", font_color); theme->set_color("font_color_hover", "CheckButton", font_color_hl); theme->set_color("font_color_pressed", "CheckButton", accent_color); @@ -679,6 +690,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("radio_checked", "PopupMenu", theme->get_icon("GuiRadioChecked", "EditorIcons")); theme->set_icon("radio_unchecked", "PopupMenu", theme->get_icon("GuiRadioUnchecked", "EditorIcons")); theme->set_icon("submenu", "PopupMenu", theme->get_icon("ArrowRight", "EditorIcons")); + theme->set_icon("submenu_mirrored", "PopupMenu", theme->get_icon("ArrowLeft", "EditorIcons")); theme->set_icon("visibility_hidden", "PopupMenu", theme->get_icon("GuiVisibilityHidden", "EditorIcons")); theme->set_icon("visibility_visible", "PopupMenu", theme->get_icon("GuiVisibilityVisible", "EditorIcons")); theme->set_icon("visibility_xray", "PopupMenu", theme->get_icon("GuiVisibilityXray", "EditorIcons")); @@ -707,6 +719,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("unchecked", "Tree", theme->get_icon("GuiUnchecked", "EditorIcons")); theme->set_icon("arrow", "Tree", theme->get_icon("GuiTreeArrowDown", "EditorIcons")); theme->set_icon("arrow_collapsed", "Tree", theme->get_icon("GuiTreeArrowRight", "EditorIcons")); + theme->set_icon("arrow_collapsed_mirrored", "Tree", theme->get_icon("GuiTreeArrowLeft", "EditorIcons")); theme->set_icon("updown", "Tree", theme->get_icon("GuiTreeUpdown", "EditorIcons")); theme->set_icon("select_arrow", "Tree", theme->get_icon("GuiDropdown", "EditorIcons")); theme->set_stylebox("bg_focus", "Tree", style_focus); @@ -851,7 +864,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("DebuggerPanel", "EditorStyles", style_panel_debugger); Ref<StyleBoxFlat> style_panel_invisible_top = style_content_panel->duplicate(); - int stylebox_offset = theme->get_font("tab_fg", "TabContainer")->get_height() + theme->get_stylebox("tab_fg", "TabContainer")->get_minimum_size().height + theme->get_stylebox("panel", "TabContainer")->get_default_margin(MARGIN_TOP); + int stylebox_offset = theme->get_font("tab_fg", "TabContainer")->get_height(theme->get_font_size("tab_fg", "TabContainer")) + theme->get_stylebox("tab_fg", "TabContainer")->get_minimum_size().height + theme->get_stylebox("panel", "TabContainer")->get_default_margin(MARGIN_TOP); style_panel_invisible_top->set_expand_margin_size(MARGIN_TOP, -stylebox_offset); style_panel_invisible_top->set_default_margin(MARGIN_TOP, 0); theme->set_stylebox("BottomPanelDebuggerOverride", "EditorStyles", style_panel_invisible_top); @@ -931,6 +944,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_constant("title_height", "Window", 24 * EDSCALE); theme->set_constant("resize_margin", "Window", 4 * EDSCALE); theme->set_font("title_font", "Window", theme->get_font("title", "EditorFonts")); + theme->set_font_size("title_font_size", "Window", theme->get_font_size("title_size", "EditorFonts")); // complex window, for now only Editor settings and Project settings Ref<StyleBoxFlat> style_complex_window = style_window->duplicate(); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 543546b152..c65c796e5e 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -68,6 +68,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory } subdirectory_item->set_text(0, dname); + subdirectory_item->set_structured_text_bidi_override(0, STRUCTURED_TEXT_FILE); subdirectory_item->set_icon(0, get_theme_icon("Folder", "EditorIcons")); subdirectory_item->set_icon_modulate(0, get_theme_color("folder_icon_modulate", "FileDialog")); subdirectory_item->set_selectable(0, true); @@ -136,6 +137,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory TreeItem *file_item = tree->create_item(subdirectory_item); file_item->set_text(0, fi.name); + file_item->set_structured_text_bidi_override(0, STRUCTURED_TEXT_FILE); file_item->set_icon(0, _get_tree_item_icon(!fi.import_broken, fi.type)); String file_metadata = lpath.plus_file(fi.name); file_item->set_metadata(0, file_metadata); @@ -320,6 +322,8 @@ void FileSystemDock::_update_display_mode(bool p_force) { void FileSystemDock::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_TRANSLATION_CHANGED: + case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: case NOTIFICATION_ENTER_TREE: { if (initialized) { return; @@ -348,8 +352,13 @@ void FileSystemDock::_notification(int p_what) { file_list_search_box->set_clear_button_enabled(true); file_list_button_sort->set_icon(get_theme_icon("Sort", ei)); - button_hist_next->set_icon(get_theme_icon("Forward", ei)); - button_hist_prev->set_icon(get_theme_icon("Back", ei)); + if (is_layout_rtl()) { + button_hist_next->set_icon(get_theme_icon("Back", ei)); + button_hist_prev->set_icon(get_theme_icon("Forward", ei)); + } else { + button_hist_next->set_icon(get_theme_icon("Forward", ei)); + button_hist_prev->set_icon(get_theme_icon("Back", ei)); + } file_list_popup->connect("id_pressed", callable_mp(this, &FileSystemDock::_file_list_rmb_option)); tree_popup->connect("id_pressed", callable_mp(this, &FileSystemDock::_tree_rmb_option)); @@ -402,8 +411,13 @@ void FileSystemDock::_notification(int p_what) { String ei = "EditorIcons"; button_reload->set_icon(get_theme_icon("Reload", ei)); button_toggle_display_mode->set_icon(get_theme_icon("Panels2", ei)); - button_hist_next->set_icon(get_theme_icon("Forward", ei)); - button_hist_prev->set_icon(get_theme_icon("Back", ei)); + if (is_layout_rtl()) { + button_hist_next->set_icon(get_theme_icon("Back", ei)); + button_hist_prev->set_icon(get_theme_icon("Forward", ei)); + } else { + button_hist_next->set_icon(get_theme_icon("Forward", ei)); + button_hist_prev->set_icon(get_theme_icon("Back", ei)); + } if (file_list_display_mode == FILE_LIST_DISPLAY_LIST) { button_file_list_display_mode->set_icon(get_theme_icon("FileThumbnail", "EditorIcons")); } else { @@ -2693,6 +2707,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { toolbar_hbc->add_child(button_hist_next); current_path = memnew(LineEdit); + current_path->set_structured_text_bidi_override(Control::STRUCTURED_TEXT_FILE); current_path->set_h_size_flags(SIZE_EXPAND_FILL); _set_current_path_text(path); toolbar_hbc->add_child(current_path); diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp index c2ccbdb08c..8d3f0eb21f 100644 --- a/editor/find_in_files.cpp +++ b/editor/find_in_files.cpp @@ -571,6 +571,7 @@ FindInFilesPanel::FindInFilesPanel() { _search_text_label = memnew(Label); _search_text_label->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font("source", "EditorFonts")); + _search_text_label->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size("source_size", "EditorFonts")); hbc->add_child(_search_text_label); _progress_bar = memnew(ProgressBar); @@ -599,6 +600,7 @@ FindInFilesPanel::FindInFilesPanel() { _results_display = memnew(Tree); _results_display->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font("source", "EditorFonts")); + _results_display->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size("source_size", "EditorFonts")); _results_display->set_v_size_flags(SIZE_EXPAND_FILL); _results_display->connect("item_selected", callable_mp(this, &FindInFilesPanel::_on_result_selected)); _results_display->connect("item_edited", callable_mp(this, &FindInFilesPanel::_on_item_edited)); @@ -755,10 +757,11 @@ void FindInFilesPanel::draw_result_text(Object *item_obj, Rect2 rect) { Result r = E->value(); String item_text = item->get_text(_with_replace ? 1 : 0); Ref<Font> font = _results_display->get_theme_font("font"); + int font_size = _results_display->get_theme_font_size("font_size"); Rect2 match_rect = rect; - match_rect.position.x += font->get_string_size(item_text.left(r.begin_trimmed)).x; - match_rect.size.x = font->get_string_size(_search_text_label->get_text()).x; + match_rect.position.x += font->get_string_size(item_text.left(r.begin_trimmed), font_size).x; + match_rect.size.x = font->get_string_size(_search_text_label->get_text(), font_size).x; match_rect.position.y += 1 * EDSCALE; match_rect.size.y -= 2 * EDSCALE; diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp index 4e6e2d0237..f3bad8d86d 100644 --- a/editor/groups_editor.cpp +++ b/editor/groups_editor.cpp @@ -361,9 +361,16 @@ void GroupDialog::_delete_group_item(const String &p_name) { void GroupDialog::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_TRANSLATION_CHANGED: + case Control::NOTIFICATION_LAYOUT_DIRECTION_CHANGED: case NOTIFICATION_ENTER_TREE: { - add_button->set_icon(groups->get_theme_icon("Forward", "EditorIcons")); - remove_button->set_icon(groups->get_theme_icon("Back", "EditorIcons")); + if (is_layout_rtl()) { + add_button->set_icon(groups->get_theme_icon("Back", "EditorIcons")); + remove_button->set_icon(groups->get_theme_icon("Forward", "EditorIcons")); + } else { + add_button->set_icon(groups->get_theme_icon("Forward", "EditorIcons")); + remove_button->set_icon(groups->get_theme_icon("Back", "EditorIcons")); + } add_filter->set_right_icon(groups->get_theme_icon("Search", "EditorIcons")); add_filter->set_clear_button_enabled(true); diff --git a/editor/icons/AutoEndBackwards.svg b/editor/icons/AutoEndBackwards.svg new file mode 100644 index 0000000000..c6de305069 --- /dev/null +++ b/editor/icons/AutoEndBackwards.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m2 14c-.552262-.000055-.999945-.447738-1-1v-10c.000055-.5522619.447738-.9999448 1-1h8c.303863-.0001753.591325.1378063.78125.375l4 5c.291397.3649711.291397.8830289 0 1.248l-4 5c-.189538.237924-.477058.376652-.78125.37695h-8zm1-2h6.5195004l3.1991996-4-3.1991996-4h-6.5195004zm6.0000004-2v-4l1.9999996 2z" fill-rule="evenodd"/><path d="m3.8685125 4.9095434h4.1550816v1.1637426h-2.6154217v1.1117544h2.4594562v1.1637428h-2.4594562v1.3676976h2.7034024v1.1637432h-4.2430623z" stroke-width=".204755"/></g></svg> diff --git a/editor/icons/AutoPlayBackwards.svg b/editor/icons/AutoPlayBackwards.svg new file mode 100644 index 0000000000..20602ba348 --- /dev/null +++ b/editor/icons/AutoPlayBackwards.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13.999798 2a-1.0001 1.0001 0 0 1 1 1v10a-1.0001 1.0001 0 0 1 -1 1h-8.0000003a-1.0001 1.0001 0 0 1 -.78125-.375l-4-5a-1.0001 1.0001 0 0 1 0-1.248l4-5a-1.0001 1.0001 0 0 1 .78125-.37695h8.0000003zm-1 2h-6.5195003l-3.1992 4 3.1992 4h6.5195003zm-3.0000003 1c1.1046003 0 2.0000003.8954 2.0000003 2v4h-1v-2h-2.0000003v2h-1v-4c0-1.1046.89543-2 2-2zm0 1a-1 1 0 0 0 -1 1v1h2.0000003v-1a-1 1 0 0 0 -1.0000003-1zm-3 0v4l-2-2z" fill="#e0e0e0" fill-rule="evenodd"/></svg> diff --git a/editor/icons/BitmapFont.svg b/editor/icons/BitmapFont.svg deleted file mode 100644 index d3ab5f7dd7..0000000000 --- a/editor/icons/BitmapFont.svg +++ /dev/null @@ -1 +0,0 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1037.4v4h1v-1h1v-1h4v10h-1v1h-1v1h6v-1h-1v-1h-1v-10h4v1h1v1h1v-4z" fill="#84c2ff" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/DynamicFont.svg b/editor/icons/DynamicFont.svg deleted file mode 100644 index bbaa12ea1b..0000000000 --- a/editor/icons/DynamicFont.svg +++ /dev/null @@ -1 +0,0 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m1 1037.4v2 1h1a1 1 0 0 1 1-1h2v6a1 1 0 0 1 -1 1v1h1 2 1v-1a1 1 0 0 1 -1-1v-6h2a1 1 0 0 1 1 1h1v-1-2h-4-2z" fill="#e0e0e0"/><path d="m4 5v2 1h1a1 1 0 0 1 1-1h2v6a1 1 0 0 1 -1 1v1h1 2 1v-1a1 1 0 0 1 -1-1v-6h2a1 1 0 0 1 1 1h1v-1-2h-4-2z" fill="#84c2ff" transform="translate(0 1036.4)"/></g></svg> diff --git a/editor/icons/DynamicFontData.svg b/editor/icons/FontData.svg index 7ee88582a5..7ee88582a5 100644 --- a/editor/icons/DynamicFontData.svg +++ b/editor/icons/FontData.svg diff --git a/editor/icons/GuiResizerMirrored.svg b/editor/icons/GuiResizerMirrored.svg new file mode 100644 index 0000000000..8227f5b648 --- /dev/null +++ b/editor/icons/GuiResizerMirrored.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill-opacity=".588" fill="#fff" d="M4 3a1 1 0 0 1 1 1v6h6a1 1 0 0 1 0 2H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z"/></svg> diff --git a/editor/icons/GuiTabMirrored.svg b/editor/icons/GuiTabMirrored.svg new file mode 100644 index 0000000000..a0011a5b2d --- /dev/null +++ b/editor/icons/GuiTabMirrored.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8"><path fill-opacity=".196" fill="#fff" d="M2 0v8H0V0zm5.014.002a-1 1 0 0 1 .693.291-1 1 0 0 1 0 1.414L5.414 4l2.293 2.293a-1 1 0 0 1 0 1.414-1 1 0 0 1-1.414 0l-3-3a-1 1 0 0 1 0-1.414l3-3a-1 1 0 0 1 .72-.29z"/></svg> diff --git a/editor/icons/GuiToggleOffMirrored.svg b/editor/icons/GuiToggleOffMirrored.svg new file mode 100644 index 0000000000..d650de9cda --- /dev/null +++ b/editor/icons/GuiToggleOffMirrored.svg @@ -0,0 +1 @@ +<svg height="26" width="42" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="matrix(-1 0 0 1 42 0)"><rect fill-opacity=".188" height="16" rx="9" width="38" x="2" y="5"/><circle cx="10" cy="13" r="5"/></g></svg> diff --git a/editor/icons/GuiToggleOnMirrored.svg b/editor/icons/GuiToggleOnMirrored.svg new file mode 100644 index 0000000000..7339b6efd2 --- /dev/null +++ b/editor/icons/GuiToggleOnMirrored.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="42" height="26"><path fill="#e0e0e0" d="M31 5c4.986 0 9 3.568 9 8s-4.014 8-9 8H11c-4.986 0-9-3.568-9-8s4.014-8 9-8zM10 8a-5 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-5z"/></svg> diff --git a/editor/icons/GuiTreeArrowLeft.svg b/editor/icons/GuiTreeArrowLeft.svg new file mode 100644 index 0000000000..d0f7b36fab --- /dev/null +++ b/editor/icons/GuiTreeArrowLeft.svg @@ -0,0 +1 @@ +<svg height="12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m7 9-3-3 3-3" style="fill:none;stroke:#fff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:.392"/></svg> diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp index c88cd8ea5f..75f89fbfb5 100644 --- a/editor/inspector_dock.cpp +++ b/editor/inspector_dock.cpp @@ -332,13 +332,20 @@ Container *InspectorDock::get_addon_area() { void InspectorDock::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_TRANSLATION_CHANGED: + case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { set_theme(editor->get_gui_base()->get_theme()); resource_new_button->set_icon(get_theme_icon("New", "EditorIcons")); resource_load_button->set_icon(get_theme_icon("Load", "EditorIcons")); resource_save_button->set_icon(get_theme_icon("Save", "EditorIcons")); - backward_button->set_icon(get_theme_icon("Back", "EditorIcons")); - forward_button->set_icon(get_theme_icon("Forward", "EditorIcons")); + if (is_layout_rtl()) { + backward_button->set_icon(get_theme_icon("Forward", "EditorIcons")); + forward_button->set_icon(get_theme_icon("Back", "EditorIcons")); + } else { + backward_button->set_icon(get_theme_icon("Back", "EditorIcons")); + forward_button->set_icon(get_theme_icon("Forward", "EditorIcons")); + } history_menu->set_icon(get_theme_icon("History", "EditorIcons")); object_menu->set_icon(get_theme_icon("Tools", "EditorIcons")); warning->set_icon(get_theme_icon("NodeWarning", "EditorIcons")); @@ -524,7 +531,11 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) { backward_button = memnew(Button); backward_button->set_flat(true); general_options_hb->add_child(backward_button); - backward_button->set_icon(get_theme_icon("Back", "EditorIcons")); + if (is_layout_rtl()) { + backward_button->set_icon(get_theme_icon("Forward", "EditorIcons")); + } else { + backward_button->set_icon(get_theme_icon("Back", "EditorIcons")); + } backward_button->set_flat(true); backward_button->set_tooltip(TTR("Go to the previous edited object in history.")); backward_button->set_disabled(true); @@ -533,7 +544,11 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) { forward_button = memnew(Button); forward_button->set_flat(true); general_options_hb->add_child(forward_button); - forward_button->set_icon(get_theme_icon("Forward", "EditorIcons")); + if (is_layout_rtl()) { + forward_button->set_icon(get_theme_icon("Back", "EditorIcons")); + } else { + forward_button->set_icon(get_theme_icon("Forward", "EditorIcons")); + } forward_button->set_flat(true); forward_button->set_tooltip(TTR("Go to the next edited object in history.")); forward_button->set_disabled(true); diff --git a/editor/localization_editor.cpp b/editor/localization_editor.cpp index e725ce482d..2a21885c4c 100644 --- a/editor/localization_editor.cpp +++ b/editor/localization_editor.cpp @@ -37,6 +37,24 @@ #include "scene/gui/control.h" void LocalizationEditor::_notification(int p_what) { + if (p_what == NOTIFICATION_TEXT_SERVER_CHANGED) { + ts_name->set_text(TTR("Text server: ") + TS->get_name()); + + FileAccessRef file_check = FileAccess::create(FileAccess::ACCESS_RESOURCES); + if (TS->has_feature(TextServer::FEATURE_USE_SUPPORT_DATA)) { + if (file_check->file_exists("res://" + TS->get_support_data_filename())) { + ts_data_status->set_text(TTR("Support data: ") + TTR("Installed")); + ts_install->set_disabled(true); + } else { + ts_data_status->set_text(TTR("Support data: ") + TTR("Not installed")); + ts_install->set_disabled(false); + } + } else { + ts_data_status->set_text(TTR("Support data: ") + TTR("Not supported")); + ts_install->set_disabled(false); + } + ts_data_info->set_text(TTR("Info: ") + TS->get_support_data_info()); + } if (p_what == NOTIFICATION_ENTER_TREE) { translation_list->connect("button_pressed", callable_mp(this, &LocalizationEditor::_translation_delete)); translation_pot_list->connect("button_pressed", callable_mp(this, &LocalizationEditor::_pot_delete)); @@ -622,6 +640,26 @@ void LocalizationEditor::update_translations() { updating_translations = false; } +void LocalizationEditor::_install_ts_data() { + if (TS->has_feature(TextServer::FEATURE_USE_SUPPORT_DATA)) { + TS->save_support_data("res://" + TS->get_support_data_filename()); + } + + FileAccessRef file_check = FileAccess::create(FileAccess::ACCESS_RESOURCES); + if (TS->has_feature(TextServer::FEATURE_USE_SUPPORT_DATA)) { + if (file_check->file_exists("res://" + TS->get_support_data_filename())) { + ts_data_status->set_text(TTR("Support data: ") + TTR("Installed")); + ts_install->set_disabled(true); + } else { + ts_data_status->set_text(TTR("Support data: ") + TTR("Not installed")); + ts_install->set_disabled(false); + } + } else { + ts_data_status->set_text(TTR("Support data: ") + TTR("Not supported")); + ts_install->set_disabled(false); + } +} + void LocalizationEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("update_translations"), &LocalizationEditor::update_translations); @@ -791,4 +829,37 @@ LocalizationEditor::LocalizationEditor() { pot_file_open_dialog->connect("file_selected", callable_mp(this, &LocalizationEditor::_pot_add)); add_child(pot_file_open_dialog); } + + { + VBoxContainer *tvb = memnew(VBoxContainer); + tvb->set_name(TTR("Text Server Data")); + translations->add_child(tvb); + + ts_name = memnew(Label(TTR("Text server: ") + TS->get_name())); + tvb->add_child(ts_name); + + ts_data_status = memnew(Label(TTR("Support data: "))); + tvb->add_child(ts_data_status); + + ts_data_info = memnew(Label(TTR("Info: ") + TS->get_support_data_info())); + tvb->add_child(ts_data_info); + + ts_install = memnew(Button(TTR("Install support data..."))); + ts_install->connect("pressed", callable_mp(this, &LocalizationEditor::_install_ts_data)); + tvb->add_child(ts_install); + + FileAccessRef file_check = FileAccess::create(FileAccess::ACCESS_RESOURCES); + if (TS->has_feature(TextServer::FEATURE_USE_SUPPORT_DATA)) { + if (file_check->file_exists("res://" + TS->get_support_data_filename())) { + ts_data_status->set_text(TTR("Support data: ") + TTR("Installed")); + ts_install->set_disabled(true); + } else { + ts_data_status->set_text(TTR("Support data: ") + TTR("Not installed")); + ts_install->set_disabled(false); + } + } else { + ts_data_status->set_text(TTR("Support data: ") + TTR("Not supported")); + ts_install->set_disabled(false); + } + } } diff --git a/editor/localization_editor.h b/editor/localization_editor.h index 3c077d9c77..43b6bb60f6 100644 --- a/editor/localization_editor.h +++ b/editor/localization_editor.h @@ -58,6 +58,11 @@ class LocalizationEditor : public VBoxContainer { Vector<TreeItem *> translation_filter_treeitems; Vector<int> translation_locales_idxs_remap; + Label *ts_name; + Label *ts_data_status; + Label *ts_data_info; + Button *ts_install; + Tree *translation_pot_list; EditorFileDialog *pot_file_open_dialog; EditorFileDialog *pot_generate_dialog; @@ -89,6 +94,8 @@ class LocalizationEditor : public VBoxContainer { void _pot_generate(const String &p_file); void _update_pot_file_extensions(); + void _install_ts_data(); + protected: void _notification(int p_what); static void _bind_methods(); diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp index 7a3fb1ff52..0b61db6835 100644 --- a/editor/plugins/abstract_polygon_2d_editor.cpp +++ b/editor/plugins/abstract_polygon_2d_editor.cpp @@ -551,9 +551,10 @@ void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overl if (vertex == hover_point) { Ref<Font> font = get_theme_font("font", "Label"); + int font_size = get_theme_font_size("font_size", "Label"); String num = String::num(vertex.vertex); - Size2 num_size = font->get_string_size(num); - p_overlay->draw_string(font, point - num_size * 0.5, num, Color(1.0, 1.0, 1.0, 0.5)); + Size2 num_size = font->get_string_size(num, font_size); + p_overlay->draw_string(font, point - num_size * 0.5, num, HALIGN_LEFT, -1, font_size, Color(1.0, 1.0, 1.0, 0.5)); } } } diff --git a/editor/plugins/animation_blend_space_1d_editor.cpp b/editor/plugins/animation_blend_space_1d_editor.cpp index d335b29c2f..223484044a 100644 --- a/editor/plugins/animation_blend_space_1d_editor.cpp +++ b/editor/plugins/animation_blend_space_1d_editor.cpp @@ -201,6 +201,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_draw() { linecolor_soft.a *= 0.5; Ref<Font> font = get_theme_font("font", "Label"); + int font_size = get_theme_font_size("font_size", "Label"); Ref<Texture2D> icon = get_theme_icon("KeyValue", "EditorIcons"); Ref<Texture2D> icon_selected = get_theme_icon("KeySelected", "EditorIcons"); @@ -221,7 +222,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_draw() { float x = point; blend_space_draw->draw_line(Point2(x, s.height - 1), Point2(x, s.height - 5 * EDSCALE), linecolor); - blend_space_draw->draw_string(font, Point2(x + 2 * EDSCALE, s.height - 2 * EDSCALE - font->get_height() + font->get_ascent()), "0", linecolor); + blend_space_draw->draw_string(font, Point2(x + 2 * EDSCALE, s.height - 2 * EDSCALE - font->get_height(font_size) + font->get_ascent(font_size)), "0", HALIGN_LEFT, -1, font_size, linecolor); blend_space_draw->draw_line(Point2(x, s.height - 5 * EDSCALE), Point2(x, 0), linecolor_soft); } diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp index 60a5188af7..94785a5422 100644 --- a/editor/plugins/animation_blend_space_2d_editor.cpp +++ b/editor/plugins/animation_blend_space_2d_editor.cpp @@ -396,6 +396,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() { Color linecolor_soft = linecolor; linecolor_soft.a *= 0.5; Ref<Font> font = get_theme_font("font", "Label"); + int font_size = get_theme_font_size("font_size", "Label"); Ref<Texture2D> icon = get_theme_icon("KeyValue", "EditorIcons"); Ref<Texture2D> icon_selected = get_theme_icon("KeySelected", "EditorIcons"); @@ -412,14 +413,14 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() { if (blend_space->get_min_space().y < 0) { int y = (blend_space->get_max_space().y / (blend_space->get_max_space().y - blend_space->get_min_space().y)) * s.height; blend_space_draw->draw_line(Point2(0, y), Point2(5 * EDSCALE, y), linecolor); - blend_space_draw->draw_string(font, Point2(2 * EDSCALE, y - font->get_height() + font->get_ascent()), "0", linecolor); + blend_space_draw->draw_string(font, Point2(2 * EDSCALE, y - font->get_height(font_size) + font->get_ascent(font_size)), "0", HALIGN_LEFT, -1, font_size, linecolor); blend_space_draw->draw_line(Point2(5 * EDSCALE, y), Point2(s.width, y), linecolor_soft); } if (blend_space->get_min_space().x < 0) { int x = (-blend_space->get_min_space().x / (blend_space->get_max_space().x - blend_space->get_min_space().x)) * s.width; blend_space_draw->draw_line(Point2(x, s.height - 1), Point2(x, s.height - 5 * EDSCALE), linecolor); - blend_space_draw->draw_string(font, Point2(x + 2 * EDSCALE, s.height - 2 * EDSCALE - font->get_height() + font->get_ascent()), "0", linecolor); + blend_space_draw->draw_string(font, Point2(x + 2 * EDSCALE, s.height - 2 * EDSCALE - font->get_height(font_size) + font->get_ascent(font_size)), "0", HALIGN_LEFT, -1, font_size, linecolor); blend_space_draw->draw_line(Point2(x, s.height - 5 * EDSCALE), Point2(x, 0), linecolor_soft); } diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 1e56e3d11f..6b30aa325c 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -105,6 +105,8 @@ void AnimationPlayerEditor::_notification(int p_what) { case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { add_theme_style_override("panel", editor->get_gui_base()->get_theme_stylebox("panel", "Panel")); } break; + case NOTIFICATION_TRANSLATION_CHANGED: + case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: case NOTIFICATION_THEME_CHANGED: { autoplay->set_icon(get_theme_icon("AutoPlay", "EditorIcons")); diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index 4634d15941..c59e056f4f 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -559,6 +559,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { Ref<StyleBox> style_selected = get_theme_stylebox("state_machine_selectedframe", "GraphNode"); Ref<Font> font = get_theme_font("title_font", "GraphNode"); + int font_size = get_theme_font_size("title_font_size", "GraphNode"); Color font_color = get_theme_color("title_color", "GraphNode"); Ref<Texture2D> play = get_theme_icon("Play", "EditorIcons"); Ref<Texture2D> auto_play = get_theme_icon("AutoPlay", "EditorIcons"); @@ -612,9 +613,9 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { Ref<StyleBox> sb = E->get() == selected_node ? style_selected : style; Size2 s = sb->get_minimum_size(); - int strsize = font->get_string_size(name).width; + int strsize = font->get_string_size(name, font_size).width; s.width += strsize; - s.height += MAX(font->get_height(), play->get_height()); + s.height += MAX(font->get_height(font_size), play->get_height()); s.width += sep + play->get_width(); if (needs_editor) { s.width += sep + edit->get_width(); @@ -741,7 +742,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { Ref<AnimationNode> anode = state_machine->get_node(name); bool needs_editor = AnimationTreeEditor::get_singleton()->can_edit(anode); Ref<StyleBox> sb = name == selected_node ? style_selected : style; - int strsize = font->get_string_size(name).width; + int strsize = font->get_string_size(name, font_size).width; NodeRect &nr = node_rects.write[i]; @@ -759,12 +760,12 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { bool onstart = state_machine->get_start_node() == name; if (onstart) { - state_machine_draw->draw_string(font, offset + Vector2(0, -font->get_height() - 3 * EDSCALE + font->get_ascent()), TTR("Start"), font_color); + state_machine_draw->draw_string(font, offset + Vector2(0, -font->get_height(font_size) - 3 * EDSCALE + font->get_ascent(font_size)), TTR("Start"), HALIGN_LEFT, -1, font_size, font_color); } if (state_machine->get_end_node() == name) { - int endofs = nr.node.size.x - font->get_string_size(TTR("End")).x; - state_machine_draw->draw_string(font, offset + Vector2(endofs, -font->get_height() - 3 * EDSCALE + font->get_ascent()), TTR("End"), font_color); + int endofs = nr.node.size.x - font->get_string_size(TTR("End"), font_size).x; + state_machine_draw->draw_string(font, offset + Vector2(endofs, -font->get_height(font_size) - 3 * EDSCALE + font->get_ascent(font_size)), TTR("End"), HALIGN_LEFT, -1, font_size, font_color); } offset.x += sb->get_offset().x; @@ -781,10 +782,10 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { } offset.x += sep + play->get_width(); - nr.name.position = offset + Vector2(0, (h - font->get_height()) / 2).floor(); - nr.name.size = Vector2(strsize, font->get_height()); + nr.name.position = offset + Vector2(0, (h - font->get_height(font_size)) / 2).floor(); + nr.name.size = Vector2(strsize, font->get_height(font_size)); - state_machine_draw->draw_string(font, nr.name.position + Vector2(0, font->get_ascent()), name, font_color); + state_machine_draw->draw_string(font, nr.name.position + Vector2(0, font->get_ascent(font_size)), name, HALIGN_LEFT, -1, font_size, font_color); offset.x += strsize + sep; if (needs_editor) { @@ -880,7 +881,7 @@ void AnimationNodeStateMachineEditor::_update_graph() { } void AnimationNodeStateMachineEditor::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED || p_what == NOTIFICATION_LAYOUT_DIRECTION_CHANGED || p_what == NOTIFICATION_TRANSLATION_CHANGED) { error_panel->add_theme_style_override("panel", get_theme_stylebox("bg", "Tree")); error_label->add_theme_color_override("font_color", get_theme_color("error_color", "Editor")); panel->add_theme_style_override("panel", get_theme_stylebox("bg", "Tree")); diff --git a/editor/plugins/audio_stream_editor_plugin.cpp b/editor/plugins/audio_stream_editor_plugin.cpp index e6f6b6f2e0..998916349c 100644 --- a/editor/plugins/audio_stream_editor_plugin.cpp +++ b/editor/plugins/audio_stream_editor_plugin.cpp @@ -236,11 +236,13 @@ AudioStreamEditor::AudioStreamEditor() { _current_label->set_align(Label::ALIGN_RIGHT); _current_label->set_h_size_flags(SIZE_EXPAND_FILL); _current_label->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font("status_source", "EditorFonts")); + _current_label->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size("status_source_size", "EditorFonts")); _current_label->set_modulate(Color(1, 1, 1, 0.5)); hbox->add_child(_current_label); _duration_label = memnew(Label); _duration_label->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font("status_source", "EditorFonts")); + _duration_label->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size("status_source_size", "EditorFonts")); hbox->add_child(_duration_label); } diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 6acf80a2c1..47a30ad5d7 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -52,7 +52,6 @@ #include "scene/gui/subviewport_container.h" #include "scene/main/canvas_layer.h" #include "scene/main/window.h" -#include "scene/resources/dynamic_font.h" #include "scene/resources/packed_scene.h" // Min and Max are power of two in order to play nicely with successive increment. @@ -857,7 +856,11 @@ Vector2 CanvasItemEditor::_anchor_to_position(const Control *p_control, Vector2 Transform2D parent_transform = p_control->get_transform().affine_inverse(); Rect2 parent_rect = p_control->get_parent_anchorable_rect(); - return parent_transform.xform(parent_rect.position + Vector2(parent_rect.size.x * anchor.x, parent_rect.size.y * anchor.y)); + if (p_control->is_layout_rtl()) { + return parent_transform.xform(parent_rect.position + Vector2(parent_rect.size.x - parent_rect.size.x * anchor.x, parent_rect.size.y * anchor.y)); + } else { + return parent_transform.xform(parent_rect.position + Vector2(parent_rect.size.x * anchor.x, parent_rect.size.y * anchor.y)); + } } Vector2 CanvasItemEditor::_position_to_anchor(const Control *p_control, Vector2 position) { @@ -866,7 +869,11 @@ Vector2 CanvasItemEditor::_position_to_anchor(const Control *p_control, Vector2 Rect2 parent_rect = p_control->get_parent_anchorable_rect(); Vector2 output = Vector2(); - output.x = (parent_rect.size.x == 0) ? 0.0 : (p_control->get_transform().xform(position).x - parent_rect.position.x) / parent_rect.size.x; + if (p_control->is_layout_rtl()) { + output.x = (parent_rect.size.x == 0) ? 0.0 : (parent_rect.size.x - p_control->get_transform().xform(position).x - parent_rect.position.x) / parent_rect.size.x; + } else { + output.x = (parent_rect.size.x == 0) ? 0.0 : (p_control->get_transform().xform(position).x - parent_rect.position.x) / parent_rect.size.x; + } output.y = (parent_rect.size.y == 0) ? 0.0 : (p_control->get_transform().xform(position).y - parent_rect.position.y) / parent_rect.size.y; return output; } @@ -1628,7 +1635,11 @@ bool CanvasItemEditor::_gui_input_anchors(const Ref<InputEvent> &p_event) { for (int i = 0; i < 4; i++) { anchor_pos[i] = (transform * control->get_global_transform_with_canvas()).xform(_anchor_to_position(control, anchor_pos[i])); anchor_rects[i] = Rect2(anchor_pos[i], anchor_handle->get_size()); - anchor_rects[i].position -= anchor_handle->get_size() * Vector2(float(i == 0 || i == 3), float(i <= 1)); + if (control->is_layout_rtl()) { + anchor_rects[i].position -= anchor_handle->get_size() * Vector2(float(i == 1 || i == 2), float(i <= 1)); + } else { + anchor_rects[i].position -= anchor_handle->get_size() * Vector2(float(i == 0 || i == 3), float(i <= 1)); + } } DragType dragger[] = { @@ -2771,7 +2782,8 @@ void CanvasItemEditor::_draw_text_at_position(Point2 p_position, String p_string Color color = get_theme_color("font_color", "Editor"); color.a = 0.8; Ref<Font> font = get_theme_font("font", "Label"); - Size2 text_size = font->get_string_size(p_string); + int font_size = get_theme_font_size("font_size", "Label"); + Size2 text_size = font->get_string_size(p_string, font_size); switch (p_side) { case MARGIN_LEFT: p_position += Vector2(-text_size.x - 5, text_size.y / 2); @@ -2786,18 +2798,18 @@ void CanvasItemEditor::_draw_text_at_position(Point2 p_position, String p_string p_position += Vector2(-text_size.x / 2, text_size.y + 5); break; } - viewport->draw_string(font, p_position, p_string, color); + viewport->draw_string(font, p_position, p_string, HALIGN_LEFT, -1, font_size, color); } void CanvasItemEditor::_draw_margin_at_position(int p_value, Point2 p_position, Margin p_side) { - String str = vformat("%d px", p_value); + String str = TS->format_number(vformat("%d " + TTR("px"), p_value)); if (p_value != 0) { _draw_text_at_position(p_position, str, p_side); } } void CanvasItemEditor::_draw_percentage_at_position(float p_value, Point2 p_position, Margin p_side) { - String str = vformat("%.1f %%", p_value * 100.0); + String str = TS->format_number(vformat("%.1f ", p_value * 100.0)) + TS->percent_sign(); if (p_value != 0) { _draw_text_at_position(p_position, str, p_side); } @@ -2841,17 +2853,19 @@ void CanvasItemEditor::_draw_guides() { Color text_color = get_theme_color("font_color", "Editor"); text_color.a = 0.5; if (drag_type == DRAG_DOUBLE_GUIDE || drag_type == DRAG_V_GUIDE) { - String str = vformat("%d px", Math::round(xform.affine_inverse().xform(dragged_guide_pos).x)); + String str = TS->format_number(vformat("%d px", Math::round(xform.affine_inverse().xform(dragged_guide_pos).x))); Ref<Font> font = get_theme_font("font", "Label"); - Size2 text_size = font->get_string_size(str); - viewport->draw_string(font, Point2(dragged_guide_pos.x + 10, RULER_WIDTH + text_size.y / 2 + 10), str, text_color); + int font_size = get_theme_font_size("font_size", "Label"); + Size2 text_size = font->get_string_size(str, font_size); + viewport->draw_string(font, Point2(dragged_guide_pos.x + 10, RULER_WIDTH + text_size.y / 2 + 10), str, HALIGN_LEFT, -1, font_size, text_color); viewport->draw_line(Point2(dragged_guide_pos.x, 0), Point2(dragged_guide_pos.x, viewport->get_size().y), guide_color, Math::round(EDSCALE)); } if (drag_type == DRAG_DOUBLE_GUIDE || drag_type == DRAG_H_GUIDE) { - String str = vformat("%d px", Math::round(xform.affine_inverse().xform(dragged_guide_pos).y)); + String str = TS->format_number(vformat("%d px", Math::round(xform.affine_inverse().xform(dragged_guide_pos).y))); Ref<Font> font = get_theme_font("font", "Label"); - Size2 text_size = font->get_string_size(str); - viewport->draw_string(font, Point2(RULER_WIDTH + 10, dragged_guide_pos.y + text_size.y / 2 + 10), str, text_color); + int font_size = get_theme_font_size("font_size", "Label"); + Size2 text_size = font->get_string_size(str, font_size); + viewport->draw_string(font, Point2(RULER_WIDTH + 10, dragged_guide_pos.y + text_size.y / 2 + 10), str, HALIGN_LEFT, -1, font_size, text_color); viewport->draw_line(Point2(0, dragged_guide_pos.y), Point2(viewport->get_size().x, dragged_guide_pos.y), guide_color, Math::round(EDSCALE)); } } @@ -2876,6 +2890,7 @@ void CanvasItemEditor::_draw_rulers() { Color font_color = get_theme_color("font_color", "Editor"); font_color.a = 0.8; Ref<Font> font = get_theme_font("rulers", "EditorFonts"); + int font_size = get_theme_font_size("rulers_size", "EditorFonts"); // The rule transform Transform2D ruler_transform = Transform2D(); @@ -2922,7 +2937,7 @@ void CanvasItemEditor::_draw_rulers() { if (i % (major_subdivision * minor_subdivision) == 0) { viewport->draw_line(Point2(position.x, 0), Point2(position.x, RULER_WIDTH), graduation_color, Math::round(EDSCALE)); float val = (ruler_transform * major_subdivide * minor_subdivide).xform(Point2(i, 0)).x; - viewport->draw_string(font, Point2(position.x + 2, font->get_height()), vformat(((int)val == val) ? "%d" : "%.1f", val), font_color); + viewport->draw_string(font, Point2(position.x + 2, font->get_height(font_size)), TS->format_number(vformat(((int)val == val) ? "%d" : "%.1f", val)), HALIGN_LEFT, -1, font_size, font_color); } else { if (i % minor_subdivision == 0) { viewport->draw_line(Point2(position.x, RULER_WIDTH * 0.33), Point2(position.x, RULER_WIDTH), graduation_color, Math::round(EDSCALE)); @@ -2940,9 +2955,9 @@ void CanvasItemEditor::_draw_rulers() { viewport->draw_line(Point2(0, position.y), Point2(RULER_WIDTH, position.y), graduation_color, Math::round(EDSCALE)); float val = (ruler_transform * major_subdivide * minor_subdivide).xform(Point2(0, i)).y; - Transform2D text_xform = Transform2D(-Math_PI / 2.0, Point2(font->get_height(), position.y - 2)); + Transform2D text_xform = Transform2D(-Math_PI / 2.0, Point2(font->get_height(font_size), position.y - 2)); viewport->draw_set_transform_matrix(viewport->get_transform() * text_xform); - viewport->draw_string(font, Point2(), vformat(((int)val == val) ? "%d" : "%.1f", val), font_color); + viewport->draw_string(font, Point2(), TS->format_number(vformat(((int)val == val) ? "%d" : "%.1f", val)), HALIGN_LEFT, -1, font_size, font_color); viewport->draw_set_transform_matrix(viewport->get_transform()); } else { @@ -3054,17 +3069,18 @@ void CanvasItemEditor::_draw_ruler_tool() { } Ref<Font> font = get_theme_font("bold", "EditorFonts"); + int font_size = get_theme_font_size("bold_size", "EditorFonts"); Color font_color = get_theme_color("font_color", "Editor"); Color font_secondary_color = font_color; font_secondary_color.a = 0.5; - float text_height = font->get_height(); + float text_height = font->get_height(font_size); const float text_width = 76; const float angle_text_width = 54; Point2 text_pos = (begin + end) / 2 - Vector2(text_width / 2, text_height / 2); text_pos.x = CLAMP(text_pos.x, text_width / 2, viewport->get_rect().size.x - text_width * 1.5); text_pos.y = CLAMP(text_pos.y, text_height * 1.5, viewport->get_rect().size.y - text_height * 1.5); - viewport->draw_string(font, text_pos, vformat("%.2f px", length_vector.length()), font_color); + viewport->draw_string(font, text_pos, TS->format_number(vformat("%.2f " + TTR("px"), length_vector.length())), HALIGN_LEFT, -1, font_size, font_color); if (draw_secondary_lines) { const float horizontal_angle_rad = atan2(length_vector.y, length_vector.x); @@ -3074,16 +3090,16 @@ void CanvasItemEditor::_draw_ruler_tool() { Point2 text_pos2 = text_pos; text_pos2.x = begin.x < text_pos.x ? MIN(text_pos.x - text_width, begin.x - text_width / 2) : MAX(text_pos.x + text_width, begin.x - text_width / 2); - viewport->draw_string(font, text_pos2, vformat("%.2f px", length_vector.y), font_secondary_color); + viewport->draw_string(font, text_pos2, TS->format_number(vformat("%.2f " + TTR("px"), length_vector.y)), HALIGN_LEFT, -1, font_size, font_secondary_color); Point2 v_angle_text_pos = Point2(); v_angle_text_pos.x = CLAMP(begin.x - angle_text_width / 2, angle_text_width / 2, viewport->get_rect().size.x - angle_text_width); v_angle_text_pos.y = begin.y < end.y ? MIN(text_pos2.y - 2 * text_height, begin.y - text_height * 0.5) : MAX(text_pos2.y + text_height * 3, begin.y + text_height * 1.5); - viewport->draw_string(font, v_angle_text_pos, vformat("%d deg", vertical_angle), font_secondary_color); + viewport->draw_string(font, v_angle_text_pos, TS->format_number(vformat("%d " + TTR("deg"), vertical_angle)), HALIGN_LEFT, -1, font_size, font_secondary_color); text_pos2 = text_pos; text_pos2.y = end.y < text_pos.y ? MIN(text_pos.y - text_height * 2, end.y - text_height / 2) : MAX(text_pos.y + text_height * 2, end.y - text_height / 2); - viewport->draw_string(font, text_pos2, vformat("%.2f px", length_vector.x), font_secondary_color); + viewport->draw_string(font, text_pos2, TS->format_number(vformat("%.2f " + TTR("px"), length_vector.x)), HALIGN_LEFT, -1, font_size, font_secondary_color); Point2 h_angle_text_pos = Point2(); h_angle_text_pos.x = CLAMP(end.x - angle_text_width / 2, angle_text_width / 2, viewport->get_rect().size.x - angle_text_width); @@ -3100,7 +3116,7 @@ void CanvasItemEditor::_draw_ruler_tool() { h_angle_text_pos.y = MIN(text_pos.y - height_multiplier * text_height, MIN(end.y - text_height * 0.5, text_pos2.y - height_multiplier * text_height)); } } - viewport->draw_string(font, h_angle_text_pos, vformat("%d deg", horizontal_angle), font_secondary_color); + viewport->draw_string(font, h_angle_text_pos, TS->format_number(vformat("%d " + TTR("deg"), horizontal_angle)), HALIGN_LEFT, -1, font_size, font_secondary_color); // Angle arcs int arc_point_count = 8; @@ -3137,17 +3153,17 @@ void CanvasItemEditor::_draw_ruler_tool() { text_pos.y = CLAMP(text_pos.y, text_height * 2.5, viewport->get_rect().size.y - text_height / 2); if (draw_secondary_lines) { - viewport->draw_string(font, text_pos, vformat("%.2f units", (length_vector / grid_step).length()), font_color); + viewport->draw_string(font, text_pos, TS->format_number(vformat("%.2f " + TTR("units"), (length_vector / grid_step).length())), HALIGN_LEFT, -1, font_size, font_color); Point2 text_pos2 = text_pos; text_pos2.x = begin.x < text_pos.x ? MIN(text_pos.x - text_width, begin.x - text_width / 2) : MAX(text_pos.x + text_width, begin.x - text_width / 2); - viewport->draw_string(font, text_pos2, vformat("%d units", roundf(length_vector.y / grid_step.y)), font_secondary_color); + viewport->draw_string(font, text_pos2, TS->format_number(vformat("%d " + TTR("units"), roundf(length_vector.y / grid_step.y))), HALIGN_LEFT, -1, font_size, font_secondary_color); text_pos2 = text_pos; text_pos2.y = end.y < text_pos.y ? MIN(text_pos.y - text_height * 2, end.y + text_height / 2) : MAX(text_pos.y + text_height * 2, end.y + text_height / 2); - viewport->draw_string(font, text_pos2, vformat("%d units", roundf(length_vector.x / grid_step.x)), font_secondary_color); + viewport->draw_string(font, text_pos2, TS->format_number(vformat("%d " + TTR("units"), roundf(length_vector.x / grid_step.x))), HALIGN_LEFT, -1, font_size, font_secondary_color); } else { - viewport->draw_string(font, text_pos, vformat("%d units", roundf((length_vector / grid_step).length())), font_color); + viewport->draw_string(font, text_pos, TS->format_number(vformat("%d " + TTR("units"), roundf((length_vector / grid_step).length()))), HALIGN_LEFT, -1, font_size, font_color); } } } else { @@ -3177,10 +3193,17 @@ void CanvasItemEditor::_draw_control_anchors(Control *control) { // Draw the anchors handles Rect2 anchor_rects[4]; - anchor_rects[0] = Rect2(anchors_pos[0] - anchor_handle->get_size(), anchor_handle->get_size()); - anchor_rects[1] = Rect2(anchors_pos[1] - Vector2(0.0, anchor_handle->get_size().y), Point2(-anchor_handle->get_size().x, anchor_handle->get_size().y)); - anchor_rects[2] = Rect2(anchors_pos[2], -anchor_handle->get_size()); - anchor_rects[3] = Rect2(anchors_pos[3] - Vector2(anchor_handle->get_size().x, 0.0), Point2(anchor_handle->get_size().x, -anchor_handle->get_size().y)); + if (control->is_layout_rtl()) { + anchor_rects[0] = Rect2(anchors_pos[0] - Vector2(0.0, anchor_handle->get_size().y), Point2(-anchor_handle->get_size().x, anchor_handle->get_size().y)); + anchor_rects[1] = Rect2(anchors_pos[1] - anchor_handle->get_size(), anchor_handle->get_size()); + anchor_rects[2] = Rect2(anchors_pos[2] - Vector2(anchor_handle->get_size().x, 0.0), Point2(anchor_handle->get_size().x, -anchor_handle->get_size().y)); + anchor_rects[3] = Rect2(anchors_pos[3], -anchor_handle->get_size()); + } else { + anchor_rects[0] = Rect2(anchors_pos[0] - anchor_handle->get_size(), anchor_handle->get_size()); + anchor_rects[1] = Rect2(anchors_pos[1] - Vector2(0.0, anchor_handle->get_size().y), Point2(-anchor_handle->get_size().x, anchor_handle->get_size().y)); + anchor_rects[2] = Rect2(anchors_pos[2], -anchor_handle->get_size()); + anchor_rects[3] = Rect2(anchors_pos[3] - Vector2(anchor_handle->get_size().x, 0.0), Point2(anchor_handle->get_size().x, -anchor_handle->get_size().y)); + } for (int i = 0; i < 4; i++) { anchor_handle->draw_rect(ci, anchor_rects[i]); @@ -3744,6 +3767,7 @@ void CanvasItemEditor::_draw_hover() { String node_name = hovering_results[i].name; Ref<Font> font = get_theme_font("font", "Label"); + int font_size = get_theme_font_size("font_size", "Label"); Size2 node_name_size = font->get_string_size(node_name); Size2 item_size = Size2(node_icon->get_size().x + 4 + node_name_size.x, MAX(node_icon->get_size().y, node_name_size.y - 3)); @@ -3761,7 +3785,7 @@ void CanvasItemEditor::_draw_hover() { viewport->draw_texture(node_icon, pos, Color(1.0, 1.0, 1.0, 0.5)); // Draw name - viewport->draw_string(font, pos + Point2(node_icon->get_size().x + 4, item_size.y - 3), node_name, Color(1.0, 1.0, 1.0, 0.5)); + viewport->draw_string(font, pos + Point2(node_icon->get_size().x + 4, item_size.y - 3), node_name, HALIGN_LEFT, -1, font_size, Color(1.0, 1.0, 1.0, 0.5)); } } @@ -4342,8 +4366,13 @@ void CanvasItemEditor::_update_scrollbars() { } // Move and resize the scrollbars, avoiding overlap. - v_scroll->set_begin(Point2(size.width - vmin.width, (show_rulers) ? RULER_WIDTH : 0)); - v_scroll->set_end(Point2(size.width, size.height - (h_scroll->is_visible() ? hmin.height : 0))); + if (is_layout_rtl()) { + v_scroll->set_begin(Point2(0, (show_rulers) ? RULER_WIDTH : 0)); + v_scroll->set_end(Point2(vmin.width, size.height - (h_scroll->is_visible() ? hmin.height : 0))); + } else { + v_scroll->set_begin(Point2(size.width - vmin.width, (show_rulers) ? RULER_WIDTH : 0)); + v_scroll->set_end(Point2(size.width, size.height - (h_scroll->is_visible() ? hmin.height : 0))); + } h_scroll->set_begin(Point2((show_rulers) ? RULER_WIDTH : 0, size.height - hmin.height)); h_scroll->set_end(Point2(size.width - (v_scroll->is_visible() ? vmin.width : 0), size.height)); @@ -4540,9 +4569,9 @@ void CanvasItemEditor::_update_zoom_label() { // even if their display doesn't have a particularly low DPI. if (zoom >= 10) { // Don't show a decimal when the zoom level is higher than 1000 %. - zoom_text = rtos(Math::round((zoom / MAX(1, EDSCALE)) * 100)) + " %"; + zoom_text = TS->format_number(rtos(Math::round((zoom / MAX(1, EDSCALE)) * 100))) + " " + TS->percent_sign(); } else { - zoom_text = rtos(Math::stepify((zoom / MAX(1, EDSCALE)) * 100, 0.1)) + " %"; + zoom_text = TS->format_number(rtos(Math::stepify((zoom / MAX(1, EDSCALE)) * 100, 0.1))) + " " + TS->percent_sign(); } zoom_reset->set_text(zoom_text); @@ -5703,6 +5732,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { warning_child_of_container->set_text(TTR("Warning: Children of a container get their position and size determined only by their parent.")); warning_child_of_container->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color("warning_color", "Editor")); warning_child_of_container->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font("main", "EditorFonts")); + warning_child_of_container->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size("main_size", "EditorFonts")); add_control_to_info_overlay(warning_child_of_container); h_scroll = memnew(HScrollBar); @@ -5727,10 +5757,8 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { zoom_reset = memnew(Button); zoom_reset->set_flat(true); zoom_hb->add_child(zoom_reset); - Ref<DynamicFont> font = zoom_reset->get_theme_font("font")->duplicate(false); - font->set_outline_size(1); - font->set_outline_color(Color(0, 0, 0)); - zoom_reset->add_theme_font_override("font", font); + zoom_reset->add_theme_constant_override("outline_size", 1); + zoom_reset->add_theme_color_override("font_outline_modulate", Color(0, 0, 0)); zoom_reset->add_theme_color_override("font_color", Color(1, 1, 1)); zoom_reset->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_zoom_reset)); zoom_reset->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_reset", TTR("Zoom Reset"), KEY_MASK_CMD | KEY_0)); diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp index 539ab03f5b..4768cac217 100644 --- a/editor/plugins/curve_editor_plugin.cpp +++ b/editor/plugins/curve_editor_plugin.cpp @@ -518,7 +518,9 @@ void CurveEditor::set_hover_point_index(int index) { void CurveEditor::update_view_transform() { Ref<Font> font = get_theme_font("font", "Label"); - const real_t margin = font->get_height() + 2 * EDSCALE; + int font_size = get_theme_font_size("font_size", "Label"); + + const real_t margin = font->get_height(font_size) + 2 * EDSCALE; float min_y = 0; float max_y = 1; @@ -662,18 +664,19 @@ void CurveEditor::_draw() { draw_set_transform_matrix(Transform2D()); Ref<Font> font = get_theme_font("font", "Label"); - float font_height = font->get_height(); + int font_size = get_theme_font_size("font_size", "Label"); + float font_height = font->get_height(font_size); Color text_color = get_theme_color("font_color", "Editor"); { // X axis float y = curve.get_min_value(); Vector2 off(0, font_height - 1); - draw_string(font, get_view_pos(Vector2(0, y)) + off, "0.0", text_color); - draw_string(font, get_view_pos(Vector2(0.25, y)) + off, "0.25", text_color); - draw_string(font, get_view_pos(Vector2(0.5, y)) + off, "0.5", text_color); - draw_string(font, get_view_pos(Vector2(0.75, y)) + off, "0.75", text_color); - draw_string(font, get_view_pos(Vector2(1, y)) + off, "1.0", text_color); + draw_string(font, get_view_pos(Vector2(0, y)) + off, "0.0", HALIGN_LEFT, -1, font_size, text_color); + draw_string(font, get_view_pos(Vector2(0.25, y)) + off, "0.25", HALIGN_LEFT, -1, font_size, text_color); + draw_string(font, get_view_pos(Vector2(0.5, y)) + off, "0.5", HALIGN_LEFT, -1, font_size, text_color); + draw_string(font, get_view_pos(Vector2(0.75, y)) + off, "0.75", HALIGN_LEFT, -1, font_size, text_color); + draw_string(font, get_view_pos(Vector2(1, y)) + off, "1.0", HALIGN_LEFT, -1, font_size, text_color); } { @@ -682,9 +685,9 @@ void CurveEditor::_draw() { float m1 = 0.5 * (curve.get_min_value() + curve.get_max_value()); float m2 = curve.get_max_value(); Vector2 off(1, -1); - draw_string(font, get_view_pos(Vector2(0, m0)) + off, String::num(m0, 2), text_color); - draw_string(font, get_view_pos(Vector2(0, m1)) + off, String::num(m1, 2), text_color); - draw_string(font, get_view_pos(Vector2(0, m2)) + off, String::num(m2, 3), text_color); + draw_string(font, get_view_pos(Vector2(0, m0)) + off, String::num(m0, 2), HALIGN_LEFT, -1, font_size, text_color); + draw_string(font, get_view_pos(Vector2(0, m1)) + off, String::num(m1, 2), HALIGN_LEFT, -1, font_size, text_color); + draw_string(font, get_view_pos(Vector2(0, m2)) + off, String::num(m2, 3), HALIGN_LEFT, -1, font_size, text_color); } // Draw tangents for current point @@ -744,10 +747,10 @@ void CurveEditor::_draw() { if (_selected_point > 0 && _selected_point + 1 < curve.get_point_count()) { text_color.a *= 0.4; - draw_string(font, Vector2(50 * EDSCALE, font_height), TTR("Hold Shift to edit tangents individually"), text_color); + draw_string(font, Vector2(50 * EDSCALE, font_height), TTR("Hold Shift to edit tangents individually"), HALIGN_LEFT, -1, font_size, text_color); } else if (curve.get_point_count() == 0) { text_color.a *= 0.4; - draw_string(font, Vector2(50 * EDSCALE, font_height), TTR("Right click to add point"), text_color); + draw_string(font, Vector2(50 * EDSCALE, font_height), TTR("Right click to add point"), HALIGN_LEFT, -1, font_size, text_color); } } diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index 3cf4dc5ac8..2fc0e35f82 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -37,7 +37,7 @@ #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "scene/resources/bit_map.h" -#include "scene/resources/dynamic_font.h" +#include "scene/resources/font.h" #include "scene/resources/material.h" #include "scene/resources/mesh.h" #include "servers/audio/audio_stream.h" @@ -798,25 +798,79 @@ void EditorFontPreviewPlugin::_bind_methods() { } bool EditorFontPreviewPlugin::handles(const String &p_type) const { - return ClassDB::is_parent_class(p_type, "DynamicFontData") || ClassDB::is_parent_class(p_type, "DynamicFont"); -} + return ClassDB::is_parent_class(p_type, "FontData") || ClassDB::is_parent_class(p_type, "Font"); +} + +struct FSample { + String script; + String sample; +}; + +static FSample _samples[] = { + { "hani", U"漢語" }, + { "armn", U"Աբ" }, + { "copt", U"Αα" }, + { "cyrl", U"Аб" }, + { "grek", U"Αα" }, + { "hebr", U"אב" }, + { "arab", U"اب" }, + { "syrc", U"ܐܒ" }, + { "thaa", U"ހށ" }, + { "deva", U"आ" }, + { "beng", U"আ" }, + { "guru", U"ਆ" }, + { "gujr", U"આ" }, + { "orya", U"ଆ" }, + { "taml", U"ஆ" }, + { "telu", U"ఆ" }, + { "knda", U"ಆ" }, + { "mylm", U"ആ" }, + { "sinh", U"ආ" }, + { "thai", U"กิ" }, + { "laoo", U"ກິ" }, + { "tibt", U"ༀ" }, + { "mymr", U"က" }, + { "geor", U"Ⴀა" }, + { "hang", U"한글" }, + { "ethi", U"ሀ" }, + { "cher", U"Ꭳ" }, + { "cans", U"ᐁ" }, + { "ogam", U"ᚁ" }, + { "runr", U"ᚠ" }, + { "tglg", U"ᜀ" }, + { "hano", U"ᜠ" }, + { "buhd", U"ᝀ" }, + { "tagb", U"ᝠ" }, + { "khmr", U"ក" }, + { "mong", U"ᠠ" }, + { "limb", U"ᤁ" }, + { "tale", U"ᥐ" }, + { "latn", U"Ab" }, + { "zyyy", U"😀" }, + { "", U"" } +}; Ref<Texture2D> EditorFontPreviewPlugin::generate_from_path(const String &p_path, const Size2 &p_size) const { RES res = ResourceLoader::load(p_path); - Ref<DynamicFont> sampled_font; - if (res->is_class("DynamicFont")) { + Ref<Font> sampled_font; + if (res->is_class("Font")) { sampled_font = res->duplicate(); - if (sampled_font->get_outline_color() == Color(1, 1, 1, 1)) { - sampled_font->set_outline_color(Color(0, 0, 0, 1)); - } - } else if (res->is_class("DynamicFontData")) { + } else if (res->is_class("FontData")) { sampled_font.instance(); - sampled_font->set_font_data(res); + sampled_font->add_data(res->duplicate()); } - sampled_font->set_size(50); - String sampled_text = "Abg"; - Vector2 size = sampled_font->get_string_size(sampled_text); + String sample; + for (int j = 0; j < sampled_font->get_data_count(); j++) { + for (int i = 0; _samples[i].script != String(); i++) { + if (sampled_font->get_data(j)->is_script_supported(_samples[i].script)) { + if (sampled_font->get_data(j)->has_char(_samples[i].sample[0])) { + sample += _samples[i].sample; + } + } + } + } + Vector2 size = sampled_font->get_string_size(sample, 50); Vector2 pos; @@ -825,7 +879,7 @@ Ref<Texture2D> EditorFontPreviewPlugin::generate_from_path(const String &p_path, Ref<Font> font = sampled_font; - font->draw(canvas_item, pos, sampled_text); + font->draw_string(canvas_item, pos, sample, HALIGN_LEFT, -1.f, 50, Color(1, 1, 1)); preview_done = false; RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture diff --git a/editor/plugins/font_editor_plugin.cpp b/editor/plugins/font_editor_plugin.cpp new file mode 100644 index 0000000000..a82547182c --- /dev/null +++ b/editor/plugins/font_editor_plugin.cpp @@ -0,0 +1,331 @@ +/*************************************************************************/ +/* font_editor_plugin.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "font_editor_plugin.h" + +#include "editor/editor_scale.h" + +void FontDataPreview::_notification(int p_what) { + if (p_what == NOTIFICATION_DRAW) { + Color text_color = get_theme_color("font_color", "Label"); + Color line_color = text_color; + line_color.a *= 0.6; + Vector2 pos = (get_size() - line->get_size()) / 2; + line->draw(get_canvas_item(), pos, text_color); + draw_line(Vector2(0, pos.y + line->get_line_ascent()), Vector2(pos.x - 5, pos.y + line->get_line_ascent()), line_color); + draw_line(Vector2(pos.x + line->get_size().x + 5, pos.y + line->get_line_ascent()), Vector2(get_size().x, pos.y + line->get_line_ascent()), line_color); + } +} + +void FontDataPreview::_bind_methods() {} + +Size2 FontDataPreview::get_minimum_size() const { + return Vector2(64, 64) * EDSCALE; +} + +struct FSample { + String script; + String sample; +}; + +static FSample _samples[] = { + { "hani", U"漢語" }, + { "armn", U"Աբ" }, + { "copt", U"Αα" }, + { "cyrl", U"Аб" }, + { "grek", U"Αα" }, + { "hebr", U"אב" }, + { "arab", U"اب" }, + { "syrc", U"ܐܒ" }, + { "thaa", U"ހށ" }, + { "deva", U"आ" }, + { "beng", U"আ" }, + { "guru", U"ਆ" }, + { "gujr", U"આ" }, + { "orya", U"ଆ" }, + { "taml", U"ஆ" }, + { "telu", U"ఆ" }, + { "knda", U"ಆ" }, + { "mylm", U"ആ" }, + { "sinh", U"ආ" }, + { "thai", U"กิ" }, + { "laoo", U"ກິ" }, + { "tibt", U"ༀ" }, + { "mymr", U"က" }, + { "geor", U"Ⴀა" }, + { "hang", U"한글" }, + { "ethi", U"ሀ" }, + { "cher", U"Ꭳ" }, + { "cans", U"ᐁ" }, + { "ogam", U"ᚁ" }, + { "runr", U"ᚠ" }, + { "tglg", U"ᜀ" }, + { "hano", U"ᜠ" }, + { "buhd", U"ᝀ" }, + { "tagb", U"ᝠ" }, + { "khmr", U"ក" }, + { "mong", U"ᠠ" }, + { "limb", U"ᤁ" }, + { "tale", U"ᥐ" }, + { "latn", U"Ab" }, + { "zyyy", U"😀" }, + { "", U"" } +}; + +void FontDataPreview::set_data(const Ref<FontData> &p_data) { + Ref<Font> f = memnew(Font); + f->add_data(p_data); + + line->clear(); + + String sample; + for (int i = 0; _samples[i].script != String(); i++) { + if (p_data->is_script_supported(_samples[i].script)) { + if (p_data->has_char(_samples[i].sample[0])) { + sample += _samples[i].sample; + } + } + } + line->add_string(sample, f, 72); + + update(); +} + +FontDataPreview::FontDataPreview() { + line.instance(); +} + +/*************************************************************************/ + +void FontDataEditor::_notification(int p_what) { + if (p_what == NOTIFICATION_SORT_CHILDREN) { + int split_width = get_name_split_ratio() * get_size().width; + button->set_size(Size2(get_theme_icon("Add", "EditorIcons")->get_width(), get_size().height)); + if (is_layout_rtl()) { + if (le != nullptr) { + fit_child_in_rect(le, Rect2(Vector2(split_width, 0), Size2(split_width, get_size().height))); + } + fit_child_in_rect(chk, Rect2(Vector2(split_width - chk->get_size().x, 0), Size2(chk->get_size().x, get_size().height))); + fit_child_in_rect(button, Rect2(Vector2(0, 0), Size2(button->get_size().width, get_size().height))); + } else { + if (le != nullptr) { + fit_child_in_rect(le, Rect2(Vector2(0, 0), Size2(split_width, get_size().height))); + } + fit_child_in_rect(chk, Rect2(Vector2(split_width, 0), Size2(chk->get_size().x, get_size().height))); + fit_child_in_rect(button, Rect2(Vector2(get_size().width - button->get_size().width, 0), Size2(button->get_size().width, get_size().height))); + } + update(); + } + if (p_what == NOTIFICATION_DRAW) { + int split_width = get_name_split_ratio() * get_size().width; + Color dark_color = get_theme_color("dark_color_2", "Editor"); + if (is_layout_rtl()) { + draw_rect(Rect2(Vector2(0, 0), Size2(split_width, get_size().height)), dark_color); + } else { + draw_rect(Rect2(Vector2(split_width, 0), Size2(split_width, get_size().height)), dark_color); + } + } + if (p_what == NOTIFICATION_THEME_CHANGED) { + if (le != nullptr) { + button->set_icon(get_theme_icon("Add", "EditorIcons")); + } else { + button->set_icon(get_theme_icon("Remove", "EditorIcons")); + } + queue_sort(); + } + if (p_what == NOTIFICATION_RESIZED) { + queue_sort(); + } +} + +void FontDataEditor::update_property() { + if (le == nullptr) { + bool c = get_edited_object()->get(get_edited_property()); + chk->set_pressed(c); + chk->set_disabled(is_read_only()); + } +} + +Size2 FontDataEditor::get_minimum_size() const { + return Size2(0, 60); +} + +void FontDataEditor::_bind_methods() { +} + +void FontDataEditor::init_lang_add() { + le = memnew(LineEdit); + le->set_placeholder("Language code"); + le->set_custom_minimum_size(Size2(get_size().width / 2, 0)); + le->set_editable(true); + add_child(le); + + button->set_icon(get_theme_icon("Add", "EditorIcons")); + button->connect("pressed", callable_mp(this, &FontDataEditor::add_lang)); +} + +void FontDataEditor::init_lang_edit() { + button->set_icon(get_theme_icon("Remove", "EditorIcons")); + button->connect("pressed", callable_mp(this, &FontDataEditor::remove_lang)); + chk->connect("toggled", callable_mp(this, &FontDataEditor::toggle_lang)); +} + +void FontDataEditor::init_script_add() { + le = memnew(LineEdit); + le->set_placeholder("Script code"); + le->set_custom_minimum_size(Size2(get_size().width / 2, 0)); + le->set_editable(true); + add_child(le); + + button->set_icon(get_theme_icon("Add", "EditorIcons")); + button->connect("pressed", callable_mp(this, &FontDataEditor::add_script)); +} + +void FontDataEditor::init_script_edit() { + button->set_icon(get_theme_icon("Remove", "EditorIcons")); + button->connect("pressed", callable_mp(this, &FontDataEditor::remove_script)); + chk->connect("toggled", callable_mp(this, &FontDataEditor::toggle_script)); +} + +void FontDataEditor::add_lang() { + FontData *fd = Object::cast_to<FontData>(get_edited_object()); + if (fd != nullptr && !le->get_text().empty()) { + fd->set_language_support_override(le->get_text(), chk->is_pressed()); + le->set_text(""); + chk->set_pressed(false); + } +} + +void FontDataEditor::add_script() { + FontData *fd = Object::cast_to<FontData>(get_edited_object()); + if (fd != nullptr && le->get_text().length() == 4) { + fd->set_script_support_override(le->get_text(), chk->is_pressed()); + le->set_text(""); + chk->set_pressed(false); + } +} + +void FontDataEditor::toggle_lang(bool p_pressed) { + FontData *fd = Object::cast_to<FontData>(get_edited_object()); + if (fd != nullptr) { + String lang = String(get_edited_property()).replace("language_support_override/", ""); + fd->set_language_support_override(lang, p_pressed); + } +} + +void FontDataEditor::toggle_script(bool p_pressed) { + FontData *fd = Object::cast_to<FontData>(get_edited_object()); + if (fd != nullptr) { + String script = String(get_edited_property()).replace("script_support_override/", ""); + fd->set_script_support_override(script, p_pressed); + } +} + +void FontDataEditor::remove_lang() { + FontData *fd = Object::cast_to<FontData>(get_edited_object()); + if (fd != nullptr) { + String lang = String(get_edited_property()).replace("language_support_override/", ""); + fd->remove_language_support_override(lang); + } +} + +void FontDataEditor::remove_script() { + FontData *fd = Object::cast_to<FontData>(get_edited_object()); + if (fd != nullptr) { + String script = String(get_edited_property()).replace("script_support_override/", ""); + fd->remove_script_support_override(script); + } +} + +FontDataEditor::FontDataEditor() { + chk = memnew(CheckBox); + chk->set_text(TTR("On")); + chk->set_flat(true); + add_child(chk); + + button = memnew(Button); + button->set_flat(true); + add_child(button); +} + +/*************************************************************************/ + +bool EditorInspectorPluginFont::can_handle(Object *p_object) { + return Object::cast_to<FontData>(p_object) != nullptr; +} + +void EditorInspectorPluginFont::parse_begin(Object *p_object) { + FontData *fd = Object::cast_to<FontData>(p_object); + ERR_FAIL_COND(!fd); + + FontDataPreview *editor = memnew(FontDataPreview); + editor->set_data(fd); + add_custom_control(editor); +} + +bool EditorInspectorPluginFont::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) { + if (p_path.begins_with("language_support_override/") && p_object->is_class("FontData")) { + String lang = p_path.replace("language_support_override/", ""); + + FontDataEditor *editor = memnew(FontDataEditor); + if (lang != "_new") { + editor->init_lang_edit(); + } else { + editor->init_lang_add(); + } + add_property_editor(p_path, editor); + + return true; + } + + if (p_path.begins_with("script_support_override/") && p_object->is_class("FontData")) { + String script = p_path.replace("script_support_override/", ""); + + FontDataEditor *editor = memnew(FontDataEditor); + if (script != "_new") { + editor->init_script_edit(); + } else { + editor->init_script_add(); + } + add_property_editor(p_path, editor); + + return true; + } + + return false; +} + +/*************************************************************************/ + +FontEditorPlugin::FontEditorPlugin(EditorNode *p_node) { + Ref<EditorInspectorPluginFont> fd_plugin; + fd_plugin.instance(); + EditorInspector::add_inspector_plugin(fd_plugin); +} diff --git a/editor/plugins/font_editor_plugin.h b/editor/plugins/font_editor_plugin.h new file mode 100644 index 0000000000..1d3ffc8857 --- /dev/null +++ b/editor/plugins/font_editor_plugin.h @@ -0,0 +1,111 @@ +/*************************************************************************/ +/* font_editor_plugin.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef FONT_EDITOR_PLUGIN_H +#define FONT_EDITOR_PLUGIN_H + +#include "editor/editor_node.h" +#include "editor/editor_plugin.h" +#include "scene/resources/font.h" +#include "scene/resources/text_line.h" + +class FontDataPreview : public Control { + GDCLASS(FontDataPreview, Control); + +protected: + void _notification(int p_what); + static void _bind_methods(); + + Ref<TextLine> line; + +public: + virtual Size2 get_minimum_size() const override; + + void set_data(const Ref<FontData> &p_data); + + FontDataPreview(); +}; + +/*************************************************************************/ + +class FontDataEditor : public EditorProperty { + GDCLASS(FontDataEditor, EditorProperty); + + LineEdit *le = nullptr; + CheckBox *chk = nullptr; + Button *button = nullptr; + + void toggle_lang(bool p_pressed); + void toggle_script(bool p_pressed); + void add_lang(); + void add_script(); + void remove_lang(); + void remove_script(); + +protected: + void _notification(int p_what); + + static void _bind_methods(); + +public: + virtual Size2 get_minimum_size() const override; + virtual void update_property() override; + + void init_lang_add(); + void init_lang_edit(); + void init_script_add(); + void init_script_edit(); + + FontDataEditor(); +}; + +/*************************************************************************/ + +class EditorInspectorPluginFont : public EditorInspectorPlugin { + GDCLASS(EditorInspectorPluginFont, EditorInspectorPlugin); + +public: + virtual bool can_handle(Object *p_object) override; + virtual void parse_begin(Object *p_object) override; + virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) override; +}; + +/*************************************************************************/ + +class FontEditorPlugin : public EditorPlugin { + GDCLASS(FontEditorPlugin, EditorPlugin); + +public: + FontEditorPlugin(EditorNode *p_node); + + virtual String get_name() const override { return "Font"; } +}; + +#endif // FONT_EDITOR_PLUGIN_H diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 8420faa302..fd5c4df3f3 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -138,7 +138,7 @@ void ViewportRotationControl::_draw_axis(const Axis2D &p_axis) { if (front) { String axis_name = direction == 0 ? "X" : (direction == 1 ? "Y" : "Z"); draw_circle(p_axis.screen_point, AXIS_CIRCLE_RADIUS, c); - draw_char(get_theme_font("rotation_control", "EditorFonts"), p_axis.screen_point + Vector2i(-4, 5) * EDSCALE, axis_name, "", Color(0.3, 0.3, 0.3)); + draw_char(get_theme_font("rotation_control", "EditorFonts"), p_axis.screen_point + Vector2i(-4, 5) * EDSCALE, axis_name, "", get_theme_font_size("rotation_control_size", "EditorFonts"), Color(0.3, 0.3, 0.3)); } else { draw_circle(p_axis.screen_point, AXIS_CIRCLE_RADIUS * (0.55 + (0.2 * (1.0 + p_axis.z_axis))), c); } @@ -2593,7 +2593,7 @@ void Node3DEditorViewport::_notification(int p_what) { } } -static void draw_indicator_bar(Control &surface, real_t fill, const Ref<Texture2D> icon, const Ref<Font> font, const String &text) { +static void draw_indicator_bar(Control &surface, real_t fill, const Ref<Texture2D> icon, const Ref<Font> font, int font_size, const String &text) { // Adjust bar size from control height const Vector2 surface_size = surface.get_size(); const real_t h = surface_size.y / 2.0; @@ -2613,7 +2613,7 @@ static void draw_indicator_bar(Control &surface, real_t fill, const Ref<Texture2 surface.draw_texture(icon, icon_pos); // Draw text below the bar (for speed/zoom information). - surface.draw_string(font, Vector2(icon_pos.x, icon_pos.y + icon_size.y + 16 * EDSCALE), text); + surface.draw_string(font, Vector2(icon_pos.x, icon_pos.y + icon_size.y + 16 * EDSCALE), text, HALIGN_LEFT, -1.f, font_size); } void Node3DEditorViewport::_draw() { @@ -2651,10 +2651,11 @@ void Node3DEditorViewport::_draw() { if (message_time > 0) { Ref<Font> font = get_theme_font("font", "Label"); + int font_size = get_theme_font_size("font_size", "Label"); Point2 msgpos = Point2(5, get_size().y - 20); - font->draw(ci, msgpos + Point2(1, 1), message, Color(0, 0, 0, 0.8)); - font->draw(ci, msgpos + Point2(-1, -1), message, Color(0, 0, 0, 0.8)); - font->draw(ci, msgpos, message, Color(1, 1, 1, 1)); + font->draw_string(ci, msgpos + Point2(1, 1), message, HALIGN_LEFT, -1, font_size, Color(0, 0, 0, 0.8)); + font->draw_string(ci, msgpos + Point2(-1, -1), message, HALIGN_LEFT, -1, font_size, Color(0, 0, 0, 0.8)); + font->draw_string(ci, msgpos, message, HALIGN_LEFT, -1, font_size, Color(1, 1, 1, 1)); } if (_edit.mode == TRANSFORM_ROTATE) { @@ -2717,6 +2718,7 @@ void Node3DEditorViewport::_draw() { 1.0 - logscale_t, get_theme_icon("ViewportSpeed", "EditorIcons"), get_theme_font("font", "Label"), + get_theme_font_size("font_size", "Label"), vformat("%s u/s", String::num(freelook_speed).pad_decimals(precision))); } @@ -2743,6 +2745,7 @@ void Node3DEditorViewport::_draw() { logscale_t, get_theme_icon("ViewportZoom", "EditorIcons"), get_theme_font("font", "Label"), + get_theme_font_size("font_size", "Label"), vformat("%s u", String::num(cursor.distance).pad_decimals(precision))); } } diff --git a/editor/plugins/ot_features_plugin.cpp b/editor/plugins/ot_features_plugin.cpp new file mode 100644 index 0000000000..3478148521 --- /dev/null +++ b/editor/plugins/ot_features_plugin.cpp @@ -0,0 +1,213 @@ +/*************************************************************************/ +/* ot_features_plugin.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "ot_features_plugin.h" + +#include "editor/editor_scale.h" + +void OpenTypeFeaturesEditor::_value_changed(double val) { + if (setting) { + return; + } + + emit_changed(get_edited_property(), spin->get_value()); +} + +void OpenTypeFeaturesEditor::update_property() { + double val = get_edited_object()->get(get_edited_property()); + setting = true; + spin->set_value(val); + setting = false; +} + +void OpenTypeFeaturesEditor::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + Color base = get_theme_color("accent_color", "Editor"); + + button->set_icon(get_theme_icon("Remove", "EditorIcons")); + button->set_size(get_theme_icon("Remove", "EditorIcons")->get_size()); + spin->set_custom_label_color(true, base); + } +} + +void OpenTypeFeaturesEditor::_remove_feature() { + get_edited_object()->set(get_edited_property(), -1); +} + +void OpenTypeFeaturesEditor::_bind_methods() { +} + +OpenTypeFeaturesEditor::OpenTypeFeaturesEditor() { + HBoxContainer *bc = memnew(HBoxContainer); + add_child(bc); + + spin = memnew(EditorSpinSlider); + spin->set_flat(true); + bc->add_child(spin); + add_focusable(spin); + spin->connect("value_changed", callable_mp(this, &OpenTypeFeaturesEditor::_value_changed)); + spin->set_h_size_flags(SIZE_EXPAND_FILL); + + spin->set_min(0); + spin->set_max(65536); + spin->set_step(1); + spin->set_hide_slider(false); + spin->set_allow_greater(false); + spin->set_allow_lesser(false); + + button = memnew(Button); + button->set_tooltip(RTR("Remove feature")); + button->set_flat(true); + bc->add_child(button); + + button->connect("pressed", callable_mp(this, &OpenTypeFeaturesEditor::_remove_feature)); + + setting = false; +} + +/*************************************************************************/ + +void OpenTypeFeaturesAdd::_add_feature(int p_option) { + get_edited_object()->set("opentype_features/" + TS->tag_to_name(p_option), 1); +} + +void OpenTypeFeaturesAdd::update_property() { + menu->clear(); + menu_ss->clear(); + menu_cv->clear(); + menu_cu->clear(); + bool have_ss = false; + bool have_cv = false; + bool have_cu = false; + Dictionary features = Object::cast_to<Control>(get_edited_object())->get_theme_font("font")->get_feature_list(); + for (const Variant *ftr = features.next(nullptr); ftr != nullptr; ftr = features.next(ftr)) { + String ftr_name = TS->tag_to_name(*ftr); + if (ftr_name.begins_with("stylistic_set_")) { + menu_ss->add_item(ftr_name.capitalize(), (int32_t)*ftr); + have_ss = true; + } else if (ftr_name.begins_with("character_variant_")) { + menu_cv->add_item(ftr_name.capitalize(), (int32_t)*ftr); + have_cv = true; + } else if (ftr_name.begins_with("custom_")) { + menu_cu->add_item(ftr_name.replace("custom_", ""), (int32_t)*ftr); + have_cu = true; + } else { + menu->add_item(ftr_name.capitalize(), (int32_t)*ftr); + } + } + if (have_ss) { + menu->add_submenu_item(RTR("Stylistic Sets"), "SSMenu"); + } + if (have_cv) { + menu->add_submenu_item(RTR("Character Variants"), "CVMenu"); + } + if (have_cu) { + menu->add_submenu_item(RTR("Custom"), "CUMenu"); + } +} + +void OpenTypeFeaturesAdd::_features_menu() { + Size2 size = get_size(); + menu->set_position(get_screen_position() + Size2(0, size.height * get_global_transform().get_scale().y)); + menu->popup(); +} + +void OpenTypeFeaturesAdd::_notification(int p_what) { + if (p_what == NOTIFICATION_THEME_CHANGED || p_what == NOTIFICATION_ENTER_TREE) { + set_label(""); + button->set_icon(get_theme_icon("Add", "EditorIcons")); + button->set_size(get_theme_icon("Add", "EditorIcons")->get_size()); + } +} + +void OpenTypeFeaturesAdd::_bind_methods() { +} + +OpenTypeFeaturesAdd::OpenTypeFeaturesAdd() { + menu = memnew(PopupMenu); + add_child(menu); + + menu_cv = memnew(PopupMenu); + menu_cv->set_name("CVMenu"); + menu->add_child(menu_cv); + + menu_ss = memnew(PopupMenu); + menu_ss->set_name("SSMenu"); + menu->add_child(menu_ss); + + menu_cu = memnew(PopupMenu); + menu_cu->set_name("CUMenu"); + menu->add_child(menu_cu); + + button = memnew(Button); + button->set_flat(true); + button->set_text(RTR("Add feature...")); + button->set_tooltip(RTR("Add feature...")); + add_child(button); + + button->connect("pressed", callable_mp(this, &OpenTypeFeaturesAdd::_features_menu)); + menu->connect("id_pressed", callable_mp(this, &OpenTypeFeaturesAdd::_add_feature)); + menu_cv->connect("id_pressed", callable_mp(this, &OpenTypeFeaturesAdd::_add_feature)); + menu_ss->connect("id_pressed", callable_mp(this, &OpenTypeFeaturesAdd::_add_feature)); + menu_cu->connect("id_pressed", callable_mp(this, &OpenTypeFeaturesAdd::_add_feature)); +} + +/*************************************************************************/ + +bool EditorInspectorPluginOpenTypeFeatures::can_handle(Object *p_object) { + return (Object::cast_to<Control>(p_object) != nullptr); +} + +void EditorInspectorPluginOpenTypeFeatures::parse_begin(Object *p_object) { +} + +void EditorInspectorPluginOpenTypeFeatures::parse_category(Object *p_object, const String &p_parse_category) { +} + +bool EditorInspectorPluginOpenTypeFeatures::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) { + if (p_path == "opentype_features/_new") { + OpenTypeFeaturesAdd *editor = memnew(OpenTypeFeaturesAdd); + add_property_editor(p_path, editor); + return true; + } else if (p_path.begins_with("opentype_features")) { + OpenTypeFeaturesEditor *editor = memnew(OpenTypeFeaturesEditor); + add_property_editor(p_path, editor); + return true; + } + return false; +} + +/*************************************************************************/ + +OpenTypeFeaturesEditorPlugin::OpenTypeFeaturesEditorPlugin(EditorNode *p_node) { + Ref<EditorInspectorPluginOpenTypeFeatures> ftr_plugin; + ftr_plugin.instance(); + EditorInspector::add_inspector_plugin(ftr_plugin); +} diff --git a/editor/plugins/ot_features_plugin.h b/editor/plugins/ot_features_plugin.h new file mode 100644 index 0000000000..5b5f367b24 --- /dev/null +++ b/editor/plugins/ot_features_plugin.h @@ -0,0 +1,105 @@ +/*************************************************************************/ +/* ot_features_plugin.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef OT_FEATURES_PLUGIN_H +#define OT_FEATURES_PLUGIN_H + +#include "editor/editor_node.h" +#include "editor/editor_plugin.h" +#include "editor/editor_properties.h" + +/*************************************************************************/ + +class OpenTypeFeaturesEditor : public EditorProperty { + GDCLASS(OpenTypeFeaturesEditor, EditorProperty); + EditorSpinSlider *spin; + bool setting = true; + void _value_changed(double p_val); + Button *button = nullptr; + + void _remove_feature(); + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + virtual void update_property() override; + OpenTypeFeaturesEditor(); +}; + +/*************************************************************************/ + +class OpenTypeFeaturesAdd : public EditorProperty { + GDCLASS(OpenTypeFeaturesAdd, EditorProperty); + + Button *button = nullptr; + PopupMenu *menu = nullptr; + PopupMenu *menu_ss = nullptr; + PopupMenu *menu_cv = nullptr; + PopupMenu *menu_cu = nullptr; + + void _add_feature(int p_option); + void _features_menu(); + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + virtual void update_property() override; + + OpenTypeFeaturesAdd(); +}; + +/*************************************************************************/ + +class EditorInspectorPluginOpenTypeFeatures : public EditorInspectorPlugin { + GDCLASS(EditorInspectorPluginOpenTypeFeatures, EditorInspectorPlugin); + +public: + virtual bool can_handle(Object *p_object) override; + virtual void parse_begin(Object *p_object) override; + virtual void parse_category(Object *p_object, const String &p_parse_category) override; + virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) override; +}; + +/*************************************************************************/ + +class OpenTypeFeaturesEditorPlugin : public EditorPlugin { + GDCLASS(OpenTypeFeaturesEditorPlugin, EditorPlugin); + +public: + OpenTypeFeaturesEditorPlugin(EditorNode *p_node); + + virtual String get_name() const override { return "OpenTypeFeatures"; } +}; + +#endif // OT_FEATURES_PLUGIN_H diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 8dd7d6d6e2..e7b6959ac6 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -1485,12 +1485,19 @@ void ScriptEditor::_notification(int p_what) { EditorFileSystem::get_singleton()->connect("filesystem_changed", callable_mp(this, &ScriptEditor::_filesystem_changed)); [[fallthrough]]; } + case NOTIFICATION_TRANSLATION_CHANGED: + case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: case NOTIFICATION_THEME_CHANGED: { help_search->set_icon(get_theme_icon("HelpSearch", "EditorIcons")); site_search->set_icon(get_theme_icon("Instance", "EditorIcons")); - script_forward->set_icon(get_theme_icon("Forward", "EditorIcons")); - script_back->set_icon(get_theme_icon("Back", "EditorIcons")); + if (is_layout_rtl()) { + script_forward->set_icon(get_theme_icon("Back", "EditorIcons")); + script_back->set_icon(get_theme_icon("Forward", "EditorIcons")); + } else { + script_forward->set_icon(get_theme_icon("Forward", "EditorIcons")); + script_back->set_icon(get_theme_icon("Back", "EditorIcons")); + } members_overview_alphabeta_sort_button->set_icon(get_theme_icon("Sort", "EditorIcons")); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 7feb7cb3d3..8cf22b3aa0 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -1697,6 +1697,8 @@ void ScriptTextEditor::_enable_code_editor() { 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->add_theme_font_size_override( + "normal_font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size("main_size", "EditorFonts")); warnings_panel->connect("meta_clicked", callable_mp(this, &ScriptTextEditor::_warning_clicked)); add_child(context_menu); diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp index 52da8dea19..d662714752 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_3d_editor_plugin.cpp @@ -114,10 +114,11 @@ void BoneTransformEditor::_notification(int p_what) { } case NOTIFICATION_SORT_CHILDREN: { const Ref<Font> font = get_theme_font("font", "Tree"); + int font_size = get_theme_font_size("font_size", "Tree"); Point2 buffer; buffer.x += get_theme_constant("inspector_margin", "Editor"); - buffer.y += font->get_height(); + buffer.y += font->get_height(font_size); buffer.y += get_theme_constant("vseparation", "Tree"); const float vector_height = translation_property->get_size().y; diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp index f8facb0fd5..9b760c0e50 100644 --- a/editor/plugins/texture_editor_plugin.cpp +++ b/editor/plugins/texture_editor_plugin.cpp @@ -79,6 +79,7 @@ void TextureEditor::_notification(int p_what) { draw_texture_rect(texture, Rect2(ofs_x, ofs_y, tex_width, tex_height)); Ref<Font> font = get_theme_font("font", "Label"); + int font_size = get_theme_font_size("font_size", "Label"); String format; if (Object::cast_to<ImageTexture>(*texture)) { @@ -90,16 +91,16 @@ void TextureEditor::_notification(int p_what) { } String text = itos(texture->get_width()) + "x" + itos(texture->get_height()) + " " + format; - Size2 rect = font->get_string_size(text); + Size2 rect = font->get_string_size(text, font_size); - Vector2 draw_from = size - rect + Size2(-2, font->get_ascent() - 2); + Vector2 draw_from = size - rect + Size2(-2, font->get_ascent(font_size) - 2); if (draw_from.x < 0) { draw_from.x = 0; } - draw_string(font, draw_from + Vector2(2, 2), text, Color(0, 0, 0, 0.5), size.width); - draw_string(font, draw_from - Vector2(2, 2), text, Color(0, 0, 0, 0.5), size.width); - draw_string(font, draw_from, text, Color(1, 1, 1, 1), size.width); + draw_string(font, draw_from + Vector2(2, 2), text, HALIGN_LEFT, size.width, font_size, Color(0, 0, 0, 0.5)); + draw_string(font, draw_from - Vector2(2, 2), text, HALIGN_LEFT, size.width, font_size, Color(0, 0, 0, 0.5)); + draw_string(font, draw_from, text, HALIGN_LEFT, size.width, font_size, Color(1, 1, 1, 1)); } } diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index 932ded6938..8ab82b63c3 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -78,9 +78,12 @@ void ThemeEditor::_name_menu_about_to_show() { Theme::get_default()->get_font_list(fromtype, &names); break; case 3: - Theme::get_default()->get_color_list(fromtype, &names); + Theme::get_default()->get_font_size_list(fromtype, &names); break; case 4: + Theme::get_default()->get_color_list(fromtype, &names); + break; + case 5: Theme::get_default()->get_constant_list(fromtype, &names); break; } @@ -88,6 +91,7 @@ void ThemeEditor::_name_menu_about_to_show() { theme->get_icon_list(fromtype, &names); theme->get_stylebox_list(fromtype, &names); theme->get_font_list(fromtype, &names); + theme->get_font_size_list(fromtype, &names); theme->get_color_list(fromtype, &names); theme->get_constant_list(fromtype, &names); } @@ -120,6 +124,7 @@ struct _TECategory { Set<RefItem<StyleBox>> stylebox_items; Set<RefItem<Font>> font_items; + Set<Item<int>> font_size_items; Set<RefItem<Texture2D>> icon_items; Set<Item<Color>> color_items; @@ -160,6 +165,15 @@ void ThemeEditor::_save_template_cbk(String fname) { tc.font_items.insert(it); } + List<StringName> font_size_list; + Theme::get_default()->get_font_size_list(E->key(), &font_list); + for (List<StringName>::Element *F = font_size_list.front(); F; F = F->next()) { + _TECategory::Item<int> it; + it.name = F->get(); + it.item = Theme::get_default()->get_font_size(F->get(), E->key()); + tc.font_size_items.insert(it); + } + List<StringName> icon_list; Theme::get_default()->get_icon_list(E->key(), &icon_list); for (List<StringName>::Element *F = icon_list.front(); F; F = F->next()) { @@ -284,6 +298,14 @@ void ThemeEditor::_save_template_cbk(String fname) { file->store_line(E->key() + "." + F->get().name + " = default"); } + if (tc.font_size_items.size()) { + file->store_line("\n; Font Size Items:\n"); + } + + for (Set<_TECategory::Item<int>>::Element *F = tc.font_size_items.front(); F; F = F->next()) { + file->store_line(E->key() + "." + F->get().name + " = default"); + } + if (tc.icon_items.size()) { file->store_line("\n; Icon Items:\n"); } @@ -327,9 +349,12 @@ void ThemeEditor::_dialog_cbk() { theme->set_font(name_edit->get_text(), type_edit->get_text(), Ref<Font>()); break; case 3: - theme->set_color(name_edit->get_text(), type_edit->get_text(), Color()); + theme->set_font_size(name_edit->get_text(), type_edit->get_text(), -1); break; case 4: + theme->set_color(name_edit->get_text(), type_edit->get_text(), Color()); + break; + case 5: theme->set_constant(name_edit->get_text(), type_edit->get_text(), 0); break; } @@ -362,6 +387,13 @@ void ThemeEditor::_dialog_cbk() { } { names.clear(); + Theme::get_default()->get_font_size_list(fromtype, &names); + for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + theme->set_font_size(E->get(), fromtype, Theme::get_default()->get_font_size(E->get(), fromtype)); + } + } + { + names.clear(); Theme::get_default()->get_color_list(fromtype, &names); for (List<StringName>::Element *E = names.front(); E; E = E->next()) { theme->set_color(E->get(), fromtype, Theme::get_default()->get_color(E->get(), fromtype)); @@ -387,9 +419,12 @@ void ThemeEditor::_dialog_cbk() { theme->clear_font(name_edit->get_text(), type_edit->get_text()); break; case 3: - theme->clear_color(name_edit->get_text(), type_edit->get_text()); + theme->clear_font_size(name_edit->get_text(), type_edit->get_text()); break; case 4: + theme->clear_color(name_edit->get_text(), type_edit->get_text()); + break; + case 5: theme->clear_constant(name_edit->get_text(), type_edit->get_text()); break; } @@ -422,6 +457,13 @@ void ThemeEditor::_dialog_cbk() { } { names.clear(); + Theme::get_default()->get_font_size_list(fromtype, &names); + for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + theme->clear_font_size(E->get(), fromtype); + } + } + { + names.clear(); Theme::get_default()->get_color_list(fromtype, &names); for (List<StringName>::Element *E = names.front(); E; E = E->next()) { theme->clear_color(E->get(), fromtype); @@ -486,6 +528,13 @@ void ThemeEditor::_theme_menu_cbk(int p_option) { theme->set_font(E->get(), type, Ref<Font>()); } + List<StringName> font_sizes; + base_theme->get_font_size_list(type, &font_sizes); + + for (List<StringName>::Element *E = font_sizes.front(); E; E = E->next()) { + theme->set_font_size(E->get(), type, base_theme->get_font_size(E->get(), type)); + } + List<StringName> colors; base_theme->get_color_list(type, &colors); @@ -860,6 +909,7 @@ ThemeEditor::ThemeEditor() { type_select->add_item(TTR("Icon")); type_select->add_item(TTR("Style")); type_select->add_item(TTR("Font")); + type_select->add_item(TTR("Font Size")); type_select->add_item(TTR("Color")); type_select->add_item(TTR("Constant")); diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index 7b516175b2..ceec3f1830 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -2165,6 +2165,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { tile_info->set_modulate(Color(1, 1, 1, 0.8)); tile_info->set_mouse_filter(MOUSE_FILTER_IGNORE); tile_info->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font("main", "EditorFonts")); + tile_info->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size("main_size", "EditorFonts")); // The tile info is only displayed after a tile has been hovered. tile_info->hide(); CanvasItemEditor::get_singleton()->add_control_to_info_overlay(tile_info); diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index 714f38bd56..9dc01d83d7 100644 --- a/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp @@ -279,6 +279,8 @@ void TileSetEditor::_notification(int p_what) { case NOTIFICATION_READY: { add_theme_constant_override("autohide", 1); // Fixes the dragger always showing up. } break; + case NOTIFICATION_TRANSLATION_CHANGED: + case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { tileset_toolbar_buttons[TOOL_TILESET_ADD_TEXTURE]->set_icon(get_theme_icon("ToolAddNode", "EditorIcons")); @@ -296,8 +298,13 @@ void TileSetEditor::_notification(int p_what) { tools[BITMASK_CLEAR]->set_icon(get_theme_icon("Clear", "EditorIcons")); tools[SHAPE_NEW_POLYGON]->set_icon(get_theme_icon("CollisionPolygon2D", "EditorIcons")); tools[SHAPE_NEW_RECTANGLE]->set_icon(get_theme_icon("CollisionShape2D", "EditorIcons")); - tools[SELECT_PREVIOUS]->set_icon(get_theme_icon("ArrowLeft", "EditorIcons")); - tools[SELECT_NEXT]->set_icon(get_theme_icon("ArrowRight", "EditorIcons")); + if (is_layout_rtl()) { + tools[SELECT_PREVIOUS]->set_icon(get_theme_icon("ArrowLeft", "EditorIcons")); + tools[SELECT_NEXT]->set_icon(get_theme_icon("ArrowRight", "EditorIcons")); + } else { + tools[SELECT_PREVIOUS]->set_icon(get_theme_icon("ArrowRight", "EditorIcons")); + tools[SELECT_NEXT]->set_icon(get_theme_icon("ArrowLeft", "EditorIcons")); + } tools[SHAPE_DELETE]->set_icon(get_theme_icon("Remove", "EditorIcons")); tools[SHAPE_KEEP_INSIDE_TILE]->set_icon(get_theme_icon("Snap", "EditorIcons")); tools[TOOL_GRID_SNAP]->set_icon(get_theme_icon("SnapGrid", "EditorIcons")); @@ -1173,11 +1180,12 @@ void TileSetEditor::_on_workspace_overlay_draw() { } String tile_id_name = String::num(t_id, 0) + ": " + tileset->tile_get_name(t_id); Ref<Font> font = get_theme_font("font", "Label"); - region.set_size(font->get_string_size(tile_id_name)); + int font_size = get_theme_font_size("font_size", "Label"); + region.set_size(font->get_string_size(tile_id_name, font_size)); workspace_overlay->draw_rect(region, c); region.position.y += region.size.y - 2; c = Color(0.1, 0.1, 0.1); - workspace_overlay->draw_string(font, region.position, tile_id_name, c); + workspace_overlay->draw_string(font, region.position, tile_id_name, HALIGN_LEFT, -1, font_size, c); } delete tiles; } diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index f3fc22b313..3116885065 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -713,6 +713,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { } expression_box->add_theme_font_override("font", VisualShaderEditor::get_singleton()->get_theme_font("expression", "EditorFonts")); + expression_box->add_theme_font_size_override("font_size", VisualShaderEditor::get_singleton()->get_theme_font_size("expression_size", "EditorFonts")); expression_box->add_theme_color_override("font_color", text_color); expression_syntax_highlighter->set_number_color(number_color); expression_syntax_highlighter->set_symbol_color(symbol_color); @@ -2237,6 +2238,7 @@ void VisualShaderEditor::_notification(int p_what) { } preview_text->add_theme_font_override("font", get_theme_font("expression", "EditorFonts")); + preview_text->add_theme_font_size_override("font_size", get_theme_font_size("expression_size", "EditorFonts")); preview_text->add_theme_color_override("font_color", text_color); syntax_highlighter->set_number_color(number_color); syntax_highlighter->set_symbol_color(symbol_color); @@ -2247,6 +2249,7 @@ void VisualShaderEditor::_notification(int p_what) { syntax_highlighter->add_color_region("//", "", comment_color, true); error_text->add_theme_font_override("font", get_theme_font("status_source", "EditorFonts")); + error_text->add_theme_font_size_override("font_size", get_theme_font_size("status_source_size", "EditorFonts")); error_text->add_theme_color_override("font_color", get_theme_color("error_color", "Editor")); } diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index f26d44d75a..bbe6a73f8f 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -804,6 +804,7 @@ public: project_path = memnew(LineEdit); project_path->set_h_size_flags(Control::SIZE_EXPAND_FILL); + project_path->set_structured_text_bidi_override(Control::STRUCTURED_TEXT_FILE); pphb->add_child(project_path); install_path_container = memnew(VBoxContainer); @@ -818,6 +819,7 @@ public: install_path = memnew(LineEdit); install_path->set_h_size_flags(Control::SIZE_EXPAND_FILL); + install_path->set_structured_text_bidi_override(Control::STRUCTURED_TEXT_FILE); iphb->add_child(install_path); // status icon @@ -956,7 +958,7 @@ public: } break; case NOTIFICATION_DRAW: { if (hover) { - draw_style_box(get_theme_stylebox("hover", "Tree"), Rect2(Point2(), get_size() - Size2(10, 0) * EDSCALE)); + draw_style_box(get_theme_stylebox("hover", "Tree"), Rect2(Point2(), get_size())); } } break; } @@ -1367,6 +1369,7 @@ void ProjectList::create_project_item_control(int p_index) { vb->add_child(ec); Label *title = memnew(Label(!item.missing ? item.project_name : TTR("Missing Project"))); title->add_theme_font_override("font", get_theme_font("title", "EditorFonts")); + title->add_theme_font_size_override("font_size", get_theme_font_size("title_size", "EditorFonts")); title->add_theme_color_override("font_color", font_color); title->set_clip_text(true); vb->add_child(title); @@ -1393,6 +1396,7 @@ void ProjectList::create_project_item_control(int p_index) { } Label *fpath = memnew(Label(item.path)); + fpath->set_structured_text_bidi_override(Control::STRUCTURED_TEXT_FILE); path_hb->add_child(fpath); fpath->set_h_size_flags(Control::SIZE_EXPAND_FILL); fpath->set_modulate(Color(1, 1, 1, 0.5)); @@ -1723,12 +1727,16 @@ void ProjectList::erase_selected_projects() { void ProjectList::_panel_draw(Node *p_hb) { Control *hb = Object::cast_to<Control>(p_hb); - hb->draw_line(Point2(0, hb->get_size().y + 1), Point2(hb->get_size().x - 10, hb->get_size().y + 1), get_theme_color("guide_color", "Tree")); + if (is_layout_rtl() && get_v_scrollbar()->is_visible_in_tree()) { + hb->draw_line(Point2(get_v_scrollbar()->get_minimum_size().x, hb->get_size().y + 1), Point2(hb->get_size().x, hb->get_size().y + 1), get_theme_color("guide_color", "Tree")); + } else { + hb->draw_line(Point2(0, hb->get_size().y + 1), Point2(hb->get_size().x, hb->get_size().y + 1), get_theme_color("guide_color", "Tree")); + } String key = _projects[p_hb->get_index()].project_key; if (_selected_project_keys.has(key)) { - hb->draw_style_box(get_theme_stylebox("selected", "Tree"), Rect2(Point2(), hb->get_size() - Size2(10, 0) * EDSCALE)); + hb->draw_style_box(get_theme_stylebox("selected", "Tree"), Rect2(Point2(), hb->get_size())); } } @@ -1814,6 +1822,11 @@ void ProjectList::_bind_methods() { void ProjectManager::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_TRANSLATION_CHANGED: + case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: { + settings_hb->set_anchors_and_margins_preset(Control::PRESET_TOP_RIGHT); + update(); + } break; case NOTIFICATION_ENTER_TREE: { search_box->set_right_icon(get_theme_icon("Search", "EditorIcons")); search_box->set_clear_button_enabled(true); @@ -2417,10 +2430,13 @@ ProjectManager::ProjectManager() { DisplayServer::get_singleton()->window_set_size(DisplayServer::get_singleton()->window_get_size() * MAX(1, EDSCALE)); } - String cp; - cp += 0xA9; // TRANSLATORS: This refers to the application where users manage their Godot projects. - DisplayServer::get_singleton()->window_set_title(VERSION_NAME + String(" - ") + TTR("Project Manager") + " - " + cp + " 2007-2020 Juan Linietsky, Ariel Manzur & Godot Contributors"); + if (TS->is_locale_right_to_left(TranslationServer::get_singleton()->get_tool_locale())) { + // For RTL languages, embed translated part of the title (using control characters) to ensure correct order. + DisplayServer::get_singleton()->window_set_title(VERSION_NAME + String(" - ") + String::chr(0x202B) + TTR("Project Manager") + String::chr(0x202C) + String::chr(0x200E) + " - " + String::chr(0xA9) + " 2007-2020 Juan Linietsky, Ariel Manzur & Godot Contributors"); + } else { + DisplayServer::get_singleton()->window_set_title(VERSION_NAME + String(" - ") + TTR("Project Manager") + " - " + String::chr(0xA9) + " 2007-2020 Juan Linietsky, Ariel Manzur & Godot Contributors"); + } FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files")); @@ -2552,9 +2568,10 @@ ProjectManager::ProjectManager() { { // Version info and language options - HBoxContainer *settings_hb = memnew(HBoxContainer); + settings_hb = memnew(HBoxContainer); settings_hb->set_alignment(BoxContainer::ALIGN_END); settings_hb->set_h_grow_direction(Control::GROW_DIRECTION_BEGIN); + settings_hb->set_anchors_and_margins_preset(Control::PRESET_TOP_RIGHT); Label *version_label = memnew(Label); String hash = String(VERSION_HASH); @@ -2598,7 +2615,6 @@ ProjectManager::ProjectManager() { settings_hb->add_child(language_btn); center_box->add_child(settings_hb); - settings_hb->set_anchors_and_margins_preset(Control::PRESET_TOP_RIGHT); } if (StreamPeerSSL::is_available()) { diff --git a/editor/project_manager.h b/editor/project_manager.h index 212d693f1d..0a8a86eb4f 100644 --- a/editor/project_manager.h +++ b/editor/project_manager.h @@ -74,6 +74,8 @@ class ProjectManager : public Control { ConfirmationDialog *ask_update_settings; ConfirmationDialog *open_templates; + HBoxContainer *settings_hb; + AcceptDialog *run_error_diag; AcceptDialog *dialog_error; ProjectDialog *npdialog; diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index 1e4ed0c552..847af0f2c2 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -501,7 +501,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: List<String> names; names.push_back("value:"); config_value_editors(1, 1, 50, names); - value_editor[0]->set_text(String::num(v)); + value_editor[0]->set_text(TS->format_number(String::num(v))); } } break; @@ -1389,6 +1389,7 @@ void CustomPropertyEditor::_draw_easing() { bool flip = hint_text == "attenuation"; Ref<Font> f = easing_draw->get_theme_font("font", "Label"); + int font_size = easing_draw->get_theme_font_size("font_size", "Label"); Color color = easing_draw->get_theme_color("font_color", "Label"); for (int i = 1; i <= points; i++) { @@ -1406,7 +1407,7 @@ void CustomPropertyEditor::_draw_easing() { prev = h; } - f->draw(ci, Point2(10, 10 + f->get_ascent()), String::num(exp, 2), color); + f->draw_string(ci, Point2(10, 10 + f->get_ascent(font_size)), String::num(exp, 2), HALIGN_LEFT, -1, font_size, color); } void CustomPropertyEditor::_text_edit_changed() { @@ -1432,7 +1433,7 @@ void CustomPropertyEditor::_modified(String p_string) { updating = true; switch (type) { case Variant::INT: { - String text = value_editor[0]->get_text(); + String text = TS->parse_number(value_editor[0]->get_text()); Ref<Expression> expr; expr.instance(); Error err = expr->parse(text); @@ -1447,7 +1448,7 @@ void CustomPropertyEditor::_modified(String p_string) { } break; case Variant::FLOAT: { if (hint != PROPERTY_HINT_EXP_EASING) { - String text = value_editor[0]->get_text(); + String text = TS->parse_number(value_editor[0]->get_text()); v = _parse_real_expression(text); emit_signal("variant_changed"); } diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index ec225c3c38..d946a08fbf 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -1990,6 +1990,9 @@ void SceneTreeDock::_do_create(Node *p_parent) { if (ms.height < 4) { ms.height = 40; } + if (ct->is_layout_rtl()) { + ct->set_position(ct->get_position() - Vector2(ms.x, 0)); + } ct->set_size(ms); } } diff --git a/editor/shader_globals_editor.cpp b/editor/shader_globals_editor.cpp index 915aec6d9a..8345c49a92 100644 --- a/editor/shader_globals_editor.cpp +++ b/editor/shader_globals_editor.cpp @@ -483,5 +483,8 @@ ShaderGlobalsEditor::ShaderGlobalsEditor() { } ShaderGlobalsEditor::~ShaderGlobalsEditor() { + if (is_visible_in_tree()) { + inspector->edit(nullptr); + } memdelete(interface); } |