Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add LabelSettings resource for quick Label theme property override. #62139

Merged
merged 1 commit into from
Jul 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/classes/Label.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
<member name="horizontal_alignment" type="int" setter="set_horizontal_alignment" getter="get_horizontal_alignment" enum="HorizontalAlignment" default="0">
Controls the text's horizontal alignment. Supports left, center, right, and fill, or justify. Set it to one of the [enum HorizontalAlignment] constants.
</member>
<member name="label_settings" type="LabelSettings" setter="set_label_settings" getter="get_label_settings">
Resource to override [Theme] font, outline and shadow properties.
</member>
<member name="language" type="String" setter="set_language" getter="get_language" default="&quot;&quot;">
Language code used for line-breaking and text shaping algorithms, if left empty current locale is used instead.
</member>
Expand Down
39 changes: 39 additions & 0 deletions doc/classes/LabelSettings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="LabelSettings" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
Resource to override [Theme] font, outline and shadow properties of the [Label].
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<members>
<member name="font" type="Font" setter="set_font" getter="get_font">
[Font] of the [Label]'s text.
</member>
<member name="font_color" type="Color" setter="set_font_color" getter="get_font_color" default="Color(0.875, 0.875, 0.875, 1)">
Default text [Color] of the [Label].
</member>
<member name="font_size" type="int" setter="set_font_size" getter="get_font_size" default="16">
Font size of the [Label]'s text.
</member>
<member name="line_spacing" type="float" setter="set_line_spacing" getter="get_line_spacing" default="0.0">
Vertical space between lines in multiline text.
</member>
<member name="outline_color" type="Color" setter="set_outline_color" getter="get_outline_color" default="Color(1, 1, 1, 1)">
The tint of text outline.
</member>
<member name="outline_size" type="int" setter="set_outline_size" getter="get_outline_size" default="0">
Text outline size.
</member>
<member name="shadow_color" type="Color" setter="set_shadow_color" getter="get_shadow_color" default="Color(1, 1, 1, 1)">
The tint of text shadow.
</member>
<member name="shadow_offset" type="Vector2" setter="set_shadow_offset" getter="get_shadow_offset" default="Vector2(1, 1)">
The offset of the text's shadow.
</member>
<member name="shadow_size" type="int" setter="set_shadow_size" getter="get_shadow_size" default="0">
The size of the text's shadow.
</member>
</members>
</class>
1 change: 1 addition & 0 deletions editor/icons/LabelSettings.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
65 changes: 47 additions & 18 deletions scene/gui/label.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "label.h"

#include "core/config/project_settings.h"
#include "core/core_string_names.h"
#include "core/string/print_string.h"
#include "core/string/translation.h"

Expand Down Expand Up @@ -64,7 +65,7 @@ bool Label::is_uppercase() const {
}

int Label::get_line_height(int p_line) const {
Ref<Font> font = get_theme_font(SNAME("font"));
Ref<Font> font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("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) {
Expand All @@ -74,7 +75,8 @@ int Label::get_line_height(int p_line) const {
}
return h;
} else {
return font->get_height(get_theme_font_size(SNAME("font_size")));
int font_size = settings.is_valid() ? settings->get_font_size() : get_theme_font_size(SNAME("font_size"));
return font->get_height(font_size);
}
}

Expand All @@ -91,8 +93,8 @@ void Label::_shape() {
} else {
TS->shaped_text_set_direction(text_rid, (TextServer::Direction)text_direction);
}
const Ref<Font> &font = get_theme_font(SNAME("font"));
int font_size = get_theme_font_size(SNAME("font_size"));
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"));
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) {
Expand Down Expand Up @@ -223,9 +225,8 @@ void Label::_shape() {
}

void Label::_update_visible() {
int line_spacing = get_theme_constant(SNAME("line_spacing"), SNAME("Label"));
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"));
Ref<Font> font = get_theme_font(SNAME("font"));
int lines_visible = lines_rid.size();

if (max_lines_visible >= 0 && lines_visible > max_lines_visible) {
Expand Down Expand Up @@ -295,17 +296,19 @@ void Label::_notification(int p_what) {

RID ci = get_canvas_item();

bool has_settings = settings.is_valid();

Size2 string_size;
Size2 size = get_size();
Ref<StyleBox> style = get_theme_stylebox(SNAME("normal"));
Ref<Font> font = get_theme_font(SNAME("font"));
Color font_color = get_theme_color(SNAME("font_color"));
Color font_shadow_color = get_theme_color(SNAME("font_shadow_color"));
Point2 shadow_ofs(get_theme_constant(SNAME("shadow_offset_x")), get_theme_constant(SNAME("shadow_offset_y")));
int line_spacing = get_theme_constant(SNAME("line_spacing"));
Color font_outline_color = get_theme_color(SNAME("font_outline_color"));
int outline_size = get_theme_constant(SNAME("outline_size"));
int shadow_outline_size = get_theme_constant(SNAME("shadow_outline_size"));
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"));
bool rtl = (TS->shaped_text_get_inferred_direction(text_rid) == TextServer::DIRECTION_RTL);
bool rtl_layout = is_layout_rtl();

Expand Down Expand Up @@ -552,8 +555,10 @@ Size2 Label::get_minimum_size() const {

Size2 min_size = minsize;

Ref<Font> font = get_theme_font(SNAME("font"));
min_size.height = MAX(min_size.height, font->get_height(get_theme_font_size(SNAME("font_size"))));
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"));

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();
if (autowrap_mode != TextServer::AUTOWRAP_OFF) {
Expand All @@ -578,9 +583,8 @@ int Label::get_line_count() const {
}

int Label::get_visible_line_count() const {
Ref<Font> font = get_theme_font(SNAME("font"));
Ref<StyleBox> style = get_theme_stylebox(SNAME("normal"));
int line_spacing = get_theme_constant(SNAME("line_spacing"));
int line_spacing = settings.is_valid() ? settings->get_line_spacing() : get_theme_constant(SNAME("line_spacing"));
int lines_visible = 0;
float total_h = 0.0;
for (int64_t i = lines_skipped; i < lines_rid.size(); i++) {
Expand Down Expand Up @@ -641,6 +645,28 @@ void Label::set_text(const String &p_string) {
update_minimum_size();
}

void Label::_invalidate() {
font_dirty = true;
update();
}

void Label::set_label_settings(const Ref<LabelSettings> &p_settings) {
if (settings != p_settings) {
if (settings.is_valid()) {
settings->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Label::_invalidate));
}
settings = p_settings;
if (settings.is_valid()) {
settings->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Label::_invalidate), varray(), CONNECT_REFERENCE_COUNTED);
}
_invalidate();
}
}

Ref<LabelSettings> Label::get_label_settings() const {
return settings;
}

void Label::set_text_direction(Control::TextDirection p_text_direction) {
ERR_FAIL_COND((int)p_text_direction < -1 || (int)p_text_direction > 3);
if (text_direction != p_text_direction) {
Expand Down Expand Up @@ -804,6 +830,8 @@ void Label::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_vertical_alignment"), &Label::get_vertical_alignment);
ClassDB::bind_method(D_METHOD("set_text", "text"), &Label::set_text);
ClassDB::bind_method(D_METHOD("get_text"), &Label::get_text);
ClassDB::bind_method(D_METHOD("set_label_settings", "settings"), &Label::set_label_settings);
ClassDB::bind_method(D_METHOD("get_label_settings"), &Label::get_label_settings);
ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &Label::set_text_direction);
ClassDB::bind_method(D_METHOD("get_text_direction"), &Label::get_text_direction);
ClassDB::bind_method(D_METHOD("set_language", "language"), &Label::set_language);
Expand Down Expand Up @@ -836,6 +864,7 @@ void Label::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_structured_text_bidi_override_options"), &Label::get_structured_text_bidi_override_options);

ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "label_settings", PROPERTY_HINT_RESOURCE_TYPE, "LabelSettings"), "set_label_settings", "get_label_settings");
ADD_PROPERTY(PropertyInfo(Variant::INT, "horizontal_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_horizontal_alignment", "get_horizontal_alignment");
ADD_PROPERTY(PropertyInfo(Variant::INT, "vertical_alignment", PROPERTY_HINT_ENUM, "Top,Center,Bottom,Fill"), "set_vertical_alignment", "get_vertical_alignment");
ADD_PROPERTY(PropertyInfo(Variant::INT, "autowrap_mode", PROPERTY_HINT_ENUM, "Off,Arbitrary,Word,Word (Smart)"), "set_autowrap_mode", "get_autowrap_mode");
Expand Down
7 changes: 7 additions & 0 deletions scene/gui/label.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#define LABEL_H

#include "scene/gui/control.h"
#include "scene/resources/label_settings.h"

class Label : public Control {
GDCLASS(Label, Control);
Expand Down Expand Up @@ -65,8 +66,11 @@ class Label : public Control {
int lines_skipped = 0;
int max_lines_visible = -1;

Ref<LabelSettings> settings;

void _update_visible();
void _shape();
void _invalidate();

protected:
void _notification(int p_what);
Expand All @@ -85,6 +89,9 @@ class Label : public Control {
void set_text(const String &p_string);
String get_text() const;

void set_label_settings(const Ref<LabelSettings> &p_settings);
Ref<LabelSettings> get_label_settings() const;

void set_text_direction(TextDirection p_text_direction);
TextDirection get_text_direction() const;

Expand Down
3 changes: 3 additions & 0 deletions scene/register_scene_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@
#include "scene/resources/gradient.h"
#include "scene/resources/height_map_shape_3d.h"
#include "scene/resources/immediate_mesh.h"
#include "scene/resources/label_settings.h"
#include "scene/resources/material.h"
#include "scene/resources/mesh.h"
#include "scene/resources/mesh_data_tool.h"
Expand Down Expand Up @@ -860,6 +861,8 @@ void register_scene_types() {

GDREGISTER_CLASS(Curve);

GDREGISTER_CLASS(LabelSettings);

GDREGISTER_CLASS(SceneReplicationConfig);

GDREGISTER_CLASS(TextLine);
Expand Down
Loading