diff --git a/core/core_constants.cpp b/core/core_constants.cpp index 57ea10c0746..db22a9ecf6d 100644 --- a/core/core_constants.cpp +++ b/core/core_constants.cpp @@ -128,6 +128,7 @@ void register_global_constants() { BIND_CORE_ENUM_CONSTANT(HALIGN_LEFT); BIND_CORE_ENUM_CONSTANT(HALIGN_CENTER); BIND_CORE_ENUM_CONSTANT(HALIGN_RIGHT); + BIND_CORE_ENUM_CONSTANT(HALIGN_FILL); BIND_CORE_ENUM_CONSTANT(VALIGN_TOP); BIND_CORE_ENUM_CONSTANT(VALIGN_CENTER); diff --git a/core/math/math_defs.h b/core/math/math_defs.h index 5192722839d..4d97f72ebf5 100644 --- a/core/math/math_defs.h +++ b/core/math/math_defs.h @@ -73,7 +73,8 @@ enum Orientation { enum HAlign { HALIGN_LEFT, HALIGN_CENTER, - HALIGN_RIGHT + HALIGN_RIGHT, + HALIGN_FILL, }; enum VAlign { diff --git a/core/string/translation.cpp b/core/string/translation.cpp index df8a26e5ce4..7b8c28e2e2d 100644 --- a/core/string/translation.cpp +++ b/core/string/translation.cpp @@ -34,6 +34,11 @@ #include "core/io/resource_loader.h" #include "core/os/os.h" +#ifdef TOOLS_ENABLED +#include "editor/editor_settings.h" +#include "main/main.h" +#endif + // ISO 639-1 language codes, with the addition of glibc locales with their // regional identifiers. This list must match the language names (in English) // of locale_names. @@ -1214,6 +1219,22 @@ void TranslationServer::set_tool_translation(const Ref &p_translati tool_translation = p_translation; } +Ref TranslationServer::get_tool_translation() const { + return tool_translation; +} + +String TranslationServer::get_tool_locale() { +#ifdef TOOLS_ENABLED + if (TranslationServer::get_singleton()->get_tool_translation().is_valid() && (Engine::get_singleton()->is_editor_hint() || Main::is_project_manager())) { + return tool_translation->get_locale(); + } else { +#else + { +#endif + return get_locale(); + } +} + StringName TranslationServer::tool_translate(const StringName &p_message, const StringName &p_context) const { if (tool_translation.is_valid()) { StringName r = tool_translation->get_message(p_message, p_context); diff --git a/core/string/translation.h b/core/string/translation.h index 8d34f7997e4..c7ffe4d065f 100644 --- a/core/string/translation.h +++ b/core/string/translation.h @@ -110,7 +110,9 @@ public: static String standardize_locale(const String &p_locale); static String get_language_code(const String &p_locale); + String get_tool_locale(); void set_tool_translation(const Ref &p_translation); + Ref get_tool_translation() const; StringName tool_translate(const StringName &p_message, const StringName &p_context = "") const; StringName tool_translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context = "") const; void set_doc_translation(const Ref &p_translation); diff --git a/core/templates/hashfuncs.h b/core/templates/hashfuncs.h index 86bb1b5228e..1ed9ab19876 100644 --- a/core/templates/hashfuncs.h +++ b/core/templates/hashfuncs.h @@ -114,6 +114,24 @@ static inline uint32_t make_uint32_t(T p_in) { return _u._u32; } +static inline uint64_t hash_djb2_one_float_64(double p_in, uint64_t p_prev = 5381) { + union { + double d; + uint64_t i; + } u; + + // Normalize +/- 0.0 and NaN values so they hash the same. + if (p_in == 0.0f) { + u.d = 0.0; + } else if (Math::is_nan(p_in)) { + u.d = Math_NAN; + } else { + u.d = p_in; + } + + return ((p_prev << 5) + p_prev) + u.i; +} + static inline uint64_t hash_djb2_one_64(uint64_t p_in, uint64_t p_prev = 5381) { return ((p_prev << 5) + p_prev) + p_in; } diff --git a/doc/classes/BitmapFont.xml b/doc/classes/BitmapFont.xml deleted file mode 100644 index 87cffdaca06..00000000000 --- a/doc/classes/BitmapFont.xml +++ /dev/null @@ -1,112 +0,0 @@ - - - - Renders text using fonts under the [url=https://www.angelcode.com/products/bmfont/]BMFont[/url] format. - Handles files with the [code].fnt[/code] extension. - - - Renders text using [code]*.fnt[/code] fonts containing texture atlases. Supports distance fields. For using vector font files like TTF directly, see [DynamicFont]. - - - - - - - - - - - - - - - - - - - Adds a character to the font, where [code]character[/code] is the Unicode value, [code]texture[/code] is the texture index, [code]rect[/code] is the region in the texture (in pixels!), [code]align[/code] is the (optional) alignment for the character and [code]advance[/code] is the (optional) advance. - - - - - - - - - - - - - Adds a kerning pair to the [BitmapFont] as a difference. Kerning pairs are special cases where a typeface advance is determined by the next character. - - - - - - - - - Adds a texture to the [BitmapFont]. - - - - - - - Clears all the font data and settings. - - - - - - - - - Creates a BitmapFont from the [code]*.fnt[/code] file at [code]path[/code]. - - - - - - - - - - - Returns a kerning pair as a difference. - - - - - - - - - Returns the font atlas texture at index [code]idx[/code]. - - - - - - - Returns the number of textures in the BitmapFont atlas. - - - - - - Ascent (number of pixels above the baseline). - - - If [code]true[/code], distance field hint is enabled. - - - The fallback font. - - - Total font height (ascent plus descent) in pixels. - - - - - diff --git a/doc/classes/DynamicFontData.xml b/doc/classes/DynamicFontData.xml deleted file mode 100644 index 45585f17e00..00000000000 --- a/doc/classes/DynamicFontData.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - Used with [DynamicFont] to describe the location of a font file. - - - Used with [DynamicFont] to describe the location of a vector font file for dynamic rendering at runtime. - - - https://godotengine.org/asset-library/asset/676 - - - - - - If [code]true[/code], the font is rendered with anti-aliasing. This property applies both to the main font and its outline (if it has one). - - - The path to the vector font file. - - - The font hinting mode used by FreeType. See [enum Hinting] for options. - - - - - Disables font hinting (smoother but less crisp). - - - Use the light font hinting mode. - - - Use the default font hinting mode (crisper but less smooth). - - - diff --git a/doc/classes/Font.xml b/doc/classes/Font.xml deleted file mode 100644 index f49fbf0d2a4..00000000000 --- a/doc/classes/Font.xml +++ /dev/null @@ -1,128 +0,0 @@ - - - - Internationalized font and text drawing support. - - - Font contains a Unicode-compatible character set, as well as the ability to draw it with variable width, ascent, descent and kerning. For creating fonts from TTF files (or other font formats), see the editor support for fonts. - [b]Note:[/b] If a DynamicFont doesn't contain a character used in a string, the character in question will be replaced with codepoint [code]0xfffd[/code] if it's available in the DynamicFont. If this replacement character isn't available in the DynamicFont, the character will be hidden without displaying any replacement character in the string. - [b]Note:[/b] If a BitmapFont doesn't contain a character used in a string, the character in question will be hidden without displaying any replacement character in the string. - - - - - - - - - - - - - - - - - - - - - Draw [code]string[/code] into a canvas item using the font at a given position, with [code]modulate[/code] color, and optionally clipping the width. [code]position[/code] specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. - See also [method CanvasItem.draw_string]. - - - - - - - - - - - - - - - - - - - Draw character [code]char[/code] into a canvas item using the font at a given position, with [code]modulate[/code] color, and optionally kerning if [code]next[/code] is passed. clipping the width. [code]position[/code] specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. The width used by the character is returned, making this function useful for drawing strings character by character. - - - - - - - Returns the font ascent (number of pixels above the baseline). - - - - - - - - - - - Returns the size of a character, optionally taking kerning into account if the next character is provided. - - - - - - - Returns the font descent (number of pixels below the baseline). - - - - - - - Returns the total font height (ascent plus descent) in pixels. - - - - - - - - - Returns the size of a string, taking kerning and advance into account. - - - - - - - - - - - Returns the size that the string would have with word wrapping enabled with a fixed [code]width[/code]. - - - - - - - Returns [code]true[/code] if the font has an outline. - - - - - - - - - - - - - After editing a font (changing size, ascent, char rects, etc.). Call this function to propagate changes to controls that might use it. - - - - - - diff --git a/doc/classes/Label.xml b/doc/classes/Label.xml index 570d7f075bf..01719ecbfd7 100644 --- a/doc/classes/Label.xml +++ b/doc/classes/Label.xml @@ -111,7 +111,7 @@ [Color] of the text's shadow effect. - The tint of [Font]'s outline. See [member DynamicFont.outline_color]. + The tint of [Font]'s outline. Vertical space between lines in multiline [Label]. diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp index 17b03fd4797..22adf4f2671 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 = 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 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 6f30d5a492d..d4d4c7d8099 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 = 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 &p_animation) { Size2 AnimationTimelineEdit::get_minimum_size() const { Size2 ms = add_track->get_minimum_size(); Ref 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 = get_theme_font("font", "Label"); + int font_size = get_theme_font_size("font_size", "Label"); Color color = get_theme_color("font_color", "Label"); Ref 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 = 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 texture = get_theme_icon("Object", "EditorIcons"); Ref 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 = 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 &p_type, co Size2 AnimationTrackEditGroup::get_minimum_size() const { Ref 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 9fc67000f90..4d962893437 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 3182bca0ebc..c4a8b310ecb 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 &p_event) { Ref magnify_gesture = p_event; if (magnify_gesture.is_valid()) { + /* Ref font = text_editor->get_theme_font("font"); if (font.is_valid()) { @@ -742,6 +743,8 @@ void CodeTextEditor::_text_editor_gui_input(const Ref &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 &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 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 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 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 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(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 &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 b38170cbf51..d8f89d440eb 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 _get_completion_icon(const ScriptCodeCompletionOption &p_option); - void _font_resize_timeout(); - bool _add_font_size(int p_delta); void _input(const Ref &event); void _text_editor_gui_input(const Ref &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 47fe2827588..44c5f83e9a0 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 graph_style_box = get_theme_stylebox("normal", "TextEdit"); Ref 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 8bd21fff5c2..930aca6e5a6 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 baeb06794a6..d7a09d6b0cb 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 = 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 8504d61d2f9..165a5c8546f 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::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::Element *E = l.front(); E; E = E->next()) { PropertyDoc pd; diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp index cbde7d593af..95802a0b9c1 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 = 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 a3deb951306..6dc0fffd925 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 = 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 = 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 69edefd75c0..f7cb5428ce3 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 EditorExportPlatform::get_option_icon(int p_index) const { Ref theme = EditorNode::get_singleton()->get_editor_theme(); ERR_FAIL_COND_V(theme.is_null(), Ref()); - 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 & 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 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 e3923a48c5e..ffdd7c7fa84 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 100c76c32b7..f5bb4921d48 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" +#include "scene/resources/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); +#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 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 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 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 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 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 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 p_theme) { @@ -96,7 +100,7 @@ void editor_register_fonts(Ref 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 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 CustomFont; + Ref 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 p_theme) { /* Custom Bold font */ String custom_font_path_bold = EditorSettings::get_singleton()->get("interface/editor/main_font_bold"); - Ref CustomFontBold; + Ref 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 p_theme) { /* Custom source code font */ String custom_font_path_source = EditorSettings::get_singleton()->get("interface/editor/code_font"); - Ref CustomFontSource; + Ref 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 p_theme) { /* Droid Sans */ - Ref DefaultFont; + Ref 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 DefaultFontBold; + Ref 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 FontFallback; + Ref 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 FontJapanese; + Ref 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 FontArabic; + Ref 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 FontHebrew; + Ref 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 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 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 FontThai; + Ref 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 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 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 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 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 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 FontHindi; + Ref 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 dfmono; + Ref 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 30aebd2b1fd..72bd2b57eb9 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 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 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 371100652ff..0c419168c03 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 = 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(get_child(i)); @@ -108,7 +109,8 @@ void EditorProperty::_notification(int p_what) { { int child_room = size.width * (1.0 - split_ratio); Ref 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 = 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 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 &p_event) { Ref 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 &p_event) { Ref 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 &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(object); @@ -744,7 +788,7 @@ void EditorProperty::_gui_input(const Ref &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 = 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 = 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 = get_theme_font("font", "Tree"); + int font_size = get_theme_font_size("font_size", "Tree"); Ref 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 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 = 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 = 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 &p_event) { Ref mb = p_event; if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { Ref 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 36b80a7dd42..10b10134860 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 6fbafc7ff3e..9c713f748e0 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 df_output_code = get_theme_font("output_source", "EditorFonts"); + Ref 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 9fcb5fff356..ff8f089c265 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 1443302f3fb..2c4e403a817 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 df = get_theme_icon("DistractionFree", "EditorIcons"); open_big_text->set_icon(df); Ref 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 = 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 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 font = memnew(DynamicFont); - font->set_font_data(res); + if (at == "Font" && ClassDB::is_parent_class(res->get_class(), "FontData")) { + Ref font = memnew(Font); + font->add_data(res); res = font; break; } diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 2cf0bed7d00..0ea112d48c0 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -262,13 +262,30 @@ void EditorSettings::_load_defaults(Ref 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 locales_to_skip = String("ar,bn,fa,he,hi,ml,si,ta,te,ur").split(","); + // Skip locales if Text server lack required features. + Vector 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 + } + + 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 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 efc966c6c44..d72510d40d1 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 &p_event) { @@ -214,10 +214,11 @@ void EditorSpinSlider::_notification(int p_what) { draw_style_box(sb, Rect2(Vector2(), get_size())); } Ref 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 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 updown2 = get_theme_icon("updown", "SpinBox"); @@ -330,9 +331,10 @@ void EditorSpinSlider::_notification(int p_what) { Size2 EditorSpinSlider::get_minimum_size() const { Ref sb = get_theme_stylebox("normal", "LineEdit"); Ref 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 expr; expr.instance(); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 768e5bccbcd..88976ed332e 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -600,12 +600,18 @@ Ref create_editor_theme(const Ref 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 create_editor_theme(const Ref 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 create_editor_theme(const Ref 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 create_editor_theme(const Ref 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 create_editor_theme(const Ref p_theme) { theme->set_stylebox("DebuggerPanel", "EditorStyles", style_panel_debugger); Ref 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 create_editor_theme(const Ref 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 style_complex_window = style_window->duplicate(); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 543546b1528..c65c796e5e8 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 c2ccbdb08ca..8d3f0eb21f6 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 = _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 4e6e2d02376..f3bad8d86d7 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 00000000000..c6de305069f --- /dev/null +++ b/editor/icons/AutoEndBackwards.svg @@ -0,0 +1 @@ + diff --git a/editor/icons/AutoPlayBackwards.svg b/editor/icons/AutoPlayBackwards.svg new file mode 100644 index 00000000000..20602ba348a --- /dev/null +++ b/editor/icons/AutoPlayBackwards.svg @@ -0,0 +1 @@ + diff --git a/editor/icons/BitmapFont.svg b/editor/icons/BitmapFont.svg deleted file mode 100644 index d3ab5f7dd7f..00000000000 --- a/editor/icons/BitmapFont.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/editor/icons/DynamicFont.svg b/editor/icons/DynamicFont.svg deleted file mode 100644 index bbaa12ea1bb..00000000000 --- a/editor/icons/DynamicFont.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/editor/icons/DynamicFontData.svg b/editor/icons/FontData.svg similarity index 100% rename from editor/icons/DynamicFontData.svg rename to editor/icons/FontData.svg diff --git a/editor/icons/GuiResizerMirrored.svg b/editor/icons/GuiResizerMirrored.svg new file mode 100644 index 00000000000..8227f5b648d --- /dev/null +++ b/editor/icons/GuiResizerMirrored.svg @@ -0,0 +1 @@ + diff --git a/editor/icons/GuiTabMirrored.svg b/editor/icons/GuiTabMirrored.svg new file mode 100644 index 00000000000..a0011a5b2dc --- /dev/null +++ b/editor/icons/GuiTabMirrored.svg @@ -0,0 +1 @@ + diff --git a/editor/icons/GuiToggleOffMirrored.svg b/editor/icons/GuiToggleOffMirrored.svg new file mode 100644 index 00000000000..d650de9cdae --- /dev/null +++ b/editor/icons/GuiToggleOffMirrored.svg @@ -0,0 +1 @@ + diff --git a/editor/icons/GuiToggleOnMirrored.svg b/editor/icons/GuiToggleOnMirrored.svg new file mode 100644 index 00000000000..7339b6efd2a --- /dev/null +++ b/editor/icons/GuiToggleOnMirrored.svg @@ -0,0 +1 @@ + diff --git a/editor/icons/GuiTreeArrowLeft.svg b/editor/icons/GuiTreeArrowLeft.svg new file mode 100644 index 00000000000..d0f7b36fab9 --- /dev/null +++ b/editor/icons/GuiTreeArrowLeft.svg @@ -0,0 +1 @@ + diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp index c88cd8ea5fb..75f89fbfb5a 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 e725ce482d3..2a21885c4cd 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 3c077d9c77e..43b6bb60f62 100644 --- a/editor/localization_editor.h +++ b/editor/localization_editor.h @@ -58,6 +58,11 @@ class LocalizationEditor : public VBoxContainer { Vector translation_filter_treeitems; Vector 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 7a3fb1ff52a..0b61db6835f 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 = 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 d335b29c2f8..223484044aa 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 = get_theme_font("font", "Label"); + int font_size = get_theme_font_size("font_size", "Label"); Ref icon = get_theme_icon("KeyValue", "EditorIcons"); Ref 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 60a5188af79..94785a54224 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 = get_theme_font("font", "Label"); + int font_size = get_theme_font_size("font_size", "Label"); Ref icon = get_theme_icon("KeyValue", "EditorIcons"); Ref 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 1e56e3d11f2..6b30aa325ca 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 4634d159419..c59e056f4f2 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 style_selected = get_theme_stylebox("state_machine_selectedframe", "GraphNode"); Ref 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 play = get_theme_icon("Play", "EditorIcons"); Ref auto_play = get_theme_icon("AutoPlay", "EditorIcons"); @@ -612,9 +613,9 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { Ref 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 anode = state_machine->get_node(name); bool needs_editor = AnimationTreeEditor::get_singleton()->can_edit(anode); Ref 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 e6f6b6f2e0e..998916349c4 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 6acf80a2c10..47a30ad5d71 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 &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 = 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 = 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 = 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 = 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 = 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 = 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 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 539ab03f5bd..4768cac2170 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 = 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 = 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 3cf4dc5ac84..2fc0e35f822 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 EditorFontPreviewPlugin::generate_from_path(const String &p_path, const Size2 &p_size) const { RES res = ResourceLoader::load(p_path); - Ref sampled_font; - if (res->is_class("DynamicFont")) { + Ref 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 EditorFontPreviewPlugin::generate_from_path(const String &p_path, Ref 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 00000000000..a82547182ca --- /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 &p_data) { + Ref 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(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(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(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(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(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(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(p_object) != nullptr; +} + +void EditorInspectorPluginFont::parse_begin(Object *p_object) { + FontData *fd = Object::cast_to(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 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 00000000000..1d3ffc88577 --- /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 line; + +public: + virtual Size2 get_minimum_size() const override; + + void set_data(const Ref &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 8420faa3021..fd5c4df3f38 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 icon, const Ref font, const String &text) { +static void draw_indicator_bar(Control &surface, real_t fill, const Ref icon, const Ref 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 0) { Ref 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 00000000000..34781485215 --- /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(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(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 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 00000000000..5b5f367b248 --- /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 8dd7d6d6e2c..e7b6959ac6e 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 7feb7cb3d3f..8cf22b3aa03 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 52da8dea19a..d6627147528 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 = 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 f8facb0fd51..9b760c0e50a 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 = get_theme_font("font", "Label"); + int font_size = get_theme_font_size("font_size", "Label"); String format; if (Object::cast_to(*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 932ded69388..8ab82b63c3e 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> stylebox_items; Set> font_items; + Set> font_size_items; Set> icon_items; Set> color_items; @@ -160,6 +165,15 @@ void ThemeEditor::_save_template_cbk(String fname) { tc.font_items.insert(it); } + List font_size_list; + Theme::get_default()->get_font_size_list(E->key(), &font_list); + for (List::Element *F = font_size_list.front(); F; F = F->next()) { + _TECategory::Item it; + it.name = F->get(); + it.item = Theme::get_default()->get_font_size(F->get(), E->key()); + tc.font_size_items.insert(it); + } + List icon_list; Theme::get_default()->get_icon_list(E->key(), &icon_list); for (List::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>::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()); 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; } @@ -360,6 +385,13 @@ void ThemeEditor::_dialog_cbk() { theme->set_font(E->get(), fromtype, Ref()); } } + { + names.clear(); + Theme::get_default()->get_font_size_list(fromtype, &names); + for (List::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); @@ -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; } @@ -420,6 +455,13 @@ void ThemeEditor::_dialog_cbk() { theme->clear_font(E->get(), fromtype); } } + { + names.clear(); + Theme::get_default()->get_font_size_list(fromtype, &names); + for (List::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); @@ -486,6 +528,13 @@ void ThemeEditor::_theme_menu_cbk(int p_option) { theme->set_font(E->get(), type, Ref()); } + List font_sizes; + base_theme->get_font_size_list(type, &font_sizes); + + for (List::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 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 7b516175b23..ceec3f18304 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 714f38bd561..9dc01d83d78 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 = 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 f3fc22b3138..31168850658 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 f26d44d75af..bbe6a73f8f2 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(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 212d693f1db..0a8a86eb4f2 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 1e4ed0c5521..847af0f2c2c 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 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 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 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 ec225c3c380..d946a08fbf2 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 915aec6d9a9..8345c49a926 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); } diff --git a/main/main.cpp b/main/main.cpp index cd97e3282df..3bef04b15d3 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -124,6 +124,7 @@ static bool _start_success = false; // Drivers +String text_driver = ""; static int text_driver_idx = -1; static int display_driver_idx = -1; static int audio_driver_idx = -1; @@ -310,14 +311,7 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print(" --rendering-driver Rendering driver (depends on display driver).\n"); - OS::get_singleton()->print(" --text-driver Text driver (Fonts, BiDi, shaping) ["); - for (int i = 0; i < TextServerManager::get_interface_count(); i++) { - if (i > 0) { - OS::get_singleton()->print(", "); - } - OS::get_singleton()->print("'%s'", TextServerManager::get_interface_name(i).utf8().get_data()); - } - OS::get_singleton()->print("].\n"); + OS::get_singleton()->print(" --text-driver Text driver (Fonts, BiDi, shaping)\n"); OS::get_singleton()->print("\n"); @@ -558,7 +552,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph I = args.front(); - String text_driver = ""; String display_driver = ""; String audio_driver = ""; String tablet_driver = ""; @@ -667,32 +660,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } else if (I->get() == "--text-driver") { if (I->next()) { text_driver = I->next()->get(); - bool found = false; - for (int i = 0; i < TextServerManager::get_interface_count(); i++) { - if (text_driver == TextServerManager::get_interface_name(i)) { - found = true; - } - } - - if (!found) { - OS::get_singleton()->print("Unknown text driver '%s', aborting.\nValid options are ", - text_driver.utf8().get_data()); - - for (int i = 0; i < TextServerManager::get_interface_count(); i++) { - if (i == TextServerManager::get_interface_count() - 1) { - OS::get_singleton()->print(" and "); - } else if (i != 0) { - OS::get_singleton()->print(", "); - } - - OS::get_singleton()->print("'%s'", TextServerManager::get_interface_name(i).utf8().get_data()); - } - - OS::get_singleton()->print(".\n"); - - goto error; - } - N = I->next()->next(); } else { OS::get_singleton()->print("Missing text driver argument, aborting.\n"); @@ -1208,11 +1175,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->set_cmdline(execpath, main_args); - GLOBAL_DEF("display/window/text_name", ""); - if (text_driver == "") { - text_driver = GLOBAL_GET("display/window/text_name"); - } - GLOBAL_DEF("rendering/quality/driver/driver_name", "Vulkan"); ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/driver/driver_name", PropertyInfo(Variant::STRING, @@ -1282,6 +1244,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } } + GLOBAL_DEF("display/window/force_right_to_left_layout_direction", false); + if (!force_lowdpi) { OS::get_singleton()->_allow_hidpi = GLOBAL_DEF("display/window/dpi/allow_hidpi", false); } @@ -1343,35 +1307,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->_render_thread_mode = OS::RenderThreadMode(rtm); } - /* Determine text driver */ - - if (text_driver != "") { - /* Load user selected text server. */ - for (int i = 0; i < TextServerManager::get_interface_count(); i++) { - if (text_driver == TextServerManager::get_interface_name(i)) { - text_driver_idx = i; - break; - } - } - } - - if (text_driver_idx < 0) { - /* If not selected, use one with the most features available. */ - int max_features = 0; - for (int i = 0; i < TextServerManager::get_interface_count(); i++) { - uint32_t ftrs = TextServerManager::get_interface_features(i); - int features = 0; - while (ftrs) { - features += ftrs & 1; - ftrs >>= 1; - } - if (features >= max_features) { - max_features = features; - text_driver_idx = i; - } - } - } - /* Determine audio and video drivers */ for (int i = 0; i < DisplayServer::get_create_function_count(); i++) { @@ -1533,6 +1468,41 @@ Error Main::setup2(Thread::ID p_main_tid_override) { Thread::_main_thread_id = p_main_tid_override; } + /* Determine text driver */ + + GLOBAL_DEF("display/window/text_name", ""); + if (text_driver == "") { + text_driver = GLOBAL_GET("display/window/text_name"); + } + + if (text_driver != "") { + /* Load user selected text server. */ + for (int i = 0; i < TextServerManager::get_interface_count(); i++) { + if (text_driver == TextServerManager::get_interface_name(i)) { + text_driver_idx = i; + break; + } + } + } + + if (text_driver_idx < 0) { + /* If not selected, use one with the most features available. */ + int max_features = 0; + for (int i = 0; i < TextServerManager::get_interface_count(); i++) { + uint32_t ftrs = TextServerManager::get_interface_features(i); + int features = 0; + while (ftrs) { + features += ftrs & 1; + ftrs >>= 1; + } + if (features >= max_features) { + max_features = features; + text_driver_idx = i; + } + } + } + printf("Using %s text server...\n", TextServerManager::get_interface_name(text_driver_idx).utf8().get_data()); + /* Initialize Text Server */ { diff --git a/modules/mono/editor/code_completion.cpp b/modules/mono/editor/code_completion.cpp index f1919c2501e..2d37b1306cc 100644 --- a/modules/mono/editor/code_completion.cpp +++ b/modules/mono/editor/code_completion.cpp @@ -228,6 +228,18 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr } } } break; + case CompletionKind::THEME_FONT_SIZES: { + Ref