diff options
-rw-r--r-- | doc/classes/GraphNode.xml | 21 | ||||
-rw-r--r-- | editor/editor_fonts.cpp | 80 | ||||
-rw-r--r-- | editor/editor_settings.cpp | 1 | ||||
-rw-r--r-- | editor/editor_themes.cpp | 76 | ||||
-rw-r--r-- | editor/plugins/visual_shader_editor_plugin.cpp | 23 | ||||
-rw-r--r-- | modules/visual_script/editor/visual_script_editor.cpp | 12 | ||||
-rw-r--r-- | scene/gui/graph_node.cpp | 81 | ||||
-rw-r--r-- | scene/gui/graph_node.h | 10 | ||||
-rw-r--r-- | scene/resources/default_theme/default_theme.cpp | 3 |
9 files changed, 249 insertions, 58 deletions
diff --git a/doc/classes/GraphNode.xml b/doc/classes/GraphNode.xml index 173da63a15..5f0dca0402 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]. </description> </method> + <method name="is_slot_draw_stylebox" qualifiers="const"> + <return type="bool" /> + <argument index="0" name="idx" type="int" /> + <description> + Returns true if the background [StyleBox] of the slot [code]idx[/code] is drawn. + </description> + </method> <method name="is_slot_enabled_left" qualifiers="const"> <return type="bool" /> <argument index="0" name="idx" type="int" /> @@ -152,6 +159,7 @@ <argument index="6" name="color_right" type="Color" /> <argument index="7" name="custom_left" type="Texture2D" default="null" /> <argument index="8" name="custom_right" type="Texture2D" default="null" /> + <argument index="9" name="enable" type="bool" default="true" /> <description> 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]. </description> </method> + <method name="set_slot_draw_stylebox"> + <return type="void" /> + <argument index="0" name="idx" type="int" /> + <argument index="1" name="draw_stylebox" type="bool" /> + <description> + Toggles the background [StyleBox] of the slot [code]idx[/code]. + </description> + </method> <method name="set_slot_enabled_left"> <return type="void" /> <argument index="0" name="idx" type="int" /> @@ -301,6 +317,8 @@ <theme_item name="title_color" data_type="color" type="Color" default="Color(0.875, 0.875, 0.875, 1)"> Color of the title text. </theme_item> + <theme_item name="close_h_offset" data_type="constant" type="int" default="22"> + </theme_item> <theme_item name="close_offset" data_type="constant" type="int" default="22"> The vertical offset of the close button. </theme_item> @@ -343,5 +361,8 @@ <theme_item name="selected_frame" data_type="style" type="StyleBox"> The background used when the [GraphNode] is selected. </theme_item> + <theme_item name="slot" data_type="style" type="StyleBox"> + The [StyleBox] used for each slot of the [GraphNode]. + </theme_item> </theme_items> </class> diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp index 3e18499b97..51d4d474c5 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<Font> 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<String> variation_tags = m_variations.split(","); \ + for (int i = 0; i < variation_tags.size(); i++) { \ + Vector<String> 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<Font> 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<Font> 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<String> variation_tags = m_variations.split(","); \ + for (int i = 0; i < variation_tags.size(); i++) { \ + Vector<String> 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<Font> m_name; \ m_name.instantiate(); \ @@ -189,13 +241,14 @@ m_name->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE); \ MAKE_FALLBACKS(m_name); -Ref<FontData> 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<FontData> 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<FontData> font; font.instantiate(); Vector<uint8_t> 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<FontData> load_cached_external_font(const String &p_path, TextServer::Hintin return font; } -Ref<FontData> 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<FontData> 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<FontData> 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<Theme> p_theme) { EditorSettings::get_singleton()->set_manually("interface/editor/main_font", ""); } + Ref<FontData> 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<FontData> CustomFontSlanted; if (CustomFont.is_valid()) { CustomFontSlanted = CustomFont->duplicate(); @@ -282,6 +343,13 @@ void editor_register_fonts(Ref<Theme> p_theme) { CustomFontBold->set_embolden(embolden_strength); } + Ref<FontData> 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<Theme> p_theme) { /* Noto Sans */ Ref<FontData> DefaultFont = load_cached_internal_font(_font_NotoSans_Regular, _font_NotoSans_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning); + Ref<FontData> DefaultFontMSDF = load_cached_internal_font(_font_NotoSans_Regular, _font_NotoSans_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning, true); Ref<FontData> DefaultFontBold = load_cached_internal_font(_font_NotoSans_Bold, _font_NotoSans_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning); + Ref<FontData> DefaultFontBoldMSDF = load_cached_internal_font(_font_NotoSans_Bold, _font_NotoSans_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning, true); Ref<FontData> FontArabic = load_cached_internal_font(_font_NotoNaskhArabicUI_Regular, _font_NotoNaskhArabicUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning); Ref<FontData> FontArabicBold = load_cached_internal_font(_font_NotoNaskhArabicUI_Bold, _font_NotoNaskhArabicUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning); Ref<FontData> 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<Theme> 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 bdabff20f9..7b2f703113 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -682,6 +682,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> 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 0400aa74b5..92db4fce15 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -741,17 +741,28 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("pressed", "EditorLogFilterButton", editor_log_button_pressed); // OptionButton - theme->set_stylebox("focus", "OptionButton", style_widget_focus); - + Ref<StyleBoxFlat> style_option_button_focus = style_widget_focus->duplicate(); + Ref<StyleBoxFlat> style_option_button_normal = style_widget->duplicate(); + Ref<StyleBoxFlat> style_option_button_hover = style_widget_hover->duplicate(); + Ref<StyleBoxFlat> style_option_button_pressed = style_widget_pressed->duplicate(); + Ref<StyleBoxFlat> 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<Theme> create_editor_theme(const Ref<Theme> 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<Theme> create_editor_theme(const Ref<Theme> 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<StyleBoxFlat> 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<StyleBoxFlat> 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<StyleBoxFlat> 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<StyleBoxFlat> 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<StyleBoxFlat> 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<StyleBoxFlat> 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<StyleBoxFlat> 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<StyleBoxFlat> 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<StyleBoxFlat> graphsbbreakpoint = graphsbselected->duplicate(); graphsbbreakpoint->set_draw_center(false); graphsbbreakpoint->set_border_color(warning_color); @@ -1472,10 +1488,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> 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<StyleBoxFlat> smgraphsb = make_flat_stylebox(dark_color_3 * Color(1, 1, 1, 0.7), gn_margin_side, 24, gn_margin_side, 5, corner_width); + Ref<StyleBoxEmpty> graphsbslot = make_empty_stylebox(12, 0, 12, 0); + Ref<StyleBoxFlat> 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<StyleBoxFlat> 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<StyleBoxFlat> 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<Theme> create_editor_theme(const Ref<Theme> 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<Theme> create_editor_theme(const Ref<Theme> 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 dc07ac7c39..641989bb63 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<Theme> vstheme; + vstheme.instantiate(); + Ref<Font> 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<VisualShaderNode> vsnode = visual_shader->get_node(p_type, p_id); Ref<VisualShaderNodeResizableBase> resizable_node = Object::cast_to<VisualShaderNodeResizableBase>(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<VisualShader> &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 06fa90eb29..35a2bddac6 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<Theme> vstheme; + vstheme.instantiate(); + Ref<Font> 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<Texture2D> seq_port = Control::get_theme_icon(SNAME("VisualShaderPort"), SNAME("EditorIcons")); List<int> 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); } @@ -4577,6 +4584,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 e3ecd17ed8..31be9c4b9d 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<PropertyInfo> *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<StyleBox> sb = get_theme_stylebox(SNAME("frame")); + Ref<StyleBox> 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<StyleBox> 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<StyleBox> sb_slot = get_theme_stylebox(SNAME("slot")); + Ref<Texture2D> port = get_theme_icon(SNAME("port")); Ref<Texture2D> close = get_theme_icon(SNAME("close")); Ref<Texture2D> 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<Texture2D> 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<Texture2D> 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<Control>(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<Texture2D> &p_custom_left, const Ref<Texture2D> &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<Texture2D> &p_custom_left, const Ref<Texture2D> &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<StyleBox> sb = get_theme_stylebox(SNAME("frame")); + Ref<StyleBox> 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<Texture2D> 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<Texture2D>()), DEFVAL(Ref<Texture2D>())); + 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<Texture2D>()), DEFVAL(Ref<Texture2D>()), 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 7eb5f27cff..44f58533fc 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<Texture2D> custom_slot_left; Ref<Texture2D> 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<Texture2D> &p_custom_left = Ref<Texture2D>(), const Ref<Texture2D> &p_custom_right = Ref<Texture2D>()); + 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<Texture2D> &p_custom_left = Ref<Texture2D>(), const Ref<Texture2D> &p_custom_right = Ref<Texture2D>(), 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<int> get_allowed_size_flags_horizontal() const override; virtual Vector<int> 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 271cf61171..4fb44446d9 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> &theme, const Ref<Font> &default_font, const graphnode_breakpoint->set_border_color(Color(0.9, 0.29, 0.3)); Ref<StyleBoxFlat> 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<StyleBoxEmpty> 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> &theme, const Ref<Font> &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> &theme, const Ref<Font> &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 |