Merge pull request #32354 from Relintai/rich-text-label-struct-refactor
Implement #32347 - (RichTextLabel's Item's should be structs)
This commit is contained in:
commit
17a81a32d8
4 changed files with 93 additions and 144 deletions
|
@ -120,3 +120,7 @@ CharFXTransform::CharFXTransform() {
|
|||
color = Color();
|
||||
character = 0;
|
||||
}
|
||||
|
||||
CharFXTransform::~CharFXTransform() {
|
||||
environment.clear();
|
||||
}
|
||||
|
|
|
@ -64,6 +64,8 @@ public:
|
|||
Dictionary environment;
|
||||
|
||||
CharFXTransform();
|
||||
~CharFXTransform();
|
||||
|
||||
uint64_t get_relative_index() { return relative_index; }
|
||||
void set_relative_index(uint64_t p_index) { relative_index = p_index; }
|
||||
uint64_t get_absolute_index() { return absolute_index; }
|
||||
|
|
|
@ -348,6 +348,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
|
|||
int it_char_start = p_char_count;
|
||||
|
||||
Vector<ItemFX *> fx_stack = Vector<ItemFX *>();
|
||||
_fetch_item_fx_stack(text, fx_stack);
|
||||
bool custom_fx_ok = true;
|
||||
|
||||
if (p_mode == PROCESS_DRAW) {
|
||||
|
@ -359,8 +360,14 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
|
|||
strikethrough = true;
|
||||
}
|
||||
|
||||
fade = _fetch_by_type<ItemFade>(text, ITEM_FADE);
|
||||
_fetch_item_stack<ItemFX>(text, fx_stack);
|
||||
Item *fade_item = it;
|
||||
while (fade_item) {
|
||||
if (fade_item->type == ITEM_FADE) {
|
||||
fade = static_cast<ItemFade *>(fade_item);
|
||||
break;
|
||||
}
|
||||
fade_item = fade_item->parent;
|
||||
}
|
||||
|
||||
} else if (p_mode == PROCESS_CACHE) {
|
||||
l.char_count += text->text.length();
|
||||
|
@ -467,18 +474,16 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
|
|||
faded_visibility > 0.0f);
|
||||
|
||||
for (int j = 0; j < fx_stack.size(); j++) {
|
||||
ItemCustomFX *item_custom = Object::cast_to<ItemCustomFX>(fx_stack[j]);
|
||||
ItemShake *item_shake = Object::cast_to<ItemShake>(fx_stack[j]);
|
||||
ItemWave *item_wave = Object::cast_to<ItemWave>(fx_stack[j]);
|
||||
ItemTornado *item_tornado = Object::cast_to<ItemTornado>(fx_stack[j]);
|
||||
ItemRainbow *item_rainbow = Object::cast_to<ItemRainbow>(fx_stack[j]);
|
||||
ItemFX *item_fx = fx_stack[j];
|
||||
|
||||
if (item_fx->type == ITEM_CUSTOMFX && custom_fx_ok) {
|
||||
ItemCustomFX *item_custom = static_cast<ItemCustomFX *>(item_fx);
|
||||
|
||||
Ref<CharFXTransform> charfx = item_custom->char_fx_transform;
|
||||
Ref<RichTextEffect> custom_effect = item_custom->custom_effect;
|
||||
|
||||
if (item_custom && custom_fx_ok) {
|
||||
Ref<CharFXTransform> charfx = Ref<CharFXTransform>(memnew(CharFXTransform));
|
||||
Ref<RichTextEffect> custom_effect = _get_custom_effect_by_code(item_custom->identifier);
|
||||
if (!custom_effect.is_null()) {
|
||||
charfx->elapsed_time = item_custom->elapsed_time;
|
||||
charfx->environment = item_custom->environment;
|
||||
charfx->relative_index = c_item_offset;
|
||||
charfx->absolute_index = p_char_count;
|
||||
charfx->visibility = visible;
|
||||
|
@ -494,7 +499,9 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
|
|||
visible &= charfx->visibility;
|
||||
fx_char = charfx->character;
|
||||
}
|
||||
} else if (item_shake) {
|
||||
} else if (item_fx->type == ITEM_SHAKE) {
|
||||
ItemShake *item_shake = static_cast<ItemShake *>(item_fx);
|
||||
|
||||
uint64_t char_current_rand = item_shake->offset_random(c_item_offset);
|
||||
uint64_t char_previous_rand = item_shake->offset_previous_random(c_item_offset);
|
||||
uint64_t max_rand = 2147483647;
|
||||
|
@ -509,14 +516,20 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
|
|||
Math::cos(current_offset),
|
||||
n_time)) *
|
||||
(float)item_shake->strength / 10.0f;
|
||||
} else if (item_wave) {
|
||||
} else if (item_fx->type == ITEM_WAVE) {
|
||||
ItemWave *item_wave = static_cast<ItemWave *>(item_fx);
|
||||
|
||||
double value = Math::sin(item_wave->frequency * item_wave->elapsed_time + ((p_ofs.x + pofs) / 50)) * (item_wave->amplitude / 10.0f);
|
||||
fx_offset += Point2(0, 1) * value;
|
||||
} else if (item_tornado) {
|
||||
} else if (item_fx->type == ITEM_TORNADO) {
|
||||
ItemTornado *item_tornado = static_cast<ItemTornado *>(item_fx);
|
||||
|
||||
double torn_x = Math::sin(item_tornado->frequency * item_tornado->elapsed_time + ((p_ofs.x + pofs) / 50)) * (item_tornado->radius);
|
||||
double torn_y = Math::cos(item_tornado->frequency * item_tornado->elapsed_time + ((p_ofs.x + pofs) / 50)) * (item_tornado->radius);
|
||||
fx_offset += Point2(torn_x, torn_y);
|
||||
} else if (item_rainbow) {
|
||||
} else if (item_fx->type == ITEM_RAINBOW) {
|
||||
ItemRainbow *item_rainbow = static_cast<ItemRainbow *>(item_fx);
|
||||
|
||||
fx_color = fx_color.from_hsv(item_rainbow->frequency * (item_rainbow->elapsed_time + ((p_ofs.x + pofs) / 50)),
|
||||
item_rainbow->saturation,
|
||||
item_rainbow->value,
|
||||
|
@ -884,7 +897,11 @@ void RichTextLabel::_update_scroll() {
|
|||
void RichTextLabel::_update_fx(RichTextLabel::ItemFrame *p_frame, float p_delta_time) {
|
||||
Item *it = p_frame;
|
||||
while (it) {
|
||||
ItemFX *ifx = Object::cast_to<ItemFX>(it);
|
||||
ItemFX *ifx = NULL;
|
||||
|
||||
if (it->type == ITEM_CUSTOMFX || it->type == ITEM_SHAKE || it->type == ITEM_WAVE || it->type == ITEM_TORNADO || it->type == ITEM_RAINBOW) {
|
||||
ifx = static_cast<ItemFX *>(it);
|
||||
}
|
||||
|
||||
if (!ifx) {
|
||||
it = _get_next_item(it, true);
|
||||
|
@ -893,7 +910,12 @@ void RichTextLabel::_update_fx(RichTextLabel::ItemFrame *p_frame, float p_delta_
|
|||
|
||||
ifx->elapsed_time += p_delta_time;
|
||||
|
||||
ItemShake *shake = Object::cast_to<ItemShake>(it);
|
||||
ItemShake *shake = NULL;
|
||||
|
||||
if (it->type == ITEM_SHAKE) {
|
||||
shake = static_cast<ItemShake *>(it);
|
||||
}
|
||||
|
||||
if (shake) {
|
||||
bool cycle = (shake->elapsed_time > (1.0f / shake->rate));
|
||||
if (cycle) {
|
||||
|
@ -983,9 +1005,6 @@ void RichTextLabel::_notification(int p_what) {
|
|||
case NOTIFICATION_INTERNAL_PROCESS: {
|
||||
float dt = get_process_delta_time();
|
||||
|
||||
for (int i = 0; i < custom_effects.size(); i++) {
|
||||
}
|
||||
|
||||
_update_fx(main, dt);
|
||||
update();
|
||||
}
|
||||
|
@ -1408,6 +1427,17 @@ bool RichTextLabel::_find_by_type(Item *p_item, ItemType p_type) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void RichTextLabel::_fetch_item_fx_stack(Item *p_item, Vector<ItemFX *> &r_stack) {
|
||||
Item *item = p_item;
|
||||
while (item) {
|
||||
if (item->type == ITEM_CUSTOMFX || item->type == ITEM_SHAKE || item->type == ITEM_WAVE || item->type == ITEM_TORNADO || item->type == ITEM_RAINBOW) {
|
||||
r_stack.push_back(static_cast<ItemFX *>(item));
|
||||
}
|
||||
|
||||
item = item->parent;
|
||||
}
|
||||
}
|
||||
|
||||
bool RichTextLabel::_find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item) {
|
||||
Item *item = p_item;
|
||||
|
||||
|
@ -1776,10 +1806,10 @@ void RichTextLabel::push_rainbow(float p_saturation, float p_value, float p_freq
|
|||
_add_item(item, true);
|
||||
}
|
||||
|
||||
void RichTextLabel::push_customfx(String p_identifier, Dictionary p_environment) {
|
||||
void RichTextLabel::push_customfx(Ref<RichTextEffect> p_custom_effect, Dictionary p_environment) {
|
||||
ItemCustomFX *item = memnew(ItemCustomFX);
|
||||
item->identifier = p_identifier;
|
||||
item->environment = p_environment;
|
||||
item->custom_effect = p_custom_effect;
|
||||
item->char_fx_transform->environment = p_environment;
|
||||
_add_item(item, true);
|
||||
}
|
||||
|
||||
|
@ -2287,7 +2317,7 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
|
|||
Ref<RichTextEffect> effect = _get_custom_effect_by_code(identifier);
|
||||
|
||||
if (!effect.is_null()) {
|
||||
push_customfx(identifier, properties);
|
||||
push_customfx(effect, properties);
|
||||
pos = brk_end + 1;
|
||||
tag_stack.push_front(identifier);
|
||||
set_process_internal(true);
|
||||
|
@ -2700,17 +2730,16 @@ Size2 RichTextLabel::get_minimum_size() const {
|
|||
}
|
||||
|
||||
Ref<RichTextEffect> RichTextLabel::_get_custom_effect_by_code(String p_bbcode_identifier) {
|
||||
Ref<RichTextEffect> r;
|
||||
for (int i = 0; i < custom_effects.size(); i++) {
|
||||
if (!custom_effects[i].is_valid())
|
||||
continue;
|
||||
|
||||
if (custom_effects[i]->get_bbcode() == p_bbcode_identifier) {
|
||||
r = custom_effects[i];
|
||||
return custom_effects[i];
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
return Ref<RichTextEffect>();
|
||||
}
|
||||
|
||||
Dictionary RichTextLabel::parse_expressions_for_values(Vector<String> p_expressions) {
|
||||
|
|
|
@ -81,7 +81,7 @@ protected:
|
|||
static void _bind_methods();
|
||||
|
||||
private:
|
||||
class Item;
|
||||
struct Item;
|
||||
|
||||
struct Line {
|
||||
|
||||
|
@ -103,10 +103,7 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
class Item : public Object {
|
||||
GDCLASS(Item, Object);
|
||||
|
||||
public:
|
||||
struct Item {
|
||||
int index;
|
||||
Item *parent;
|
||||
ItemType type;
|
||||
|
@ -129,10 +126,7 @@ private:
|
|||
virtual ~Item() { _clear_children(); }
|
||||
};
|
||||
|
||||
class ItemFrame : public Item {
|
||||
GDCLASS(ItemFrame, Item);
|
||||
|
||||
public:
|
||||
struct ItemFrame : public Item {
|
||||
int parent_line;
|
||||
bool cell;
|
||||
Vector<Line> lines;
|
||||
|
@ -147,95 +141,59 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
class ItemText : public Item {
|
||||
GDCLASS(ItemText, Item);
|
||||
|
||||
public:
|
||||
struct ItemText : public Item {
|
||||
String text;
|
||||
ItemText() { type = ITEM_TEXT; }
|
||||
};
|
||||
|
||||
class ItemImage : public Item {
|
||||
GDCLASS(ItemImage, Item);
|
||||
|
||||
public:
|
||||
struct ItemImage : public Item {
|
||||
Ref<Texture> image;
|
||||
ItemImage() { type = ITEM_IMAGE; }
|
||||
};
|
||||
|
||||
class ItemFont : public Item {
|
||||
GDCLASS(ItemFont, Item);
|
||||
|
||||
public:
|
||||
struct ItemFont : public Item {
|
||||
Ref<Font> font;
|
||||
ItemFont() { type = ITEM_FONT; }
|
||||
};
|
||||
|
||||
class ItemColor : public Item {
|
||||
GDCLASS(ItemColor, Item);
|
||||
|
||||
public:
|
||||
struct ItemColor : public Item {
|
||||
Color color;
|
||||
ItemColor() { type = ITEM_COLOR; }
|
||||
};
|
||||
|
||||
class ItemUnderline : public Item {
|
||||
GDCLASS(ItemUnderline, Item);
|
||||
|
||||
public:
|
||||
struct ItemUnderline : public Item {
|
||||
ItemUnderline() { type = ITEM_UNDERLINE; }
|
||||
};
|
||||
|
||||
class ItemStrikethrough : public Item {
|
||||
GDCLASS(ItemStrikethrough, Item);
|
||||
|
||||
public:
|
||||
struct ItemStrikethrough : public Item {
|
||||
ItemStrikethrough() { type = ITEM_STRIKETHROUGH; }
|
||||
};
|
||||
|
||||
class ItemMeta : public Item {
|
||||
GDCLASS(ItemMeta, Item);
|
||||
|
||||
public:
|
||||
struct ItemMeta : public Item {
|
||||
Variant meta;
|
||||
ItemMeta() { type = ITEM_META; }
|
||||
};
|
||||
|
||||
class ItemAlign : public Item {
|
||||
GDCLASS(ItemAlign, Item);
|
||||
|
||||
public:
|
||||
struct ItemAlign : public Item {
|
||||
Align align;
|
||||
ItemAlign() { type = ITEM_ALIGN; }
|
||||
};
|
||||
|
||||
class ItemIndent : public Item {
|
||||
GDCLASS(ItemIndent, Item);
|
||||
|
||||
public:
|
||||
struct ItemIndent : public Item {
|
||||
int level;
|
||||
ItemIndent() { type = ITEM_INDENT; }
|
||||
};
|
||||
|
||||
class ItemList : public Item {
|
||||
GDCLASS(ItemList, Item);
|
||||
|
||||
public:
|
||||
struct ItemList : public Item {
|
||||
ListType list_type;
|
||||
ItemList() { type = ITEM_LIST; }
|
||||
};
|
||||
|
||||
class ItemNewline : public Item {
|
||||
GDCLASS(ItemNewline, Item);
|
||||
|
||||
public:
|
||||
struct ItemNewline : public Item {
|
||||
ItemNewline() { type = ITEM_NEWLINE; }
|
||||
};
|
||||
|
||||
class ItemTable : public Item {
|
||||
GDCLASS(ItemTable, Item);
|
||||
|
||||
public:
|
||||
struct ItemTable : public Item {
|
||||
struct Column {
|
||||
bool expand;
|
||||
int expand_ratio;
|
||||
|
@ -249,20 +207,14 @@ private:
|
|||
ItemTable() { type = ITEM_TABLE; }
|
||||
};
|
||||
|
||||
class ItemFade : public Item {
|
||||
GDCLASS(ItemFade, Item);
|
||||
|
||||
public:
|
||||
struct ItemFade : public Item {
|
||||
int starting_index;
|
||||
int length;
|
||||
|
||||
ItemFade() { type = ITEM_FADE; }
|
||||
};
|
||||
|
||||
class ItemFX : public Item {
|
||||
GDCLASS(ItemFX, Item);
|
||||
|
||||
public:
|
||||
struct ItemFX : public Item {
|
||||
float elapsed_time;
|
||||
|
||||
ItemFX() {
|
||||
|
@ -270,10 +222,7 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
class ItemShake : public ItemFX {
|
||||
GDCLASS(ItemShake, ItemFX);
|
||||
|
||||
public:
|
||||
struct ItemShake : public ItemFX {
|
||||
int strength;
|
||||
float rate;
|
||||
uint64_t _current_rng;
|
||||
|
@ -302,10 +251,7 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
class ItemWave : public ItemFX {
|
||||
GDCLASS(ItemWave, ItemFX);
|
||||
|
||||
public:
|
||||
struct ItemWave : public ItemFX {
|
||||
float frequency;
|
||||
float amplitude;
|
||||
|
||||
|
@ -316,10 +262,7 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
class ItemTornado : public ItemFX {
|
||||
GDCLASS(ItemTornado, ItemFX);
|
||||
|
||||
public:
|
||||
struct ItemTornado : public ItemFX {
|
||||
float radius;
|
||||
float frequency;
|
||||
|
||||
|
@ -330,10 +273,7 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
class ItemRainbow : public ItemFX {
|
||||
GDCLASS(ItemRainbow, ItemFX);
|
||||
|
||||
public:
|
||||
struct ItemRainbow : public ItemFX {
|
||||
float saturation;
|
||||
float value;
|
||||
float frequency;
|
||||
|
@ -346,22 +286,21 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
class ItemCustomFX : public ItemFX {
|
||||
GDCLASS(ItemCustomFX, ItemFX);
|
||||
|
||||
public:
|
||||
String identifier;
|
||||
Dictionary environment;
|
||||
struct ItemCustomFX : public ItemFX {
|
||||
Ref<CharFXTransform> char_fx_transform;
|
||||
Ref<RichTextEffect> custom_effect;
|
||||
|
||||
ItemCustomFX() {
|
||||
identifier = "";
|
||||
environment = Dictionary();
|
||||
type = ITEM_CUSTOMFX;
|
||||
|
||||
char_fx_transform.instance();
|
||||
}
|
||||
|
||||
virtual ~ItemCustomFX() {
|
||||
_clear_children();
|
||||
environment.clear();
|
||||
|
||||
char_fx_transform.unref();
|
||||
custom_effect.unref();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -440,32 +379,7 @@ private:
|
|||
bool _find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item = NULL);
|
||||
bool _find_layout_subitem(Item *from, Item *to);
|
||||
bool _find_by_type(Item *p_item, ItemType p_type);
|
||||
template <typename T>
|
||||
T *_fetch_by_type(Item *p_item, ItemType p_type) {
|
||||
Item *item = p_item;
|
||||
T *result = NULL;
|
||||
while (item) {
|
||||
if (item->type == p_type) {
|
||||
result = Object::cast_to<T>(item);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
item = item->parent;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
template <typename T>
|
||||
void _fetch_item_stack(Item *p_item, Vector<T *> &r_stack) {
|
||||
Item *item = p_item;
|
||||
while (item) {
|
||||
T *found = Object::cast_to<T>(item);
|
||||
if (found) {
|
||||
r_stack.push_back(found);
|
||||
}
|
||||
item = item->parent;
|
||||
}
|
||||
}
|
||||
void _fetch_item_fx_stack(Item *p_item, Vector<ItemFX *> &r_stack);
|
||||
|
||||
void _update_scroll();
|
||||
void _update_fx(ItemFrame *p_frame, float p_delta_time);
|
||||
|
@ -509,7 +423,7 @@ public:
|
|||
void push_wave(float p_frequency, float p_amplitude);
|
||||
void push_tornado(float p_frequency, float p_radius);
|
||||
void push_rainbow(float p_saturation, float p_value, float p_frequency);
|
||||
void push_customfx(String p_identifier, Dictionary p_environment);
|
||||
void push_customfx(Ref<RichTextEffect> p_custom_effect, Dictionary p_environment);
|
||||
void set_table_column_expand(int p_column, bool p_expand, int p_ratio = 1);
|
||||
int get_current_table_column() const;
|
||||
void push_cell();
|
||||
|
|
Loading…
Reference in a new issue