diff options
Diffstat (limited to 'scene')
-rw-r--r-- | scene/animation/animation_blend_tree.cpp | 15 | ||||
-rw-r--r-- | scene/animation/animation_tree.cpp | 2 | ||||
-rw-r--r-- | scene/gui/code_edit.cpp | 23 | ||||
-rw-r--r-- | scene/gui/code_edit.h | 2 | ||||
-rw-r--r-- | scene/gui/container.cpp | 5 | ||||
-rw-r--r-- | scene/gui/label.cpp | 102 | ||||
-rw-r--r-- | scene/gui/menu_button.cpp | 8 | ||||
-rw-r--r-- | scene/gui/rich_text_label.cpp | 57 | ||||
-rw-r--r-- | scene/gui/tab_container.cpp | 2 | ||||
-rw-r--r-- | scene/main/viewport.cpp | 17 | ||||
-rw-r--r-- | scene/resources/font.cpp | 51 | ||||
-rw-r--r-- | scene/resources/material.cpp | 6 |
12 files changed, 169 insertions, 121 deletions
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index d11387902a..af186072ac 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -248,27 +248,26 @@ double AnimationNodeOneShot::process(double p_time, bool p_seek) { if (fade_in > 0) { blend = time / fade_in; } else { - blend = 0; //wtf + blend = 0; } - - } else if (!do_start && remaining < fade_out) { - if (fade_out) { + } else if (!do_start && remaining <= fade_out) { + if (fade_out > 0) { blend = (remaining / fade_out); } else { - blend = 1.0; + blend = 0; } } else { blend = 1.0; } - float main_rem; + double main_rem; if (mix == MIX_MODE_ADD) { main_rem = blend_input(0, p_time, p_seek, 1.0, FILTER_IGNORE, !sync); } else { main_rem = blend_input(0, p_time, p_seek, 1.0 - blend, FILTER_BLEND, !sync); } - float os_rem = blend_input(1, os_seek ? time : p_time, os_seek, blend, FILTER_PASS, false); + double os_rem = blend_input(1, os_seek ? time : p_time, os_seek, blend, FILTER_PASS, false); if (do_start) { remaining = os_rem; @@ -718,7 +717,7 @@ double AnimationNodeTransition::process(double p_time, bool p_seek) { } else { // cross-fading from prev to current - float blend = xfade ? (prev_xfading / xfade) : 1; + float blend = xfade == 0 ? 0 : (prev_xfading / xfade); if (!p_seek && switched) { //just switched, seek to start of current diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 88fb960164..9ca8d478b1 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -958,7 +958,7 @@ void AnimationTree::_process_graph(real_t p_delta) { Variant::interpolate(t->value, value, blend, t->value); - } else if (delta != 0) { + } else { List<int> indices; a->value_track_get_key_indices(i, time, delta, &indices); diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index e7769f9372..4dfd6902e6 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -467,7 +467,7 @@ void CodeEdit::gui_input(const Ref<InputEvent> &p_gui_input) { } /* MISC */ - if (k->is_action("ui_cancel", true)) { + if (!code_hint.is_empty() && k->is_action("ui_cancel", true)) { set_code_hint(""); accept_event(); return; @@ -1725,14 +1725,17 @@ bool CodeEdit::is_code_completion_enabled() const { void CodeEdit::set_code_completion_prefixes(const TypedArray<String> &p_prefixes) { code_completion_prefixes.clear(); for (int i = 0; i < p_prefixes.size(); i++) { - code_completion_prefixes.insert(p_prefixes[i]); + const String prefix = p_prefixes[i]; + + ERR_CONTINUE_MSG(prefix.is_empty(), "Code completion prefix cannot be empty."); + code_completion_prefixes.insert(prefix[0]); } } TypedArray<String> CodeEdit::get_code_completion_prefixes() const { TypedArray<String> prefixes; - for (Set<String>::Element *E = code_completion_prefixes.front(); E; E = E->next()) { - prefixes.push_back(E->get()); + for (const Set<char32_t>::Element *E = code_completion_prefixes.front(); E; E = E->next()) { + prefixes.push_back(String::chr(E->get())); } return prefixes; } @@ -1795,9 +1798,9 @@ void CodeEdit::request_code_completion(bool p_force) { String line = get_line(get_caret_line()); int ofs = CLAMP(get_caret_column(), 0, line.length()); - if (ofs > 0 && (is_in_string(get_caret_line(), ofs) != -1 || _is_char(line[ofs - 1]) || code_completion_prefixes.has(String::chr(line[ofs - 1])))) { + if (ofs > 0 && (is_in_string(get_caret_line(), ofs) != -1 || _is_char(line[ofs - 1]) || code_completion_prefixes.has(line[ofs - 1]))) { emit_signal(SNAME("request_code_completion")); - } else if (ofs > 1 && line[ofs - 1] == ' ' && code_completion_prefixes.has(String::chr(line[ofs - 2]))) { + } else if (ofs > 1 && line[ofs - 1] == ' ' && code_completion_prefixes.has(line[ofs - 2])) { emit_signal(SNAME("request_code_completion")); } } @@ -1969,7 +1972,7 @@ void CodeEdit::confirm_code_completion(bool p_replace) { end_complex_operation(); cancel_code_completion(); - if (code_completion_prefixes.has(String::chr(last_completion_char))) { + if (code_completion_prefixes.has(last_completion_char)) { request_code_completion(); } } @@ -2764,7 +2767,7 @@ void CodeEdit::_filter_code_completion_candidates_impl() { bool prev_is_word = false; /* Cancel if we are at the close of a string. */ - if (in_string == -1 && first_quote_col == cofs - 1) { + if (caret_column > 0 && in_string == -1 && first_quote_col == cofs - 1) { cancel_code_completion(); return; /* In a string, therefore we are trying to complete the string text. */ @@ -2790,9 +2793,9 @@ void CodeEdit::_filter_code_completion_candidates_impl() { /* If all else fails, check for a prefix. */ /* Single space between caret and prefix is okay. */ bool prev_is_prefix = false; - if (cofs > 0 && code_completion_prefixes.has(String::chr(line[cofs - 1]))) { + if (cofs > 0 && code_completion_prefixes.has(line[cofs - 1])) { prev_is_prefix = true; - } else if (cofs > 1 && line[cofs - 1] == ' ' && code_completion_prefixes.has(String::chr(line[cofs - 2]))) { + } else if (cofs > 1 && line[cofs - 1] == ' ' && code_completion_prefixes.has(line[cofs - 2])) { prev_is_prefix = true; } diff --git a/scene/gui/code_edit.h b/scene/gui/code_edit.h index 740548d559..d8eccb7d32 100644 --- a/scene/gui/code_edit.h +++ b/scene/gui/code_edit.h @@ -214,7 +214,7 @@ private: int code_completion_longest_line = 0; Rect2i code_completion_rect; - Set<String> code_completion_prefixes; + Set<char32_t> code_completion_prefixes; List<ScriptCodeCompletionOption> code_completion_option_submitted; List<ScriptCodeCompletionOption> code_completion_option_sources; String code_completion_base; diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp index c97434f69b..11941529cd 100644 --- a/scene/gui/container.cpp +++ b/scene/gui/container.cpp @@ -96,17 +96,18 @@ void Container::fit_child_in_rect(Control *p_child, const Rect2 &p_rect) { ERR_FAIL_COND(!p_child); ERR_FAIL_COND(p_child->get_parent() != this); + bool rtl = is_layout_rtl(); Size2 minsize = p_child->get_combined_minimum_size(); Rect2 r = p_rect; if (!(p_child->get_h_size_flags() & SIZE_FILL)) { r.size.x = minsize.width; if (p_child->get_h_size_flags() & SIZE_SHRINK_END) { - r.position.x += p_rect.size.width - minsize.width; + r.position.x += rtl ? 0 : (p_rect.size.width - minsize.width); } else if (p_child->get_h_size_flags() & SIZE_SHRINK_CENTER) { r.position.x += Math::floor((p_rect.size.x - minsize.width) / 2); } else { - r.position.x += 0; + r.position.x += rtl ? (p_rect.size.width - minsize.width) : 0; } } diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 5600816b2d..18cde25e55 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -92,8 +92,12 @@ void Label::_shape() { const Ref<Font> &font = get_theme_font(SNAME("font")); int font_size = get_theme_font_size(SNAME("font_size")); ERR_FAIL_COND(font.is_null()); - TS->shaped_text_add_string(text_rid, (uppercase) ? xl_text.to_upper() : xl_text, font->get_rids(), font_size, opentype_features, (language != "") ? language : TranslationServer::get_singleton()->get_tool_locale()); - TS->shaped_text_set_bidi_override(text_rid, structured_text_parser(st_parser, st_args, xl_text)); + String text = (uppercase) ? xl_text.to_upper() : xl_text; + if (visible_chars >= 0) { + text = text.substr(0, visible_chars); + } + TS->shaped_text_add_string(text_rid, text, font->get_rids(), font_size, opentype_features, (language != "") ? language : TranslationServer::get_singleton()->get_tool_locale()); + TS->shaped_text_set_bidi_override(text_rid, structured_text_parser(st_parser, st_args, text)); dirty = false; lines_dirty = true; } @@ -258,11 +262,18 @@ 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; + } dirty = true; update(); } + if (p_what == NOTIFICATION_LAYOUT_DIRECTION_CHANGED) { + update(); + } + if (p_what == NOTIFICATION_DRAW) { if (clip) { RenderingServer::get_singleton()->canvas_item_set_clip(get_canvas_item(), true); @@ -286,6 +297,7 @@ void Label::_notification(int p_what) { int outline_size = get_theme_constant(SNAME("outline_size")); int shadow_outline_size = get_theme_constant(SNAME("shadow_outline_size")); bool rtl = TS->shaped_text_get_direction(text_rid); + bool rtl_layout = is_layout_rtl(); style->draw(ci, Rect2(Point2(0, 0), get_size())); @@ -342,24 +354,6 @@ void Label::_notification(int p_what) { } } - int visible_glyphs = -1; - int glyhps_drawn = 0; - if (percent_visible < 1) { - int total_glyphs = 0; - for (int i = lines_skipped; i < last_line; i++) { - const Vector<TextServer::Glyph> visual = TS->shaped_text_get_glyphs(lines_rid[i]); - const TextServer::Glyph *glyphs = visual.ptr(); - int gl_size = visual.size(); - for (int j = 0; j < gl_size; j++) { - if ((glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { - total_glyphs++; - } - } - } - - visible_glyphs = MIN(total_glyphs, visible_chars); - } - Vector2 ofs; ofs.y = style->get_offset().y + vbegin; for (int i = lines_skipped; i < last_line; i++) { @@ -375,13 +369,21 @@ void Label::_notification(int p_what) { } break; case ALIGN_LEFT: { - ofs.x = style->get_offset().x; + if (rtl_layout) { + ofs.x = int(size.width - style->get_margin(SIDE_RIGHT) - line_size.width); + } else { + ofs.x = style->get_offset().x; + } } break; case ALIGN_CENTER: { ofs.x = int(size.width - line_size.width) / 2; } break; case ALIGN_RIGHT: { - ofs.x = int(size.width - style->get_margin(SIDE_RIGHT) - line_size.width); + if (rtl_layout) { + ofs.x = style->get_offset().x; + } else { + ofs.x = int(size.width - style->get_margin(SIDE_RIGHT) - line_size.width); + } } break; } @@ -407,14 +409,6 @@ void Label::_notification(int p_what) { // Draw main text. for (int j = 0; j < gl_size; j++) { for (int k = 0; k < glyphs[j].repeat; k++) { - if (visible_glyphs != -1) { - if ((glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { - if (glyhps_drawn >= visible_glyphs) { - return; - } - } - } - // Trim when necessary. if (trim_data.trim_pos >= 0) { if (rtl) { @@ -431,7 +425,6 @@ void Label::_notification(int p_what) { // Draw glyph outlines and shadow. draw_glyph_outline(glyphs[j], ci, font_color, font_shadow_color, font_outline_color, shadow_outline_size, outline_size, offset, shadow_ofs); offset.x += glyphs[j].advance; - glyhps_drawn++; } } // Draw LTR ellipsis string when necessary. @@ -462,14 +455,6 @@ void Label::_notification(int p_what) { // Draw main text. for (int j = 0; j < gl_size; j++) { for (int k = 0; k < glyphs[j].repeat; k++) { - if (visible_glyphs != -1) { - if ((glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { - if (glyhps_drawn >= visible_glyphs) { - return; - } - } - } - // Trim when necessary. if (trim_data.trim_pos >= 0) { if (rtl) { @@ -486,7 +471,6 @@ void Label::_notification(int p_what) { // Draw glyph outlines and shadow. draw_glyph(glyphs[j], ci, font_color, ofs); ofs.x += glyphs[j].advance; - glyhps_drawn++; } } // Draw LTR ellipsis string when necessary. @@ -709,16 +693,16 @@ String Label::get_text() const { } void Label::set_visible_characters(int p_amount) { - visible_chars = p_amount; - if (get_total_character_count() > 0) { - percent_visible = (float)p_amount / (float)get_total_character_count(); - } else { - percent_visible = 1.0; - } - if (p_amount == -1) { - lines_dirty = true; + 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(); + } else { + percent_visible = 1.0; + } + dirty = true; + update(); } - update(); } int Label::get_visible_characters() const { @@ -726,15 +710,17 @@ int Label::get_visible_characters() const { } void Label::set_percent_visible(float p_percent) { - if (p_percent < 0 || p_percent >= 1) { - visible_chars = -1; - percent_visible = 1; - lines_dirty = true; - } else { - visible_chars = get_total_character_count() * p_percent; - percent_visible = p_percent; + if (percent_visible != p_percent) { + if (p_percent < 0 || p_percent >= 1) { + visible_chars = -1; + percent_visible = 1; + } else { + visible_chars = get_total_character_count() * p_percent; + percent_visible = p_percent; + } + dirty = true; + update(); } - update(); } float Label::get_percent_visible() const { @@ -889,7 +875,7 @@ 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_PROPERTY(PropertyInfo(Variant::INT, "visible_characters", PROPERTY_HINT_RANGE, "-1,128000,1", PROPERTY_USAGE_EDITOR), "set_visible_characters", "get_visible_characters"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_characters", PROPERTY_HINT_RANGE, "-1,128000,1"), "set_visible_characters", "get_visible_characters"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "percent_visible", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_percent_visible", "get_percent_visible"); 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"); diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index 0cc53a7832..ceb2092e3a 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -89,13 +89,15 @@ void MenuButton::pressed() { emit_signal(SNAME("about_to_popup")); Size2 size = get_size() * get_viewport()->get_canvas_transform().get_scale(); + popup->set_size(Size2(size.width, 0)); Point2 gp = get_screen_position(); gp.y += size.y; - + if (is_layout_rtl()) { + gp.x += size.width - popup->get_size().width; + } popup->set_position(gp); - - popup->set_size(Size2(size.width, 0)); popup->set_parent_rect(Rect2(Point2(gp - popup->get_position()), size)); + popup->take_mouse_focus(); popup->popup(); } diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index d4788775c5..2314b7a1da 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -399,8 +399,9 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> // Shape current paragraph. String text; Item *it_to = (p_line + 1 < p_frame->lines.size()) ? p_frame->lines[p_line + 1].from : nullptr; + int remaining_characters = visible_characters - l.char_offset; for (Item *it = l.from; it && it != it_to; it = _get_next_item(it)) { - if (visible_characters >= 0 && l.char_offset + l.char_count > visible_characters) { + if (visible_characters >= 0 && remaining_characters <= 0) { break; } switch (it->type) { @@ -427,7 +428,8 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> } l.text_buf->add_string("\n", font, font_size, Dictionary(), ""); text += "\n"; - l.char_count += 1; + l.char_count++; + remaining_characters--; } break; case ITEM_TEXT: { ItemText *t = (ItemText *)it; @@ -442,9 +444,10 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> Dictionary font_ftr = _find_font_features(it); String lang = _find_language(it); String tx = t->text; - if (visible_characters >= 0 && l.char_offset + l.char_count + tx.length() > visible_characters) { - tx = tx.substr(0, l.char_offset + l.char_count + tx.length() - visible_characters); + if (visible_characters >= 0 && remaining_characters >= 0) { + tx = tx.substr(0, remaining_characters); } + remaining_characters -= tx.length(); l.text_buf->add_string(tx, font, font_size, font_ftr, lang); text += tx; @@ -454,7 +457,8 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> ItemImage *img = (ItemImage *)it; l.text_buf->add_object((uint64_t)it, img->image->get_size(), img->inline_align, 1); text += String::chr(0xfffc); - l.char_count += 1; + l.char_count++; + remaining_characters--; } break; case ITEM_TABLE: { ItemTable *table = static_cast<ItemTable *>(it); @@ -483,6 +487,7 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> int cell_ch = (char_offset - (l.char_offset + l.char_count)); l.char_count += cell_ch; t_char_count += cell_ch; + remaining_characters -= cell_ch; table->columns.write[column].min_width = MAX(table->columns[column].min_width, ceil(frame->lines[i].text_buf->get_size().x)); table->columns.write[column].max_width = MAX(table->columns[column].max_width, ceil(frame->lines[i].text_buf->get_non_wraped_size().x)); @@ -3855,7 +3860,12 @@ String RichTextLabel::get_parsed_text() const { String text = ""; Item *it = main; while (it) { - if (it->type == ITEM_TEXT) { + if (it->type == ITEM_DROPCAP) { + const ItemDropcap *dc = (ItemDropcap *)it; + if (dc != nullptr) { + text += dc->text; + } + } else if (it->type == ITEM_TEXT) { ItemText *t = static_cast<ItemText *>(it); text += t->text; } else if (it->type == ITEM_NEWLINE) { @@ -3926,7 +3936,6 @@ void RichTextLabel::set_percent_visible(float p_percent) { if (p_percent < 0 || p_percent >= 1) { visible_characters = -1; percent_visible = 1; - } else { visible_characters = get_total_character_count() * p_percent; percent_visible = p_percent; @@ -4160,16 +4169,20 @@ void RichTextLabel::_bind_methods() { } void RichTextLabel::set_visible_characters(int p_visible) { - visible_characters = p_visible; - if (p_visible == -1) { - percent_visible = 1; - } else { - int total_char_count = get_total_character_count(); - if (total_char_count > 0) { - percent_visible = (float)p_visible / (float)total_char_count; + if (visible_characters != p_visible) { + visible_characters = p_visible; + if (p_visible == -1) { + percent_visible = 1; + } else { + int total_char_count = get_total_character_count(); + if (total_char_count > 0) { + percent_visible = (float)p_visible / (float)total_char_count; + } } + main->first_invalid_line = 0; //invalidate ALL + _validate_line_caches(main); + update(); } - update(); } int RichTextLabel::get_visible_characters() const { @@ -4177,9 +4190,19 @@ int RichTextLabel::get_visible_characters() const { } int RichTextLabel::get_total_character_count() const { + // Note: Do not use line buffer "char_count", it includes only visible characters. int tc = 0; - for (int i = 0; i < current_frame->lines.size(); i++) { - tc += current_frame->lines[i].char_count; + Item *it = main; + while (it) { + if (it->type == ITEM_TEXT) { + ItemText *t = static_cast<ItemText *>(it); + tc += t->text.length(); + } else if (it->type == ITEM_NEWLINE) { + tc++; + } else if (it->type == ITEM_IMAGE) { + tc++; + } + it = _get_next_item(it, true); } return tc; diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index 137ce7e96f..a423dc0173 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -538,7 +538,6 @@ void TabContainer::_notification(int p_what) { void TabContainer::_draw_tab(Ref<StyleBox> &p_tab_style, Color &p_font_color, int p_index, float p_x) { Control *control = get_tab_control(p_index); RID canvas = get_canvas_item(); - Ref<Font> font = get_theme_font(SNAME("font")); Color font_outline_color = get_theme_color(SNAME("font_outline_color")); int outline_size = get_theme_constant(SNAME("outline_size")); int icon_text_distance = get_theme_constant(SNAME("icon_separation")); @@ -1134,7 +1133,6 @@ Size2 TabContainer::get_minimum_size() const { Ref<StyleBox> tab_unselected = get_theme_stylebox(SNAME("tab_unselected")); Ref<StyleBox> tab_selected = get_theme_stylebox(SNAME("tab_selected")); Ref<StyleBox> tab_disabled = get_theme_stylebox(SNAME("tab_disabled")); - Ref<Font> font = get_theme_font(SNAME("font")); if (tabs_visible) { ms.y += MAX(MAX(tab_unselected->get_minimum_size().y, tab_selected->get_minimum_size().y), tab_disabled->get_minimum_size().y); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index cef1b830df..b3b743370b 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1972,35 +1972,30 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { Control *from = gui.key_focus ? gui.key_focus : nullptr; - // Keyboard focus. - Ref<InputEventKey> k = p_event; - // Need to check for mods, otherwise any combination of alt/ctrl/shift+<up/down/left/right/etc> is handled here when it shouldn't be. - bool mods = k.is_valid() && (k->is_ctrl_pressed() || k->is_alt_pressed() || k->is_shift_pressed() || k->is_meta_pressed()); - if (from && p_event->is_pressed()) { Control *next = nullptr; - if (p_event->is_action_pressed("ui_focus_next", true)) { + if (p_event->is_action_pressed("ui_focus_next", true, true)) { next = from->find_next_valid_focus(); } - if (p_event->is_action_pressed("ui_focus_prev", true)) { + if (p_event->is_action_pressed("ui_focus_prev", true, true)) { next = from->find_prev_valid_focus(); } - if (!mods && p_event->is_action_pressed("ui_up", true)) { + if (p_event->is_action_pressed("ui_up", true, true)) { next = from->_get_focus_neighbor(SIDE_TOP); } - if (!mods && p_event->is_action_pressed("ui_left", true)) { + if (p_event->is_action_pressed("ui_left", true, true)) { next = from->_get_focus_neighbor(SIDE_LEFT); } - if (!mods && p_event->is_action_pressed("ui_right", true)) { + if (p_event->is_action_pressed("ui_right", true, true)) { next = from->_get_focus_neighbor(SIDE_RIGHT); } - if (!mods && p_event->is_action_pressed("ui_down", true)) { + if (p_event->is_action_pressed("ui_down", true, true)) { next = from->_get_focus_neighbor(SIDE_BOTTOM); } diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index 7af8e900fd..29bd56eebd 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -689,227 +689,272 @@ void FontData::remove_cache(int p_cache_index) { } Array FontData::get_size_cache_list(int p_cache_index) const { + ERR_FAIL_COND_V(p_cache_index < 0, Array()); _ensure_rid(p_cache_index); return TS->font_get_size_cache_list(cache[p_cache_index]); } void FontData::clear_size_cache(int p_cache_index) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_clear_size_cache(cache[p_cache_index]); } void FontData::remove_size_cache(int p_cache_index, const Vector2i &p_size) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_remove_size_cache(cache[p_cache_index], p_size); } void FontData::set_variation_coordinates(int p_cache_index, const Dictionary &p_variation_coordinates) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_set_variation_coordinates(cache[p_cache_index], p_variation_coordinates); emit_changed(); } Dictionary FontData::get_variation_coordinates(int p_cache_index) const { + ERR_FAIL_COND_V(p_cache_index < 0, Dictionary()); _ensure_rid(p_cache_index); return TS->font_get_variation_coordinates(cache[p_cache_index]); } void FontData::set_ascent(int p_cache_index, int p_size, real_t p_ascent) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_set_ascent(cache[p_cache_index], p_size, p_ascent); } real_t FontData::get_ascent(int p_cache_index, int p_size) const { + ERR_FAIL_COND_V(p_cache_index < 0, 0.f); _ensure_rid(p_cache_index); return TS->font_get_ascent(cache[p_cache_index], p_size); } void FontData::set_descent(int p_cache_index, int p_size, real_t p_descent) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_set_descent(cache[p_cache_index], p_size, p_descent); } real_t FontData::get_descent(int p_cache_index, int p_size) const { + ERR_FAIL_COND_V(p_cache_index < 0, 0.f); _ensure_rid(p_cache_index); return TS->font_get_descent(cache[p_cache_index], p_size); } void FontData::set_underline_position(int p_cache_index, int p_size, real_t p_underline_position) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_set_underline_position(cache[p_cache_index], p_size, p_underline_position); } real_t FontData::get_underline_position(int p_cache_index, int p_size) const { + ERR_FAIL_COND_V(p_cache_index < 0, 0.f); _ensure_rid(p_cache_index); return TS->font_get_underline_position(cache[p_cache_index], p_size); } void FontData::set_underline_thickness(int p_cache_index, int p_size, real_t p_underline_thickness) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_set_underline_thickness(cache[p_cache_index], p_size, p_underline_thickness); } real_t FontData::get_underline_thickness(int p_cache_index, int p_size) const { + ERR_FAIL_COND_V(p_cache_index < 0, 0.f); _ensure_rid(p_cache_index); return TS->font_get_underline_thickness(cache[p_cache_index], p_size); } void FontData::set_scale(int p_cache_index, int p_size, real_t p_scale) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_set_scale(cache[p_cache_index], p_size, p_scale); } real_t FontData::get_scale(int p_cache_index, int p_size) const { + ERR_FAIL_COND_V(p_cache_index < 0, 0.f); _ensure_rid(p_cache_index); return TS->font_get_scale(cache[p_cache_index], p_size); } void FontData::set_spacing(int p_cache_index, int p_size, TextServer::SpacingType p_spacing, int p_value) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_set_spacing(cache[p_cache_index], p_size, p_spacing, p_value); } int FontData::get_spacing(int p_cache_index, int p_size, TextServer::SpacingType p_spacing) const { + ERR_FAIL_COND_V(p_cache_index < 0, 0); _ensure_rid(p_cache_index); return TS->font_get_spacing(cache[p_cache_index], p_size, p_spacing); } int FontData::get_texture_count(int p_cache_index, const Vector2i &p_size) const { + ERR_FAIL_COND_V(p_cache_index < 0, 0); _ensure_rid(p_cache_index); return TS->font_get_texture_count(cache[p_cache_index], p_size); } void FontData::clear_textures(int p_cache_index, const Vector2i &p_size) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_clear_textures(cache[p_cache_index], p_size); } void FontData::remove_texture(int p_cache_index, const Vector2i &p_size, int p_texture_index) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_remove_texture(cache[p_cache_index], p_size, p_texture_index); } void FontData::set_texture_image(int p_cache_index, const Vector2i &p_size, int p_texture_index, const Ref<Image> &p_image) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_set_texture_image(cache[p_cache_index], p_size, p_texture_index, p_image); } Ref<Image> FontData::get_texture_image(int p_cache_index, const Vector2i &p_size, int p_texture_index) const { + ERR_FAIL_COND_V(p_cache_index < 0, Ref<Image>()); _ensure_rid(p_cache_index); return TS->font_get_texture_image(cache[p_cache_index], p_size, p_texture_index); } void FontData::set_texture_offsets(int p_cache_index, const Vector2i &p_size, int p_texture_index, const PackedInt32Array &p_offset) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_set_texture_offsets(cache[p_cache_index], p_size, p_texture_index, p_offset); } PackedInt32Array FontData::get_texture_offsets(int p_cache_index, const Vector2i &p_size, int p_texture_index) const { + ERR_FAIL_COND_V(p_cache_index < 0, PackedInt32Array()); _ensure_rid(p_cache_index); return TS->font_get_texture_offsets(cache[p_cache_index], p_size, p_texture_index); } Array FontData::get_glyph_list(int p_cache_index, const Vector2i &p_size) const { + ERR_FAIL_COND_V(p_cache_index < 0, Array()); _ensure_rid(p_cache_index); return TS->font_get_glyph_list(cache[p_cache_index], p_size); } void FontData::clear_glyphs(int p_cache_index, const Vector2i &p_size) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_clear_glyphs(cache[p_cache_index], p_size); } void FontData::remove_glyph(int p_cache_index, const Vector2i &p_size, int32_t p_glyph) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_remove_glyph(cache[p_cache_index], p_size, p_glyph); } void FontData::set_glyph_advance(int p_cache_index, int p_size, int32_t p_glyph, const Vector2 &p_advance) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_set_glyph_advance(cache[p_cache_index], p_size, p_glyph, p_advance); } Vector2 FontData::get_glyph_advance(int p_cache_index, int p_size, int32_t p_glyph) const { + ERR_FAIL_COND_V(p_cache_index < 0, Vector2()); _ensure_rid(p_cache_index); return TS->font_get_glyph_advance(cache[p_cache_index], p_size, p_glyph); } void FontData::set_glyph_offset(int p_cache_index, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_offset) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_set_glyph_offset(cache[p_cache_index], p_size, p_glyph, p_offset); } Vector2 FontData::get_glyph_offset(int p_cache_index, const Vector2i &p_size, int32_t p_glyph) const { + ERR_FAIL_COND_V(p_cache_index < 0, Vector2()); _ensure_rid(p_cache_index); return TS->font_get_glyph_offset(cache[p_cache_index], p_size, p_glyph); } void FontData::set_glyph_size(int p_cache_index, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_gl_size) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_set_glyph_size(cache[p_cache_index], p_size, p_glyph, p_gl_size); } Vector2 FontData::get_glyph_size(int p_cache_index, const Vector2i &p_size, int32_t p_glyph) const { + ERR_FAIL_COND_V(p_cache_index < 0, Vector2()); _ensure_rid(p_cache_index); return TS->font_get_glyph_size(cache[p_cache_index], p_size, p_glyph); } void FontData::set_glyph_uv_rect(int p_cache_index, const Vector2i &p_size, int32_t p_glyph, const Rect2 &p_uv_rect) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_set_glyph_uv_rect(cache[p_cache_index], p_size, p_glyph, p_uv_rect); } Rect2 FontData::get_glyph_uv_rect(int p_cache_index, const Vector2i &p_size, int32_t p_glyph) const { + ERR_FAIL_COND_V(p_cache_index < 0, Rect2()); _ensure_rid(p_cache_index); return TS->font_get_glyph_uv_rect(cache[p_cache_index], p_size, p_glyph); } void FontData::set_glyph_texture_idx(int p_cache_index, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_set_glyph_texture_idx(cache[p_cache_index], p_size, p_glyph, p_texture_idx); } int FontData::get_glyph_texture_idx(int p_cache_index, const Vector2i &p_size, int32_t p_glyph) const { + ERR_FAIL_COND_V(p_cache_index < 0, 0); _ensure_rid(p_cache_index); return TS->font_get_glyph_texture_idx(cache[p_cache_index], p_size, p_glyph); } Array FontData::get_kerning_list(int p_cache_index, int p_size) const { + ERR_FAIL_COND_V(p_cache_index < 0, Array()); _ensure_rid(p_cache_index); return TS->font_get_kerning_list(cache[p_cache_index], p_size); } void FontData::clear_kerning_map(int p_cache_index, int p_size) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_clear_kerning_map(cache[p_cache_index], p_size); } void FontData::remove_kerning(int p_cache_index, int p_size, const Vector2i &p_glyph_pair) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_remove_kerning(cache[p_cache_index], p_size, p_glyph_pair); } void FontData::set_kerning(int p_cache_index, int p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_set_kerning(cache[p_cache_index], p_size, p_glyph_pair, p_kerning); } Vector2 FontData::get_kerning(int p_cache_index, int p_size, const Vector2i &p_glyph_pair) const { + ERR_FAIL_COND_V(p_cache_index < 0, Vector2()); _ensure_rid(p_cache_index); return TS->font_get_kerning(cache[p_cache_index], p_size, p_glyph_pair); } void FontData::render_range(int p_cache_index, const Vector2i &p_size, char32_t p_start, char32_t p_end) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_render_range(cache[p_cache_index], p_size, p_start, p_end); } void FontData::render_glyph(int p_cache_index, const Vector2i &p_size, int32_t p_index) { + ERR_FAIL_COND(p_cache_index < 0); _ensure_rid(p_cache_index); TS->font_render_glyph(cache[p_cache_index], p_size, p_index); } RID FontData::get_cache_rid(int p_cache_index) const { + ERR_FAIL_COND_V(p_cache_index < 0, RID()); _ensure_rid(p_cache_index); return cache[p_cache_index]; } @@ -1008,10 +1053,8 @@ void Font::_data_changed() { void Font::_ensure_rid(int p_index) const { // Find or create cache record. - for (int i = 0; i < rids.size(); i++) { - if (!rids[i].is_valid() && data[i].is_valid()) { - rids.write[i] = data[i]->find_cache(variation_coordinates); - } + if (!rids[p_index].is_valid() && data[p_index].is_valid()) { + rids.write[p_index] = data[p_index]->find_cache(variation_coordinates); } } diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 77a68151c4..643b0e34b9 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -790,12 +790,10 @@ void BaseMaterial3D::_update_shader() { } } break; case BILLBOARD_FIXED_Y: { - code += " MODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0],WORLD_MATRIX[1],vec4(normalize(cross(CAMERA_MATRIX[0].xyz,WORLD_MATRIX[1].xyz)), 0.0),WORLD_MATRIX[3]);\n"; + code += " MODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(vec4(normalize(cross(vec3(0.0, 1.0, 0.0), CAMERA_MATRIX[2].xyz)),0.0),vec4(0.0, 1.0, 0.0, 0.0),vec4(normalize(cross(CAMERA_MATRIX[0].xyz, vec3(0.0, 1.0, 0.0))),0.0),WORLD_MATRIX[3]);\n"; if (flags[FLAG_BILLBOARD_KEEP_SCALE]) { - code += " MODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(WORLD_MATRIX[0].xyz), 0.0, 0.0, 0.0),vec4(0.0, 1.0, 0.0, 0.0),vec4(0.0, 0.0, length(WORLD_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; - } else { - code += " MODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(1.0, 0.0, 0.0, 0.0),vec4(0.0, 1.0/length(WORLD_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0),vec4(0.0, 0.0, 0.0 ,1.0));\n"; + code += " MODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(WORLD_MATRIX[0].xyz), 0.0, 0.0, 0.0),vec4(0.0, length(WORLD_MATRIX[1].xyz), 0.0, 0.0),vec4(0.0, 0.0, length(WORLD_MATRIX[2].xyz), 0.0),vec4(0.0, 0.0, 0.0, 1.0));\n"; } } break; case BILLBOARD_PARTICLES: { |