You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-23 15:16:17 +00:00
[Complex Text Layouts] Refactor Font class, default themes and controls to use Text Server interface.
Implement interface mirroring. Add TextLine and TextParagraph classes. Handle UTF-16 input on macOS and Windows.
This commit is contained in:
@@ -30,13 +30,37 @@
|
||||
|
||||
#include "graph_node.h"
|
||||
|
||||
#include "core/string/translation.h"
|
||||
|
||||
bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
|
||||
if (!p_name.operator String().begins_with("slot/")) {
|
||||
String str = p_name;
|
||||
if (str.begins_with("opentype_features/")) {
|
||||
String name = str.get_slicec('/', 1);
|
||||
int32_t tag = TS->name_to_tag(name);
|
||||
double value = p_value;
|
||||
if (value == -1) {
|
||||
if (opentype_features.has(tag)) {
|
||||
opentype_features.erase(tag);
|
||||
_shape();
|
||||
update();
|
||||
}
|
||||
} else {
|
||||
if ((double)opentype_features[tag] != value) {
|
||||
opentype_features[tag] = value;
|
||||
_shape();
|
||||
update();
|
||||
}
|
||||
}
|
||||
_change_notify();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!str.begins_with("slot/")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int idx = p_name.operator String().get_slice("/", 1).to_int();
|
||||
String what = p_name.operator String().get_slice("/", 2);
|
||||
int idx = str.get_slice("/", 1).to_int();
|
||||
String what = str.get_slice("/", 2);
|
||||
|
||||
Slot si;
|
||||
if (slot_info.has(idx)) {
|
||||
@@ -65,12 +89,25 @@ bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
|
||||
}
|
||||
|
||||
bool GraphNode::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
if (!p_name.operator String().begins_with("slot/")) {
|
||||
String str = p_name;
|
||||
if (str.begins_with("opentype_features/")) {
|
||||
String name = str.get_slicec('/', 1);
|
||||
int32_t tag = TS->name_to_tag(name);
|
||||
if (opentype_features.has(tag)) {
|
||||
r_ret = opentype_features[tag];
|
||||
return true;
|
||||
} else {
|
||||
r_ret = -1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!str.begins_with("slot/")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int idx = p_name.operator String().get_slice("/", 1).to_int();
|
||||
String what = p_name.operator String().get_slice("/", 2);
|
||||
int idx = str.get_slice("/", 1).to_int();
|
||||
String what = str.get_slice("/", 2);
|
||||
|
||||
Slot si;
|
||||
if (slot_info.has(idx)) {
|
||||
@@ -97,6 +134,12 @@ bool GraphNode::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
}
|
||||
|
||||
void GraphNode::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
|
||||
String name = TS->tag_to_name(*ftr);
|
||||
p_list->push_back(PropertyInfo(Variant::FLOAT, "opentype_features/" + name));
|
||||
}
|
||||
p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
|
||||
|
||||
int idx = 0;
|
||||
for (int i = 0; i < get_child_count(); i++) {
|
||||
Control *c = Object::cast_to<Control>(get_child(i));
|
||||
@@ -213,7 +256,6 @@ void GraphNode::_notification(int p_what) {
|
||||
int close_h_offset = get_theme_constant("close_h_offset");
|
||||
Color close_color = get_theme_color("close_color");
|
||||
Color resizer_color = get_theme_color("resizer_color");
|
||||
Ref<Font> title_font = get_theme_font("title_font");
|
||||
int title_offset = get_theme_constant("title_offset");
|
||||
int title_h_offset = get_theme_constant("title_h_offset");
|
||||
Color title_color = get_theme_color("title_color");
|
||||
@@ -241,7 +283,8 @@ void GraphNode::_notification(int p_what) {
|
||||
w -= close->get_width();
|
||||
}
|
||||
|
||||
draw_string(title_font, Point2(sb->get_margin(MARGIN_LEFT) + title_h_offset, -title_font->get_height() + title_font->get_ascent() + title_offset), title, title_color, w);
|
||||
title_buf->set_width(w);
|
||||
title_buf->draw(get_canvas_item(), Point2(sb->get_margin(MARGIN_LEFT) + title_h_offset, -title_buf->get_size().y + title_offset), title_color);
|
||||
if (show_close) {
|
||||
Vector2 cpos = Point2(w + sb->get_margin(MARGIN_LEFT) + close_h_offset, -close->get_height() + close_offset);
|
||||
draw_texture(close, cpos, close_color);
|
||||
@@ -285,12 +328,30 @@ void GraphNode::_notification(int p_what) {
|
||||
_resort();
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
|
||||
case NOTIFICATION_TRANSLATION_CHANGED:
|
||||
case NOTIFICATION_THEME_CHANGED: {
|
||||
_shape();
|
||||
|
||||
minimum_size_changed();
|
||||
update();
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void GraphNode::_shape() {
|
||||
Ref<Font> font = get_theme_font("title_font");
|
||||
int font_size = get_theme_font_size("title_font_size");
|
||||
|
||||
title_buf->clear();
|
||||
if (text_direction == Control::TEXT_DIRECTION_INHERITED) {
|
||||
title_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR);
|
||||
} else {
|
||||
title_buf->set_direction((TextServer::Direction)text_direction);
|
||||
}
|
||||
title_buf->add_string(title, font, font_size, opentype_features, (language != "") ? language : TranslationServer::get_singleton()->get_tool_locale());
|
||||
}
|
||||
|
||||
void GraphNode::set_slot(int p_idx, bool p_enable_left, int p_type_left, const Color &p_color_left, bool p_enable_right, int p_type_right, const Color &p_color_right, const Ref<Texture2D> &p_custom_left, const Ref<Texture2D> &p_custom_right) {
|
||||
ERR_FAIL_COND(p_idx < 0);
|
||||
|
||||
@@ -368,14 +429,12 @@ Color GraphNode::get_slot_color_right(int p_idx) const {
|
||||
}
|
||||
|
||||
Size2 GraphNode::get_minimum_size() const {
|
||||
Ref<Font> title_font = get_theme_font("title_font");
|
||||
|
||||
int sep = get_theme_constant("separation");
|
||||
Ref<StyleBox> sb = get_theme_stylebox("frame");
|
||||
bool first = true;
|
||||
|
||||
Size2 minsize;
|
||||
minsize.x = title_font->get_string_size(title).x;
|
||||
minsize.x = title_buf->get_size().x;
|
||||
if (show_close) {
|
||||
Ref<Texture2D> close = get_theme_icon("close");
|
||||
minsize.x += sep + close->get_width();
|
||||
@@ -410,6 +469,8 @@ void GraphNode::set_title(const String &p_title) {
|
||||
return;
|
||||
}
|
||||
title = p_title;
|
||||
_shape();
|
||||
|
||||
update();
|
||||
_change_notify("title");
|
||||
minimum_size_changed();
|
||||
@@ -419,6 +480,54 @@ String GraphNode::get_title() const {
|
||||
return title;
|
||||
}
|
||||
|
||||
void GraphNode::set_text_direction(Control::TextDirection p_text_direction) {
|
||||
ERR_FAIL_COND((int)p_text_direction < -1 || (int)p_text_direction > 3);
|
||||
if (text_direction != p_text_direction) {
|
||||
text_direction = p_text_direction;
|
||||
_shape();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
Control::TextDirection GraphNode::get_text_direction() const {
|
||||
return text_direction;
|
||||
}
|
||||
|
||||
void GraphNode::clear_opentype_features() {
|
||||
opentype_features.clear();
|
||||
_shape();
|
||||
update();
|
||||
}
|
||||
|
||||
void GraphNode::set_opentype_feature(const String &p_name, int p_value) {
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!opentype_features.has(tag) || (int)opentype_features[tag] != p_value) {
|
||||
opentype_features[tag] = p_value;
|
||||
_shape();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
int GraphNode::get_opentype_feature(const String &p_name) const {
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!opentype_features.has(tag)) {
|
||||
return -1;
|
||||
}
|
||||
return opentype_features[tag];
|
||||
}
|
||||
|
||||
void GraphNode::set_language(const String &p_language) {
|
||||
if (language != p_language) {
|
||||
language = p_language;
|
||||
_shape();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
String GraphNode::get_language() const {
|
||||
return language;
|
||||
}
|
||||
|
||||
void GraphNode::set_offset(const Vector2 &p_offset) {
|
||||
offset = p_offset;
|
||||
emit_signal("offset_changed");
|
||||
@@ -658,6 +767,14 @@ bool GraphNode::is_resizable() const {
|
||||
void GraphNode::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_title", "title"), &GraphNode::set_title);
|
||||
ClassDB::bind_method(D_METHOD("get_title"), &GraphNode::get_title);
|
||||
ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &GraphNode::set_text_direction);
|
||||
ClassDB::bind_method(D_METHOD("get_text_direction"), &GraphNode::get_text_direction);
|
||||
ClassDB::bind_method(D_METHOD("set_opentype_feature", "tag", "value"), &GraphNode::set_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("get_opentype_feature", "tag"), &GraphNode::get_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("clear_opentype_features"), &GraphNode::clear_opentype_features);
|
||||
ClassDB::bind_method(D_METHOD("set_language", "language"), &GraphNode::set_language);
|
||||
ClassDB::bind_method(D_METHOD("get_language"), &GraphNode::get_language);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_gui_input"), &GraphNode::_gui_input);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_slot", "idx", "enable_left", "type_left", "color_left", "enable_right", "type_right", "color_right", "custom_left", "custom_right"), &GraphNode::set_slot, DEFVAL(Ref<Texture2D>()), DEFVAL(Ref<Texture2D>()));
|
||||
@@ -699,6 +816,8 @@ void GraphNode::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_overlay"), &GraphNode::get_overlay);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,LTR,RTL,Inherited"), "set_text_direction", "get_text_direction");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_close"), "set_show_close_button", "is_close_button_visible");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "resizable"), "set_resizable", "is_resizable");
|
||||
@@ -718,6 +837,7 @@ void GraphNode::_bind_methods() {
|
||||
}
|
||||
|
||||
GraphNode::GraphNode() {
|
||||
title_buf.instance();
|
||||
overlay = OVERLAY_DISABLED;
|
||||
show_close = false;
|
||||
connpos_dirty = true;
|
||||
|
||||
Reference in New Issue
Block a user