diff --git a/doc/classes/GraphNode.xml b/doc/classes/GraphNode.xml
index 173da63a157..5f0dca04028 100644
--- a/doc/classes/GraphNode.xml
+++ b/doc/classes/GraphNode.xml
@@ -119,6 +119,13 @@
Returns the right (output) type of the slot [code]idx[/code].
+
+
+
+
+ Returns true if the background [StyleBox] of the slot [code]idx[/code] is drawn.
+
+
@@ -152,6 +159,7 @@
+
Sets properties of the slot with ID [code]idx[/code].
If [code]enable_left[/code]/[code]right[/code], a port will appear and the slot will be able to be connected from this side.
@@ -178,6 +186,14 @@
Sets the [Color] of the right (output) side of the slot [code]idx[/code] to [code]color_right[/code].
+
+
+
+
+
+ Toggles the background [StyleBox] of the slot [code]idx[/code].
+
+
@@ -301,6 +317,8 @@
Color of the title text.
+
+
The vertical offset of the close button.
@@ -343,5 +361,8 @@
The background used when the [GraphNode] is selected.
+
+ The [StyleBox] used for each slot of the [GraphNode].
+
diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp
index 3e18499b97d..51d4d474c55 100644
--- a/editor/editor_fonts.cpp
+++ b/editor/editor_fonts.cpp
@@ -110,6 +110,32 @@
m_name->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE); \
MAKE_FALLBACKS(m_name);
+#define MAKE_DEFAULT_FONT_MSDF(m_name, m_variations) \
+ Ref m_name; \
+ m_name.instantiate(); \
+ if (CustomFont.is_valid()) { \
+ m_name->add_data(CustomFontMSDF); \
+ m_name->add_data(DefaultFontMSDF); \
+ } else { \
+ m_name->add_data(DefaultFontMSDF); \
+ } \
+ { \
+ Dictionary variations; \
+ if (!m_variations.is_empty()) { \
+ Vector variation_tags = m_variations.split(","); \
+ for (int i = 0; i < variation_tags.size(); i++) { \
+ Vector tokens = variation_tags[i].split("="); \
+ if (tokens.size() == 2) { \
+ variations[tokens[0]] = tokens[1].to_float(); \
+ } \
+ } \
+ } \
+ m_name->set_variation_coordinates(variations); \
+ } \
+ m_name->set_spacing(TextServer::SPACING_TOP, -EDSCALE); \
+ m_name->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE); \
+ MAKE_FALLBACKS(m_name);
+
#define MAKE_SLANTED_FONT(m_name, m_variations) \
Ref m_name; \
m_name.instantiate(); \
@@ -163,6 +189,32 @@
m_name->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE); \
MAKE_FALLBACKS_BOLD(m_name);
+#define MAKE_BOLD_FONT_MSDF(m_name, m_variations) \
+ Ref m_name; \
+ m_name.instantiate(); \
+ if (CustomFontBold.is_valid()) { \
+ m_name->add_data(CustomFontBoldMSDF); \
+ m_name->add_data(DefaultFontBoldMSDF); \
+ } else { \
+ m_name->add_data(DefaultFontBoldMSDF); \
+ } \
+ { \
+ Dictionary variations; \
+ if (!m_variations.is_empty()) { \
+ Vector variation_tags = m_variations.split(","); \
+ for (int i = 0; i < variation_tags.size(); i++) { \
+ Vector tokens = variation_tags[i].split("="); \
+ if (tokens.size() == 2) { \
+ variations[tokens[0]] = tokens[1].to_float(); \
+ } \
+ } \
+ } \
+ m_name->set_variation_coordinates(variations); \
+ } \
+ m_name->set_spacing(TextServer::SPACING_TOP, -EDSCALE); \
+ m_name->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE); \
+ MAKE_FALLBACKS_BOLD(m_name);
+
#define MAKE_SOURCE_FONT(m_name, m_variations) \
Ref m_name; \
m_name.instantiate(); \
@@ -189,13 +241,14 @@
m_name->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE); \
MAKE_FALLBACKS(m_name);
-Ref load_cached_external_font(const String &p_path, TextServer::Hinting p_hinting, bool p_aa, bool p_autohint, TextServer::SubpixelPositioning p_font_subpixel_positioning) {
+Ref load_cached_external_font(const String &p_path, TextServer::Hinting p_hinting, bool p_aa, bool p_autohint, TextServer::SubpixelPositioning p_font_subpixel_positioning, bool p_msdf = false) {
Ref font;
font.instantiate();
Vector data = FileAccess::get_file_as_array(p_path);
font->set_data(data);
+ font->set_multichannel_signed_distance_field(p_msdf);
font->set_antialiased(p_aa);
font->set_hinting(p_hinting);
font->set_force_autohinter(p_autohint);
@@ -204,11 +257,12 @@ Ref load_cached_external_font(const String &p_path, TextServer::Hintin
return font;
}
-Ref load_cached_internal_font(const uint8_t *p_data, size_t p_size, TextServer::Hinting p_hinting, bool p_aa, bool p_autohint, TextServer::SubpixelPositioning p_font_subpixel_positioning) {
+Ref load_cached_internal_font(const uint8_t *p_data, size_t p_size, TextServer::Hinting p_hinting, bool p_aa, bool p_autohint, TextServer::SubpixelPositioning p_font_subpixel_positioning, bool p_msdf = false) {
Ref font;
font.instantiate();
font->set_data_ptr(p_data, p_size);
+ font->set_multichannel_signed_distance_field(p_msdf);
font->set_antialiased(p_aa);
font->set_hinting(p_hinting);
font->set_force_autohinter(p_autohint);
@@ -261,6 +315,13 @@ void editor_register_fonts(Ref p_theme) {
EditorSettings::get_singleton()->set_manually("interface/editor/main_font", "");
}
+ Ref CustomFontMSDF;
+ if (custom_font_path.length() > 0 && dir->file_exists(custom_font_path)) {
+ CustomFontMSDF = load_cached_external_font(custom_font_path, font_hinting, font_antialiased, true, font_subpixel_positioning, true);
+ } else {
+ EditorSettings::get_singleton()->set_manually("interface/editor/main_font", "");
+ }
+
Ref CustomFontSlanted;
if (CustomFont.is_valid()) {
CustomFontSlanted = CustomFont->duplicate();
@@ -282,6 +343,13 @@ void editor_register_fonts(Ref p_theme) {
CustomFontBold->set_embolden(embolden_strength);
}
+ Ref CustomFontBoldMSDF;
+ if (custom_font_path.length() > 0 && dir->file_exists(custom_font_path)) {
+ CustomFontBoldMSDF = load_cached_external_font(custom_font_path, font_hinting, font_antialiased, true, font_subpixel_positioning, true);
+ } else {
+ EditorSettings::get_singleton()->set_manually("interface/editor/main_font_bold", "");
+ }
+
/* Custom source code font */
String custom_font_path_source = EditorSettings::get_singleton()->get("interface/editor/code_font");
@@ -295,7 +363,9 @@ void editor_register_fonts(Ref p_theme) {
/* Noto Sans */
Ref DefaultFont = load_cached_internal_font(_font_NotoSans_Regular, _font_NotoSans_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
+ Ref DefaultFontMSDF = load_cached_internal_font(_font_NotoSans_Regular, _font_NotoSans_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning, true);
Ref DefaultFontBold = load_cached_internal_font(_font_NotoSans_Bold, _font_NotoSans_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
+ Ref DefaultFontBoldMSDF = load_cached_internal_font(_font_NotoSans_Bold, _font_NotoSans_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning, true);
Ref FontArabic = load_cached_internal_font(_font_NotoNaskhArabicUI_Regular, _font_NotoNaskhArabicUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
Ref FontArabicBold = load_cached_internal_font(_font_NotoNaskhArabicUI_Bold, _font_NotoNaskhArabicUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
Ref FontBengali = load_cached_internal_font(_font_NotoSansBengaliUI_Regular, _font_NotoSansBengaliUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
@@ -347,12 +417,18 @@ void editor_register_fonts(Ref p_theme) {
p_theme->set_font_size("main_size", "EditorFonts", default_font_size);
p_theme->set_font("main", "EditorFonts", df);
+ MAKE_DEFAULT_FONT_MSDF(df_msdf, String());
+ p_theme->set_font("main_msdf", "EditorFonts", df_msdf);
+
// Bold font
MAKE_BOLD_FONT(df_bold, String());
MAKE_SLANTED_FONT(df_italic, String());
p_theme->set_font_size("bold_size", "EditorFonts", default_font_size);
p_theme->set_font("bold", "EditorFonts", df_bold);
+ MAKE_BOLD_FONT_MSDF(df_bold_msdf, String());
+ p_theme->set_font("main_bold_msdf", "EditorFonts", df_bold_msdf);
+
// Title font
p_theme->set_font_size("title_size", "EditorFonts", default_font_size + 1 * EDSCALE);
p_theme->set_font("title", "EditorFonts", df_bold);
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index c276c922df1..e251a666103 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -681,6 +681,7 @@ void EditorSettings::_load_defaults(Ref p_extra_config) {
// Visual editors
EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/visual_editors/minimap_opacity", 0.85, "0.0,1.0,0.01")
+ EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "editors/visual_editors/visualshader/port_preview_size", 160, "100,400,0.01")
/* Run */
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index a9c435a265b..3b159d9f3de 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -741,17 +741,28 @@ Ref create_editor_theme(const Ref p_theme) {
theme->set_stylebox("pressed", "EditorLogFilterButton", editor_log_button_pressed);
// OptionButton
- theme->set_stylebox("focus", "OptionButton", style_widget_focus);
+ Ref style_option_button_focus = style_widget_focus->duplicate();
+ Ref style_option_button_normal = style_widget->duplicate();
+ Ref style_option_button_hover = style_widget_hover->duplicate();
+ Ref style_option_button_pressed = style_widget_pressed->duplicate();
+ Ref style_option_button_disabled = style_widget_disabled->duplicate();
+ style_option_button_focus->set_default_margin(SIDE_RIGHT, 4 * EDSCALE);
+ style_option_button_normal->set_default_margin(SIDE_RIGHT, 4 * EDSCALE);
+ style_option_button_hover->set_default_margin(SIDE_RIGHT, 4 * EDSCALE);
+ style_option_button_pressed->set_default_margin(SIDE_RIGHT, 4 * EDSCALE);
+ style_option_button_disabled->set_default_margin(SIDE_RIGHT, 4 * EDSCALE);
+
+ theme->set_stylebox("focus", "OptionButton", style_option_button_focus);
theme->set_stylebox("normal", "OptionButton", style_widget);
theme->set_stylebox("hover", "OptionButton", style_widget_hover);
theme->set_stylebox("pressed", "OptionButton", style_widget_pressed);
theme->set_stylebox("disabled", "OptionButton", style_widget_disabled);
- theme->set_stylebox("normal_mirrored", "OptionButton", style_widget);
- theme->set_stylebox("hover_mirrored", "OptionButton", style_widget_hover);
- theme->set_stylebox("pressed_mirrored", "OptionButton", style_widget_pressed);
- theme->set_stylebox("disabled_mirrored", "OptionButton", style_widget_disabled);
+ theme->set_stylebox("normal_mirrored", "OptionButton", style_option_button_normal);
+ theme->set_stylebox("hover_mirrored", "OptionButton", style_option_button_hover);
+ theme->set_stylebox("pressed_mirrored", "OptionButton", style_option_button_pressed);
+ theme->set_stylebox("disabled_mirrored", "OptionButton", style_option_button_disabled);
theme->set_color("font_color", "OptionButton", font_color);
theme->set_color("font_hover_color", "OptionButton", font_hover_color);
@@ -1435,7 +1446,6 @@ Ref create_editor_theme(const Ref p_theme) {
style_minimap_node = make_flat_stylebox(Color(0, 0, 0), 0, 0, 0, 0);
}
style_minimap_camera->set_border_width_all(1);
- style_minimap_node->set_corner_radius_all(1);
theme->set_stylebox("camera", "GraphEditMinimap", style_minimap_camera);
theme->set_stylebox("node", "GraphEditMinimap", style_minimap_node);
@@ -1450,20 +1460,26 @@ Ref create_editor_theme(const Ref p_theme) {
theme->set_color("resizer_color", "GraphEditMinimap", minimap_resizer_color);
// GraphNode
- const int gn_margin_side = 28;
+ const int gn_margin_side = 2;
+ const int gn_margin_bottom = 2;
- Ref graphsb = make_flat_stylebox(dark_color_3 * Color(1, 1, 1, 0.7), gn_margin_side, 24, gn_margin_side, 5, corner_width);
+ Color graphnode_bg = dark_color_3;
+ if (!dark_theme) {
+ graphnode_bg = prop_section_color;
+ }
+
+ Ref graphsb = make_flat_stylebox(graphnode_bg.lerp(style_tree_bg->get_bg_color(), 0.3), gn_margin_side, 24, gn_margin_side, gn_margin_bottom, corner_width);
graphsb->set_border_width_all(border_width);
- graphsb->set_border_color(dark_color_3);
- Ref graphsbselected = make_flat_stylebox(dark_color_3 * Color(1, 1, 1, 0.9), gn_margin_side, 24, gn_margin_side, 5, corner_width);
+ graphsb->set_border_color(graphnode_bg);
+ Ref graphsbselected = make_flat_stylebox(graphnode_bg * Color(1, 1, 1, 1), gn_margin_side, 24, gn_margin_side, gn_margin_bottom, corner_width);
graphsbselected->set_border_width_all(2 * EDSCALE + border_width);
- graphsbselected->set_border_color(Color(accent_color.r, accent_color.g, accent_color.b, 0.9));
- Ref graphsbcomment = make_flat_stylebox(dark_color_3 * Color(1, 1, 1, 0.3), gn_margin_side, 24, gn_margin_side, 5, corner_width);
+ graphsbselected->set_border_color(Color(accent_color.r, accent_color.g, accent_color.b, 0.6));
+ Ref graphsbcomment = make_flat_stylebox(graphnode_bg * Color(1, 1, 1, 0.3), gn_margin_side, 24, gn_margin_side, gn_margin_bottom, corner_width);
graphsbcomment->set_border_width_all(border_width);
- graphsbcomment->set_border_color(dark_color_3);
- Ref graphsbcommentselected = make_flat_stylebox(dark_color_3 * Color(1, 1, 1, 0.4), gn_margin_side, 24, gn_margin_side, 5, corner_width);
+ graphsbcomment->set_border_color(graphnode_bg);
+ Ref graphsbcommentselected = make_flat_stylebox(graphnode_bg * Color(1, 1, 1, 0.4), gn_margin_side, 24, gn_margin_side, gn_margin_bottom, corner_width);
graphsbcommentselected->set_border_width_all(border_width);
- graphsbcommentselected->set_border_color(dark_color_3);
+ graphsbcommentselected->set_border_color(graphnode_bg);
Ref graphsbbreakpoint = graphsbselected->duplicate();
graphsbbreakpoint->set_draw_center(false);
graphsbbreakpoint->set_border_color(warning_color);
@@ -1472,10 +1488,11 @@ Ref create_editor_theme(const Ref p_theme) {
graphsbposition->set_draw_center(false);
graphsbposition->set_border_color(error_color);
graphsbposition->set_shadow_color(error_color * Color(1.0, 1.0, 1.0, 0.2));
- Ref smgraphsb = make_flat_stylebox(dark_color_3 * Color(1, 1, 1, 0.7), gn_margin_side, 24, gn_margin_side, 5, corner_width);
+ Ref graphsbslot = make_empty_stylebox(12, 0, 12, 0);
+ Ref smgraphsb = make_flat_stylebox(dark_color_3 * Color(1, 1, 1, 0.7), gn_margin_side, 24, gn_margin_side, gn_margin_bottom, corner_width);
smgraphsb->set_border_width_all(border_width);
- smgraphsb->set_border_color(dark_color_3);
- Ref smgraphsbselected = make_flat_stylebox(dark_color_3 * Color(1, 1, 1, 0.9), gn_margin_side, 24, gn_margin_side, 5, corner_width);
+ smgraphsb->set_border_color(graphnode_bg);
+ Ref smgraphsbselected = make_flat_stylebox(graphnode_bg * Color(1, 1, 1, 0.9), gn_margin_side, 24, gn_margin_side, gn_margin_bottom, corner_width);
smgraphsbselected->set_border_width_all(2 * EDSCALE + border_width);
smgraphsbselected->set_border_color(Color(accent_color.r, accent_color.g, accent_color.b, 0.9));
smgraphsbselected->set_shadow_size(8 * EDSCALE);
@@ -1492,19 +1509,20 @@ Ref create_editor_theme(const Ref p_theme) {
theme->set_stylebox("comment_focus", "GraphNode", graphsbcommentselected);
theme->set_stylebox("breakpoint", "GraphNode", graphsbbreakpoint);
theme->set_stylebox("position", "GraphNode", graphsbposition);
+ theme->set_stylebox("slot", "GraphNode", graphsbslot);
theme->set_stylebox("state_machine_frame", "GraphNode", smgraphsb);
theme->set_stylebox("state_machine_selected_frame", "GraphNode", smgraphsbselected);
- Color default_node_color = dark_color_1.inverted();
- theme->set_color("title_color", "GraphNode", default_node_color);
- default_node_color.a = 0.7;
- theme->set_color("close_color", "GraphNode", default_node_color);
- theme->set_color("resizer_color", "GraphNode", default_node_color);
+ Color node_decoration_color = dark_color_1.inverted();
+ theme->set_color("title_color", "GraphNode", node_decoration_color);
+ node_decoration_color.a = 0.7;
+ theme->set_color("close_color", "GraphNode", node_decoration_color);
+ theme->set_color("resizer_color", "GraphNode", node_decoration_color);
- theme->set_constant("port_offset", "GraphNode", 14 * EDSCALE);
- theme->set_constant("title_h_offset", "GraphNode", -16 * EDSCALE);
- theme->set_constant("title_offset", "GraphNode", 20 * EDSCALE);
- theme->set_constant("close_h_offset", "GraphNode", 20 * EDSCALE);
+ theme->set_constant("port_offset", "GraphNode", 0);
+ theme->set_constant("title_h_offset", "GraphNode", 12 * EDSCALE);
+ theme->set_constant("title_offset", "GraphNode", 21 * EDSCALE);
+ theme->set_constant("close_h_offset", "GraphNode", -2 * EDSCALE);
theme->set_constant("close_offset", "GraphNode", 20 * EDSCALE);
theme->set_constant("separation", "GraphNode", 1 * EDSCALE);
@@ -1512,6 +1530,8 @@ Ref create_editor_theme(const Ref p_theme) {
theme->set_icon("resizer", "GraphNode", theme->get_icon(SNAME("GuiResizer"), SNAME("EditorIcons")));
theme->set_icon("port", "GraphNode", theme->get_icon(SNAME("GuiGraphNodePort"), SNAME("EditorIcons")));
+ theme->set_font("title_font", "GraphNode", theme->get_font(SNAME("main_bold_msdf"), SNAME("EditorFonts")));
+
// GridContainer
theme->set_constant("v_separation", "GridContainer", Math::round(widget_default_margin.y - 2 * EDSCALE));
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 85238ce4a54..9ad49e32af8 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -148,6 +148,7 @@ void VisualShaderGraphPlugin::show_port_preview(VisualShader::Type p_type, int p
if (links[p_node_id].preview_pos != -1) {
links[p_node_id].graph_node->move_child(vbox, links[p_node_id].preview_pos);
}
+ links[p_node_id].graph_node->set_slot_draw_stylebox(vbox->get_index(), false);
Control *offset = memnew(Control);
offset->set_custom_minimum_size(Size2(0, 5 * EDSCALE));
@@ -386,6 +387,14 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
"alpha"
};
+ // Visual shader specific theme for MSDF font.
+ Ref vstheme;
+ vstheme.instantiate();
+ Ref label_font = EditorNode::get_singleton()->get_editor_theme()->get_font("main_msdf", "EditorFonts");
+ vstheme->set_font("font", "Label", label_font);
+ vstheme->set_font("font", "LineEdit", label_font);
+ vstheme->set_font("font", "Button", label_font);
+
Ref vsnode = visual_shader->get_node(p_type, p_id);
Ref resizable_node = Object::cast_to(vsnode.ptr());
@@ -406,8 +415,10 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
custom_node->_set_initialized(true);
}
+ // Create graph node.
GraphNode *node = memnew(GraphNode);
graph->add_child(node);
+ node->set_theme(vstheme);
editor->_update_created_node(node);
register_link(p_type, p_id, vsnode.ptr(), node);
@@ -942,12 +953,12 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
if (vsnode->get_output_port_for_preview() >= 0) {
show_port_preview(p_type, p_id, vsnode->get_output_port_for_preview());
+ } else {
+ offset = memnew(Control);
+ offset->set_custom_minimum_size(Size2(0, 4 * EDSCALE));
+ node->add_child(offset);
}
- offset = memnew(Control);
- offset->set_custom_minimum_size(Size2(0, 4 * EDSCALE));
- node->add_child(offset);
-
String error = vsnode->get_warning(mode, p_type);
if (!error.is_empty()) {
Label *error_label = memnew(Label);
@@ -4652,6 +4663,7 @@ VisualShaderEditor::VisualShaderEditor() {
graph->get_zoom_hbox()->set_h_size_flags(SIZE_EXPAND_FILL);
graph->set_v_size_flags(SIZE_EXPAND_FILL);
graph->set_h_size_flags(SIZE_EXPAND_FILL);
+ graph->set_show_zoom_label(true);
add_child(graph);
graph->set_drag_forwarding(this);
float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity");
@@ -6252,7 +6264,8 @@ void VisualShaderNodePortPreview::setup(const Ref &p_shader, Visua
}
Size2 VisualShaderNodePortPreview::get_minimum_size() const {
- return Size2(100, 100) * EDSCALE;
+ int port_preview_size = EditorSettings::get_singleton()->get("editors/visual_editors/visualshader/port_preview_size");
+ return Size2(port_preview_size, port_preview_size) * EDSCALE;
}
void VisualShaderNodePortPreview::_notification(int p_what) {
diff --git a/modules/visual_script/editor/visual_script_editor.cpp b/modules/visual_script/editor/visual_script_editor.cpp
index 9e6c0ef7734..4847b24f615 100644
--- a/modules/visual_script/editor/visual_script_editor.cpp
+++ b/modules/visual_script/editor/visual_script_editor.cpp
@@ -647,6 +647,14 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
Control::get_theme_icon(SNAME("PackedColorArray"), SNAME("EditorIcons"))
};
+ // Visual script specific theme for MSDF font.
+ Ref vstheme;
+ vstheme.instantiate();
+ Ref label_font = EditorNode::get_singleton()->get_editor_theme()->get_font("main_msdf", "EditorFonts");
+ vstheme->set_font("font", "Label", label_font);
+ vstheme->set_font("font", "LineEdit", label_font);
+ vstheme->set_font("font", "Button", label_font);
+
Ref seq_port = Control::get_theme_icon(SNAME("VisualShaderPort"), SNAME("EditorIcons"));
List node_ids;
script->get_node_list(&node_ids);
@@ -960,9 +968,8 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
slot_idx++;
}
-
graph->add_child(gnode);
-
+ gnode->set_theme(vstheme);
if (gnode->is_comment()) {
graph->move_child(gnode, 0);
}
@@ -4575,6 +4582,7 @@ VisualScriptEditor::VisualScriptEditor() {
add_child(graph);
graph->set_v_size_flags(Control::SIZE_EXPAND_FILL);
graph->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ graph->set_show_zoom_label(true);
graph->connect("node_selected", callable_mp(this, &VisualScriptEditor::_node_selected));
graph->connect("begin_node_move", callable_mp(this, &VisualScriptEditor::_begin_node_move));
graph->connect("end_node_move", callable_mp(this, &VisualScriptEditor::_end_node_move));
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index 85b32a52b54..45f036d8fcf 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -93,11 +93,13 @@ bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
si.color_right = p_value;
} else if (what == "right_icon") {
si.custom_slot_right = p_value;
+ } else if (what == "draw_stylebox") {
+ si.draw_stylebox = p_value;
} else {
return false;
}
- set_slot(idx, si.enable_left, si.type_left, si.color_left, si.enable_right, si.type_right, si.color_right, si.custom_slot_left, si.custom_slot_right);
+ set_slot(idx, si.enable_left, si.type_left, si.color_left, si.enable_right, si.type_right, si.color_right, si.custom_slot_left, si.custom_slot_right, si.draw_stylebox);
update();
return true;
}
@@ -144,6 +146,8 @@ bool GraphNode::_get(const StringName &p_name, Variant &r_ret) const {
r_ret = si.color_right;
} else if (what == "right_icon") {
r_ret = si.custom_slot_right;
+ } else if (what == "draw_stylebox") {
+ r_ret = si.draw_stylebox;
} else {
return false;
}
@@ -175,7 +179,7 @@ void GraphNode::_get_property_list(List *p_list) const {
p_list->push_back(PropertyInfo(Variant::INT, base + "right_type"));
p_list->push_back(PropertyInfo(Variant::COLOR, base + "right_color"));
p_list->push_back(PropertyInfo(Variant::OBJECT, base + "right_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL));
-
+ p_list->push_back(PropertyInfo(Variant::BOOL, base + "draw_stylebox"));
idx++;
}
}
@@ -185,6 +189,7 @@ void GraphNode::_resort() {
Size2i new_size = get_size();
Ref sb = get_theme_stylebox(SNAME("frame"));
+ Ref sb_slot = get_theme_stylebox(SNAME("slot"));
int sep = get_theme_constant(SNAME("separation"));
@@ -204,7 +209,7 @@ void GraphNode::_resort() {
continue;
}
- Size2i size = c->get_combined_minimum_size();
+ Size2i size = c->get_combined_minimum_size() + (slot_info[i].draw_stylebox ? sb_slot->get_minimum_size() : Size2());
_MinSizeCache msc;
stretch_min += size.height;
@@ -312,7 +317,9 @@ void GraphNode::_resort() {
int size = to - from;
- Rect2 rect(sb->get_margin(SIDE_LEFT), from, w, size);
+ float margin = sb->get_margin(SIDE_LEFT) + (slot_info[i].draw_stylebox ? sb_slot->get_margin(SIDE_LEFT) : 0);
+ float width = w - (slot_info[i].draw_stylebox ? sb_slot->get_minimum_size().x : 0);
+ Rect2 rect(margin, from, width, size);
fit_child_in_rect(c, rect);
cache_y.push_back(from - sb->get_margin(SIDE_TOP) + size * 0.5);
@@ -351,14 +358,14 @@ void GraphNode::_notification(int p_what) {
Ref sb;
if (comment) {
- sb = get_theme_stylebox(selected ? "comment_focus" : "comment");
+ sb = get_theme_stylebox(selected ? SNAME("comment_focus") : SNAME("comment"));
} else {
- sb = get_theme_stylebox(selected ? "selected_frame" : "frame");
+ sb = get_theme_stylebox(selected ? SNAME("selected_frame") : SNAME("frame"));
}
- //sb=sb->duplicate();
- //sb->call("set_modulate",modulate);
+ Ref sb_slot = get_theme_stylebox(SNAME("slot"));
+
Ref port = get_theme_icon(SNAME("port"));
Ref close = get_theme_icon(SNAME("close"));
Ref resizer = get_theme_icon(SNAME("resizer"));
@@ -389,13 +396,9 @@ void GraphNode::_notification(int p_what) {
int w = get_size().width - sb->get_minimum_size().x;
- if (show_close) {
- w -= close->get_width();
- }
-
title_buf->draw(get_canvas_item(), Point2(sb->get_margin(SIDE_LEFT) + title_h_offset, -title_buf->get_size().y + title_offset), title_color);
if (show_close) {
- Vector2 cpos = Point2(w + sb->get_margin(SIDE_LEFT) + close_h_offset, -close->get_height() + close_offset);
+ Vector2 cpos = Point2(w + sb->get_margin(SIDE_LEFT) + close_h_offset - close->get_width(), -close->get_height() + close_offset);
draw_texture(close, cpos, close_color);
close_rect.position = cpos;
close_rect.size = close->get_size();
@@ -411,7 +414,7 @@ void GraphNode::_notification(int p_what) {
continue;
}
const Slot &s = slot_info[E.key];
- //left
+ // Left port.
if (s.enable_left) {
Ref p = port;
if (s.custom_slot_left.is_valid()) {
@@ -419,6 +422,7 @@ void GraphNode::_notification(int p_what) {
}
p->draw(get_canvas_item(), icofs + Point2(edgeofs, cache_y[E.key]), s.color_left);
}
+ // Right port.
if (s.enable_right) {
Ref p = port;
if (s.custom_slot_right.is_valid()) {
@@ -426,6 +430,15 @@ void GraphNode::_notification(int p_what) {
}
p->draw(get_canvas_item(), icofs + Point2(get_size().x - edgeofs, cache_y[E.key]), s.color_right);
}
+
+ // Draw slot stylebox.
+ if (s.draw_stylebox) {
+ Control *c = Object::cast_to(get_child(E.key));
+ Rect2 c_rect = c->get_rect();
+ c_rect.position.x = sb->get_margin(SIDE_LEFT);
+ c_rect.size.width = w;
+ draw_style_box(sb_slot, c_rect);
+ }
}
if (resizable) {
@@ -482,7 +495,7 @@ void GraphNode::_validate_property(PropertyInfo &property) const {
}
#endif
-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 &p_custom_left, const Ref &p_custom_right) {
+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 &p_custom_left, const Ref &p_custom_right, bool p_draw_stylebox) {
ERR_FAIL_COND_MSG(p_idx < 0, vformat("Cannot set slot with p_idx (%d) lesser than zero.", p_idx));
if (!p_enable_left && p_type_left == 0 && p_color_left == Color(1, 1, 1, 1) &&
@@ -501,6 +514,7 @@ void GraphNode::set_slot(int p_idx, bool p_enable_left, int p_type_left, const C
s.color_right = p_color_right;
s.custom_slot_left = p_custom_left;
s.custom_slot_right = p_custom_right;
+ s.draw_stylebox = p_draw_stylebox;
slot_info[p_idx] = s;
update();
connpos_dirty = true;
@@ -622,16 +636,39 @@ Color GraphNode::get_slot_color_right(int p_idx) const {
return slot_info[p_idx].color_right;
}
+bool GraphNode::is_slot_draw_stylebox(int p_idx) const {
+ if (!slot_info.has(p_idx)) {
+ return false;
+ }
+ return slot_info[p_idx].draw_stylebox;
+}
+
+void GraphNode::set_slot_draw_stylebox(int p_idx, bool p_enable) {
+ ERR_FAIL_COND_MSG(p_idx < 0, vformat("Cannot set draw_stylebox for the slot with p_idx (%d) lesser than zero.", p_idx));
+
+ slot_info[p_idx].draw_stylebox = p_enable;
+ update();
+ connpos_dirty = true;
+
+ emit_signal(SNAME("slot_updated"), p_idx);
+}
+
Size2 GraphNode::get_minimum_size() const {
- int sep = get_theme_constant(SNAME("separation"));
Ref sb = get_theme_stylebox(SNAME("frame"));
+ Ref sb_slot = get_theme_stylebox(SNAME("slot"));
+
+ int sep = get_theme_constant(SNAME("separation"));
+ int title_h_offset = get_theme_constant(SNAME("title_h_offset"));
+
bool first = true;
Size2 minsize;
- minsize.x = title_buf->get_size().x;
+ minsize.x = title_buf->get_size().x + title_h_offset;
if (show_close) {
+ int close_h_offset = get_theme_constant(SNAME("close_h_offset"));
Ref close = get_theme_icon(SNAME("close"));
- minsize.x += sep + close->get_width();
+ //TODO: Remove this magic number after GraphNode rework.
+ minsize.x += 12 + close->get_width() + close_h_offset;
}
for (int i = 0; i < get_child_count(); i++) {
@@ -644,6 +681,9 @@ Size2 GraphNode::get_minimum_size() const {
}
Size2i size = c->get_combined_minimum_size();
+ if (slot_info.has(i)) {
+ size += slot_info[i].draw_stylebox ? sb_slot->get_minimum_size() : Size2();
+ }
minsize.y += size.y;
minsize.x = MAX(minsize.x, size.x);
@@ -989,7 +1029,7 @@ void GraphNode::_bind_methods() {
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("set_slot", "idx", "enable_left", "type_left", "color_left", "enable_right", "type_right", "color_right", "custom_left", "custom_right"), &GraphNode::set_slot, DEFVAL(Ref()), DEFVAL(Ref()));
+ ClassDB::bind_method(D_METHOD("set_slot", "idx", "enable_left", "type_left", "color_left", "enable_right", "type_right", "color_right", "custom_left", "custom_right", "enable"), &GraphNode::set_slot, DEFVAL(Ref()), DEFVAL(Ref()), DEFVAL(true));
ClassDB::bind_method(D_METHOD("clear_slot", "idx"), &GraphNode::clear_slot);
ClassDB::bind_method(D_METHOD("clear_all_slots"), &GraphNode::clear_all_slots);
@@ -1011,6 +1051,9 @@ void GraphNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_slot_color_right", "idx", "color_right"), &GraphNode::set_slot_color_right);
ClassDB::bind_method(D_METHOD("get_slot_color_right", "idx"), &GraphNode::get_slot_color_right);
+ ClassDB::bind_method(D_METHOD("is_slot_draw_stylebox", "idx"), &GraphNode::is_slot_draw_stylebox);
+ ClassDB::bind_method(D_METHOD("set_slot_draw_stylebox", "idx", "draw_stylebox"), &GraphNode::set_slot_draw_stylebox);
+
ClassDB::bind_method(D_METHOD("set_position_offset", "offset"), &GraphNode::set_position_offset);
ClassDB::bind_method(D_METHOD("get_position_offset"), &GraphNode::get_position_offset);
diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h
index 75e10b82b5c..9481a7452d1 100644
--- a/scene/gui/graph_node.h
+++ b/scene/gui/graph_node.h
@@ -54,6 +54,7 @@ private:
Color color_right = Color(1, 1, 1, 1);
Ref custom_slot_left;
Ref custom_slot_right;
+ bool draw_stylebox = true;
};
String title;
@@ -115,7 +116,7 @@ protected:
public:
bool has_point(const Point2 &p_point) const override;
- void 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 &p_custom_left = Ref(), const Ref &p_custom_right = Ref());
+ void 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 &p_custom_left = Ref(), const Ref &p_custom_right = Ref(), bool p_draw_stylebox = true);
void clear_slot(int p_idx);
void clear_all_slots();
@@ -137,6 +138,9 @@ public:
void set_slot_color_right(int p_idx, const Color &p_color_right);
Color get_slot_color_right(int p_idx) const;
+ bool is_slot_draw_stylebox(int p_idx) const;
+ void set_slot_draw_stylebox(int p_idx, bool p_enable);
+
void set_title(const String &p_title);
String get_title() const;
@@ -185,7 +189,9 @@ public:
virtual Vector get_allowed_size_flags_horizontal() const override;
virtual Vector get_allowed_size_flags_vertical() const override;
- bool is_resizing() const { return resizing; }
+ bool is_resizing() const {
+ return resizing;
+ }
GraphNode();
};
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 271cf61171e..4fb44446d9f 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -686,6 +686,7 @@ void fill_default_theme(Ref &theme, const Ref &default_font, const
graphnode_breakpoint->set_border_color(Color(0.9, 0.29, 0.3));
Ref graphnode_position = make_flat_stylebox(style_pressed_color, 18, 42, 18, 12, 6, true, 4);
graphnode_position->set_border_color(Color(0.98, 0.89, 0.27));
+ Ref graphnode_slot = make_empty_stylebox(0, 0, 0, 0);
theme->set_stylebox("frame", "GraphNode", graphnode_normal);
theme->set_stylebox("selected_frame", "GraphNode", graphnode_selected);
@@ -693,6 +694,7 @@ void fill_default_theme(Ref &theme, const Ref &default_font, const
theme->set_stylebox("comment_focus", "GraphNode", graphnode_comment_selected);
theme->set_stylebox("breakpoint", "GraphNode", graphnode_breakpoint);
theme->set_stylebox("position", "GraphNode", graphnode_position);
+ theme->set_stylebox("slot", "GraphNode", graphnode_slot);
theme->set_icon("port", "GraphNode", icons["graph_port"]);
theme->set_icon("close", "GraphNode", icons["close"]);
@@ -704,6 +706,7 @@ void fill_default_theme(Ref &theme, const Ref &default_font, const
theme->set_constant("separation", "GraphNode", 2 * scale);
theme->set_constant("title_offset", "GraphNode", 26 * scale);
theme->set_constant("close_offset", "GraphNode", 22 * scale);
+ theme->set_constant("close_h_offset", "GraphNode", 22 * scale);
theme->set_constant("port_offset", "GraphNode", 0);
// Tree