summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
authorFerenc Arn <tagcup@yahoo.com>2016-10-17 14:03:47 -0500
committerFerenc Arn <tagcup@yahoo.com>2017-09-21 21:43:33 -0400
commitb4417161f536ede56c204b9c626fc8d406ed6af4 (patch)
tree73dad9576d141e4388f7616d5c6a23dcf9c91e84 /scene
parentb51180caa3063937d2155233fd0bf8155c317ba9 (diff)
RichTextLabel: Added get_visible_line_count method.
Also exposed get_line_count to GDScript.
Diffstat (limited to 'scene')
-rw-r--r--scene/gui/rich_text_label.cpp66
-rw-r--r--scene/gui/rich_text_label.h4
2 files changed, 54 insertions, 16 deletions
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 71b9c4ec72..d9287e6f63 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -84,7 +84,7 @@ Rect2 RichTextLabel::_get_text_rect() {
Ref<StyleBox> style = get_stylebox("normal");
return Rect2(style->get_offset(), get_size() - style->get_minimum_size());
}
-void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &y, int p_width, int p_line, ProcessMode p_mode, const Ref<Font> &p_base_font, const Color &p_base_color, const Point2i &p_click_pos, Item **r_click_item, int *r_click_char, bool *r_outside, int p_char_count) {
+int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &y, int p_width, int p_line, ProcessMode p_mode, const Ref<Font> &p_base_font, const Color &p_base_color, const Point2i &p_click_pos, Item **r_click_item, int *r_click_char, bool *r_outside, int p_char_count) {
RID ci;
if (r_outside)
@@ -104,9 +104,11 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int
int line = 0;
int spaces = 0;
+ int height = get_size().y;
+
if (p_mode != PROCESS_CACHE) {
- ERR_FAIL_INDEX(line, l.offset_caches.size());
+ ERR_FAIL_INDEX_V(line, l.offset_caches.size(), 0);
line_ofs = l.offset_caches[line];
}
@@ -133,12 +135,20 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int
//line height should be the font height for the first time, this ensures that an empty line will never have zero height and successive newlines are displayed
int line_height = cfont->get_height();
+ int nonblank_line_count = 0; //number of nonblank lines as counted during PROCESS_DRAW
+
Variant meta;
+#define RETURN return nonblank_line_count
+
#define NEW_LINE \
{ \
if (p_mode != PROCESS_CACHE) { \
line++; \
+ if (!line_is_blank) { \
+ nonblank_line_count++; \
+ } \
+ line_is_blank = true; \
if (line < l.offset_caches.size()) \
line_ofs = l.offset_caches[line]; \
wofs = margin; \
@@ -168,7 +178,7 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int
if (r_outside) *r_outside = true; \
*r_click_item = it; \
*r_click_char = rchar; \
- return; \
+ RETURN; \
} \
}
@@ -185,7 +195,7 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int
if (r_outside) *r_outside = true; \
*r_click_item = it; \
*r_click_char = rchar; \
- return; \
+ RETURN; \
} \
NEW_LINE \
}
@@ -196,7 +206,7 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int
if (r_outside) *r_outside = false; \
*r_click_item = it; \
*r_click_char = rchar; \
- return; \
+ RETURN; \
} \
wofs += m_width; \
}
@@ -206,6 +216,9 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int
line_height = m_height; \
}
+#define YRANGE_VISIBLE(m_top, m_height) \
+ (m_height > 0 && ((m_top >= 0 && m_top < height) || ((m_top + m_height - 1) >= 0 && (m_top + m_height - 1) < height)))
+
Color selection_fg;
Color selection_bg;
@@ -214,8 +227,10 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int
selection_fg = get_color("font_color_selected");
selection_bg = get_color("selection_color");
}
+
int rchar = 0;
int lh = 0;
+ bool line_is_blank = true;
while (it) {
@@ -327,7 +342,10 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int
int cw = 0;
- bool visible = visible_characters < 0 || p_char_count < visible_characters;
+ bool visible = visible_characters < 0 || p_char_count < visible_characters && YRANGE_VISIBLE(y + lh - (fh - 0 * ascent), fh); //getting rid of ascent seems to work??
+ if (visible)
+ line_is_blank = false;
+
if (c[i] == '\t')
visible = false;
@@ -384,7 +402,9 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int
ENSURE_WIDTH(img->image->get_width());
- bool visible = visible_characters < 0 || p_char_count < visible_characters;
+ bool visible = visible_characters < 0 || p_char_count < visible_characters && YRANGE_VISIBLE(y + lh - font->get_descent() - img->image->get_height(), img->image->get_height());
+ if (visible)
+ line_is_blank = false;
if (p_mode == PROCESS_DRAW && visible) {
img->image->draw(ci, p_ofs + Point2(align_ofs + wofs, y + lh - font->get_descent() - img->image->get_height()));
@@ -398,8 +418,10 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int
case ITEM_NEWLINE: {
lh = 0;
- if (p_mode != PROCESS_CACHE)
+ if (p_mode != PROCESS_CACHE) {
lh = line < l.height_caches.size() ? l.height_caches[line] : 1;
+ line_is_blank = true;
+ }
} break;
case ITEM_TABLE: {
@@ -436,7 +458,7 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int
idx++;
}
- //compute available width and total radio (for expanders)
+ //compute available width and total ratio (for expanders)
int total_ratio = 0;
int available_width = p_width - hseparation * (table->columns.size() - 1);
@@ -494,12 +516,14 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int
int lines_ofs = p_ofs.y + offset.y + draw_ofs.y;
bool visible = lines_ofs < get_size().height && lines_ofs + lines_h >= 0;
+ if (visible)
+ line_is_blank = false;
for (int i = 0; i < frame->lines.size(); i++) {
if (visible) {
if (p_mode == PROCESS_DRAW) {
- _process_line(frame, p_ofs + offset + draw_ofs + Vector2(0, yofs), ly, table->columns[column].width, i, PROCESS_DRAW, cfont, ccolor);
+ nonblank_line_count += _process_line(frame, p_ofs + offset + draw_ofs + Vector2(0, yofs), ly, table->columns[column].width, i, PROCESS_DRAW, cfont, ccolor);
} else if (p_mode == PROCESS_POINTER) {
_process_line(frame, p_ofs + offset + draw_ofs + Vector2(0, yofs), ly, table->columns[column].width, i, PROCESS_POINTER, cfont, ccolor, p_click_pos, r_click_item, r_click_char, r_outside);
}
@@ -547,15 +571,17 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int
if (r_outside) *r_outside = true;
*r_click_item = itp;
*r_click_char = rchar;
- return;
+ RETURN;
}
break;
}
}
-
NEW_LINE;
+ RETURN;
+
+#undef RETURN
#undef NEW_LINE
#undef ENSURE_WIDTH
#undef ADVANCE
@@ -665,14 +691,14 @@ void RichTextLabel::_notification(int p_what) {
if (from_line >= main->lines.size())
break; //nothing to draw
-
int y = (main->lines[from_line].height_accum_cache - main->lines[from_line].height_cache) - ofs;
Ref<Font> base_font = get_font("normal_font");
Color base_color = get_color("default_color");
+ visible_line_count = 0;
while (y < size.height && from_line < main->lines.size()) {
- _process_line(main, text_rect.get_position(), y, text_rect.get_size().width - scroll_w, from_line, PROCESS_DRAW, base_font, base_color, Point2i(), NULL, NULL, NULL, total_chars);
+ visible_line_count += _process_line(main, text_rect.get_position(), y, text_rect.get_size().width - scroll_w, from_line, PROCESS_DRAW, base_font, base_color, Point2i(), NULL, NULL, NULL, total_chars);
total_chars += main->lines[from_line].char_count;
from_line++;
}
@@ -1013,7 +1039,7 @@ void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) {
if (p_frame->first_invalid_line == p_frame->lines.size())
return;
- //validate invalid lines!s
+ //validate invalid lines
Size2 size = get_size();
Rect2 text_rect = _get_text_rect();
@@ -1665,6 +1691,12 @@ int RichTextLabel::get_line_count() const {
return current_frame->lines.size();
}
+int RichTextLabel::get_visible_line_count() const {
+ if (!is_visible())
+ return 0;
+ return visible_line_count;
+}
+
void RichTextLabel::set_selection_enabled(bool p_enabled) {
selection.enabled = p_enabled;
@@ -1907,6 +1939,9 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_use_bbcode", "enable"), &RichTextLabel::set_use_bbcode);
ClassDB::bind_method(D_METHOD("is_using_bbcode"), &RichTextLabel::is_using_bbcode);
+ ClassDB::bind_method(D_METHOD("get_line_count"), &RichTextLabel::get_line_count);
+ ClassDB::bind_method(D_METHOD("get_visible_line_count"), &RichTextLabel::get_visible_line_count);
+
ADD_GROUP("BBCode", "bbcode_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bbcode_enabled"), "set_use_bbcode", "is_using_bbcode");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "bbcode_text", PROPERTY_HINT_MULTILINE_TEXT), "set_bbcode", "get_bbcode");
@@ -1995,6 +2030,7 @@ RichTextLabel::RichTextLabel() {
visible_characters = -1;
percent_visible = 1;
+ visible_line_count = 0;
set_clip_contents(true);
}
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index 4db2c3a8e9..24c1e5eb59 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -217,6 +217,7 @@ private:
int scroll_w;
bool updating_scroll;
int current_idx;
+ int visible_line_count;
int tab_size;
bool underline_meta;
@@ -260,7 +261,7 @@ private:
int visible_characters;
float percent_visible;
- void _process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &y, int p_width, int p_line, ProcessMode p_mode, const Ref<Font> &p_base_font, const Color &p_base_color, const Point2i &p_click_pos = Point2i(), Item **r_click_item = NULL, int *r_click_char = NULL, bool *r_outside = NULL, int p_char_count = 0);
+ int _process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &y, int p_width, int p_line, ProcessMode p_mode, const Ref<Font> &p_base_font, const Color &p_base_color, const Point2i &p_click_pos = Point2i(), Item **r_click_item = NULL, int *r_click_char = NULL, bool *r_outside = NULL, int p_char_count = 0);
void _find_click(ItemFrame *p_frame, const Point2i &p_click, Item **r_click_item = NULL, int *r_click_char = NULL, bool *r_outside = NULL);
Ref<Font> _find_font(Item *p_item);
@@ -325,6 +326,7 @@ public:
void scroll_to_line(int p_line);
int get_line_count() const;
+ int get_visible_line_count() const;
VScrollBar *get_v_scroll() { return vscroll; }