summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/classes/Callable.xml4
-rw-r--r--doc/classes/Control.xml1
-rw-r--r--doc/classes/TabContainer.xml3
-rw-r--r--editor/editor_node.cpp7
-rw-r--r--editor/editor_node.h1
-rw-r--r--editor/editor_run.cpp5
-rw-r--r--editor/editor_themes.cpp62
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.extended.cs26
-rw-r--r--scene/3d/mesh_instance_3d.cpp9
-rw-r--r--scene/gui/tab_container.cpp4
-rw-r--r--scene/main/canvas_item.cpp3
-rw-r--r--scene/main/window.cpp28
-rw-r--r--scene/main/window.h3
-rw-r--r--scene/resources/default_theme/default_theme.cpp1
14 files changed, 111 insertions, 46 deletions
diff --git a/doc/classes/Callable.xml b/doc/classes/Callable.xml
index 6838bdeb70..1fcaf6d866 100644
--- a/doc/classes/Callable.xml
+++ b/doc/classes/Callable.xml
@@ -75,6 +75,10 @@
<return type="void" />
<description>
Calls the method represented by this [Callable] in deferred mode, i.e. during the idle frame. Arguments can be passed and should match the method's signature.
+ [codeblock]
+ func _ready():
+ grab_focus.call_deferred()
+ [/codeblock]
</description>
</method>
<method name="get_method" qualifiers="const">
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index 0e71dbd0b1..71798d2574 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -553,6 +553,7 @@
<return type="void" />
<description>
Steal the focus from another control and become the focused control (see [member focus_mode]).
+ [b]Note[/b]: Using this method together with [method Callable.call_deferred] makes it more reliable, especially when called inside [method Node._ready].
</description>
</method>
<method name="has_focus" qualifiers="const">
diff --git a/doc/classes/TabContainer.xml b/doc/classes/TabContainer.xml
index 74f258072c..302f9b329b 100644
--- a/doc/classes/TabContainer.xml
+++ b/doc/classes/TabContainer.xml
@@ -258,5 +258,8 @@
<theme_item name="tab_unselected" data_type="style" type="StyleBox">
The style of the other, unselected tabs.
</theme_item>
+ <theme_item name="tabbar_background" data_type="style" type="StyleBox">
+ The style for the background fill of the [TabBar] area.
+ </theme_item>
</theme_items>
</class>
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 6b68c4127f..0f2e0c8fcb 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -753,6 +753,8 @@ void EditorNode::_notification(int p_what) {
gui_base->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("Background"), SNAME("EditorStyles")));
scene_root_parent->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("Content"), SNAME("EditorStyles")));
bottom_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("panel"), SNAME("TabContainer")));
+
+ tabbar_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("tabbar_background"), SNAME("TabContainer")));
scene_tabs->add_theme_style_override("tab_selected", gui_base->get_theme_stylebox(SNAME("SceneTabFG"), SNAME("EditorStyles")));
scene_tabs->add_theme_style_override("tab_unselected", gui_base->get_theme_stylebox(SNAME("SceneTabBG"), SNAME("EditorStyles")));
@@ -6490,8 +6492,11 @@ EditorNode::EditorNode() {
tab_preview->set_position(Point2(2, 2) * EDSCALE);
tab_preview_panel->add_child(tab_preview);
+ tabbar_panel = memnew(PanelContainer);
+ tabbar_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("tabbar_background"), SNAME("TabContainer")));
+ srt->add_child(tabbar_panel);
tabbar_container = memnew(HBoxContainer);
- srt->add_child(tabbar_container);
+ tabbar_panel->add_child(tabbar_container);
scene_tabs = memnew(TabBar);
scene_tabs->add_theme_style_override("tab_selected", gui_base->get_theme_stylebox(SNAME("SceneTabFG"), SNAME("EditorStyles")));
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 792d2fc879..7e66e14ce0 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -426,6 +426,7 @@ private:
int dock_popup_selected_idx = -1;
int dock_select_rect_over_idx = -1;
+ PanelContainer *tabbar_panel = nullptr;
HBoxContainer *tabbar_container = nullptr;
Button *distraction_free = nullptr;
Button *scene_tab_add = nullptr;
diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp
index 3b828951e4..b909129b18 100644
--- a/editor/editor_run.cpp
+++ b/editor/editor_run.cpp
@@ -258,6 +258,11 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie) {
}
}
+ // Pass the debugger stop shortcut to the running instance(s).
+ String shortcut;
+ VariantWriter::write_to_string(ED_GET_SHORTCUT("editor/stop"), shortcut);
+ OS::get_singleton()->set_environment("__GODOT_EDITOR_STOP_SHORTCUT__", shortcut);
+
printf("Running: %s", exec.utf8().get_data());
for (const String &E : args) {
printf(" %s", E.utf8().get_data());
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index d20caef51c..088239c2d9 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -656,45 +656,46 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// TabBar
- Ref<StyleBoxFlat> style_tab_selected = style_widget->duplicate();
+ Ref<StyleBoxFlat> style_tab_base = style_widget->duplicate();
- // Add a highlight line at the top of the selected tab.
- style_tab_selected->set_border_width_all(0);
- style_tab_selected->set_default_margin(SIDE_LEFT, widget_default_margin.x - border_width);
- style_tab_selected->set_border_width(SIDE_TOP, Math::round(2 * EDSCALE));
- // Make the highlight line prominent, but not too prominent as to not be distracting.
- Color tab_highlight = dark_color_2.lerp(accent_color, 0.75);
- style_tab_selected->set_border_color(tab_highlight);
+ style_tab_base->set_border_width_all(0);
// Don't round the top corners to avoid creating a small blank space between the tabs and the main panel.
// This also makes the top highlight look better.
- style_tab_selected->set_corner_radius_all(0);
+ style_tab_base->set_corner_detail(corner_width);
+ style_tab_base->set_corner_radius_all(0);
+ style_tab_base->set_corner_radius(CORNER_TOP_LEFT, corner_radius * EDSCALE);
+ style_tab_base->set_corner_radius(CORNER_TOP_RIGHT, corner_radius * EDSCALE);
// Prevent visible artifacts and cover the top-left rounded corner of the panel below the tab if selected
// We can't prevent them with both rounded corners and non-zero border width, though
- style_tab_selected->set_expand_margin_size(SIDE_BOTTOM, corner_width > 0 ? corner_width : border_width);
-
+ style_tab_base->set_expand_margin_size(SIDE_BOTTOM, corner_width > 0 ? corner_width : border_width);
// When using a border width greater than 0, visually line up the left of the selected tab with the underlying panel.
- style_tab_selected->set_expand_margin_size(SIDE_LEFT, -border_width);
+ style_tab_base->set_expand_margin_size(SIDE_LEFT, -border_width);
+
+ style_tab_base->set_default_margin(SIDE_LEFT, widget_default_margin.x + 5 * EDSCALE);
+ style_tab_base->set_default_margin(SIDE_RIGHT, widget_default_margin.x + 5 * EDSCALE);
+ style_tab_base->set_default_margin(SIDE_BOTTOM, widget_default_margin.y);
+ style_tab_base->set_default_margin(SIDE_TOP, widget_default_margin.y);
+
+ Ref<StyleBoxFlat> style_tab_selected = style_tab_base->duplicate();
- style_tab_selected->set_default_margin(SIDE_LEFT, widget_default_margin.x + 2 * EDSCALE);
- style_tab_selected->set_default_margin(SIDE_RIGHT, widget_default_margin.x + 2 * EDSCALE);
- style_tab_selected->set_default_margin(SIDE_BOTTOM, widget_default_margin.y);
- style_tab_selected->set_default_margin(SIDE_TOP, widget_default_margin.y);
style_tab_selected->set_bg_color(base_color);
+ // Add a highlight line at the top of the selected tab.
+ style_tab_selected->set_border_width(SIDE_TOP, Math::round(2 * EDSCALE));
+ // Make the highlight line prominent, but not too prominent as to not be distracting.
+ Color tab_highlight = dark_color_2.lerp(accent_color, 0.75);
+ style_tab_selected->set_border_color(tab_highlight);
+ style_tab_selected->set_corner_radius_all(0);
- Ref<StyleBoxFlat> style_tab_unselected = style_tab_selected->duplicate();
- style_tab_unselected->set_bg_color(dark_color_1);
+ Ref<StyleBoxFlat> style_tab_unselected = style_tab_base->duplicate();
style_tab_unselected->set_expand_margin_size(SIDE_BOTTOM, 0);
+ style_tab_unselected->set_bg_color(dark_color_1);
// Add some spacing between unselected tabs to make them easier to distinguish from each other
style_tab_unselected->set_border_color(Color(0, 0, 0, 0));
- style_tab_unselected->set_border_width(SIDE_LEFT, Math::round(1 * EDSCALE));
- style_tab_unselected->set_border_width(SIDE_RIGHT, Math::round(1 * EDSCALE));
- style_tab_unselected->set_default_margin(SIDE_LEFT, widget_default_margin.x + 2 * EDSCALE);
- style_tab_unselected->set_default_margin(SIDE_RIGHT, widget_default_margin.x + 2 * EDSCALE);
- Ref<StyleBoxFlat> style_tab_disabled = style_tab_selected->duplicate();
- style_tab_disabled->set_bg_color(disabled_bg_color);
+ Ref<StyleBoxFlat> style_tab_disabled = style_tab_base->duplicate();
style_tab_disabled->set_expand_margin_size(SIDE_BOTTOM, 0);
+ style_tab_disabled->set_bg_color(disabled_bg_color);
style_tab_disabled->set_border_color(disabled_bg_color);
// Editor background
@@ -1199,6 +1200,13 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_constant("line_separation", "ItemList", 3 * EDSCALE);
// TabBar & TabContainer
+ Ref<StyleBoxFlat> style_tabbar_background = make_flat_stylebox(dark_color_1, 0, 0, 0, 0);
+ style_tabbar_background->set_expand_margin_size(SIDE_BOTTOM, corner_width > 0 ? corner_width : border_width);
+ style_tabbar_background->set_corner_detail(corner_width);
+ style_tabbar_background->set_corner_radius(CORNER_TOP_LEFT, corner_radius * EDSCALE);
+ style_tabbar_background->set_corner_radius(CORNER_TOP_RIGHT, corner_radius * EDSCALE);
+ theme->set_stylebox("tabbar_background", "TabContainer", style_tabbar_background);
+
theme->set_stylebox("tab_selected", "TabContainer", style_tab_selected);
theme->set_stylebox("tab_unselected", "TabContainer", style_tab_unselected);
theme->set_stylebox("tab_disabled", "TabContainer", style_tab_disabled);
@@ -1234,14 +1242,14 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
Ref<StyleBoxFlat> style_content_panel = style_default->duplicate();
style_content_panel->set_border_color(dark_color_3);
style_content_panel->set_border_width_all(border_width);
+ style_content_panel->set_border_width(Side::SIDE_TOP, 0);
+ style_content_panel->set_corner_radius(CORNER_TOP_LEFT, 0);
+ style_content_panel->set_corner_radius(CORNER_TOP_RIGHT, 0);
// compensate the border
style_content_panel->set_default_margin(SIDE_TOP, (2 + margin_size_extra) * EDSCALE);
style_content_panel->set_default_margin(SIDE_RIGHT, margin_size_extra * EDSCALE);
style_content_panel->set_default_margin(SIDE_BOTTOM, margin_size_extra * EDSCALE);
style_content_panel->set_default_margin(SIDE_LEFT, margin_size_extra * EDSCALE);
- // Display border to visually split the body of the container from its possible backgrounds.
- style_content_panel->set_border_width(Side::SIDE_TOP, Math::round(2 * EDSCALE));
- style_content_panel->set_border_color(dark_color_2);
theme->set_stylebox("panel", "TabContainer", style_content_panel);
// TabContainerOdd can be used on tabs against the base color background (e.g. nested tabs).
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.extended.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.extended.cs
index 2ea3c18d26..26fffc079c 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.extended.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.extended.cs
@@ -11,31 +11,31 @@ namespace Godot.NativeInterop
case Variant.Type.Nil:
return default;
case Variant.Type.Bool:
- return new godot_variant() { Bool = src.Bool };
+ return new godot_variant() { Bool = src.Bool, Type = Variant.Type.Bool };
case Variant.Type.Int:
- return new godot_variant() { Int = src.Int };
+ return new godot_variant() { Int = src.Int, Type = Variant.Type.Int };
case Variant.Type.Float:
- return new godot_variant() { Float = src.Float };
+ return new godot_variant() { Float = src.Float, Type = Variant.Type.Float };
case Variant.Type.Vector2:
- return new godot_variant() { Vector2 = src.Vector2 };
+ return new godot_variant() { Vector2 = src.Vector2, Type = Variant.Type.Vector2 };
case Variant.Type.Vector2i:
- return new godot_variant() { Vector2i = src.Vector2i };
+ return new godot_variant() { Vector2i = src.Vector2i, Type = Variant.Type.Vector2i };
case Variant.Type.Rect2:
- return new godot_variant() { Rect2 = src.Rect2 };
+ return new godot_variant() { Rect2 = src.Rect2, Type = Variant.Type.Rect2 };
case Variant.Type.Rect2i:
- return new godot_variant() { Rect2i = src.Rect2i };
+ return new godot_variant() { Rect2i = src.Rect2i, Type = Variant.Type.Rect2i };
case Variant.Type.Vector3:
- return new godot_variant() { Vector3 = src.Vector3 };
+ return new godot_variant() { Vector3 = src.Vector3, Type = Variant.Type.Vector3 };
case Variant.Type.Vector3i:
- return new godot_variant() { Vector3i = src.Vector3i };
+ return new godot_variant() { Vector3i = src.Vector3i, Type = Variant.Type.Vector3i };
case Variant.Type.Plane:
- return new godot_variant() { Plane = src.Plane };
+ return new godot_variant() { Plane = src.Plane, Type = Variant.Type.Plane };
case Variant.Type.Quaternion:
- return new godot_variant() { Quaternion = src.Quaternion };
+ return new godot_variant() { Quaternion = src.Quaternion, Type = Variant.Type.Quaternion };
case Variant.Type.Color:
- return new godot_variant() { Color = src.Color };
+ return new godot_variant() { Color = src.Color, Type = Variant.Type.Color };
case Variant.Type.Rid:
- return new godot_variant() { RID = src.RID };
+ return new godot_variant() { RID = src.RID, Type = Variant.Type.Rid };
}
godotsharp_variant_new_copy(out godot_variant ret, src);
diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp
index 31993f898d..a76f4dd0d5 100644
--- a/scene/3d/mesh_instance_3d.cpp
+++ b/scene/3d/mesh_instance_3d.cpp
@@ -115,8 +115,8 @@ void MeshInstance3D::set_mesh(const Ref<Mesh> &p_mesh) {
if (mesh.is_valid()) {
mesh->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &MeshInstance3D::_mesh_changed));
- _mesh_changed();
set_base(mesh->get_rid());
+ _mesh_changed();
} else {
blend_shape_tracks.clear();
blend_shape_properties.clear();
@@ -380,6 +380,13 @@ void MeshInstance3D::_mesh_changed() {
}
}
+ int surface_count = mesh->get_surface_count();
+ for (int surface_index = 0; surface_index < surface_count; ++surface_index) {
+ if (surface_override_materials[surface_index].is_valid()) {
+ RS::get_singleton()->instance_set_surface_override_material(get_instance(), surface_index, surface_override_materials[surface_index]->get_rid());
+ }
+ }
+
update_gizmos();
}
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index 861a3050cb..3e04ebee6a 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -163,6 +163,10 @@ void TabContainer::_notification(int p_what) {
int header_height = _get_top_margin();
+ // Draw background for the tabbar.
+ Ref<StyleBox> tabbar_background = get_theme_stylebox(SNAME("tabbar_background"));
+ tabbar_background->draw(canvas, Rect2(0, 0, size.width, header_height));
+ // Draw the background for the tab's content.
panel->draw(canvas, Rect2(0, header_height, size.width, size.height - header_height));
// Draw the popup menu.
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index 3eb4991332..61a7600664 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -365,7 +365,7 @@ void CanvasItem::queue_redraw() {
pending_update = true;
- MessageQueue::get_singleton()->push_call(this, SNAME("_redraw_callback"));
+ MessageQueue::get_singleton()->push_callable(callable_mp(this, &CanvasItem::_redraw_callback));
}
void CanvasItem::set_modulate(const Color &p_modulate) {
@@ -867,7 +867,6 @@ void CanvasItem::force_update_transform() {
void CanvasItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("_top_level_raise_self"), &CanvasItem::_top_level_raise_self);
- ClassDB::bind_method(D_METHOD("_redraw_callback"), &CanvasItem::_redraw_callback);
#ifdef TOOLS_ENABLED
ClassDB::bind_method(D_METHOD("_edit_set_state", "state"), &CanvasItem::_edit_set_state);
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index 5328ae7b8c..1e52b644a3 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -32,7 +32,9 @@
#include "core/config/project_settings.h"
#include "core/debugger/engine_debugger.h"
+#include "core/input/shortcut.h"
#include "core/string/translation.h"
+#include "core/variant/variant_parser.h"
#include "scene/gui/control.h"
#include "scene/scene_string_names.h"
#include "scene/theme/theme_db.h"
@@ -1034,9 +1036,31 @@ bool Window::_can_consume_input_events() const {
void Window::_window_input(const Ref<InputEvent> &p_ev) {
if (EngineDebugger::is_active()) {
- // Quit from game window using F8.
+ // Quit from game window using the stop shortcut (F8 by default).
+ // The custom shortcut is provided via environment variable when running from the editor.
+ if (debugger_stop_shortcut.is_null()) {
+ String shortcut_str = OS::get_singleton()->get_environment("__GODOT_EDITOR_STOP_SHORTCUT__");
+ if (!shortcut_str.is_empty()) {
+ Variant shortcut_var;
+
+ VariantParser::StreamString ss;
+ ss.s = shortcut_str;
+
+ String errs;
+ int line;
+ VariantParser::parse(&ss, shortcut_var, errs, line);
+ debugger_stop_shortcut = shortcut_var;
+ }
+
+ if (debugger_stop_shortcut.is_null()) {
+ // Define a default shortcut if it wasn't provided or is invalid.
+ debugger_stop_shortcut.instantiate();
+ debugger_stop_shortcut->set_events({ (Variant)InputEventKey::create_reference(Key::F8) });
+ }
+ }
+
Ref<InputEventKey> k = p_ev;
- if (k.is_valid() && k->is_pressed() && !k->is_echo() && k->get_keycode() == Key::F8) {
+ if (k.is_valid() && k->is_pressed() && !k->is_echo() && debugger_stop_shortcut->matches_event(k)) {
EngineDebugger::get_singleton()->send_message("request_quit", Array());
}
}
diff --git a/scene/main/window.h b/scene/main/window.h
index a5b6b26104..238be484c0 100644
--- a/scene/main/window.h
+++ b/scene/main/window.h
@@ -35,6 +35,7 @@
class Control;
class Font;
+class Shortcut;
class StyleBox;
class Theme;
@@ -151,6 +152,8 @@ private:
void _event_callback(DisplayServer::WindowEvent p_event);
virtual bool _can_consume_input_events() const override;
+ Ref<Shortcut> debugger_stop_shortcut;
+
protected:
Viewport *_get_embedder() const;
virtual Rect2i _popup_adjust_rect() const { return Rect2i(); }
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 410f35e597..73ad1ceff7 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -831,6 +831,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("tab_unselected", "TabContainer", style_tab_unselected);
theme->set_stylebox("tab_disabled", "TabContainer", style_tab_disabled);
theme->set_stylebox("panel", "TabContainer", make_flat_stylebox(style_normal_color, 0, 0, 0, 0));
+ theme->set_stylebox("tabbar_background", "TabContainer", make_empty_stylebox(0, 0, 0, 0));
theme->set_icon("increment", "TabContainer", icons["scroll_button_right"]);
theme->set_icon("increment_highlight", "TabContainer", icons["scroll_button_right_hl"]);