summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gles2/shader_compiler_gles2.cpp2
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp2
-rw-r--r--editor/code_editor.cpp3
-rw-r--r--editor/editor_inspector.cpp2
-rw-r--r--editor/editor_profiler.cpp30
-rw-r--r--editor/editor_sectioned_inspector.cpp6
-rw-r--r--editor/editor_themes.cpp99
-rw-r--r--editor/rename_dialog.cpp51
-rw-r--r--editor/rename_dialog.h2
-rw-r--r--editor/script_create_dialog.cpp2
-rw-r--r--editor/script_editor_debugger.cpp48
-rw-r--r--editor/script_editor_debugger.h1
-rw-r--r--main/main.cpp2
-rw-r--r--modules/gdnative/SCsub20
-rw-r--r--modules/gdnative/gdnative_builders.py97
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/NodeExtensions.cs2
-rw-r--r--modules/opensimplex/doc_classes/OpenSimplexNoise.xml3
-rw-r--r--modules/opensimplex/open_simplex_noise.cpp9
-rw-r--r--modules/opensimplex/open_simplex_noise.h7
-rw-r--r--modules/svg/image_loader_svg.cpp13
-rw-r--r--platform/osx/detect.py18
-rw-r--r--platform/osx/os_osx.mm26
-rw-r--r--scene/gui/option_button.cpp9
-rw-r--r--scene/gui/tab_container.cpp16
-rw-r--r--scene/gui/tab_container.h2
25 files changed, 216 insertions, 256 deletions
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp
index 24b89aedc2..5dec6f2fee 100644
--- a/drivers/gles2/shader_compiler_gles2.cpp
+++ b/drivers/gles2/shader_compiler_gles2.cpp
@@ -80,7 +80,7 @@ static String _opstr(SL::Operator p_op) {
static String _mkid(const String &p_id) {
- String id = "m_" + p_id;
+ String id = "m_" + p_id.replace("__", "_dus_");
return id.replace("__", "_dus_"); //doubleunderscore is reserved in glsl
}
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index f43943bdff..4e4d896bd7 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -166,7 +166,7 @@ static String _opstr(SL::Operator p_op) {
static String _mkid(const String &p_id) {
- String id = "m_" + p_id;
+ String id = "m_" + p_id.replace("__", "_dus_");
return id.replace("__", "_dus_"); //doubleunderscore is reserved in glsl
}
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 4f684c7bdc..e05ace53da 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -277,7 +277,8 @@ void FindReplaceBar::_replace_all() {
}
text_edit->set_v_scroll(vsval);
- set_error(vformat(TTR("Replaced %d occurrence(s)."), rc));
+ matches_label->add_color_override("font_color", rc > 0 ? get_color("font_color", "Label") : get_color("error_color", "Editor"));
+ matches_label->set_text(vformat(TTR("%d replaced."), rc));
text_edit->call_deferred("connect", "text_changed", this, "_editor_text_changed");
results_count = -1;
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 56da7d93fa..7c1e58862e 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -1596,7 +1596,7 @@ void EditorInspector::update_tree() {
if (capitalize_paths)
cat = cat.capitalize();
- if (!filter.is_subsequence_ofi(cat) && !filter.is_subsequence_ofi(name))
+ if (!filter.is_subsequence_ofi(cat) && !filter.is_subsequence_ofi(name) && property_prefix.to_lower().find(filter.to_lower()) == -1)
continue;
}
diff --git a/editor/editor_profiler.cpp b/editor/editor_profiler.cpp
index 4807f8839c..3fdeaff19d 100644
--- a/editor/editor_profiler.cpp
+++ b/editor/editor_profiler.cpp
@@ -102,26 +102,28 @@ void EditorProfiler::clear() {
}
static String _get_percent_txt(float p_value, float p_total) {
- if (p_total == 0)
+ if (p_total == 0) {
p_total = 0.00001;
+ }
+
return String::num((p_value / p_total) * 100, 1) + "%";
}
String EditorProfiler::_get_time_as_text(const Metric &m, float p_time, int p_calls) {
- int dmode = display_mode->get_selected();
+ const int dmode = display_mode->get_selected();
if (dmode == DISPLAY_FRAME_TIME) {
- return rtos(p_time);
+ return rtos(p_time * 1000).pad_decimals(2) + " ms";
} else if (dmode == DISPLAY_AVERAGE_TIME) {
- if (p_calls == 0)
- return "0";
- else
- return rtos(p_time / p_calls);
+ if (p_calls == 0) {
+ return "0.00 ms";
+ } else {
+ return rtos((p_time / p_calls) * 1000).pad_decimals(2) + " ms";
+ }
} else if (dmode == DISPLAY_FRAME_PERCENT) {
return _get_percent_txt(p_time, m.frame_time);
} else if (dmode == DISPLAY_PHYSICS_FRAME_PERCENT) {
-
return _get_percent_txt(p_time, m.physics_frame_time);
}
@@ -729,7 +731,7 @@ EditorProfiler::EditorProfiler() {
h_split->set_v_size_flags(SIZE_EXPAND_FILL);
variables = memnew(Tree);
- variables->set_custom_minimum_size(Size2(300, 0) * EDSCALE);
+ variables->set_custom_minimum_size(Size2(320, 0) * EDSCALE);
variables->set_hide_folding(true);
h_split->add_child(variables);
variables->set_hide_root(true);
@@ -737,10 +739,10 @@ EditorProfiler::EditorProfiler() {
variables->set_column_titles_visible(true);
variables->set_column_title(0, TTR("Name"));
variables->set_column_expand(0, true);
- variables->set_column_min_width(0, 60);
+ variables->set_column_min_width(0, 60 * EDSCALE);
variables->set_column_title(1, TTR("Time"));
variables->set_column_expand(1, false);
- variables->set_column_min_width(1, 60 * EDSCALE);
+ variables->set_column_min_width(1, 100 * EDSCALE);
variables->set_column_title(2, TTR("Calls"));
variables->set_column_expand(2, false);
variables->set_column_min_width(2, 60 * EDSCALE);
@@ -749,7 +751,6 @@ EditorProfiler::EditorProfiler() {
graph = memnew(TextureRect);
graph->set_expand(true);
graph->set_mouse_filter(MOUSE_FILTER_STOP);
- //graph->set_ignore_mouse(false);
graph->connect("draw", this, "_graph_tex_draw");
graph->connect("gui_input", this, "_graph_tex_input");
graph->connect("mouse_exited", this, "_graph_tex_mouse_exit");
@@ -760,13 +761,10 @@ EditorProfiler::EditorProfiler() {
int metric_size = CLAMP(int(EDITOR_DEF("debugger/profiler_frame_history_size", 600)), 60, 1024);
frame_metrics.resize(metric_size);
last_metric = -1;
- //cursor_metric=-1;
hover_metric = -1;
EDITOR_DEF("debugger/profiler_frame_max_functions", 64);
- //display_mode=DISPLAY_FRAME_TIME;
-
frame_delay = memnew(Timer);
frame_delay->set_wait_time(0.1);
frame_delay->set_one_shot(true);
@@ -784,6 +782,4 @@ EditorProfiler::EditorProfiler() {
seeking = false;
graph_height = 1;
-
- //activate->set_disabled(true);
}
diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp
index 28825b45e1..2090c12c91 100644
--- a/editor/editor_sectioned_inspector.cpp
+++ b/editor/editor_sectioned_inspector.cpp
@@ -245,6 +245,9 @@ void SectionedInspector::update_category_list() {
if (pi.name.find(":") != -1 || pi.name == "script" || pi.name == "resource_name" || pi.name == "resource_path" || pi.name == "resource_local_to_scene" || pi.name.begins_with("_global_script"))
continue;
+ if (!filter.empty() && !filter.is_subsequence_ofi(pi.name) && !filter.is_subsequence_ofi(pi.name.replace("/", " ").capitalize()))
+ continue;
+
int sp = pi.name.find("/");
if (sp == -1)
pi.name = "global/" + pi.name;
@@ -252,9 +255,6 @@ void SectionedInspector::update_category_list() {
Vector<String> sectionarr = pi.name.split("/");
String metasection;
- if (!filter.empty() && !filter.is_subsequence_ofi(sectionarr[sectionarr.size() - 1].capitalize()))
- continue;
-
int sc = MIN(2, sectionarr.size() - 1);
for (int i = 0; i < sc; i++) {
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 621f531687..8037045e77 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -89,7 +89,11 @@ Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, float
// dumb gizmo check
bool is_gizmo = String(editor_icons_names[p_index]).begins_with("Gizmo");
- ImageLoaderSVG::create_image_from_string(img, editor_icons_sources[p_index], p_scale, true, p_convert_color);
+ // Upsample icon generation only if the editor scale isn't an integer multiplier.
+ // Generating upsampled icons is slower, and the benefit is hardly visible
+ // with integer editor scales.
+ const bool upsample = !Math::is_equal_approx(Math::round(p_scale), p_scale);
+ ImageLoaderSVG::create_image_from_string(img, editor_icons_sources[p_index], p_scale, upsample, p_convert_color);
if ((p_scale - (float)((int)p_scale)) > 0.0 || is_gizmo || p_force_filter)
icon->create_from_image(img); // in this case filter really helps
@@ -106,7 +110,15 @@ Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, float
void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = true, int p_thumb_size = 32, bool p_only_thumbs = false) {
#ifdef SVG_ENABLED
+ // The default icon theme is designed to be used for a dark theme.
+ // This dictionary stores color codes to convert to other colors
+ // for better readability on a light theme.
Dictionary dark_icon_color_dictionary;
+
+ // The names of the icons to never convert, even if one of their colors
+ // are contained in the dictionary above.
+ Set<StringName> exceptions;
+
if (!p_dark_theme) {
// convert color: FROM TO
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#e0e0e0", "#5a5a5a"); // common icon color
@@ -172,9 +184,31 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#69ec9a", "#2ce573"); // VS rid
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#79f3e8", "#12d5c3"); // VS object
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#77edb1", "#57e99f"); // VS dict
+
+ exceptions.insert("EditorPivot");
+ exceptions.insert("EditorHandle");
+ exceptions.insert("Editor3DHandle");
+ exceptions.insert("Godot");
+ exceptions.insert("PanoramaSky");
+ exceptions.insert("ProceduralSky");
+ exceptions.insert("EditorControlAnchor");
+ exceptions.insert("DefaultProjectIcon");
+ exceptions.insert("GuiCloseCustomizable");
+ exceptions.insert("GuiGraphNodePort");
+ exceptions.insert("GuiResizer");
+ exceptions.insert("ZoomMore");
+ exceptions.insert("ZoomLess");
+ exceptions.insert("ZoomReset");
+ exceptions.insert("LockViewport");
+ exceptions.insert("GroupViewport");
+ exceptions.insert("StatusError");
+ exceptions.insert("StatusSuccess");
+ exceptions.insert("StatusWarning");
+ exceptions.insert("NodeWarning");
+ exceptions.insert("OverbrightIndicator");
}
- // these ones should be converted even if we are using a dark theme
+ // These ones should be converted even if we are using a dark theme.
const Color error_color = p_theme->get_color("error_color", "Editor");
const Color success_color = p_theme->get_color("success_color", "Editor");
const Color warning_color = p_theme->get_color("warning_color", "Editor");
@@ -182,65 +216,44 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
dark_icon_color_dictionary[Color::html("#45ff8b")] = success_color;
dark_icon_color_dictionary[Color::html("#dbab09")] = warning_color;
- List<String> exceptions;
- exceptions.push_back("EditorPivot");
- exceptions.push_back("EditorHandle");
- exceptions.push_back("Editor3DHandle");
- exceptions.push_back("Godot");
- exceptions.push_back("PanoramaSky");
- exceptions.push_back("ProceduralSky");
- exceptions.push_back("EditorControlAnchor");
- exceptions.push_back("DefaultProjectIcon");
- exceptions.push_back("GuiCloseCustomizable");
- exceptions.push_back("GuiGraphNodePort");
- exceptions.push_back("GuiResizer");
- exceptions.push_back("ZoomMore");
- exceptions.push_back("ZoomLess");
- exceptions.push_back("ZoomReset");
- exceptions.push_back("LockViewport");
- exceptions.push_back("GroupViewport");
- exceptions.push_back("StatusError");
- exceptions.push_back("StatusSuccess");
- exceptions.push_back("StatusWarning");
- exceptions.push_back("NodeWarning");
- exceptions.push_back("OverbrightIndicator");
-
ImageLoaderSVG::set_convert_colors(&dark_icon_color_dictionary);
- // generate icons
- if (!p_only_thumbs)
+ // Generate icons.
+ if (!p_only_thumbs) {
for (int i = 0; i < editor_icons_count; i++) {
- List<String>::Element *is_exception = exceptions.find(editor_icons_names[i]);
- if (is_exception) exceptions.erase(is_exception);
- Ref<ImageTexture> icon = editor_generate_icon(i, !is_exception);
+ const int is_exception = exceptions.has(editor_icons_names[i]);
+ const Ref<ImageTexture> icon = editor_generate_icon(i, !is_exception);
+
p_theme->set_icon(editor_icons_names[i], "EditorIcons", icon);
}
+ }
- // generate thumb files with the given thumb size
- bool force_filter = p_thumb_size != 64 && p_thumb_size != 32; // we don't need filter with original resolution
+ // Generate thumbnail icons with the given thumbnail size.
+ // We don't need filtering when generating at one of the default resolutions.
+ const bool force_filter = p_thumb_size != 64 && p_thumb_size != 32;
if (p_thumb_size >= 64) {
- float scale = (float)p_thumb_size / 64.0 * EDSCALE;
+ const float scale = (float)p_thumb_size / 64.0 * EDSCALE;
for (int i = 0; i < editor_bg_thumbs_count; i++) {
- int index = editor_bg_thumbs_indices[i];
- List<String>::Element *is_exception = exceptions.find(editor_icons_names[index]);
- if (is_exception) exceptions.erase(is_exception);
- Ref<ImageTexture> icon = editor_generate_icon(index, !p_dark_theme && !is_exception, scale, force_filter);
+ const int index = editor_bg_thumbs_indices[i];
+ const int is_exception = exceptions.has(editor_icons_names[index]);
+ const Ref<ImageTexture> icon = editor_generate_icon(index, !p_dark_theme && !is_exception, scale, force_filter);
+
p_theme->set_icon(editor_icons_names[index], "EditorIcons", icon);
}
} else {
- float scale = (float)p_thumb_size / 32.0 * EDSCALE;
+ const float scale = (float)p_thumb_size / 32.0 * EDSCALE;
for (int i = 0; i < editor_md_thumbs_count; i++) {
- int index = editor_md_thumbs_indices[i];
- List<String>::Element *is_exception = exceptions.find(editor_icons_names[index]);
- if (is_exception) exceptions.erase(is_exception);
- Ref<ImageTexture> icon = editor_generate_icon(index, !p_dark_theme && !is_exception, scale, force_filter);
+ const int index = editor_md_thumbs_indices[i];
+ const bool is_exception = exceptions.has(editor_icons_names[index]);
+ const Ref<ImageTexture> icon = editor_generate_icon(index, !p_dark_theme && !is_exception, scale, force_filter);
+
p_theme->set_icon(editor_icons_names[index], "EditorIcons", icon);
}
}
ImageLoaderSVG::set_convert_colors(NULL);
#else
- print_line("SVG support disabled, editor icons won't be rendered.");
+ WARN_PRINT("SVG support disabled, editor icons won't be rendered.");
#endif
}
diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp
index 32fcdab4c6..7586f6eac1 100644
--- a/editor/rename_dialog.cpp
+++ b/editor/rename_dialog.cpp
@@ -109,9 +109,13 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und
const int feature_min_height = 160 * EDSCALE;
- CheckButton *chk_collapse_features = memnew(CheckButton);
- chk_collapse_features->set_text(TTR("Advanced Options"));
- vbc->add_child(chk_collapse_features);
+ cbut_regex = memnew(CheckButton);
+ cbut_regex->set_text(TTR("Use Regular Expressions"));
+ vbc->add_child(cbut_regex);
+
+ CheckButton *cbut_collapse_features = memnew(CheckButton);
+ cbut_collapse_features->set_text(TTR("Advanced Options"));
+ vbc->add_child(cbut_collapse_features);
tabc_features = memnew(TabContainer);
tabc_features->set_tab_align(TabContainer::ALIGN_LEFT);
@@ -195,7 +199,7 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und
grd_substitute->add_child(but_insert_count);
chk_per_level_counter = memnew(CheckBox);
- chk_per_level_counter->set_text(TTR("Per Level counter"));
+ chk_per_level_counter->set_text(TTR("Per-level Counter"));
chk_per_level_counter->set_tooltip(TTR("If set the counter restarts for each group of child nodes"));
vbc_substitute->add_child(chk_per_level_counter);
@@ -233,18 +237,6 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und
spn_count_padding->set_step(1);
hbc_count_options->add_child(spn_count_padding);
- // ---- Tab RegEx
-
- VBoxContainer *vbc_regex = memnew(VBoxContainer);
- vbc_regex->set_h_size_flags(SIZE_EXPAND_FILL);
- vbc_regex->set_name(TTR("Regular Expressions"));
- vbc_regex->set_custom_minimum_size(Size2(0, feature_min_height));
- tabc_features->add_child(vbc_regex);
-
- cbut_regex = memnew(CheckBox);
- cbut_regex->set_text(TTR("Regular Expressions"));
- vbc_regex->add_child(cbut_regex);
-
// ---- Tab Process
VBoxContainer *vbc_process = memnew(VBoxContainer);
@@ -268,8 +260,8 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und
opt_style = memnew(OptionButton);
opt_style->add_item(TTR("Keep"));
- opt_style->add_item(TTR("CamelCase to under_scored"));
- opt_style->add_item(TTR("under_scored to CamelCase"));
+ opt_style->add_item(TTR("PascalCase to snake_case"));
+ opt_style->add_item(TTR("snake_case to PascalCase"));
hbc_style->add_child(opt_style);
// ------ Case
@@ -299,7 +291,7 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und
lbl_preview = memnew(Label);
lbl_preview->set_text("");
- lbl_preview->add_color_override("font_color", Color(1, 0.5f, 0, 1));
+ lbl_preview->add_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor"));
vbc->add_child(lbl_preview);
// ---- Dialog related
@@ -314,7 +306,7 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und
// ---- Connections
- chk_collapse_features->connect("toggled", this, "_features_toggled");
+ cbut_collapse_features->connect("toggled", this, "_features_toggled");
// Substitite Buttons
@@ -414,9 +406,12 @@ void RenameDialog::_update_preview(String new_text) {
lbl_preview->set_text(new_name);
if (new_name == preview_node->get_name()) {
- lbl_preview->add_color_override("font_color", Color(0, 0.5f, 0.25f, 1));
+ // New name is identical to the old one. Don't color it as much to avoid distracting the user.
+ const Color accent_color = EditorNode::get_singleton()->get_gui_base()->get_color("accent_color", "Editor");
+ const Color text_color = EditorNode::get_singleton()->get_gui_base()->get_color("default_color", "RichTextLabel");
+ lbl_preview->add_color_override("font_color", accent_color.linear_interpolate(text_color, 0.5));
} else {
- lbl_preview->add_color_override("font_color", Color(0, 1, 0.5f, 1));
+ lbl_preview->add_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_color("success_color", "Editor"));
}
}
@@ -501,9 +496,9 @@ void RenameDialog::_error_handler(void *p_self, const char *p_func, const char *
}
self->has_errors = true;
- self->lbl_preview_title->set_text(TTR("Error"));
- self->lbl_preview->add_color_override("font_color", Color(1, 0.25f, 0, 1));
- self->lbl_preview->set_text(err_str);
+ self->lbl_preview_title->set_text(TTR("Regular Expression Error"));
+ self->lbl_preview->add_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor"));
+ self->lbl_preview->set_text(vformat(TTR("At character %s"), err_str));
}
String RenameDialog::_regex(const String &pattern, const String &subject, const String &replacement) {
@@ -520,18 +515,18 @@ String RenameDialog::_postprocess(const String &subject) {
String result = subject;
if (style_id == 1) {
+ // PascalCase to snake_case
- // CamelCase to Under_Line
result = result.camelcase_to_underscore(true);
result = _regex("_+", result, "_");
} else if (style_id == 2) {
+ // snake_case to PascalCase
- // Under_Line to CamelCase
RegEx pattern("_+(.?)");
Array matches = pattern.search_all(result);
- // _ name would become empty. Ignore
+ // The name `_` would become empty; ignore it.
if (matches.size() && result != "_") {
String buffer;
int start = 0;
diff --git a/editor/rename_dialog.h b/editor/rename_dialog.h
index 692e56f1a4..2825cb2cd2 100644
--- a/editor/rename_dialog.h
+++ b/editor/rename_dialog.h
@@ -75,7 +75,7 @@ class RenameDialog : public ConfirmationDialog {
TabContainer *tabc_features;
CheckBox *cbut_substitute;
- CheckBox *cbut_regex;
+ CheckButton *cbut_regex;
CheckBox *cbut_process;
CheckBox *chk_per_level_counter;
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index 35d5fe5f70..a982724d4c 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -644,7 +644,7 @@ void ScriptCreateDialog::_update_dialog() {
}
if (script_ok) {
- _msg_script_valid(true, TTR("Script is valid."));
+ _msg_script_valid(true, TTR("Script path/name is valid."));
}
// Does script have named classes?
diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp
index 71a946b256..ab4501bb8a 100644
--- a/editor/script_editor_debugger.cpp
+++ b/editor/script_editor_debugger.cpp
@@ -484,8 +484,10 @@ int ScriptEditorDebugger::_update_scene_tree(TreeItem *parent, const Array &node
void ScriptEditorDebugger::_video_mem_request() {
- ERR_FAIL_COND(connection.is_null());
- ERR_FAIL_COND(!connection->is_connected_to_host());
+ if (connection.is_null() || !connection->is_connected_to_host()) {
+ // Video RAM usage is only available while a project is being debugged.
+ return;
+ }
Array msg;
msg.push_back("request_video_mem");
@@ -806,25 +808,25 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
p.write[i] = arr[i];
if (i < perf_items.size()) {
- float v = p[i];
- String vs = rtos(v);
- String tt = vs;
+ const float value = p[i];
+ String label = rtos(value);
+ String tooltip = label;
switch (Performance::MonitorType((int)perf_items[i]->get_metadata(1))) {
case Performance::MONITOR_TYPE_MEMORY: {
- vs = String::humanize_size(v);
- tt = vs;
+ label = String::humanize_size(value);
+ tooltip = label;
} break;
case Performance::MONITOR_TYPE_TIME: {
- tt += " seconds";
- vs += " s";
+ label = rtos(value * 1000).pad_decimals(2) + " ms";
+ tooltip = label;
} break;
default: {
- tt += " " + perf_items[i]->get_text(0);
+ tooltip += " " + perf_items[i]->get_text(0);
} break;
}
- perf_items[i]->set_text(1, vs);
- perf_items[i]->set_tooltip(1, tt);
+ perf_items[i]->set_text(1, label);
+ perf_items[i]->set_tooltip(1, tooltip);
if (p[i] > perf_max[i])
perf_max.write[i] = p[i];
}
@@ -1323,6 +1325,7 @@ void ScriptEditorDebugger::_notification(int p_what) {
inspect_scene_tree->clear();
le_set->set_disabled(true);
le_clear->set_disabled(false);
+ vmem_refresh->set_disabled(false);
error_tree->clear();
error_count = 0;
warning_count = 0;
@@ -1523,6 +1526,7 @@ void ScriptEditorDebugger::stop() {
le_clear->set_disabled(false);
le_set->set_disabled(true);
profiler->set_enabled(true);
+ vmem_refresh->set_disabled(true);
inspect_scene_tree->clear();
inspector->edit(NULL);
@@ -1622,6 +1626,7 @@ void ScriptEditorDebugger::_output_clear() {
void ScriptEditorDebugger::_export_csv() {
file_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE);
+ file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
file_dialog_mode = SAVE_CSV;
file_dialog->popup_centered_ratio();
}
@@ -2187,6 +2192,13 @@ void ScriptEditorDebugger::_item_menu_id_pressed(int p_option) {
}
}
+void ScriptEditorDebugger::_tab_changed(int p_tab) {
+ if (tabs->get_tab_title(p_tab) == TTR("Video RAM")) {
+ // "Video RAM" tab was clicked, refresh the data it's dislaying when entering the tab.
+ _video_mem_request();
+ }
+}
+
void ScriptEditorDebugger::_bind_methods() {
ClassDB::bind_method(D_METHOD("_stack_dump_frame_selected"), &ScriptEditorDebugger::_stack_dump_frame_selected);
@@ -2218,6 +2230,7 @@ void ScriptEditorDebugger::_bind_methods() {
ClassDB::bind_method(D_METHOD("_error_tree_item_rmb_selected"), &ScriptEditorDebugger::_error_tree_item_rmb_selected);
ClassDB::bind_method(D_METHOD("_item_menu_id_pressed"), &ScriptEditorDebugger::_item_menu_id_pressed);
+ ClassDB::bind_method(D_METHOD("_tab_changed"), &ScriptEditorDebugger::_tab_changed);
ClassDB::bind_method(D_METHOD("_paused"), &ScriptEditorDebugger::_paused);
@@ -2258,13 +2271,13 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
tabs->add_style_override("panel", editor->get_gui_base()->get_stylebox("DebuggerPanel", "EditorStyles"));
tabs->add_style_override("tab_fg", editor->get_gui_base()->get_stylebox("DebuggerTabFG", "EditorStyles"));
tabs->add_style_override("tab_bg", editor->get_gui_base()->get_stylebox("DebuggerTabBG", "EditorStyles"));
+ tabs->connect("tab_changed", this, "_tab_changed");
add_child(tabs);
{ //debugger
VBoxContainer *vbc = memnew(VBoxContainer);
vbc->set_name(TTR("Debugger"));
- //tabs->add_child(vbc);
Control *dbg = vbc;
HBoxContainer *hbc = memnew(HBoxContainer);
@@ -2522,6 +2535,7 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
vmem_total->set_custom_minimum_size(Size2(100, 0) * EDSCALE);
vmem_hb->add_child(vmem_total);
vmem_refresh = memnew(ToolButton);
+ vmem_refresh->set_disabled(true);
vmem_hb->add_child(vmem_refresh);
vmem_vb->add_child(vmem_hb);
vmem_refresh->connect("pressed", this, "_video_mem_request");
@@ -2534,20 +2548,20 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
vmmc->set_v_size_flags(SIZE_EXPAND_FILL);
vmem_vb->add_child(vmmc);
- vmem_vb->set_name(TTR("Video Mem"));
+ vmem_vb->set_name(TTR("Video RAM"));
vmem_tree->set_columns(4);
vmem_tree->set_column_titles_visible(true);
vmem_tree->set_column_title(0, TTR("Resource Path"));
vmem_tree->set_column_expand(0, true);
vmem_tree->set_column_expand(1, false);
vmem_tree->set_column_title(1, TTR("Type"));
- vmem_tree->set_column_min_width(1, 100);
+ vmem_tree->set_column_min_width(1, 100 * EDSCALE);
vmem_tree->set_column_expand(2, false);
vmem_tree->set_column_title(2, TTR("Format"));
- vmem_tree->set_column_min_width(2, 150);
+ vmem_tree->set_column_min_width(2, 150 * EDSCALE);
vmem_tree->set_column_expand(3, false);
vmem_tree->set_column_title(3, TTR("Usage"));
- vmem_tree->set_column_min_width(3, 80);
+ vmem_tree->set_column_min_width(3, 80 * EDSCALE);
vmem_tree->set_hide_root(true);
tabs->add_child(vmem_vb);
diff --git a/editor/script_editor_debugger.h b/editor/script_editor_debugger.h
index 7d91e247b6..589a011bff 100644
--- a/editor/script_editor_debugger.h
+++ b/editor/script_editor_debugger.h
@@ -226,6 +226,7 @@ private:
void _error_tree_item_rmb_selected(const Vector2 &p_pos);
void _item_menu_id_pressed(int p_option);
+ void _tab_changed(int p_tab);
void _export_csv();
diff --git a/main/main.cpp b/main/main.cpp
index 88d4dcc1fc..3cc809b813 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1900,6 +1900,8 @@ bool Main::start() {
ProgressDialog *progress_dialog = memnew(ProgressDialog);
pmanager->add_child(progress_dialog);
sml->get_root()->add_child(pmanager);
+ // Speed up rendering slightly by disabling 3D features while in the project manager.
+ sml->get_root()->set_usage(Viewport::USAGE_2D_NO_SAMPLING);
OS::get_singleton()->set_context(OS::CONTEXT_PROJECTMAN);
project_manager = true;
}
diff --git a/modules/gdnative/SCsub b/modules/gdnative/SCsub
index 0cdd585558..a18c75fa27 100644
--- a/modules/gdnative/SCsub
+++ b/modules/gdnative/SCsub
@@ -30,23 +30,3 @@ _, gensource = env_gdnative.CommandNoCache(['include/gdnative_api_struct.gen.h',
env_gdnative.add_source_files(env.modules_sources, [gensource])
env.use_ptrcall = True
-
-
-if ARGUMENTS.get('gdnative_wrapper', False):
- gensource, = env_gdnative.CommandNoCache('gdnative_wrapper_code.gen.cpp', 'gdnative_api.json', run_in_subprocess(gdnative_builders.build_gdnative_wrapper_code))
-
- gd_wrapper_env = env.Clone()
- gd_wrapper_env.Prepend(CPPPATH=['#modules/gdnative/include/'])
-
- if gd_wrapper_env['use_lto']:
- if not env.msvc:
- gd_wrapper_env.Append(CCFLAGS=['-fno-lto'])
- gd_wrapper_env.Append(LINKFLAGS=['-fno-lto'])
- else:
- gd_wrapper_env.Append(CCFLAGS=['/GL-'])
- gd_wrapper_env.Append(LINKFLAGS=['/LTCG:OFF'])
-
- if not env.msvc:
- gd_wrapper_env.Append(CCFLAGS=['-fPIC'])
-
- lib = gd_wrapper_env.add_library("#bin/gdnative_wrapper_code", [gensource])
diff --git a/modules/gdnative/gdnative_builders.py b/modules/gdnative/gdnative_builders.py
index 20c1a2233c..0d95a65b7e 100644
--- a/modules/gdnative/gdnative_builders.py
+++ b/modules/gdnative/gdnative_builders.py
@@ -12,30 +12,6 @@ def _spaced(e):
def _build_gdnative_api_struct_header(api):
- gdnative_api_init_macro = [
- '\textern const godot_gdnative_core_api_struct *_gdnative_wrapper_api_struct;'
- ]
-
- for ext in api['extensions']:
- name = ext['name']
- gdnative_api_init_macro.append(
- '\textern const godot_gdnative_ext_{0}_api_struct *_gdnative_wrapper_{0}_api_struct;'.format(name))
-
- gdnative_api_init_macro.append('\t_gdnative_wrapper_api_struct = options->api_struct;')
- gdnative_api_init_macro.append('\tfor (unsigned int i = 0; i < _gdnative_wrapper_api_struct->num_extensions; i++) { ')
- gdnative_api_init_macro.append('\t\tswitch (_gdnative_wrapper_api_struct->extensions[i]->type) {')
-
- for ext in api['extensions']:
- name = ext['name']
- gdnative_api_init_macro.append(
- '\t\t\tcase GDNATIVE_EXT_%s:' % ext['type'])
- gdnative_api_init_macro.append(
- '\t\t\t\t_gdnative_wrapper_{0}_api_struct = (godot_gdnative_ext_{0}_api_struct *)'
- ' _gdnative_wrapper_api_struct->extensions[i];'.format(name))
- gdnative_api_init_macro.append('\t\t\t\tbreak;')
- gdnative_api_init_macro.append('\t\t}')
- gdnative_api_init_macro.append('\t}')
-
out = [
'/* THIS FILE IS GENERATED DO NOT EDIT */',
'#ifndef GODOT_GDNATIVE_API_STRUCT_H',
@@ -49,8 +25,6 @@ def _build_gdnative_api_struct_header(api):
'#include <pluginscript/godot_pluginscript.h>',
'#include <videodecoder/godot_videodecoder.h>',
'',
- '#define GDNATIVE_API_INIT(options) do { \\\n' + ' \\\n'.join(gdnative_api_init_macro) + ' \\\n } while (0)',
- '',
'#ifdef __cplusplus',
'extern "C" {',
'#endif',
@@ -238,76 +212,5 @@ def build_gdnative_api_struct(target, source, env):
fd.write(_build_gdnative_api_struct_source(api))
-def _build_gdnative_wrapper_code(api):
- out = [
- '/* THIS FILE IS GENERATED DO NOT EDIT */',
- '',
- '#include <gdnative/gdnative.h>',
- '#include <nativescript/godot_nativescript.h>',
- '#include <pluginscript/godot_pluginscript.h>',
- '#include <arvr/godot_arvr.h>',
- '#include <videodecoder/godot_videodecoder.h>',
- '',
- '#include <gdnative_api_struct.gen.h>',
- '',
- '#ifdef __cplusplus',
- 'extern "C" {',
- '#endif',
- '',
- 'godot_gdnative_core_api_struct *_gdnative_wrapper_api_struct = 0;',
- ]
-
- for ext in api['extensions']:
- name = ext['name']
- out.append('godot_gdnative_ext_' + name + '_api_struct *_gdnative_wrapper_' + name + '_api_struct = 0;')
-
- out += ['']
-
- for funcdef in api['core']['api']:
- args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']])
- out.append('%s%s(%s) {' % (_spaced(funcdef['return_type']), funcdef['name'], args))
-
- args = ', '.join(['%s' % n for t, n in funcdef['arguments']])
-
- return_line = '\treturn ' if funcdef['return_type'] != 'void' else '\t'
- return_line += '_gdnative_wrapper_api_struct->' + funcdef['name'] + '(' + args + ');'
-
- out.append(return_line)
- out.append('}')
- out.append('')
-
- for ext in api['extensions']:
- name = ext['name']
- for funcdef in ext['api']:
- args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']])
- out.append('%s%s(%s) {' % (_spaced(funcdef['return_type']), funcdef['name'], args))
-
- args = ', '.join(['%s' % n for t, n in funcdef['arguments']])
-
- return_line = '\treturn ' if funcdef['return_type'] != 'void' else '\t'
- return_line += '_gdnative_wrapper_' + name + '_api_struct->' + funcdef['name'] + '(' + args + ');'
-
- out.append(return_line)
- out.append('}')
- out.append('')
-
- out += [
- '#ifdef __cplusplus',
- '}',
- '#endif'
- ]
-
- return '\n'.join(out)
-
-
-def build_gdnative_wrapper_code(target, source, env):
- with open(source[0], 'r') as fd:
- api = json.load(fd)
-
- wrapper_file = target[0]
- with open(wrapper_file, 'w') as fd:
- fd.write(_build_gdnative_wrapper_code(api))
-
-
if __name__ == '__main__':
subprocess_main(globals())
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/NodeExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/NodeExtensions.cs
index 5023725f17..5d16260f5d 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/NodeExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/NodeExtensions.cs
@@ -9,7 +9,7 @@ namespace Godot
public T GetNodeOrNull<T>(NodePath path) where T : class
{
- return GetNode(path) as T;
+ return GetNodeOrNull(path) as T;
}
public T GetChild<T>(int idx) where T : class
diff --git a/modules/opensimplex/doc_classes/OpenSimplexNoise.xml b/modules/opensimplex/doc_classes/OpenSimplexNoise.xml
index f4f54901fb..f500925f75 100644
--- a/modules/opensimplex/doc_classes/OpenSimplexNoise.xml
+++ b/modules/opensimplex/doc_classes/OpenSimplexNoise.xml
@@ -117,7 +117,8 @@
Difference in period between [member octaves].
</member>
<member name="octaves" type="int" setter="set_octaves" getter="get_octaves" default="3">
- Number of OpenSimplex noise layers that are sampled to get the fractal noise.
+ Number of OpenSimplex noise layers that are sampled to get the fractal noise. Higher values result in more detailed noise but take more time to generate.
+ [b]Note:[/b] The maximum allowed value is 9.
</member>
<member name="period" type="float" setter="set_period" getter="get_period" default="64.0">
Period of the base octave. A lower period results in a higher-frequency noise (more value changes across the same distance).
diff --git a/modules/opensimplex/open_simplex_noise.cpp b/modules/opensimplex/open_simplex_noise.cpp
index c99588aefa..bd187e6b5b 100644
--- a/modules/opensimplex/open_simplex_noise.cpp
+++ b/modules/opensimplex/open_simplex_noise.cpp
@@ -47,7 +47,7 @@ OpenSimplexNoise::~OpenSimplexNoise() {
}
void OpenSimplexNoise::_init_seeds() {
- for (int i = 0; i < 6; ++i) {
+ for (int i = 0; i < MAX_OCTAVES; ++i) {
open_simplex_noise(seed + i * 2, &(contexts[i]));
}
}
@@ -71,7 +71,10 @@ int OpenSimplexNoise::get_seed() {
void OpenSimplexNoise::set_octaves(int p_octaves) {
if (p_octaves == octaves) return;
- octaves = CLAMP(p_octaves, 1, 6);
+
+ ERR_FAIL_COND_MSG(p_octaves > MAX_OCTAVES, vformat("The number of OpenSimplexNoise octaves is limited to %d; ignoring the new value.", MAX_OCTAVES));
+
+ octaves = CLAMP(p_octaves, 1, MAX_OCTAVES);
emit_changed();
}
@@ -182,7 +185,7 @@ void OpenSimplexNoise::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_noise_3dv", "pos"), &OpenSimplexNoise::get_noise_3dv);
ADD_PROPERTY(PropertyInfo(Variant::INT, "seed"), "set_seed", "get_seed");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "octaves", PROPERTY_HINT_RANGE, "1,6,1"), "set_octaves", "get_octaves");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "octaves", PROPERTY_HINT_RANGE, vformat("1,%d,1", MAX_OCTAVES)), "set_octaves", "get_octaves");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "period", PROPERTY_HINT_RANGE, "0.1,256.0,0.1"), "set_period", "get_period");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "persistence", PROPERTY_HINT_RANGE, "0.0,1.0,0.001"), "set_persistence", "get_persistence");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "lacunarity", PROPERTY_HINT_RANGE, "0.1,4.0,0.01"), "set_lacunarity", "get_lacunarity");
diff --git a/modules/opensimplex/open_simplex_noise.h b/modules/opensimplex/open_simplex_noise.h
index 89b12253b9..dce62bc1f9 100644
--- a/modules/opensimplex/open_simplex_noise.h
+++ b/modules/opensimplex/open_simplex_noise.h
@@ -37,11 +37,16 @@
#include "thirdparty/misc/open-simplex-noise.h"
+// The maximum number of octaves allowed. Note that these are statically allocated.
+// Higher values become exponentially slower, so this shouldn't be set too high
+// to avoid freezing the editor for long periods of time.
+#define MAX_OCTAVES 9
+
class OpenSimplexNoise : public Resource {
GDCLASS(OpenSimplexNoise, Resource);
OBJ_SAVE_TYPE(OpenSimplexNoise);
- osn_context contexts[6];
+ osn_context contexts[MAX_OCTAVES];
int seed;
float persistence; // Controls details, value in [0,1]. Higher increases grain, lower increases smoothness.
diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp
index 57097aaa06..11ae2f81bf 100644
--- a/modules/svg/image_loader_svg.cpp
+++ b/modules/svg/image_loader_svg.cpp
@@ -103,15 +103,17 @@ Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t
ERR_PRINT("SVG Corrupted");
return ERR_FILE_CORRUPT;
}
- if (convert_colors)
+
+ if (convert_colors) {
_convert_colors(svg_image);
+ }
- float upscale = upsample ? 2.0 : 1.0;
+ const float upscale = upsample ? 2.0 : 1.0;
- int w = (int)(svg_image->width * p_scale * upscale);
+ const int w = (int)(svg_image->width * p_scale * upscale);
ERR_FAIL_COND_V_MSG(w > Image::MAX_WIDTH, ERR_PARAMETER_RANGE_ERROR, vformat("Can't create image from SVG with scale %s, the resulting image size exceeds max width.", rtos(p_scale)));
- int h = (int)(svg_image->height * p_scale * upscale);
+ const int h = (int)(svg_image->height * p_scale * upscale);
ERR_FAIL_COND_V_MSG(h > Image::MAX_HEIGHT, ERR_PARAMETER_RANGE_ERROR, vformat("Can't create image from SVG with scale %s, the resulting image size exceeds max height.", rtos(p_scale)));
PoolVector<uint8_t> dst_image;
@@ -123,8 +125,9 @@ Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t
dw.release();
p_image->create(w, h, false, Image::FORMAT_RGBA8, dst_image);
- if (upsample)
+ if (upsample) {
p_image->shrink_x2();
+ }
nsvgDelete(svg_image);
diff --git a/platform/osx/detect.py b/platform/osx/detect.py
index 7882253e7a..fe839199e8 100644
--- a/platform/osx/detect.py
+++ b/platform/osx/detect.py
@@ -27,6 +27,9 @@ def get_opts():
('MACOS_SDK_PATH', 'Path to the macOS SDK', ''),
EnumVariable('debug_symbols', 'Add debugging symbols to release builds', 'yes', ('yes', 'no', 'full')),
BoolVariable('separate_debug_symbols', 'Create a separate file containing debugging symbols', False),
+ BoolVariable('use_ubsan', 'Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)', False),
+ BoolVariable('use_asan', 'Use LLVM/GCC compiler address sanitizer (ASAN))', False),
+ BoolVariable('use_tsan', 'Use LLVM/GCC compiler thread sanitizer (TSAN))', False),
]
@@ -122,6 +125,21 @@ def configure(env):
env["CC"] = "clang"
env["LINK"] = "clang++"
+ if env['use_ubsan'] or env['use_asan'] or env['use_tsan']:
+ env.extra_suffix += "s"
+
+ if env['use_ubsan']:
+ env.Append(CCFLAGS=['-fsanitize=undefined'])
+ env.Append(LINKFLAGS=['-fsanitize=undefined'])
+
+ if env['use_asan']:
+ env.Append(CCFLAGS=['-fsanitize=address'])
+ env.Append(LINKFLAGS=['-fsanitize=address'])
+
+ if env['use_tsan']:
+ env.Append(CCFLAGS=['-fsanitize=thread'])
+ env.Append(LINKFLAGS=['-fsanitize=thread'])
+
## Dependencies
if env['builtin_libtheora']:
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index 6a214b8669..53fe11b3bb 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -115,6 +115,20 @@ static Vector2 get_mouse_pos(NSPoint locationInWindow, CGFloat backingScaleFacto
return Vector2(mouse_x, mouse_y);
}
+static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) {
+ if ([NSCursor respondsToSelector:selector]) {
+ id object = [NSCursor performSelector:selector];
+ if ([object isKindOfClass:[NSCursor class]]) {
+ return object;
+ }
+ }
+ if (fallback) {
+ // Fallback should be a reasonable default, no need to check.
+ return [NSCursor performSelector:fallback];
+ }
+ return [NSCursor arrowCursor];
+}
+
@interface GodotApplication : NSApplication
@end
@@ -1813,15 +1827,15 @@ void OS_OSX::set_cursor_shape(CursorShape p_shape) {
case CURSOR_BUSY: [[NSCursor arrowCursor] set]; break;
case CURSOR_DRAG: [[NSCursor closedHandCursor] set]; break;
case CURSOR_CAN_DROP: [[NSCursor openHandCursor] set]; break;
- case CURSOR_FORBIDDEN: [[NSCursor arrowCursor] set]; break;
- case CURSOR_VSIZE: [[NSCursor resizeUpDownCursor] set]; break;
- case CURSOR_HSIZE: [[NSCursor resizeLeftRightCursor] set]; break;
- case CURSOR_BDIAGSIZE: [[NSCursor arrowCursor] set]; break;
- case CURSOR_FDIAGSIZE: [[NSCursor arrowCursor] set]; break;
+ case CURSOR_FORBIDDEN: [[NSCursor operationNotAllowedCursor] set]; break;
+ case CURSOR_VSIZE: [cursorFromSelector(@selector(_windowResizeNorthSouthCursor), @selector(resizeUpDownCursor)) set]; break;
+ case CURSOR_HSIZE: [cursorFromSelector(@selector(_windowResizeEastWestCursor), @selector(resizeLeftRightCursor)) set]; break;
+ case CURSOR_BDIAGSIZE: [cursorFromSelector(@selector(_windowResizeNorthEastSouthWestCursor)) set]; break;
+ case CURSOR_FDIAGSIZE: [cursorFromSelector(@selector(_windowResizeNorthWestSouthEastCursor)) set]; break;
case CURSOR_MOVE: [[NSCursor arrowCursor] set]; break;
case CURSOR_VSPLIT: [[NSCursor resizeUpDownCursor] set]; break;
case CURSOR_HSPLIT: [[NSCursor resizeLeftRightCursor] set]; break;
- case CURSOR_HELP: [[NSCursor arrowCursor] set]; break;
+ case CURSOR_HELP: [cursorFromSelector(@selector(_helpCursor)) set]; break;
default: {
};
}
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index 8598a953b4..3f46afa8e8 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -36,7 +36,14 @@ Size2 OptionButton::get_minimum_size() const {
Size2 minsize = Button::get_minimum_size();
if (has_icon("arrow")) {
- minsize.width += Control::get_icon("arrow")->get_width() + get_constant("hseparation");
+ const Size2 padding = get_stylebox("normal")->get_minimum_size();
+ const Size2 arrow_size = Control::get_icon("arrow")->get_size();
+
+ Size2 content_size = minsize - padding;
+ content_size.width += arrow_size.width + get_constant("hseparation");
+ content_size.height = MAX(content_size.height, arrow_size.height);
+
+ minsize = content_size + padding;
}
return minsize;
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index c3ddc41813..b045ff4fe1 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -785,23 +785,25 @@ TabContainer::TabAlign TabContainer::get_tab_align() const {
return align;
}
-void TabContainer::set_tabs_visible(bool p_visibe) {
+void TabContainer::set_tabs_visible(bool p_visible) {
- if (p_visibe == tabs_visible)
+ if (p_visible == tabs_visible)
return;
- tabs_visible = p_visibe;
+ tabs_visible = p_visible;
Vector<Control *> tabs = _get_tabs();
for (int i = 0; i < tabs.size(); i++) {
Control *c = tabs[i];
- if (p_visibe)
+ if (p_visible)
c->set_margin(MARGIN_TOP, _get_top_margin());
else
c->set_margin(MARGIN_TOP, 0);
}
+
update();
+ minimum_size_changed();
}
bool TabContainer::are_tabs_visible() const {
@@ -936,8 +938,10 @@ Size2 TabContainer::get_minimum_size() const {
Ref<StyleBox> tab_disabled = get_stylebox("tab_disabled");
Ref<Font> font = get_font("font");
- ms.y += MAX(MAX(tab_bg->get_minimum_size().y, tab_fg->get_minimum_size().y), tab_disabled->get_minimum_size().y);
- ms.y += font->get_height();
+ if (tabs_visible) {
+ ms.y += MAX(MAX(tab_bg->get_minimum_size().y, tab_fg->get_minimum_size().y), tab_disabled->get_minimum_size().y);
+ ms.y += font->get_height();
+ }
Ref<StyleBox> sb = get_stylebox("panel");
ms += sb->get_minimum_size();
diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h
index e69c2ae289..c5a9045ca6 100644
--- a/scene/gui/tab_container.h
+++ b/scene/gui/tab_container.h
@@ -87,7 +87,7 @@ public:
void set_tab_align(TabAlign p_align);
TabAlign get_tab_align() const;
- void set_tabs_visible(bool p_visibe);
+ void set_tabs_visible(bool p_visible);
bool are_tabs_visible() const;
void set_tab_title(int p_tab, const String &p_title);