diff options
Diffstat (limited to 'scene/gui')
| -rw-r--r-- | scene/gui/color_picker.cpp | 18 | ||||
| -rw-r--r-- | scene/gui/control.cpp | 2 | ||||
| -rw-r--r-- | scene/gui/dialogs.cpp | 18 | ||||
| -rw-r--r-- | scene/gui/dialogs.h | 1 | ||||
| -rw-r--r-- | scene/gui/grid_container.cpp | 37 | ||||
| -rw-r--r-- | scene/gui/rich_text_effect.cpp | 5 | ||||
| -rw-r--r-- | scene/gui/rich_text_effect.h | 2 | ||||
| -rw-r--r-- | scene/gui/rich_text_label.cpp | 85 | ||||
| -rw-r--r-- | scene/gui/rich_text_label.h | 148 | ||||
| -rw-r--r-- | scene/gui/tabs.cpp | 15 | ||||
| -rw-r--r-- | scene/gui/tabs.h | 1 | ||||
| -rw-r--r-- | scene/gui/text_edit.cpp | 4 | ||||
| -rw-r--r-- | scene/gui/texture_progress.cpp | 11 | ||||
| -rw-r--r-- | scene/gui/tree.cpp | 24 | ||||
| -rw-r--r-- | scene/gui/tree.h | 1 |
15 files changed, 189 insertions, 183 deletions
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 6dd9e401f6..ffe011e5f7 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -396,11 +396,18 @@ void ColorPicker::_update_text_value() { } void ColorPicker::_sample_draw() { - Rect2 r = Rect2(Point2(), Size2(uv_edit->get_size().width, sample->get_size().height * 0.95)); + const Rect2 r = Rect2(Point2(), Size2(uv_edit->get_size().width, sample->get_size().height * 0.95)); + if (color.a < 1.0) { sample->draw_texture_rect(get_icon("preset_bg", "ColorPicker"), r, true); } + sample->draw_rect(r, color); + + if (color.r > 1 || color.g > 1 || color.b > 1) { + // Draw an indicator to denote that the color is "overbright" and can't be displayed accurately in the preview + sample->draw_texture(get_icon("overbright_indicator", "ColorPicker"), Point2()); + } } void ColorPicker::_hsv_draw(int p_which, Control *c) { @@ -894,10 +901,15 @@ void ColorPickerButton::_notification(int p_what) { switch (p_what) { case NOTIFICATION_DRAW: { - Ref<StyleBox> normal = get_stylebox("normal"); - Rect2 r = Rect2(normal->get_offset(), get_size() - normal->get_minimum_size()); + const Ref<StyleBox> normal = get_stylebox("normal"); + const Rect2 r = Rect2(normal->get_offset(), get_size() - normal->get_minimum_size()); draw_texture_rect(Control::get_icon("bg", "ColorPickerButton"), r, true); draw_rect(r, color); + + if (color.r > 1 || color.g > 1 || color.b > 1) { + // Draw an indicator to denote that the color is "overbright" and can't be displayed accurately in the preview + draw_texture(Control::get_icon("overbright_indicator", "ColorPicker"), normal->get_offset()); + } } break; case MainLoop::NOTIFICATION_WM_QUIT_REQUEST: { diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index f8f29632b3..fc67b28095 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -2948,7 +2948,7 @@ void Control::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_global_position", PROPERTY_HINT_NONE, "", 0), "_set_global_position", "get_global_position"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_min_size"), "set_custom_minimum_size", "get_custom_minimum_size"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "rect_rotation", PROPERTY_HINT_RANGE, "-1080,1080,0.01"), "set_rotation_degrees", "get_rotation_degrees"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "rect_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater"), "set_rotation_degrees", "get_rotation_degrees"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_scale"), "set_scale", "get_scale"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_pivot_offset"), "set_pivot_offset", "get_pivot_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rect_clip_content"), "set_clip_contents", "is_clipping_contents"); diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index 9ed1d2bf45..31551d6257 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -206,9 +206,9 @@ void WindowDialog::_notification(int p_what) { Color title_color = get_color("title_color", "WindowDialog"); int title_height = get_constant("title_height", "WindowDialog"); int font_height = title_font->get_height() - title_font->get_descent() * 2; - int x = (size.x - title_font->get_string_size(title).x) / 2; + int x = (size.x - title_font->get_string_size(xl_title).x) / 2; int y = (-title_height + font_height) / 2; - title_font->draw(canvas, Point2(x, y), title, title_color, size.x - panel->get_minimum_size().x); + title_font->draw(canvas, Point2(x, y), xl_title, title_color, size.x - panel->get_minimum_size().x); } break; case NOTIFICATION_THEME_CHANGED: @@ -222,8 +222,9 @@ void WindowDialog::_notification(int p_what) { case NOTIFICATION_TRANSLATION_CHANGED: { String new_title = tr(title); - if (title != new_title) { - title = new_title; + if (new_title != xl_title) { + xl_title = new_title; + minimum_size_changed(); update(); } } break; @@ -283,9 +284,10 @@ int WindowDialog::_drag_hit_test(const Point2 &pos) const { void WindowDialog::set_title(const String &p_title) { - String new_title = tr(p_title); - if (title != new_title) { - title = new_title; + if (title != p_title) { + title = p_title; + xl_title = tr(p_title); + minimum_size_changed(); update(); } } @@ -306,7 +308,7 @@ Size2 WindowDialog::get_minimum_size() const { Ref<Font> font = get_font("title_font", "WindowDialog"); const int button_width = close_button->get_combined_minimum_size().x; - const int title_width = font->get_string_size(title).x; + const int title_width = font->get_string_size(xl_title).x; const int padding = button_width / 2; const int button_area = button_width + padding; diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h index 1a0350ba18..afd1173f28 100644 --- a/scene/gui/dialogs.h +++ b/scene/gui/dialogs.h @@ -53,6 +53,7 @@ class WindowDialog : public Popup { TextureButton *close_button; String title; + String xl_title; int drag_type; Point2 drag_offset; Point2 drag_offset_far; diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp index d0e2edc7b5..d304a37f82 100644 --- a/scene/gui/grid_container.cpp +++ b/scene/gui/grid_container.cpp @@ -36,20 +36,18 @@ void GridContainer::_notification(int p_what) { case NOTIFICATION_SORT_CHILDREN: { - int valid_controls_index; - - Map<int, int> col_minw; // max of min_width of all controls in each col (indexed by col) - Map<int, int> row_minh; // max of min_height of all controls in each row (indexed by row) - Set<int> col_expanded; // columns which have the SIZE_EXPAND flag set - Set<int> row_expanded; // rows which have the SIZE_EXPAND flag set + Map<int, int> col_minw; // Max of min_width of all controls in each col (indexed by col). + Map<int, int> row_minh; // Max of min_height of all controls in each row (indexed by row). + Set<int> col_expanded; // Columns which have the SIZE_EXPAND flag set. + Set<int> row_expanded; // Rows which have the SIZE_EXPAND flag set. int hsep = get_constant("hseparation"); int vsep = get_constant("vseparation"); int max_col = MIN(get_child_count(), columns); int max_row = get_child_count() / columns; - // Compute the per-column/per-row data - valid_controls_index = 0; + // Compute the per-column/per-row data. + int valid_controls_index = 0; for (int i = 0; i < get_child_count(); i++) { Control *c = Object::cast_to<Control>(get_child(i)); if (!c || !c->is_visible_in_tree()) @@ -77,7 +75,12 @@ void GridContainer::_notification(int p_what) { } } - // Evaluate the remaining space for expanded columns/rows + // Consider all empty columns expanded. + for (int i = valid_controls_index; i < columns; i++) { + col_expanded.insert(i); + } + + // Evaluate the remaining space for expanded columns/rows. Size2 remaining_space = get_size(); for (Map<int, int>::Element *E = col_minw.front(); E; E = E->next()) { if (!col_expanded.has(E->key())) @@ -93,7 +96,7 @@ void GridContainer::_notification(int p_what) { bool can_fit = false; while (!can_fit && col_expanded.size() > 0) { - // Check if all minwidth constraints are ok if we use the remaining space + // Check if all minwidth constraints are OK if we use the remaining space. can_fit = true; int max_index = col_expanded.front()->get(); for (Set<int>::Element *E = col_expanded.front(); E; E = E->next()) { @@ -105,7 +108,7 @@ void GridContainer::_notification(int p_what) { } } - // If not, the column with maximum minwidth is not expanded + // If not, the column with maximum minwidth is not expanded. if (!can_fit) { col_expanded.erase(max_index); remaining_space.width -= col_minw[max_index]; @@ -114,7 +117,7 @@ void GridContainer::_notification(int p_what) { can_fit = false; while (!can_fit && row_expanded.size() > 0) { - // Check if all minwidth constraints are ok if we use the remaining space + // Check if all minheight constraints are OK if we use the remaining space. can_fit = true; int max_index = row_expanded.front()->get(); for (Set<int>::Element *E = row_expanded.front(); E; E = E->next()) { @@ -126,14 +129,14 @@ void GridContainer::_notification(int p_what) { } } - // If not, the row with maximum minwidth is not expanded + // If not, the row with maximum minheight is not expanded. if (!can_fit) { row_expanded.erase(max_index); remaining_space.height -= row_minh[max_index]; } } - // Finally, fit the nodes + // Finally, fit the nodes. int col_expand = col_expanded.size() > 0 ? remaining_space.width / col_expanded.size() : 0; int row_expand = row_expanded.size() > 0 ? remaining_space.height / row_expanded.size() : 0; @@ -152,11 +155,11 @@ void GridContainer::_notification(int p_what) { if (col == 0) { col_ofs = 0; if (row > 0) - row_ofs += ((row_expanded.has(row - 1)) ? row_expand : row_minh[row - 1]) + vsep; + row_ofs += (row_expanded.has(row - 1) ? row_expand : row_minh[row - 1]) + vsep; } Point2 p(col_ofs, row_ofs); - Size2 s((col_expanded.has(col)) ? col_expand : col_minw[col], (row_expanded.has(row)) ? row_expand : row_minh[row]); + Size2 s(col_expanded.has(col) ? col_expand : col_minw[col], row_expanded.has(row) ? row_expand : row_minh[row]); fit_child_in_rect(c, Rect2(p, s)); @@ -207,7 +210,7 @@ Size2 GridContainer::get_minimum_size() const { for (int i = 0; i < get_child_count(); i++) { Control *c = Object::cast_to<Control>(get_child(i)); - if (!c || !c->is_visible_in_tree()) + if (!c || !c->is_visible()) continue; int row = valid_controls_index / columns; int col = valid_controls_index % columns; diff --git a/scene/gui/rich_text_effect.cpp b/scene/gui/rich_text_effect.cpp index 67fa85b832..f9e0be5b31 100644 --- a/scene/gui/rich_text_effect.cpp +++ b/scene/gui/rich_text_effect.cpp @@ -119,4 +119,9 @@ CharFXTransform::CharFXTransform() { offset = Point2(); color = Color(); character = 0; + elapsed_time = 0.0f; +} + +CharFXTransform::~CharFXTransform() { + environment.clear(); } diff --git a/scene/gui/rich_text_effect.h b/scene/gui/rich_text_effect.h index f9c3e15399..4330cebfe6 100644 --- a/scene/gui/rich_text_effect.h +++ b/scene/gui/rich_text_effect.h @@ -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; } diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index d9ae42d6e6..c5330c78e1 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -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]); - - 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); + 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 (!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) { diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 481f8d9746..1c90d974e4 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -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(); diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index 93b091e8d0..c24f15384b 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tabs.cpp @@ -53,7 +53,7 @@ Size2 Tabs::get_minimum_size() const { ms.width += get_constant("hseparation"); } - ms.width += Math::ceil(font->get_string_size(tabs[i].text).width); + ms.width += Math::ceil(font->get_string_size(tabs[i].xl_text).width); if (tabs[i].disabled) ms.width += tab_disabled->get_minimum_size().width; @@ -223,6 +223,9 @@ void Tabs::_notification(int p_what) { switch (p_what) { case NOTIFICATION_TRANSLATION_CHANGED: { + for (int i = 0; i < tabs.size(); ++i) { + tabs.write[i].xl_text = tr(tabs[i].text); + } minimum_size_changed(); update(); } break; @@ -318,7 +321,7 @@ void Tabs::_notification(int p_what) { w += icon->get_width() + get_constant("hseparation"); } - font->draw(ci, Point2i(w, sb->get_margin(MARGIN_TOP) + ((sb_rect.size.y - sb_ms.y) - font->get_height()) / 2 + font->get_ascent()), tabs[i].text, col, tabs[i].size_text); + font->draw(ci, Point2i(w, sb->get_margin(MARGIN_TOP) + ((sb_rect.size.y - sb_ms.y) - font->get_height()) / 2 + font->get_ascent()), tabs[i].xl_text, col, tabs[i].size_text); w += tabs[i].size_text; @@ -435,6 +438,7 @@ void Tabs::set_tab_title(int p_tab, const String &p_title) { ERR_FAIL_INDEX(p_tab, tabs.size()); tabs.write[p_tab].text = p_title; + tabs.write[p_tab].xl_text = tr(p_title); update(); minimum_size_changed(); } @@ -543,7 +547,7 @@ void Tabs::_update_cache() { for (int i = 0; i < tabs.size(); i++) { tabs.write[i].ofs_cache = mw; tabs.write[i].size_cache = get_tab_width(i); - tabs.write[i].size_text = Math::ceil(font->get_string_size(tabs[i].text).width); + tabs.write[i].size_text = Math::ceil(font->get_string_size(tabs[i].xl_text).width); mw += tabs[i].size_cache; if (tabs[i].size_cache <= min_width || i == current) { size_fixed += tabs[i].size_cache; @@ -604,6 +608,7 @@ void Tabs::add_tab(const String &p_str, const Ref<Texture> &p_icon) { Tab t; t.text = p_str; + t.xl_text = tr(p_str); t.icon = p_icon; t.disabled = false; t.ofs_cache = 0; @@ -659,7 +664,7 @@ Variant Tabs::get_drag_data(const Point2 &p_point) { tf->set_texture(tabs[tab_over].icon); drag_preview->add_child(tf); } - Label *label = memnew(Label(tabs[tab_over].text)); + Label *label = memnew(Label(tabs[tab_over].xl_text)); drag_preview->add_child(label); if (!tabs[tab_over].right_button.is_null()) { TextureRect *tf = memnew(TextureRect); @@ -808,7 +813,7 @@ int Tabs::get_tab_width(int p_idx) const { x += get_constant("hseparation"); } - x += Math::ceil(font->get_string_size(tabs[p_idx].text).width); + x += Math::ceil(font->get_string_size(tabs[p_idx].xl_text).width); if (tabs[p_idx].disabled) x += tab_disabled->get_minimum_size().width; diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h index a762b5b9cb..0edf2fedc1 100644 --- a/scene/gui/tabs.h +++ b/scene/gui/tabs.h @@ -58,6 +58,7 @@ private: struct Tab { String text; + String xl_text; Ref<Texture> icon; int ofs_cache; bool disabled; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 75c845b8db..e2bb4e3e91 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -3965,7 +3965,7 @@ void TextEdit::_base_remove_text(int p_from_line, int p_from_column, int p_to_li void TextEdit::_insert_text(int p_line, int p_char, const String &p_text, int *r_end_line, int *r_end_char) { - if (!setting_text) + if (!setting_text && idle_detect->is_inside_tree()) idle_detect->start(); if (undo_enabled) { @@ -4019,7 +4019,7 @@ void TextEdit::_insert_text(int p_line, int p_char, const String &p_text, int *r void TextEdit::_remove_text(int p_from_line, int p_from_column, int p_to_line, int p_to_column) { - if (!setting_text) + if (!setting_text && idle_detect->is_inside_tree()) idle_detect->start(); String text; diff --git a/scene/gui/texture_progress.cpp b/scene/gui/texture_progress.cpp index c534df5cbe..9b60a9d1c3 100644 --- a/scene/gui/texture_progress.cpp +++ b/scene/gui/texture_progress.cpp @@ -344,6 +344,9 @@ void TextureProgress::_notification(int p_what) { case FILL_CLOCKWISE: case FILL_COUNTER_CLOCKWISE: case FILL_CLOCKWISE_AND_COUNTER_CLOCKWISE: { + if (nine_patch_stretch) + s = get_size(); + float val = get_as_ratio() * rad_max_degrees / 360; if (val == 1) { Rect2 region = Rect2(Point2(), s); @@ -384,7 +387,13 @@ void TextureProgress::_notification(int p_what) { draw_polygon(points, colors, uvs, progress); } if (Engine::get_singleton()->is_editor_hint()) { - Point2 p = progress->get_size(); + Point2 p; + + if (nine_patch_stretch) + p = get_size(); + else + p = progress->get_size(); + p.x *= get_relative_center().x; p.y *= get_relative_center().y; p = p.floor(); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 57663bbe82..50b0b12029 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -547,6 +547,11 @@ Ref<Texture> TreeItem::get_button(int p_column, int p_idx) const { ERR_FAIL_INDEX_V(p_idx, cells[p_column].buttons.size(), Ref<Texture>()); return cells[p_column].buttons[p_idx].texture; } +String TreeItem::get_button_tooltip(int p_column, int p_idx) const { + ERR_FAIL_INDEX_V(p_column, cells.size(), String()); + ERR_FAIL_INDEX_V(p_idx, cells[p_column].buttons.size(), String()); + return cells[p_column].buttons[p_idx].tooltip; +} int TreeItem::get_button_id(int p_column, int p_idx) const { ERR_FAIL_INDEX_V(p_column, cells.size(), -1); ERR_FAIL_INDEX_V(p_idx, cells[p_column].buttons.size(), -1); @@ -795,6 +800,7 @@ void TreeItem::_bind_methods() { ClassDB::bind_method(D_METHOD("add_button", "column", "button", "button_idx", "disabled", "tooltip"), &TreeItem::add_button, DEFVAL(-1), DEFVAL(false), DEFVAL("")); ClassDB::bind_method(D_METHOD("get_button_count", "column"), &TreeItem::get_button_count); + ClassDB::bind_method(D_METHOD("get_button_tooltip", "column", "button_idx"), &TreeItem::get_button_tooltip); ClassDB::bind_method(D_METHOD("get_button", "column", "button_idx"), &TreeItem::get_button); ClassDB::bind_method(D_METHOD("set_button", "column", "button_idx", "button"), &TreeItem::set_button); ClassDB::bind_method(D_METHOD("erase_button", "column", "button_idx"), &TreeItem::erase_button); @@ -2546,7 +2552,9 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { } else { Rect2 rect = get_selected()->get_meta("__focus_rect"); if (rect.has_point(Point2(b->get_position().x, b->get_position().y))) { - edit_selected(); + if (!edit_selected()) { + emit_signal("item_double_clicked"); + } } else { emit_signal("item_double_clicked"); } @@ -2669,11 +2677,21 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { } break; case BUTTON_WHEEL_UP: { + double prev_value = v_scroll->get_value(); v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * b->get_factor() / 8); + if (v_scroll->get_value() != prev_value) { + accept_event(); + } + } break; case BUTTON_WHEEL_DOWN: { + double prev_value = v_scroll->get_value(); v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * b->get_factor() / 8); + if (v_scroll->get_value() != prev_value) { + accept_event(); + } + } break; } } @@ -2681,7 +2699,11 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { Ref<InputEventPanGesture> pan_gesture = p_event; if (pan_gesture.is_valid()) { + double prev_value = v_scroll->get_value(); v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * pan_gesture->get_delta().y / 8); + if (v_scroll->get_value() != prev_value) { + accept_event(); + } } } diff --git a/scene/gui/tree.h b/scene/gui/tree.h index f12d8fc4d2..47befb0c15 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -201,6 +201,7 @@ public: void add_button(int p_column, const Ref<Texture> &p_button, int p_id = -1, bool p_disabled = false, const String &p_tooltip = ""); int get_button_count(int p_column) const; + String get_button_tooltip(int p_column, int p_idx) const; Ref<Texture> get_button(int p_column, int p_idx) const; int get_button_id(int p_column, int p_idx) const; void erase_button(int p_column, int p_idx); |