-Many fixes and demo for RichTexLabel
-Proper ability to edit BBCode in RTL.
This commit is contained in:
parent
70752f3e4b
commit
93ce7d92c1
|
@ -0,0 +1,92 @@
|
||||||
|
Copyright (c) 2009-2011 by Accademia di Belle Arti di Urbino and students of MA course of Visual design. Some rights reserved.
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
http://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
[application]
|
||||||
|
|
||||||
|
main_scene="res://rich_text_bbcode.scn"
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 850 B |
|
@ -138,22 +138,27 @@ bool Control::_set(const StringName& p_name, const Variant& p_value) {
|
||||||
if (name.begins_with("custom_icons/")) {
|
if (name.begins_with("custom_icons/")) {
|
||||||
String dname = name.get_slice("/",1);
|
String dname = name.get_slice("/",1);
|
||||||
data.icon_override.erase(dname);
|
data.icon_override.erase(dname);
|
||||||
|
notification(NOTIFICATION_THEME_CHANGED);
|
||||||
update();
|
update();
|
||||||
} else if (name.begins_with("custom_styles/")) {
|
} else if (name.begins_with("custom_styles/")) {
|
||||||
String dname = name.get_slice("/",1);
|
String dname = name.get_slice("/",1);
|
||||||
data.style_override.erase(dname);
|
data.style_override.erase(dname);
|
||||||
|
notification(NOTIFICATION_THEME_CHANGED);
|
||||||
update();
|
update();
|
||||||
} else if (name.begins_with("custom_fonts/")) {
|
} else if (name.begins_with("custom_fonts/")) {
|
||||||
String dname = name.get_slice("/",1);
|
String dname = name.get_slice("/",1);
|
||||||
data.font_override.erase(dname);
|
data.font_override.erase(dname);
|
||||||
|
notification(NOTIFICATION_THEME_CHANGED);
|
||||||
update();
|
update();
|
||||||
} else if (name.begins_with("custom_colors/")) {
|
} else if (name.begins_with("custom_colors/")) {
|
||||||
String dname = name.get_slice("/",1);
|
String dname = name.get_slice("/",1);
|
||||||
data.color_override.erase(dname);
|
data.color_override.erase(dname);
|
||||||
|
notification(NOTIFICATION_THEME_CHANGED);
|
||||||
update();
|
update();
|
||||||
} else if (name.begins_with("custom_constants/")) {
|
} else if (name.begins_with("custom_constants/")) {
|
||||||
String dname = name.get_slice("/",1);
|
String dname = name.get_slice("/",1);
|
||||||
data.constant_override.erase(dname);
|
data.constant_override.erase(dname);
|
||||||
|
notification(NOTIFICATION_THEME_CHANGED);
|
||||||
update();
|
update();
|
||||||
} else
|
} else
|
||||||
return false;
|
return false;
|
||||||
|
@ -161,19 +166,24 @@ bool Control::_set(const StringName& p_name, const Variant& p_value) {
|
||||||
} else {
|
} else {
|
||||||
if (name.begins_with("custom_icons/")) {
|
if (name.begins_with("custom_icons/")) {
|
||||||
String dname = name.get_slice("/",1);
|
String dname = name.get_slice("/",1);
|
||||||
|
notification(NOTIFICATION_THEME_CHANGED);
|
||||||
add_icon_override(dname,p_value);
|
add_icon_override(dname,p_value);
|
||||||
} else if (name.begins_with("custom_styles/")) {
|
} else if (name.begins_with("custom_styles/")) {
|
||||||
String dname = name.get_slice("/",1);
|
String dname = name.get_slice("/",1);
|
||||||
add_style_override(dname,p_value);
|
add_style_override(dname,p_value);
|
||||||
|
notification(NOTIFICATION_THEME_CHANGED);
|
||||||
} else if (name.begins_with("custom_fonts/")) {
|
} else if (name.begins_with("custom_fonts/")) {
|
||||||
String dname = name.get_slice("/",1);
|
String dname = name.get_slice("/",1);
|
||||||
add_font_override(dname,p_value);
|
add_font_override(dname,p_value);
|
||||||
|
notification(NOTIFICATION_THEME_CHANGED);
|
||||||
} else if (name.begins_with("custom_colors/")) {
|
} else if (name.begins_with("custom_colors/")) {
|
||||||
String dname = name.get_slice("/",1);
|
String dname = name.get_slice("/",1);
|
||||||
add_color_override(dname,p_value);
|
add_color_override(dname,p_value);
|
||||||
|
notification(NOTIFICATION_THEME_CHANGED);
|
||||||
} else if (name.begins_with("custom_constants/")) {
|
} else if (name.begins_with("custom_constants/")) {
|
||||||
String dname = name.get_slice("/",1);
|
String dname = name.get_slice("/",1);
|
||||||
add_constant_override(dname,p_value);
|
add_constant_override(dname,p_value);
|
||||||
|
notification(NOTIFICATION_THEME_CHANGED);
|
||||||
} else
|
} else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,7 @@ void RichTextLabel::_process_line(int &y, int p_width, int p_line, ProcessMode p
|
||||||
int margin=_find_margin(it,p_base_font);
|
int margin=_find_margin(it,p_base_font);
|
||||||
Align align=_find_align(it);;
|
Align align=_find_align(it);;
|
||||||
int line=0;
|
int line=0;
|
||||||
|
int spaces=0;
|
||||||
|
|
||||||
if (p_mode!=PROCESS_CACHE) {
|
if (p_mode!=PROCESS_CACHE) {
|
||||||
|
|
||||||
|
@ -85,7 +86,13 @@ void RichTextLabel::_process_line(int &y, int p_width, int p_line, ProcessMode p
|
||||||
line_ofs = l.offset_caches[line];
|
line_ofs = l.offset_caches[line];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p_mode==PROCESS_CACHE) {
|
||||||
|
l.offset_caches.clear();
|
||||||
|
l.height_caches.clear();
|
||||||
|
}
|
||||||
|
|
||||||
int wofs=margin;
|
int wofs=margin;
|
||||||
|
int spaces_size=0;
|
||||||
|
|
||||||
if (p_mode!=PROCESS_CACHE && align!=ALIGN_FILL)
|
if (p_mode!=PROCESS_CACHE && align!=ALIGN_FILL)
|
||||||
wofs+=line_ofs;
|
wofs+=line_ofs;
|
||||||
|
@ -101,14 +108,13 @@ void RichTextLabel::_process_line(int &y, int p_width, int p_line, ProcessMode p
|
||||||
|
|
||||||
Variant meta;
|
Variant meta;
|
||||||
|
|
||||||
|
|
||||||
#define NEW_LINE \
|
#define NEW_LINE \
|
||||||
{\
|
{\
|
||||||
if (p_mode!=PROCESS_CACHE) {\
|
if (p_mode!=PROCESS_CACHE) {\
|
||||||
line++;\
|
line++;\
|
||||||
if (line < l.offset_caches.size())\
|
if (line < l.offset_caches.size())\
|
||||||
line_ofs=l.offset_caches[line];\
|
line_ofs=l.offset_caches[line];\
|
||||||
wofs=margin;\
|
wofs=margin;\
|
||||||
if (align!=ALIGN_FILL)\
|
if (align!=ALIGN_FILL)\
|
||||||
wofs+=line_ofs;\
|
wofs+=line_ofs;\
|
||||||
} else {\
|
} else {\
|
||||||
|
@ -117,12 +123,15 @@ void RichTextLabel::_process_line(int &y, int p_width, int p_line, ProcessMode p
|
||||||
case ALIGN_LEFT: l.offset_caches.push_back(0); break;\
|
case ALIGN_LEFT: l.offset_caches.push_back(0); break;\
|
||||||
case ALIGN_CENTER: l.offset_caches.push_back(((p_width-margin)-used)/2); break;\
|
case ALIGN_CENTER: l.offset_caches.push_back(((p_width-margin)-used)/2); break;\
|
||||||
case ALIGN_RIGHT: l.offset_caches.push_back(((p_width-margin)-used)); break;\
|
case ALIGN_RIGHT: l.offset_caches.push_back(((p_width-margin)-used)); break;\
|
||||||
case ALIGN_FILL: l.offset_caches.push_back(p_width-wofs); break;\
|
case ALIGN_FILL: l.offset_caches.push_back((p_width-margin)-used+spaces_size); break;\
|
||||||
}\
|
}\
|
||||||
l.height_caches.push_back(line_height);\
|
l.height_caches.push_back(line_height);\
|
||||||
|
l.space_caches.push_back(spaces);\
|
||||||
}\
|
}\
|
||||||
y+=line_height+get_constant(SceneStringNames::get_singleton()->line_separation);\
|
y+=line_height+get_constant(SceneStringNames::get_singleton()->line_separation);\
|
||||||
line_height=0;\
|
line_height=0;\
|
||||||
|
spaces=0;\
|
||||||
|
spaces_size=0;\
|
||||||
wofs=begin;\
|
wofs=begin;\
|
||||||
if (p_mode!=PROCESS_CACHE) {\
|
if (p_mode!=PROCESS_CACHE) {\
|
||||||
lh=line<l.height_caches.size()?l.height_caches[line]:1;\
|
lh=line<l.height_caches.size()?l.height_caches[line]:1;\
|
||||||
|
@ -138,6 +147,10 @@ void RichTextLabel::_process_line(int &y, int p_width, int p_line, ProcessMode p
|
||||||
|
|
||||||
#define ENSURE_WIDTH(m_width) \
|
#define ENSURE_WIDTH(m_width) \
|
||||||
if (wofs + m_width > p_width) {\
|
if (wofs + m_width > p_width) {\
|
||||||
|
if (p_mode==PROCESS_CACHE) {\
|
||||||
|
if (spaces>0) \
|
||||||
|
spaces-=1;\
|
||||||
|
}\
|
||||||
if (p_mode==PROCESS_POINTER && r_click_item && p_click_pos.y>=y && p_click_pos.y<=y+lh && p_click_pos.x>wofs) {\
|
if (p_mode==PROCESS_POINTER && r_click_item && p_click_pos.y>=y && p_click_pos.y<=y+lh && p_click_pos.x>wofs) {\
|
||||||
if (r_outside) *r_outside=true; \
|
if (r_outside) *r_outside=true; \
|
||||||
*r_click_item=it;\
|
*r_click_item=it;\
|
||||||
|
@ -206,30 +219,66 @@ if (m_height > line_height) {\
|
||||||
}
|
}
|
||||||
|
|
||||||
rchar=0;
|
rchar=0;
|
||||||
|
|
||||||
while(*c) {
|
while(*c) {
|
||||||
|
|
||||||
int end=0;
|
int end=0;
|
||||||
int w=0;
|
int w=0;
|
||||||
|
int fw=0;
|
||||||
|
|
||||||
lh=0;
|
lh=0;
|
||||||
if (p_mode!=PROCESS_CACHE) {
|
if (p_mode!=PROCESS_CACHE) {
|
||||||
lh=line<l.height_caches.size()?l.height_caches[line]:1;
|
lh=line<l.height_caches.size()?l.height_caches[line]:1;
|
||||||
}
|
}
|
||||||
|
bool found_space=false;
|
||||||
|
|
||||||
while (c[end]!=0 && !(end && c[end-1]==' ' && c[end]!=' ')) {
|
while (c[end]!=0 && !(end && c[end-1]==' ' && c[end]!=' ')) {
|
||||||
|
|
||||||
int cw = font->get_char_size(c[end],c[end+1]).width;
|
int cw = font->get_char_size(c[end],c[end+1]).width;
|
||||||
w+=cw;
|
w+=cw;
|
||||||
end++;
|
|
||||||
|
if (c[end]==' ') {
|
||||||
|
|
||||||
|
if (p_mode==PROCESS_CACHE) {
|
||||||
|
fw+=cw;
|
||||||
|
} else if (align==ALIGN_FILL && line<l.space_caches.size() && l.space_caches[line]>0) {
|
||||||
|
//print_line(String(c,end)+": "+itos(l.offset_caches[line])+"/"+itos(l.space_caches[line]));
|
||||||
|
//sub_space=cw;
|
||||||
|
found_space=true;
|
||||||
|
} else {
|
||||||
|
fw+=cw;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fw+=cw;
|
||||||
|
}
|
||||||
|
|
||||||
|
end++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ENSURE_WIDTH(w);
|
|
||||||
|
|
||||||
|
|
||||||
|
ENSURE_WIDTH(w);
|
||||||
|
|
||||||
|
|
||||||
|
//print_line("END: "+String::chr(c[end])+".");
|
||||||
|
if (end && c[end-1]==' ') {
|
||||||
|
spaces++;
|
||||||
|
if (p_mode==PROCESS_CACHE) {
|
||||||
|
spaces_size+=font->get_char_size(' ').width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found_space) {
|
||||||
|
fw+=l.offset_caches[line]/l.space_caches[line];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
int ofs=0;
|
int ofs=0;
|
||||||
|
|
||||||
for(int i=0;i<end;i++) {
|
for(int i=0;i<end;i++) {
|
||||||
int pofs=wofs+ofs;
|
int pofs=wofs+ofs;
|
||||||
|
|
||||||
|
@ -239,6 +288,7 @@ if (m_height > line_height) {\
|
||||||
if (p_mode==PROCESS_POINTER && r_click_char && p_click_pos.y>=y && p_click_pos.y<=y+lh) {
|
if (p_mode==PROCESS_POINTER && r_click_char && p_click_pos.y>=y && p_click_pos.y<=y+lh) {
|
||||||
//int o = (wofs+w)-p_click_pos.x;
|
//int o = (wofs+w)-p_click_pos.x;
|
||||||
|
|
||||||
|
|
||||||
int cw=font->get_char_size(c[i],c[i+1]).x;
|
int cw=font->get_char_size(c[i],c[i+1]).x;
|
||||||
|
|
||||||
if (p_click_pos.x-cw/2>pofs) {
|
if (p_click_pos.x-cw/2>pofs) {
|
||||||
|
@ -280,10 +330,15 @@ if (m_height > line_height) {\
|
||||||
cw=font->draw_char(ci,Point2(pofs,y+lh-(fh-ascent)),c[i],c[i+1],color);
|
cw=font->draw_char(ci,Point2(pofs,y+lh-(fh-ascent)),c[i],c[i+1],color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//print_line("draw char: "+String::chr(c[i]));
|
||||||
|
|
||||||
if (underline) {
|
if (underline) {
|
||||||
Color uc=color;
|
Color uc=color;
|
||||||
uc.a*=0.3;
|
uc.a*=0.5;
|
||||||
VS::get_singleton()->canvas_item_add_line(ci,Point2(pofs,y+ascent+2),Point2(pofs+cw,y+ascent+2),uc);
|
//VS::get_singleton()->canvas_item_add_line(ci,Point2(pofs,y+ascent+2),Point2(pofs+cw,y+ascent+2),uc);
|
||||||
|
int uy = y+lh-fh+ascent+2;
|
||||||
|
VS::get_singleton()->canvas_item_add_line(ci,Point2(pofs,uy),Point2(pofs+cw,uy),uc);
|
||||||
}
|
}
|
||||||
ofs+=cw;
|
ofs+=cw;
|
||||||
}
|
}
|
||||||
|
@ -292,7 +347,7 @@ if (m_height > line_height) {\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ADVANCE(w);
|
ADVANCE(fw);
|
||||||
CHECK_HEIGHT(fh); //must be done somewhere
|
CHECK_HEIGHT(fh); //must be done somewhere
|
||||||
c=&c[end];
|
c=&c[end];
|
||||||
}
|
}
|
||||||
|
@ -449,6 +504,23 @@ void RichTextLabel::_notification(int p_what) {
|
||||||
first_invalid_line=0; //invalidate ALL
|
first_invalid_line=0; //invalidate ALL
|
||||||
update();
|
update();
|
||||||
|
|
||||||
|
} break;
|
||||||
|
case NOTIFICATION_ENTER_TREE: {
|
||||||
|
|
||||||
|
if (use_bbcode)
|
||||||
|
parse_bbcode(bbcode);
|
||||||
|
first_invalid_line=0; //invalidate ALL
|
||||||
|
update();
|
||||||
|
|
||||||
|
} break;
|
||||||
|
case NOTIFICATION_THEME_CHANGED: {
|
||||||
|
|
||||||
|
if (is_inside_tree() && use_bbcode) {
|
||||||
|
parse_bbcode(bbcode);
|
||||||
|
//first_invalid_line=0; //invalidate ALL
|
||||||
|
//update();
|
||||||
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_DRAW: {
|
case NOTIFICATION_DRAW: {
|
||||||
|
|
||||||
|
@ -483,7 +555,7 @@ void RichTextLabel::_notification(int p_what) {
|
||||||
break; //nothing to draw
|
break; //nothing to draw
|
||||||
|
|
||||||
int y = (lines[from_line].height_accum_cache - lines[from_line].height_cache) - ofs;
|
int y = (lines[from_line].height_accum_cache - lines[from_line].height_cache) - ofs;
|
||||||
Ref<Font> base_font=get_font("default_font");
|
Ref<Font> base_font=get_font("normal_font");
|
||||||
Color base_color=get_color("default_color");
|
Color base_color=get_color("default_color");
|
||||||
|
|
||||||
while (y<size.height && from_line<lines.size()) {
|
while (y<size.height && from_line<lines.size()) {
|
||||||
|
@ -521,7 +593,7 @@ void RichTextLabel::_find_click(const Point2i& p_click,Item **r_click_item,int *
|
||||||
|
|
||||||
|
|
||||||
int y = (lines[from_line].height_accum_cache - lines[from_line].height_cache) - ofs;
|
int y = (lines[from_line].height_accum_cache - lines[from_line].height_cache) - ofs;
|
||||||
Ref<Font> base_font=get_font("default_font");
|
Ref<Font> base_font=get_font("normal_font");
|
||||||
Color base_color=get_color("default_color");
|
Color base_color=get_color("default_color");
|
||||||
|
|
||||||
|
|
||||||
|
@ -634,12 +706,12 @@ void RichTextLabel::_input_event(InputEvent p_event) {
|
||||||
case KEY_UP: {
|
case KEY_UP: {
|
||||||
|
|
||||||
if (vscroll->is_visible())
|
if (vscroll->is_visible())
|
||||||
vscroll->set_val( vscroll->get_val() - get_font("default_font")->get_height() );
|
vscroll->set_val( vscroll->get_val() - get_font("normal_font")->get_height() );
|
||||||
} break;
|
} break;
|
||||||
case KEY_DOWN: {
|
case KEY_DOWN: {
|
||||||
|
|
||||||
if (vscroll->is_visible())
|
if (vscroll->is_visible())
|
||||||
vscroll->set_val( vscroll->get_val() + get_font("default_font")->get_height() );
|
vscroll->set_val( vscroll->get_val() + get_font("normal_font")->get_height() );
|
||||||
} break;
|
} break;
|
||||||
case KEY_HOME: {
|
case KEY_HOME: {
|
||||||
|
|
||||||
|
@ -856,13 +928,12 @@ void RichTextLabel::_validate_line_caches() {
|
||||||
//validate invalid lines!s
|
//validate invalid lines!s
|
||||||
Size2 size = get_size();
|
Size2 size = get_size();
|
||||||
|
|
||||||
Ref<Font> base_font=get_font("default_font");
|
Ref<Font> base_font=get_font("normal_font");
|
||||||
|
|
||||||
for(int i=first_invalid_line;i<lines.size();i++) {
|
for(int i=first_invalid_line;i<lines.size();i++) {
|
||||||
|
|
||||||
int y=0;
|
int y=0;
|
||||||
_process_line(y,size.width-scroll_w,i,PROCESS_CACHE,base_font,Color());
|
_process_line(y,size.width-scroll_w,i,PROCESS_CACHE,base_font,Color());
|
||||||
|
|
||||||
lines[i].height_cache=y;
|
lines[i].height_cache=y;
|
||||||
lines[i].height_accum_cache=y;
|
lines[i].height_accum_cache=y;
|
||||||
|
|
||||||
|
@ -1152,9 +1223,19 @@ Error RichTextLabel::append_bbcode(const String& p_bbcode) {
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
List<String> tag_stack;
|
List<String> tag_stack;
|
||||||
Ref<Font> base_font=get_font("default_font");
|
Ref<Font> normal_font=get_font("normal_font");
|
||||||
|
Ref<Font> bold_font=get_font("bold_font");
|
||||||
|
Ref<Font> italics_font=get_font("italics_font");
|
||||||
|
Ref<Font> bold_italics_font=get_font("bold_italics_font");
|
||||||
|
Ref<Font> mono_font=get_font("mono_font");
|
||||||
|
|
||||||
Color base_color=get_color("default_color");
|
Color base_color=get_color("default_color");
|
||||||
|
|
||||||
|
int indent_level=0;
|
||||||
|
|
||||||
|
bool in_bold=false;
|
||||||
|
bool in_italics=false;
|
||||||
|
|
||||||
while(pos < p_bbcode.length()) {
|
while(pos < p_bbcode.length()) {
|
||||||
|
|
||||||
|
|
||||||
|
@ -1182,12 +1263,18 @@ Error RichTextLabel::append_bbcode(const String& p_bbcode) {
|
||||||
String tag = p_bbcode.substr(brk_pos+1,brk_end-brk_pos-1);
|
String tag = p_bbcode.substr(brk_pos+1,brk_end-brk_pos-1);
|
||||||
|
|
||||||
|
|
||||||
if (tag.begins_with("/")) {
|
if (tag.begins_with("/") && tag_stack.size()) {
|
||||||
|
|
||||||
bool tag_ok = tag_stack.size() && tag_stack.front()->get()==tag.substr(1,tag.length());
|
bool tag_ok = tag_stack.size() && tag_stack.front()->get()==tag.substr(1,tag.length());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (tag_stack.front()->get()=="b")
|
||||||
|
in_bold=false;
|
||||||
|
if (tag_stack.front()->get()=="i")
|
||||||
|
in_italics=false;
|
||||||
|
if (tag_stack.front()->get()=="indent")
|
||||||
|
indent_level--;
|
||||||
|
|
||||||
|
|
||||||
if (!tag_ok) {
|
if (!tag_ok) {
|
||||||
|
@ -1205,19 +1292,27 @@ Error RichTextLabel::append_bbcode(const String& p_bbcode) {
|
||||||
} else if (tag=="b") {
|
} else if (tag=="b") {
|
||||||
|
|
||||||
//use bold font
|
//use bold font
|
||||||
push_font(base_font);
|
in_bold=true;
|
||||||
|
if (in_italics)
|
||||||
|
push_font(bold_italics_font);
|
||||||
|
else
|
||||||
|
push_font(bold_font);
|
||||||
pos=brk_end+1;
|
pos=brk_end+1;
|
||||||
tag_stack.push_front(tag);
|
tag_stack.push_front(tag);
|
||||||
} else if (tag=="i") {
|
} else if (tag=="i") {
|
||||||
|
|
||||||
//use italics font
|
//use italics font
|
||||||
push_font(base_font);
|
in_italics=true;
|
||||||
|
if (in_bold)
|
||||||
|
push_font(bold_italics_font);
|
||||||
|
else
|
||||||
|
push_font(italics_font);
|
||||||
pos=brk_end+1;
|
pos=brk_end+1;
|
||||||
tag_stack.push_front(tag);
|
tag_stack.push_front(tag);
|
||||||
} else if (tag=="code") {
|
} else if (tag=="code") {
|
||||||
|
|
||||||
//use monospace font
|
//use monospace font
|
||||||
push_font(base_font);
|
push_font(mono_font);
|
||||||
pos=brk_end+1;
|
pos=brk_end+1;
|
||||||
tag_stack.push_front(tag);
|
tag_stack.push_front(tag);
|
||||||
} else if (tag=="u") {
|
} else if (tag=="u") {
|
||||||
|
@ -1232,6 +1327,43 @@ Error RichTextLabel::append_bbcode(const String& p_bbcode) {
|
||||||
push_underline();
|
push_underline();
|
||||||
pos=brk_end+1;
|
pos=brk_end+1;
|
||||||
tag_stack.push_front(tag);
|
tag_stack.push_front(tag);
|
||||||
|
} else if (tag=="center") {
|
||||||
|
|
||||||
|
//use underline
|
||||||
|
push_align(ALIGN_CENTER);
|
||||||
|
pos=brk_end+1;
|
||||||
|
tag_stack.push_front(tag);
|
||||||
|
} else if (tag=="fill") {
|
||||||
|
|
||||||
|
//use underline
|
||||||
|
push_align(ALIGN_FILL);
|
||||||
|
pos=brk_end+1;
|
||||||
|
tag_stack.push_front(tag);
|
||||||
|
} else if (tag=="right") {
|
||||||
|
|
||||||
|
//use underline
|
||||||
|
push_align(ALIGN_RIGHT);
|
||||||
|
pos=brk_end+1;
|
||||||
|
tag_stack.push_front(tag);
|
||||||
|
} else if (tag=="ul") {
|
||||||
|
|
||||||
|
//use underline
|
||||||
|
push_list(LIST_DOTS);
|
||||||
|
pos=brk_end+1;
|
||||||
|
tag_stack.push_front(tag);
|
||||||
|
} else if (tag=="ol") {
|
||||||
|
|
||||||
|
//use underline
|
||||||
|
push_list(LIST_NUMBERS);
|
||||||
|
pos=brk_end+1;
|
||||||
|
tag_stack.push_front(tag);
|
||||||
|
} else if (tag=="indent") {
|
||||||
|
|
||||||
|
//use underline
|
||||||
|
indent_level++;
|
||||||
|
push_indent(indent_level);
|
||||||
|
pos=brk_end+1;
|
||||||
|
tag_stack.push_front(tag);
|
||||||
|
|
||||||
} else if (tag=="url") {
|
} else if (tag=="url") {
|
||||||
|
|
||||||
|
@ -1244,6 +1376,7 @@ Error RichTextLabel::append_bbcode(const String& p_bbcode) {
|
||||||
|
|
||||||
pos=brk_end+1;
|
pos=brk_end+1;
|
||||||
tag_stack.push_front(tag);
|
tag_stack.push_front(tag);
|
||||||
|
|
||||||
} else if (tag.begins_with("url=")) {
|
} else if (tag.begins_with("url=")) {
|
||||||
|
|
||||||
String url = tag.substr(4,tag.length());
|
String url = tag.substr(4,tag.length());
|
||||||
|
@ -1321,7 +1454,7 @@ Error RichTextLabel::append_bbcode(const String& p_bbcode) {
|
||||||
if (font.is_valid())
|
if (font.is_valid())
|
||||||
push_font(font);
|
push_font(font);
|
||||||
else
|
else
|
||||||
push_font(base_font);
|
push_font(normal_font);
|
||||||
|
|
||||||
pos=brk_end+1;
|
pos=brk_end+1;
|
||||||
tag_stack.push_front("font");
|
tag_stack.push_front("font");
|
||||||
|
@ -1467,7 +1600,7 @@ void RichTextLabel::selection_copy() {
|
||||||
|
|
||||||
if (text!="") {
|
if (text!="") {
|
||||||
OS::get_singleton()->set_clipboard(text);
|
OS::get_singleton()->set_clipboard(text);
|
||||||
print_line("COPY: "+text);
|
//print_line("COPY: "+text);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1477,7 +1610,29 @@ bool RichTextLabel::is_selection_enabled() const {
|
||||||
return selection.enabled;
|
return selection.enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RichTextLabel::set_bbcode(const String& p_bbcode) {
|
||||||
|
bbcode=p_bbcode;
|
||||||
|
if (is_inside_tree() && use_bbcode)
|
||||||
|
parse_bbcode(p_bbcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
String RichTextLabel::get_bbcode() const {
|
||||||
|
|
||||||
|
return bbcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextLabel::set_use_bbcode(bool p_enable) {
|
||||||
|
if (use_bbcode==p_enable)
|
||||||
|
return;
|
||||||
|
use_bbcode=p_enable;
|
||||||
|
if (is_inside_tree() && use_bbcode)
|
||||||
|
parse_bbcode(bbcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RichTextLabel::is_using_bbcode() const {
|
||||||
|
|
||||||
|
return use_bbcode;
|
||||||
|
}
|
||||||
void RichTextLabel::_bind_methods() {
|
void RichTextLabel::_bind_methods() {
|
||||||
|
|
||||||
|
|
||||||
|
@ -1509,12 +1664,21 @@ void RichTextLabel::_bind_methods() {
|
||||||
ObjectTypeDB::bind_method(_MD("set_tab_size","spaces"),&RichTextLabel::set_tab_size);
|
ObjectTypeDB::bind_method(_MD("set_tab_size","spaces"),&RichTextLabel::set_tab_size);
|
||||||
ObjectTypeDB::bind_method(_MD("get_tab_size"),&RichTextLabel::get_tab_size);
|
ObjectTypeDB::bind_method(_MD("get_tab_size"),&RichTextLabel::get_tab_size);
|
||||||
|
|
||||||
|
|
||||||
ObjectTypeDB::bind_method(_MD("set_selection_enabled","enabled"),&RichTextLabel::set_selection_enabled);
|
ObjectTypeDB::bind_method(_MD("set_selection_enabled","enabled"),&RichTextLabel::set_selection_enabled);
|
||||||
ObjectTypeDB::bind_method(_MD("is_selection_enabled"),&RichTextLabel::is_selection_enabled);
|
ObjectTypeDB::bind_method(_MD("is_selection_enabled"),&RichTextLabel::is_selection_enabled);
|
||||||
|
|
||||||
ObjectTypeDB::bind_method(_MD("parse_bbcode", "bbcode"),&RichTextLabel::parse_bbcode);
|
ObjectTypeDB::bind_method(_MD("parse_bbcode", "bbcode"),&RichTextLabel::parse_bbcode);
|
||||||
ObjectTypeDB::bind_method(_MD("append_bbcode", "bbcode"),&RichTextLabel::append_bbcode);
|
ObjectTypeDB::bind_method(_MD("append_bbcode", "bbcode"),&RichTextLabel::append_bbcode);
|
||||||
|
|
||||||
|
ObjectTypeDB::bind_method(_MD("set_bbcode","text"),&RichTextLabel::set_bbcode);
|
||||||
|
ObjectTypeDB::bind_method(_MD("get_bbcode"),&RichTextLabel::get_bbcode);
|
||||||
|
|
||||||
|
ObjectTypeDB::bind_method(_MD("set_use_bbcode","enable"),&RichTextLabel::set_use_bbcode);
|
||||||
|
ObjectTypeDB::bind_method(_MD("is_using_bbcode"),&RichTextLabel::is_using_bbcode);
|
||||||
|
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"bbcode/enabled"),_SCS("set_use_bbcode"),_SCS("is_using_bbcode"));
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::STRING,"bbcode/bbcode",PROPERTY_HINT_MULTILINE_TEXT),_SCS("set_bbcode"),_SCS("get_bbcode"));
|
||||||
|
|
||||||
ADD_SIGNAL( MethodInfo("meta_clicked",PropertyInfo(Variant::NIL,"meta")));
|
ADD_SIGNAL( MethodInfo("meta_clicked",PropertyInfo(Variant::NIL,"meta")));
|
||||||
|
|
||||||
|
@ -1572,6 +1736,7 @@ RichTextLabel::RichTextLabel() {
|
||||||
vscroll->set_step(1);
|
vscroll->set_step(1);
|
||||||
vscroll->hide();
|
vscroll->hide();
|
||||||
current_idx=1;
|
current_idx=1;
|
||||||
|
use_bbcode=false;
|
||||||
|
|
||||||
selection.click=NULL;
|
selection.click=NULL;
|
||||||
selection.active=false;
|
selection.active=false;
|
||||||
|
|
|
@ -168,6 +168,7 @@ private:
|
||||||
Item *from;
|
Item *from;
|
||||||
Vector<int> offset_caches;
|
Vector<int> offset_caches;
|
||||||
Vector<int> height_caches;
|
Vector<int> height_caches;
|
||||||
|
Vector<int> space_caches;
|
||||||
int height_cache;
|
int height_cache;
|
||||||
int height_accum_cache;
|
int height_accum_cache;
|
||||||
|
|
||||||
|
@ -242,6 +243,8 @@ private:
|
||||||
void _input_event(InputEvent p_event);
|
void _input_event(InputEvent p_event);
|
||||||
Item *_get_next_item(Item* p_item);
|
Item *_get_next_item(Item* p_item);
|
||||||
|
|
||||||
|
bool use_bbcode;
|
||||||
|
String bbcode;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void _notification(int p_what);
|
void _notification(int p_what);
|
||||||
|
@ -291,9 +294,16 @@ public:
|
||||||
bool is_selection_enabled() const;
|
bool is_selection_enabled() const;
|
||||||
void selection_copy();
|
void selection_copy();
|
||||||
|
|
||||||
|
|
||||||
Error parse_bbcode(const String& p_bbcode);
|
Error parse_bbcode(const String& p_bbcode);
|
||||||
Error append_bbcode(const String& p_bbcode);
|
Error append_bbcode(const String& p_bbcode);
|
||||||
|
|
||||||
|
void set_use_bbcode(bool p_enable);
|
||||||
|
bool is_using_bbcode() const;
|
||||||
|
|
||||||
|
void set_bbcode(const String& p_bbcode);
|
||||||
|
String get_bbcode() const;
|
||||||
|
|
||||||
RichTextLabel();
|
RichTextLabel();
|
||||||
~RichTextLabel();
|
~RichTextLabel();
|
||||||
};
|
};
|
||||||
|
|
|
@ -729,7 +729,11 @@ void make_default_theme() {
|
||||||
|
|
||||||
t->set_stylebox("focus","RichTextLabel", focus );
|
t->set_stylebox("focus","RichTextLabel", focus );
|
||||||
|
|
||||||
t->set_font("default_font","RichTextLabel", default_font );
|
t->set_font("normal_font","RichTextLabel", default_font );
|
||||||
|
t->set_font("bold_font","RichTextLabel", default_font );
|
||||||
|
t->set_font("italics_font","RichTextLabel", default_font );
|
||||||
|
t->set_font("bold_italics_font","RichTextLabel", default_font );
|
||||||
|
t->set_font("mono_font","RichTextLabel", default_font );
|
||||||
|
|
||||||
t->set_color("default_color","RichTextLabel", control_font_color );
|
t->set_color("default_color","RichTextLabel", control_font_color );
|
||||||
t->set_color("font_color_selected","RichTextLabel", font_color_selection );
|
t->set_color("font_color_selected","RichTextLabel", font_color_selection );
|
||||||
|
|
|
@ -4115,7 +4115,7 @@ EditorNode::EditorNode() {
|
||||||
add_editor_plugin( memnew( ParticlesEditorPlugin(this) ) );
|
add_editor_plugin( memnew( ParticlesEditorPlugin(this) ) );
|
||||||
add_editor_plugin( memnew( ResourcePreloaderEditorPlugin(this) ) );
|
add_editor_plugin( memnew( ResourcePreloaderEditorPlugin(this) ) );
|
||||||
add_editor_plugin( memnew( ItemListEditorPlugin(this) ) );
|
add_editor_plugin( memnew( ItemListEditorPlugin(this) ) );
|
||||||
add_editor_plugin( memnew( RichTextEditorPlugin(this) ) );
|
//add_editor_plugin( memnew( RichTextEditorPlugin(this) ) );
|
||||||
add_editor_plugin( memnew( CollisionPolygonEditorPlugin(this) ) );
|
add_editor_plugin( memnew( CollisionPolygonEditorPlugin(this) ) );
|
||||||
add_editor_plugin( memnew( CollisionPolygon2DEditorPlugin(this) ) );
|
add_editor_plugin( memnew( CollisionPolygon2DEditorPlugin(this) ) );
|
||||||
add_editor_plugin( memnew( TileSetEditorPlugin(this) ) );
|
add_editor_plugin( memnew( TileSetEditorPlugin(this) ) );
|
||||||
|
|
Loading…
Reference in New Issue