diff options
Diffstat (limited to 'scene/gui/label.cpp')
-rw-r--r-- | scene/gui/label.cpp | 146 |
1 files changed, 82 insertions, 64 deletions
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 7a88afaa3b..306ca3d340 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -44,7 +44,7 @@ void Label::set_autowrap_mode(TextServer::AutowrapMode p_mode) { autowrap_mode = p_mode; lines_dirty = true; - update(); + queue_redraw(); if (clip || overrun_behavior != TextServer::OVERRUN_NO_TRIMMING) { update_minimum_size(); @@ -63,7 +63,7 @@ void Label::set_uppercase(bool p_uppercase) { uppercase = p_uppercase; dirty = true; - update(); + queue_redraw(); } bool Label::is_uppercase() const { @@ -71,7 +71,7 @@ bool Label::is_uppercase() const { } int Label::get_line_height(int p_line) const { - Ref<Font> font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font")); + Ref<Font> font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : theme_cache.font; if (p_line >= 0 && p_line < lines_rid.size()) { return TS->shaped_text_get_size(lines_rid[p_line]).y; } else if (lines_rid.size() > 0) { @@ -81,13 +81,13 @@ int Label::get_line_height(int p_line) const { } return h; } else { - int font_size = settings.is_valid() ? settings->get_font_size() : get_theme_font_size(SNAME("font_size")); + int font_size = settings.is_valid() ? settings->get_font_size() : theme_cache.font_size; return font->get_height(font_size); } } void Label::_shape() { - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal"), SNAME("Label")); + Ref<StyleBox> style = theme_cache.normal_style; int width = (get_size().width - style->get_minimum_size().width); if (dirty || font_dirty) { @@ -99,8 +99,8 @@ void Label::_shape() { } else { TS->shaped_text_set_direction(text_rid, (TextServer::Direction)text_direction); } - const Ref<Font> &font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font")); - int font_size = settings.is_valid() ? settings->get_font_size() : get_theme_font_size(SNAME("font_size")); + const Ref<Font> &font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : theme_cache.font; + int font_size = settings.is_valid() ? settings->get_font_size() : theme_cache.font_size; ERR_FAIL_COND(font.is_null()); String text = (uppercase) ? TS->string_to_upper(xl_text, language) : xl_text; if (visible_chars >= 0 && visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING) { @@ -143,8 +143,9 @@ void Label::_shape() { case TextServer::AUTOWRAP_OFF: break; } - PackedInt32Array line_breaks = TS->shaped_text_get_line_breaks(text_rid, width, 0, autowrap_flags); + autowrap_flags = autowrap_flags | TextServer::BREAK_TRIM_EDGE_SPACES; + PackedInt32Array line_breaks = TS->shaped_text_get_line_breaks(text_rid, width, 0, autowrap_flags); for (int i = 0; i < line_breaks.size(); i = i + 2) { RID line = TS->shaped_text_substr(text_rid, line_breaks[i], line_breaks[i + 1] - line_breaks[i]); lines_rid.push_back(line); @@ -231,8 +232,8 @@ void Label::_shape() { } void Label::_update_visible() { - int line_spacing = settings.is_valid() ? settings->get_line_spacing() : get_theme_constant(SNAME("line_spacing"), SNAME("Label")); - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal"), SNAME("Label")); + int line_spacing = settings.is_valid() ? settings->get_line_spacing() : theme_cache.line_spacing; + Ref<StyleBox> style = theme_cache.normal_style; int lines_visible = lines_rid.size(); if (max_lines_visible >= 0 && lines_visible > max_lines_visible) { @@ -271,6 +272,22 @@ inline void draw_glyph_outline(const Glyph &p_gl, const RID &p_canvas, const Col } } +void Label::_update_theme_item_cache() { + Control::_update_theme_item_cache(); + + theme_cache.normal_style = get_theme_stylebox(SNAME("normal")); + theme_cache.font = get_theme_font(SNAME("font")); + + theme_cache.font_size = get_theme_font_size(SNAME("font_size")); + theme_cache.line_spacing = get_theme_constant(SNAME("line_spacing")); + theme_cache.font_color = get_theme_color(SNAME("font_color")); + theme_cache.font_shadow_color = get_theme_color(SNAME("font_shadow_color")); + theme_cache.font_shadow_offset = Point2(get_theme_constant(SNAME("shadow_offset_x")), get_theme_constant(SNAME("shadow_offset_y"))); + theme_cache.font_outline_color = get_theme_color(SNAME("font_outline_color")); + theme_cache.font_outline_size = get_theme_constant(SNAME("outline_size")); + theme_cache.font_shadow_outline_size = get_theme_constant(SNAME("shadow_outline_size")); +} + void Label::_notification(int p_what) { switch (p_what) { case NOTIFICATION_TRANSLATION_CHANGED: { @@ -279,16 +296,16 @@ void Label::_notification(int p_what) { return; // Nothing new. } xl_text = new_text; - if (percent_visible < 1) { - visible_chars = get_total_character_count() * percent_visible; + if (visible_ratio < 1) { + visible_chars = get_total_character_count() * visible_ratio; } dirty = true; - update(); + queue_redraw(); } break; case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: { - update(); + queue_redraw(); } break; case NOTIFICATION_DRAW: { @@ -306,15 +323,15 @@ void Label::_notification(int p_what) { Size2 string_size; Size2 size = get_size(); - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); - Ref<Font> font = (has_settings && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font")); - Color font_color = has_settings ? settings->get_font_color() : get_theme_color(SNAME("font_color")); - Color font_shadow_color = has_settings ? settings->get_shadow_color() : get_theme_color(SNAME("font_shadow_color")); - Point2 shadow_ofs = has_settings ? settings->get_shadow_offset() : Point2(get_theme_constant(SNAME("shadow_offset_x")), get_theme_constant(SNAME("shadow_offset_y"))); - int line_spacing = has_settings ? settings->get_line_spacing() : get_theme_constant(SNAME("line_spacing")); - Color font_outline_color = has_settings ? settings->get_outline_color() : get_theme_color(SNAME("font_outline_color")); - int outline_size = has_settings ? settings->get_outline_size() : get_theme_constant(SNAME("outline_size")); - int shadow_outline_size = has_settings ? settings->get_shadow_size() : get_theme_constant(SNAME("shadow_outline_size")); + Ref<StyleBox> style = theme_cache.normal_style; + Ref<Font> font = (has_settings && settings->get_font().is_valid()) ? settings->get_font() : theme_cache.font; + Color font_color = has_settings ? settings->get_font_color() : theme_cache.font_color; + Color font_shadow_color = has_settings ? settings->get_shadow_color() : theme_cache.font_shadow_color; + Point2 shadow_ofs = has_settings ? settings->get_shadow_offset() : theme_cache.font_shadow_offset; + int line_spacing = has_settings ? settings->get_line_spacing() : theme_cache.line_spacing; + Color font_outline_color = has_settings ? settings->get_outline_color() : theme_cache.font_outline_color; + int outline_size = has_settings ? settings->get_outline_size() : theme_cache.font_outline_size; + int shadow_outline_size = has_settings ? settings->get_shadow_size() : theme_cache.font_shadow_outline_size; bool rtl = (TS->shaped_text_get_inferred_direction(text_rid) == TextServer::DIRECTION_RTL); bool rtl_layout = is_layout_rtl(); @@ -348,7 +365,7 @@ void Label::_notification(int p_what) { total_h += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing; total_glyphs += TS->shaped_text_get_glyph_count(lines_rid[i]) + TS->shaped_text_get_ellipsis_glyph_count(lines_rid[i]); } - int visible_glyphs = total_glyphs * percent_visible; + int visible_glyphs = total_glyphs * visible_ratio; int processed_glyphs = 0; total_h += style->get_margin(SIDE_TOP) + style->get_margin(SIDE_BOTTOM); @@ -544,7 +561,7 @@ void Label::_notification(int p_what) { case NOTIFICATION_THEME_CHANGED: { font_dirty = true; - update(); + queue_redraw(); } break; case NOTIFICATION_RESIZED: { @@ -561,12 +578,12 @@ Size2 Label::get_minimum_size() const { Size2 min_size = minsize; - const Ref<Font> &font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font")); - int font_size = settings.is_valid() ? settings->get_font_size() : get_theme_font_size(SNAME("font_size")); + const Ref<Font> &font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : theme_cache.font; + int font_size = settings.is_valid() ? settings->get_font_size() : theme_cache.font_size; min_size.height = MAX(min_size.height, font->get_height(font_size) + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM)); - Size2 min_style = get_theme_stylebox(SNAME("normal"))->get_minimum_size(); + Size2 min_style = theme_cache.normal_style->get_minimum_size(); if (autowrap_mode != TextServer::AUTOWRAP_OFF) { return Size2(1, (clip || overrun_behavior != TextServer::OVERRUN_NO_TRIMMING) ? 1 : min_size.height) + min_style; } else { @@ -589,8 +606,8 @@ int Label::get_line_count() const { } int Label::get_visible_line_count() const { - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); - int line_spacing = settings.is_valid() ? settings->get_line_spacing() : get_theme_constant(SNAME("line_spacing")); + Ref<StyleBox> style = theme_cache.normal_style; + int line_spacing = settings.is_valid() ? settings->get_line_spacing() : theme_cache.line_spacing; int lines_visible = 0; float total_h = 0.0; for (int64_t i = lines_skipped; i < lines_rid.size(); i++) { @@ -623,7 +640,7 @@ void Label::set_horizontal_alignment(HorizontalAlignment p_alignment) { } horizontal_alignment = p_alignment; - update(); + queue_redraw(); } HorizontalAlignment Label::get_horizontal_alignment() const { @@ -638,7 +655,7 @@ void Label::set_vertical_alignment(VerticalAlignment p_alignment) { } vertical_alignment = p_alignment; - update(); + queue_redraw(); } VerticalAlignment Label::get_vertical_alignment() const { @@ -652,16 +669,16 @@ void Label::set_text(const String &p_string) { text = p_string; xl_text = atr(p_string); dirty = true; - if (percent_visible < 1) { - visible_chars = get_total_character_count() * percent_visible; + if (visible_ratio < 1) { + visible_chars = get_total_character_count() * visible_ratio; } - update(); + queue_redraw(); update_minimum_size(); } void Label::_invalidate() { font_dirty = true; - update(); + queue_redraw(); } void Label::set_label_settings(const Ref<LabelSettings> &p_settings) { @@ -686,7 +703,7 @@ void Label::set_text_direction(Control::TextDirection p_text_direction) { if (text_direction != p_text_direction) { text_direction = p_text_direction; font_dirty = true; - update(); + queue_redraw(); } } @@ -694,7 +711,7 @@ void Label::set_structured_text_bidi_override(TextServer::StructuredTextParser p if (st_parser != p_parser) { st_parser = p_parser; dirty = true; - update(); + queue_redraw(); } } @@ -709,7 +726,7 @@ void Label::set_structured_text_bidi_override_options(Array p_args) { st_args = p_args; dirty = true; - update(); + queue_redraw(); } Array Label::get_structured_text_bidi_override_options() const { @@ -724,7 +741,7 @@ void Label::set_language(const String &p_language) { if (language != p_language) { language = p_language; dirty = true; - update(); + queue_redraw(); } } @@ -738,7 +755,7 @@ void Label::set_clip_text(bool p_clip) { } clip = p_clip; - update(); + queue_redraw(); update_minimum_size(); } @@ -753,7 +770,7 @@ void Label::set_text_overrun_behavior(TextServer::OverrunBehavior p_behavior) { overrun_behavior = p_behavior; lines_dirty = true; - update(); + queue_redraw(); if (clip || overrun_behavior != TextServer::OVERRUN_NO_TRIMMING) { update_minimum_size(); } @@ -771,14 +788,14 @@ void Label::set_visible_characters(int p_amount) { if (visible_chars != p_amount) { visible_chars = p_amount; if (get_total_character_count() > 0) { - percent_visible = (float)p_amount / (float)get_total_character_count(); + visible_ratio = (float)p_amount / (float)get_total_character_count(); } else { - percent_visible = 1.0; + visible_ratio = 1.0; } if (visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING) { dirty = true; } - update(); + queue_redraw(); } } @@ -786,28 +803,28 @@ int Label::get_visible_characters() const { return visible_chars; } -void Label::set_percent_visible(float p_percent) { - if (percent_visible != p_percent) { - if (percent_visible >= 1.0) { +void Label::set_visible_ratio(float p_ratio) { + if (visible_ratio != p_ratio) { + if (p_ratio >= 1.0) { visible_chars = -1; - percent_visible = 1.0; - } else if (percent_visible < 0.0) { + visible_ratio = 1.0; + } else if (p_ratio < 0.0) { visible_chars = 0; - percent_visible = 0.0; + visible_ratio = 0.0; } else { - visible_chars = get_total_character_count() * p_percent; - percent_visible = p_percent; + visible_chars = get_total_character_count() * p_ratio; + visible_ratio = p_ratio; } if (visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING) { dirty = true; } - update(); + queue_redraw(); } } -float Label::get_percent_visible() const { - return percent_visible; +float Label::get_visible_ratio() const { + return visible_ratio; } TextServer::VisibleCharactersBehavior Label::get_visible_characters_behavior() const { @@ -818,7 +835,7 @@ void Label::set_visible_characters_behavior(TextServer::VisibleCharactersBehavio if (visible_chars_behavior != p_behavior) { visible_chars_behavior = p_behavior; dirty = true; - update(); + queue_redraw(); } } @@ -831,7 +848,7 @@ void Label::set_lines_skipped(int p_lines) { lines_skipped = p_lines; _update_visible(); - update(); + queue_redraw(); } int Label::get_lines_skipped() const { @@ -845,7 +862,7 @@ void Label::set_max_lines_visible(int p_lines) { max_lines_visible = p_lines; _update_visible(); - update(); + queue_redraw(); } int Label::get_max_lines_visible() const { @@ -889,8 +906,8 @@ void Label::_bind_methods() { ClassDB::bind_method(D_METHOD("get_visible_characters"), &Label::get_visible_characters); ClassDB::bind_method(D_METHOD("get_visible_characters_behavior"), &Label::get_visible_characters_behavior); ClassDB::bind_method(D_METHOD("set_visible_characters_behavior", "behavior"), &Label::set_visible_characters_behavior); - ClassDB::bind_method(D_METHOD("set_percent_visible", "percent_visible"), &Label::set_percent_visible); - ClassDB::bind_method(D_METHOD("get_percent_visible"), &Label::get_percent_visible); + ClassDB::bind_method(D_METHOD("set_visible_ratio", "ratio"), &Label::set_visible_ratio); + ClassDB::bind_method(D_METHOD("get_visible_ratio"), &Label::get_visible_ratio); ClassDB::bind_method(D_METHOD("set_lines_skipped", "lines_skipped"), &Label::set_lines_skipped); ClassDB::bind_method(D_METHOD("get_lines_skipped"), &Label::get_lines_skipped); ClassDB::bind_method(D_METHOD("set_max_lines_visible", "lines_visible"), &Label::set_max_lines_visible); @@ -908,13 +925,14 @@ void Label::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_text"), "set_clip_text", "is_clipping_text"); ADD_PROPERTY(PropertyInfo(Variant::INT, "text_overrun_behavior", PROPERTY_HINT_ENUM, "Trim Nothing,Trim Characters,Trim Words,Ellipsis,Word Ellipsis"), "set_text_overrun_behavior", "get_text_overrun_behavior"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "uppercase"), "set_uppercase", "is_uppercase"); + + ADD_GROUP("Displayed Text", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "lines_skipped", PROPERTY_HINT_RANGE, "0,999,1"), "set_lines_skipped", "get_lines_skipped"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_lines_visible", PROPERTY_HINT_RANGE, "-1,999,1"), "set_max_lines_visible", "get_max_lines_visible"); - - // Note: "visible_characters" and "percent_visible" should be set after "text" to be correctly applied. + // Note: "visible_characters" and "visible_ratio" should be set after "text" to be correctly applied. ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_characters", PROPERTY_HINT_RANGE, "-1,128000,1"), "set_visible_characters", "get_visible_characters"); ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_characters_behavior", PROPERTY_HINT_ENUM, "Characters Before Shaping,Characters After Shaping,Glyphs (Layout Direction),Glyphs (Left-to-Right),Glyphs (Right-to-Left)"), "set_visible_characters_behavior", "get_visible_characters_behavior"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "percent_visible", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_percent_visible", "get_percent_visible"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visible_ratio", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_visible_ratio", "get_visible_ratio"); ADD_GROUP("BiDi", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); |