diff options
Diffstat (limited to 'scene')
-rw-r--r-- | scene/gui/text_edit.cpp | 63 | ||||
-rw-r--r-- | scene/gui/text_edit.h | 4 | ||||
-rw-r--r-- | scene/main/node.cpp | 57 | ||||
-rw-r--r-- | scene/main/node.h | 3 | ||||
-rw-r--r-- | scene/resources/material.h | 2 |
5 files changed, 107 insertions, 22 deletions
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 3306a11dd0..57426f6a21 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -500,7 +500,7 @@ void TextEdit::_update_minimap_click() { int row; _get_minimap_mouse_row(Point2i(mp.x, mp.y), row); - if (row >= get_first_visible_line() && (row < get_last_visible_line() || row >= (text.size() - 1))) { + if (row >= get_first_visible_line() && (row < get_last_full_visible_line() || row >= (text.size() - 1))) { minimap_scroll_ratio = v_scroll->get_as_ratio(); minimap_scroll_click_pos = mp.y; can_drag_minimap = true; @@ -977,6 +977,16 @@ void TextEdit::_notification(int p_what) { } } + int top_limit_y = 0; + int bottom_limit_y = get_size().height; + if (readonly) { + top_limit_y += cache.style_readonly->get_margin(SIDE_TOP); + bottom_limit_y -= cache.style_readonly->get_margin(SIDE_BOTTOM); + } else { + top_limit_y += cache.style_normal->get_margin(SIDE_TOP); + bottom_limit_y -= cache.style_normal->get_margin(SIDE_BOTTOM); + } + // draw main text int row_height = get_row_height(); int line = first_visible_line; @@ -1019,17 +1029,33 @@ void TextEdit::_notification(int p_what) { const String &str = wrap_rows[line_wrap_index]; int char_margin = xmargin_beg - cursor.x_ofs; - int ofs_readonly = 0; int ofs_x = 0; + int ofs_y = 0; if (readonly) { - ofs_readonly = cache.style_readonly->get_offset().y / 2; ofs_x = cache.style_readonly->get_offset().x / 2; + ofs_x -= cache.style_normal->get_offset().x / 2; + ofs_y = cache.style_readonly->get_offset().y / 2; + } else { + ofs_y = cache.style_normal->get_offset().y / 2; } - int ofs_y = (i * row_height + cache.line_spacing / 2) + ofs_readonly; + ofs_y += i * row_height + cache.line_spacing / 2; ofs_y -= cursor.wrap_ofs * row_height; ofs_y -= get_v_scroll_offset() * row_height; + bool clipped = false; + if (ofs_y + row_height < top_limit_y) { + // Line is outside the top margin, clip current line. + // Still need to go through the process to prepare color changes for next lines. + clipped = true; + } + + if (ofs_y > bottom_limit_y) { + // Line is outside the bottom margin, clip any remaining text. + i = draw_amount; + break; + } + if (text.is_marked(line)) { if (rtl) { RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - ofs_x - xmargin_end, ofs_y, xmargin_end - xmargin_beg, row_height), cache.mark_color); @@ -1147,7 +1173,7 @@ void TextEdit::_notification(int p_what) { char_margin = size.width - char_margin - TS->shaped_text_get_size(rid).x; } - if (selection.active && line >= selection.from_line && line <= selection.to_line) { // Selection + if (!clipped && selection.active && line >= selection.from_line && line <= selection.to_line) { // Selection int sel_from = (line > selection.from_line) ? TS->shaped_text_get_range(rid).x : selection.from_column; int sel_to = (line < selection.to_line) ? TS->shaped_text_get_range(rid).y : selection.to_column; Vector<Vector2> sel = TS->shaped_text_get_selection(rid, sel_from, sel_to); @@ -1167,7 +1193,7 @@ void TextEdit::_notification(int p_what) { } int start = TS->shaped_text_get_range(rid).x; - if (!search_text.is_empty()) { // Search highhlight + if (!clipped && !search_text.is_empty()) { // Search highhlight int search_text_col = _get_column_pos_of_word(search_text, str, search_flags, 0); while (search_text_col != -1) { Vector<Vector2> sel = TS->shaped_text_get_selection(rid, search_text_col + start, search_text_col + search_text.length() + start); @@ -1190,7 +1216,7 @@ void TextEdit::_notification(int p_what) { } } - if (highlight_all_occurrences && !only_whitespaces_highlighted && !highlighted_text.is_empty()) { // Highlight + if (!clipped && highlight_all_occurrences && !only_whitespaces_highlighted && !highlighted_text.is_empty()) { // Highlight int highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, 0); while (highlighted_text_col != -1) { Vector<Vector2> sel = TS->shaped_text_get_selection(rid, highlighted_text_col + start, highlighted_text_col + highlighted_text.length() + start); @@ -1212,7 +1238,7 @@ void TextEdit::_notification(int p_what) { } } - if (select_identifiers_enabled && highlighted_word.length() != 0) { // Highlight word + if (!clipped && select_identifiers_enabled && highlighted_word.length() != 0) { // Highlight word if (_is_char(highlighted_word[0]) || highlighted_word[0] == '.') { int highlighted_word_col = _get_column_pos_of_word(highlighted_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, 0); while (highlighted_word_col != -1) { @@ -1297,7 +1323,7 @@ void TextEdit::_notification(int p_what) { } for (int k = 0; k < glyphs[j].repeat; k++) { - if ((char_ofs + char_margin) >= xmargin_beg && (char_ofs + glyphs[j].advance + char_margin) <= xmargin_end) { + if (!clipped && (char_ofs + char_margin) >= xmargin_beg && (char_ofs + glyphs[j].advance + char_margin) <= xmargin_end) { if (glyphs[j].font_rid != RID()) { TS->font_draw_glyph(glyphs[j].font_rid, ci, glyphs[j].font_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, current_color); } else if ((glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { @@ -1327,7 +1353,7 @@ void TextEdit::_notification(int p_what) { #else int caret_width = 1; #endif - if (cursor.line == line && ((line_wrap_index == line_wrap_amount) || (cursor.column != TS->shaped_text_get_range(rid).y))) { + if (!clipped && cursor.line == line && ((line_wrap_index == line_wrap_amount) || (cursor.column != TS->shaped_text_get_range(rid).y))) { is_cursor_line_visible = true; cursor_pos.y = line_top_offset_y; @@ -1444,7 +1470,6 @@ void TextEdit::_notification(int p_what) { } } } - ofs_y += ldata->get_line_descent(line_wrap_index); } } @@ -3775,8 +3800,8 @@ void TextEdit::_scroll_lines_up() { if (!selection.active) { int cur_line = cursor.line; int cur_wrap = get_cursor_wrap_index(); - int last_vis_line = get_last_visible_line(); - int last_vis_wrap = get_last_visible_line_wrap_index(); + int last_vis_line = get_last_full_visible_line(); + int last_vis_wrap = get_last_full_visible_line_wrap_index(); if (cur_line > last_vis_line || (cur_line == last_vis_line && cur_wrap > last_vis_wrap)) { cursor_set_line(last_vis_line, false, false, last_vis_wrap); @@ -4149,8 +4174,8 @@ void TextEdit::adjust_viewport_to_cursor() { int first_vis_line = get_first_visible_line(); int first_vis_wrap = cursor.wrap_ofs; - int last_vis_line = get_last_visible_line(); - int last_vis_wrap = get_last_visible_line_wrap_index(); + int last_vis_line = get_last_full_visible_line(); + int last_vis_wrap = get_last_full_visible_line_wrap_index(); if (cur_line < first_vis_line || (cur_line == first_vis_line && cur_wrap < first_vis_wrap)) { // Cursor is above screen. @@ -6163,19 +6188,19 @@ int TextEdit::get_first_visible_line() const { return CLAMP(cursor.line_ofs, 0, text.size() - 1); } -int TextEdit::get_last_visible_line() const { +int TextEdit::get_last_full_visible_line() const { int first_vis_line = get_first_visible_line(); int last_vis_line = 0; int wi; - last_vis_line = first_vis_line + num_lines_from_rows(first_vis_line, cursor.wrap_ofs, get_visible_rows() + 1, wi) - 1; + last_vis_line = first_vis_line + num_lines_from_rows(first_vis_line, cursor.wrap_ofs, get_visible_rows(), wi) - 1; last_vis_line = CLAMP(last_vis_line, 0, text.size() - 1); return last_vis_line; } -int TextEdit::get_last_visible_line_wrap_index() const { +int TextEdit::get_last_full_visible_line_wrap_index() const { int first_vis_line = get_first_visible_line(); int wi; - num_lines_from_rows(first_vis_line, cursor.wrap_ofs, get_visible_rows() + 1, wi); + num_lines_from_rows(first_vis_line, cursor.wrap_ofs, get_visible_rows(), wi); return wi; } diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index 37299ec063..bfe9369bef 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -373,8 +373,8 @@ private: void set_line_as_center_visible(int p_line, int p_wrap_index = 0); void set_line_as_last_visible(int p_line, int p_wrap_index = 0); int get_first_visible_line() const; - int get_last_visible_line() const; - int get_last_visible_line_wrap_index() const; + int get_last_full_visible_line() const; + int get_last_full_visible_line_wrap_index() const; double get_visible_rows_offset() const; double get_v_scroll_offset() const; diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 9ac3b4a691..e109240f59 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -2138,8 +2138,17 @@ Node *Node::duplicate(int p_flags) const { #ifdef TOOLS_ENABLED Node *Node::duplicate_from_editor(Map<const Node *, Node *> &r_duplimap) const { + return duplicate_from_editor(r_duplimap, Map<RES, RES>()); +} + +Node *Node::duplicate_from_editor(Map<const Node *, Node *> &r_duplimap, const Map<RES, RES> &p_resource_remap) const { Node *dupe = _duplicate(DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS | DUPLICATE_USE_INSTANCING | DUPLICATE_FROM_EDITOR, &r_duplimap); + // This is used by SceneTreeDock's paste functionality. When pasting to foreign scene, resources are duplicated. + if (!p_resource_remap.is_empty()) { + remap_node_resources(dupe, p_resource_remap); + } + // Duplication of signals must happen after all the node descendants have been copied, // because re-targeting of connections from some descendant to another is not possible // if the emitter node comes later in tree order than the receiver @@ -2147,6 +2156,54 @@ Node *Node::duplicate_from_editor(Map<const Node *, Node *> &r_duplimap) const { return dupe; } + +void Node::remap_node_resources(Node *p_node, const Map<RES, RES> &p_resource_remap) const { + List<PropertyInfo> props; + p_node->get_property_list(&props); + + for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { + if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + continue; + } + + Variant v = p_node->get(E->get().name); + if (v.is_ref()) { + RES res = v; + if (res.is_valid()) { + if (p_resource_remap.has(res)) { + p_node->set(E->get().name, p_resource_remap[res]); + remap_nested_resources(res, p_resource_remap); + } + } + } + } + + for (int i = 0; i < p_node->get_child_count(); i++) { + remap_node_resources(p_node->get_child(i), p_resource_remap); + } +} + +void Node::remap_nested_resources(RES p_resource, const Map<RES, RES> &p_resource_remap) const { + List<PropertyInfo> props; + p_resource->get_property_list(&props); + + for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { + if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + continue; + } + + Variant v = p_resource->get(E->get().name); + if (v.is_ref()) { + RES res = v; + if (res.is_valid()) { + if (p_resource_remap.has(res)) { + p_resource->set(E->get().name, p_resource_remap[res]); + remap_nested_resources(res, p_resource_remap); + } + } + } + } +} #endif void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p_reown_map) const { diff --git a/scene/main/node.h b/scene/main/node.h index 5253ed2e45..66104b5cf5 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -362,6 +362,9 @@ public: Node *duplicate_and_reown(const Map<Node *, Node *> &p_reown_map) const; #ifdef TOOLS_ENABLED Node *duplicate_from_editor(Map<const Node *, Node *> &r_duplimap) const; + Node *duplicate_from_editor(Map<const Node *, Node *> &r_duplimap, const Map<RES, RES> &p_resource_remap) const; + void remap_node_resources(Node *p_node, const Map<RES, RES> &p_resource_remap) const; + void remap_nested_resources(RES p_resource, const Map<RES, RES> &p_resource_remap) const; #endif // used by editors, to save what has changed only diff --git a/scene/resources/material.h b/scene/resources/material.h index 595db36a57..70452a5f74 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -519,7 +519,7 @@ private: AlphaAntiAliasing alpha_antialiasing_mode = ALPHA_ANTIALIASING_OFF; - bool features[FEATURE_MAX]; + bool features[FEATURE_MAX] = {}; Ref<Texture2D> textures[TEXTURE_MAX]; |