RichTextLabel: Added get_visible_line_count method.

Also exposed get_line_count to GDScript.
This commit is contained in:
Ferenc Arn 2016-10-17 14:03:47 -05:00
parent b51180caa3
commit b4417161f5
2 changed files with 54 additions and 16 deletions

View File

@ -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);
}

View File

@ -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; }