summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/math/vector2.cpp8
-rw-r--r--core/math/vector2.h18
-rw-r--r--core/math/vector3.h12
-rw-r--r--core/math/vector3i.h12
-rw-r--r--core/variant/variant_call.cpp4
-rw-r--r--doc/classes/TabBar.xml23
-rw-r--r--doc/classes/Vector2.xml2
-rw-r--r--doc/classes/Vector2i.xml13
-rw-r--r--doc/classes/Vector3.xml2
-rw-r--r--doc/classes/Vector3i.xml13
-rw-r--r--editor/plugins/lightmap_gi_editor_plugin.cpp12
-rw-r--r--editor/plugins/lightmap_gi_editor_plugin.h2
-rw-r--r--platform/uwp/os_uwp.cpp7
-rw-r--r--scene/animation/animation_player.cpp20
-rw-r--r--scene/gui/tab_bar.cpp73
-rw-r--r--scene/gui/tab_bar.h11
16 files changed, 195 insertions, 37 deletions
diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp
index 38dad893f5..676a0004ea 100644
--- a/core/math/vector2.cpp
+++ b/core/math/vector2.cpp
@@ -210,6 +210,14 @@ Vector2i Vector2i::clamp(const Vector2i &p_min, const Vector2i &p_max) const {
CLAMP(y, p_min.y, p_max.y));
}
+int64_t Vector2i::length_squared() const {
+ return x * (int64_t)x + y * (int64_t)y;
+}
+
+double Vector2i::length() const {
+ return Math::sqrt((double)length_squared());
+}
+
Vector2i Vector2i::operator+(const Vector2i &p_v) const {
return Vector2i(x + p_v.x, y + p_v.y);
}
diff --git a/core/math/vector2.h b/core/math/vector2.h
index 493e0af27d..a340036ac7 100644
--- a/core/math/vector2.h
+++ b/core/math/vector2.h
@@ -261,11 +261,16 @@ Vector2 Vector2::lerp(const Vector2 &p_to, const real_t p_weight) const {
}
Vector2 Vector2::slerp(const Vector2 &p_to, const real_t p_weight) const {
-#ifdef MATH_CHECKS
- ERR_FAIL_COND_V_MSG(!is_normalized(), Vector2(), "The start Vector2 must be normalized.");
-#endif
- real_t theta = angle_to(p_to);
- return rotated(theta * p_weight);
+ real_t start_length_sq = length_squared();
+ real_t end_length_sq = p_to.length_squared();
+ if (unlikely(start_length_sq == 0.0 || end_length_sq == 0.0)) {
+ // Zero length vectors have no angle, so the best we can do is either lerp or throw an error.
+ return lerp(p_to, p_weight);
+ }
+ real_t start_length = Math::sqrt(start_length_sq);
+ real_t result_length = Math::lerp(start_length, Math::sqrt(end_length_sq), p_weight);
+ real_t angle = angle_to(p_to);
+ return rotated(angle * p_weight) * (result_length / start_length);
}
Vector2 Vector2::direction_to(const Vector2 &p_to) const {
@@ -344,6 +349,9 @@ struct Vector2i {
bool operator==(const Vector2i &p_vec2) const;
bool operator!=(const Vector2i &p_vec2) const;
+ int64_t length_squared() const;
+ double length() const;
+
real_t aspect() const { return width / (real_t)height; }
Vector2i sign() const { return Vector2i(SIGN(x), SIGN(y)); }
Vector2i abs() const { return Vector2i(ABS(x), ABS(y)); }
diff --git a/core/math/vector3.h b/core/math/vector3.h
index 1861627718..d7a72b05a8 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -240,8 +240,16 @@ Vector3 Vector3::lerp(const Vector3 &p_to, const real_t p_weight) const {
}
Vector3 Vector3::slerp(const Vector3 &p_to, const real_t p_weight) const {
- real_t theta = angle_to(p_to);
- return rotated(cross(p_to).normalized(), theta * p_weight);
+ real_t start_length_sq = length_squared();
+ real_t end_length_sq = p_to.length_squared();
+ if (unlikely(start_length_sq == 0.0 || end_length_sq == 0.0)) {
+ // Zero length vectors have no angle, so the best we can do is either lerp or throw an error.
+ return lerp(p_to, p_weight);
+ }
+ real_t start_length = Math::sqrt(start_length_sq);
+ real_t result_length = Math::lerp(start_length, Math::sqrt(end_length_sq), p_weight);
+ real_t angle = angle_to(p_to);
+ return rotated(cross(p_to).normalized(), angle * p_weight) * (result_length / start_length);
}
real_t Vector3::distance_to(const Vector3 &p_to) const {
diff --git a/core/math/vector3i.h b/core/math/vector3i.h
index 0f9caa349b..1416c98057 100644
--- a/core/math/vector3i.h
+++ b/core/math/vector3i.h
@@ -31,6 +31,7 @@
#ifndef VECTOR3I_H
#define VECTOR3I_H
+#include "core/math/math_funcs.h"
#include "core/string/ustring.h"
#include "core/typedefs.h"
@@ -65,6 +66,9 @@ struct Vector3i {
Vector3i::Axis min_axis_index() const;
Vector3i::Axis max_axis_index() const;
+ _FORCE_INLINE_ int64_t length_squared() const;
+ _FORCE_INLINE_ double length() const;
+
_FORCE_INLINE_ void zero();
_FORCE_INLINE_ Vector3i abs() const;
@@ -110,6 +114,14 @@ struct Vector3i {
}
};
+int64_t Vector3i::length_squared() const {
+ return x * (int64_t)x + y * (int64_t)y + z * (int64_t)z;
+}
+
+double Vector3i::length() const {
+ return Math::sqrt((double)length_squared());
+}
+
Vector3i Vector3i::abs() const {
return Vector3i(ABS(x), ABS(y), ABS(z));
}
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 64522a9908..ecf5009fb6 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1513,6 +1513,8 @@ static void _register_variant_builtin_methods() {
bind_method(Vector2i, aspect, sarray(), varray());
bind_method(Vector2i, max_axis_index, sarray(), varray());
bind_method(Vector2i, min_axis_index, sarray(), varray());
+ bind_method(Vector2i, length, sarray(), varray());
+ bind_method(Vector2i, length_squared, sarray(), varray());
bind_method(Vector2i, sign, sarray(), varray());
bind_method(Vector2i, abs, sarray(), varray());
bind_method(Vector2i, clamp, sarray("min", "max"), varray());
@@ -1594,6 +1596,8 @@ static void _register_variant_builtin_methods() {
bind_method(Vector3i, min_axis_index, sarray(), varray());
bind_method(Vector3i, max_axis_index, sarray(), varray());
+ bind_method(Vector3i, length, sarray(), varray());
+ bind_method(Vector3i, length_squared, sarray(), varray());
bind_method(Vector3i, sign, sarray(), varray());
bind_method(Vector3i, abs, sarray(), varray());
bind_method(Vector3i, clamp, sarray("min", "max"), varray());
diff --git a/doc/classes/TabBar.xml b/doc/classes/TabBar.xml
index f97b3e08d1..d0976be4b5 100644
--- a/doc/classes/TabBar.xml
+++ b/doc/classes/TabBar.xml
@@ -49,19 +49,6 @@
Returns [code]true[/code] if select with right mouse button is enabled.
</description>
</method>
- <method name="get_tab_count" qualifiers="const">
- <return type="int" />
- <description>
- Returns the number of tabs.
- </description>
- </method>
- <method name="get_tab_disabled" qualifiers="const">
- <return type="bool" />
- <argument index="0" name="tab_idx" type="int" />
- <description>
- Returns [code]true[/code] if the tab at index [code]tab_idx[/code] is disabled.
- </description>
- </method>
<method name="get_tab_icon" qualifiers="const">
<return type="Texture2D" />
<argument index="0" name="tab_idx" type="int" />
@@ -117,6 +104,13 @@
Returns the [TabBar]'s rearrange group ID.
</description>
</method>
+ <method name="is_tab_disabled" qualifiers="const">
+ <return type="bool" />
+ <argument index="0" name="tab_idx" type="int" />
+ <description>
+ Returns [code]true[/code] if the tab at index [code]tab_idx[/code] is disabled.
+ </description>
+ </method>
<method name="move_tab">
<return type="void" />
<argument index="0" name="from" type="int" />
@@ -214,6 +208,9 @@
<member name="tab_close_display_policy" type="int" setter="set_tab_close_display_policy" getter="get_tab_close_display_policy" enum="TabBar.CloseButtonDisplayPolicy" default="0">
Sets when the close button will appear on the tabs. See [enum CloseButtonDisplayPolicy] for details.
</member>
+ <member name="tab_count" type="int" setter="set_tab_count" getter="get_tab_count" default="0">
+ The number of tabs currently in the bar.
+ </member>
</members>
<signals>
<signal name="active_tab_rearranged">
diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml
index e7faa3ef0f..64256f33fd 100644
--- a/doc/classes/Vector2.xml
+++ b/doc/classes/Vector2.xml
@@ -299,7 +299,7 @@
<argument index="1" name="weight" type="float" />
<description>
Returns the result of spherical linear interpolation between this vector and [code]to[/code], by amount [code]weight[/code]. [code]weight[/code] is on the range of 0.0 to 1.0, representing the amount of interpolation.
- [b]Note:[/b] Both vectors must be normalized.
+ This method also handles interpolating the lengths if the input vectors have different lengths. For the special case of one or both input vectors having zero length, this method behaves like [method lerp].
</description>
</method>
<method name="slide" qualifiers="const">
diff --git a/doc/classes/Vector2i.xml b/doc/classes/Vector2i.xml
index 74c9c23de0..721c73d603 100644
--- a/doc/classes/Vector2i.xml
+++ b/doc/classes/Vector2i.xml
@@ -64,6 +64,19 @@
Returns a new vector with all components clamped between the components of [code]min[/code] and [code]max[/code], by running [method @GlobalScope.clamp] on each component.
</description>
</method>
+ <method name="length" qualifiers="const">
+ <return type="float" />
+ <description>
+ Returns the length (magnitude) of this vector.
+ </description>
+ </method>
+ <method name="length_squared" qualifiers="const">
+ <return type="int" />
+ <description>
+ Returns the squared length (squared magnitude) of this vector.
+ This method runs faster than [method length], so prefer it if you need to compare vectors or need the squared distance for some formula.
+ </description>
+ </method>
<method name="max_axis_index" qualifiers="const">
<return type="int" />
<description>
diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml
index 8d2ef0ecd9..ead08d86df 100644
--- a/doc/classes/Vector3.xml
+++ b/doc/classes/Vector3.xml
@@ -290,7 +290,7 @@
<argument index="1" name="weight" type="float" />
<description>
Returns the result of spherical linear interpolation between this vector and [code]to[/code], by amount [code]weight[/code]. [code]weight[/code] is on the range of 0.0 to 1.0, representing the amount of interpolation.
- [b]Note:[/b] Both vectors must be normalized.
+ This method also handles interpolating the lengths if the input vectors have different lengths. For the special case of one or both input vectors having zero length, this method behaves like [method lerp].
</description>
</method>
<method name="slide" qualifiers="const">
diff --git a/doc/classes/Vector3i.xml b/doc/classes/Vector3i.xml
index 9b952292b6..da729e1ec2 100644
--- a/doc/classes/Vector3i.xml
+++ b/doc/classes/Vector3i.xml
@@ -58,6 +58,19 @@
Returns a new vector with all components clamped between the components of [code]min[/code] and [code]max[/code], by running [method @GlobalScope.clamp] on each component.
</description>
</method>
+ <method name="length" qualifiers="const">
+ <return type="float" />
+ <description>
+ Returns the length (magnitude) of this vector.
+ </description>
+ </method>
+ <method name="length_squared" qualifiers="const">
+ <return type="int" />
+ <description>
+ Returns the squared length (squared magnitude) of this vector.
+ This method runs faster than [method length], so prefer it if you need to compare vectors or need the squared distance for some formula.
+ </description>
+ </method>
<method name="max_axis_index" qualifiers="const">
<return type="int" />
<description>
diff --git a/editor/plugins/lightmap_gi_editor_plugin.cpp b/editor/plugins/lightmap_gi_editor_plugin.cpp
index be17fc238a..2126ca1bc9 100644
--- a/editor/plugins/lightmap_gi_editor_plugin.cpp
+++ b/editor/plugins/lightmap_gi_editor_plugin.cpp
@@ -33,13 +33,14 @@
void LightmapGIEditorPlugin::_bake_select_file(const String &p_file) {
if (lightmap) {
LightmapGI::BakeError err;
+ const uint64_t time_started = OS::get_singleton()->get_ticks_msec();
if (get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root() == lightmap) {
err = lightmap->bake(lightmap, p_file, bake_func_step);
} else {
err = lightmap->bake(lightmap->get_parent(), p_file, bake_func_step);
}
- bake_func_end();
+ bake_func_end(time_started);
switch (err) {
case LightmapGI::BAKE_ERROR_NO_SAVE_PATH: {
@@ -104,11 +105,18 @@ bool LightmapGIEditorPlugin::bake_func_step(float p_progress, const String &p_de
return tmp_progress->step(p_description, p_progress * 1000, p_refresh);
}
-void LightmapGIEditorPlugin::bake_func_end() {
+void LightmapGIEditorPlugin::bake_func_end(uint64_t p_time_started) {
if (tmp_progress != nullptr) {
memdelete(tmp_progress);
tmp_progress = nullptr;
}
+
+ const int time_taken = (OS::get_singleton()->get_ticks_msec() - p_time_started) * 0.001;
+ print_line(vformat("Done baking lightmaps in %02d:%02d:%02d.", time_taken / 3600, (time_taken % 3600) / 60, time_taken % 60));
+ // Request attention in case the user was doing something else.
+ // Baking lightmaps is likely the editor task that can take the most time,
+ // so only request the attention for baking lightmaps.
+ DisplayServer::get_singleton()->window_request_attention();
}
void LightmapGIEditorPlugin::_bind_methods() {
diff --git a/editor/plugins/lightmap_gi_editor_plugin.h b/editor/plugins/lightmap_gi_editor_plugin.h
index d0edf9f324..5eec972228 100644
--- a/editor/plugins/lightmap_gi_editor_plugin.h
+++ b/editor/plugins/lightmap_gi_editor_plugin.h
@@ -47,7 +47,7 @@ class LightmapGIEditorPlugin : public EditorPlugin {
EditorFileDialog *file_dialog;
static EditorProgress *tmp_progress;
static bool bake_func_step(float p_progress, const String &p_description, void *, bool p_refresh);
- static void bake_func_end();
+ static void bake_func_end(uint64_t p_time_started);
void _bake_select_file(const String &p_file);
void _bake();
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index 728f9a1616..57603c6655 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -443,7 +443,7 @@ String OS_UWP::get_name() const {
OS::Date OS_UWP::get_date(bool p_utc) const {
SYSTEMTIME systemtime;
- if (utc) {
+ if (p_utc) {
GetSystemTime(&systemtime);
} else {
GetLocalTime(&systemtime);
@@ -460,10 +460,11 @@ OS::Date OS_UWP::get_date(bool p_utc) const {
OS::Time OS_UWP::get_time(bool p_utc) const {
SYSTEMTIME systemtime;
- if (utc)
+ if (p_utc) {
GetSystemTime(&systemtime);
- else
+ } else {
GetLocalTime(&systemtime);
+ }
Time time;
time.hour = systemtime.wHour;
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index a942fc90aa..128c6cae8b 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -625,7 +625,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
pa->object->set_indexed(pa->subpath, value, &valid); //you are not speshul
#ifdef DEBUG_ENABLED
if (!valid) {
- ERR_PRINT("Failed setting track value '" + String(pa->owner->path) + "'. Check if property exists or the type of key is valid. Animation '" + a->get_name() + "' at node '" + get_path() + "'.");
+ ERR_PRINT("Failed setting track value '" + String(pa->owner->path) + "'. Check if the property exists or the type of key is valid. Animation '" + a->get_name() + "' at node '" + get_path() + "'.");
}
#endif
@@ -1070,8 +1070,24 @@ void AnimationPlayer::_animation_update_transforms() {
bool valid;
pa->object->set_indexed(pa->subpath, pa->value_accum, &valid); //you are not speshul
#ifdef DEBUG_ENABLED
+
if (!valid) {
- ERR_PRINT("Failed setting key at time " + rtos(playback.current.pos) + " in Animation '" + get_current_animation() + "' at Node '" + get_path() + "', Track '" + String(pa->owner->path) + "'. Check if property exists or the type of key is right for the property");
+ // Get subpath as string for printing the error
+ // Cannot use `String::join(Vector<String>)` because this is a vector of StringName
+ String key_debug;
+ if (pa->subpath.size() > 0) {
+ key_debug = pa->subpath[0];
+ for (int subpath_index = 1; subpath_index < pa->subpath.size(); ++subpath_index) {
+ key_debug += ".";
+ key_debug += pa->subpath[subpath_index];
+ }
+ }
+ ERR_PRINT("Failed setting key '" + key_debug +
+ "' at time " + rtos(playback.current.pos) +
+ " in Animation '" + get_current_animation() +
+ "' at Node '" + get_path() +
+ "', Track '" + String(pa->owner->path) +
+ "'. Check if the property exists or the type of key is right for the property.");
}
#endif
diff --git a/scene/gui/tab_bar.cpp b/scene/gui/tab_bar.cpp
index f4a0a2fa56..f7ae101690 100644
--- a/scene/gui/tab_bar.cpp
+++ b/scene/gui/tab_bar.cpp
@@ -510,6 +510,13 @@ void TabBar::_notification(int p_what) {
}
}
+void TabBar::set_tab_count(int p_count) {
+ ERR_FAIL_COND(p_count < 0);
+ tabs.resize(p_count);
+ update();
+ notify_property_list_changed();
+}
+
int TabBar::get_tab_count() const {
return tabs.size();
}
@@ -635,7 +642,7 @@ void TabBar::set_tab_disabled(int p_tab, bool p_disabled) {
update();
}
-bool TabBar::get_tab_disabled(int p_tab) const {
+bool TabBar::is_tab_disabled(int p_tab) const {
ERR_FAIL_INDEX_V(p_tab, tabs.size(), false);
return tabs[p_tab].disabled;
}
@@ -765,13 +772,9 @@ void TabBar::add_tab(const String &p_str, const Ref<Texture2D> &p_icon) {
Tab t;
t.text = p_str;
t.xl_text = atr(p_str);
- t.text_buf.instantiate();
t.text_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR);
t.text_buf->add_string(t.xl_text, get_theme_font(SNAME("font")), get_theme_font_size(SNAME("font_size")), Dictionary(), TranslationServer::get_singleton()->get_tool_locale());
t.icon = p_icon;
- t.disabled = false;
- t.ofs_cache = 0;
- t.size_cache = 0;
tabs.push_back(t);
_update_cache();
@@ -786,6 +789,7 @@ void TabBar::clear_tabs() {
previous = 0;
call_deferred(SNAME("_update_hover"));
update();
+ notify_property_list_changed();
}
void TabBar::remove_tab(int p_idx) {
@@ -808,6 +812,7 @@ void TabBar::remove_tab(int p_idx) {
}
_ensure_no_over_offset();
+ notify_property_list_changed();
}
Variant TabBar::get_drag_data(const Point2 &p_point) {
@@ -966,6 +971,7 @@ void TabBar::move_tab(int from, int to) {
_update_cache();
update();
+ notify_property_list_changed();
}
int TabBar::get_tab_width(int p_idx) const {
@@ -1128,8 +1134,61 @@ bool TabBar::get_select_with_rmb() const {
return select_with_rmb;
}
+bool TabBar::_set(const StringName &p_name, const Variant &p_value) {
+ Vector<String> components = String(p_name).split("/", true, 2);
+ if (components.size() >= 2 && components[0].begins_with("tab_") && components[0].trim_prefix("tab_").is_valid_int()) {
+ int tab_index = components[0].trim_prefix("tab_").to_int();
+ String property = components[1];
+ if (property == "title") {
+ set_tab_title(tab_index, p_value);
+ return true;
+ } else if (property == "icon") {
+ set_tab_icon(tab_index, p_value);
+ return true;
+ } else if (components[1] == "disabled") {
+ set_tab_disabled(tab_index, p_value);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool TabBar::_get(const StringName &p_name, Variant &r_ret) const {
+ Vector<String> components = String(p_name).split("/", true, 2);
+ if (components.size() >= 2 && components[0].begins_with("tab_") && components[0].trim_prefix("tab_").is_valid_int()) {
+ int tab_index = components[0].trim_prefix("tab_").to_int();
+ String property = components[1];
+ if (property == "title") {
+ r_ret = get_tab_title(tab_index);
+ return true;
+ } else if (property == "icon") {
+ r_ret = get_tab_icon(tab_index);
+ return true;
+ } else if (components[1] == "disabled") {
+ r_ret = is_tab_disabled(tab_index);
+ return true;
+ }
+ }
+ return false;
+}
+
+void TabBar::_get_property_list(List<PropertyInfo> *p_list) const {
+ for (int i = 0; i < tabs.size(); i++) {
+ p_list->push_back(PropertyInfo(Variant::STRING, vformat("tab_%d/title", i)));
+
+ PropertyInfo pi = PropertyInfo(Variant::OBJECT, vformat("tab_%d/icon", i), PROPERTY_HINT_RESOURCE_TYPE, "Texture2D");
+ pi.usage &= ~(get_tab_icon(i).is_null() ? PROPERTY_USAGE_STORAGE : 0);
+ p_list->push_back(pi);
+
+ pi = PropertyInfo(Variant::BOOL, vformat("tab_%d/disabled", i));
+ pi.usage &= ~(!is_tab_disabled(i) ? PROPERTY_USAGE_STORAGE : 0);
+ p_list->push_back(pi);
+ }
+}
+
void TabBar::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update_hover"), &TabBar::_update_hover);
+ ClassDB::bind_method(D_METHOD("set_tab_count"), &TabBar::set_tab_count);
ClassDB::bind_method(D_METHOD("get_tab_count"), &TabBar::get_tab_count);
ClassDB::bind_method(D_METHOD("set_current_tab", "tab_idx"), &TabBar::set_current_tab);
ClassDB::bind_method(D_METHOD("get_current_tab"), &TabBar::get_current_tab);
@@ -1146,7 +1205,7 @@ void TabBar::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_tab_icon", "tab_idx", "icon"), &TabBar::set_tab_icon);
ClassDB::bind_method(D_METHOD("get_tab_icon", "tab_idx"), &TabBar::get_tab_icon);
ClassDB::bind_method(D_METHOD("set_tab_disabled", "tab_idx", "disabled"), &TabBar::set_tab_disabled);
- ClassDB::bind_method(D_METHOD("get_tab_disabled", "tab_idx"), &TabBar::get_tab_disabled);
+ ClassDB::bind_method(D_METHOD("is_tab_disabled", "tab_idx"), &TabBar::is_tab_disabled);
ClassDB::bind_method(D_METHOD("remove_tab", "tab_idx"), &TabBar::remove_tab);
ClassDB::bind_method(D_METHOD("add_tab", "title", "icon"), &TabBar::add_tab, DEFVAL(""), DEFVAL(Ref<Texture2D>()));
ClassDB::bind_method(D_METHOD("set_tab_alignment", "alignment"), &TabBar::set_tab_alignment);
@@ -1184,6 +1243,8 @@ void TabBar::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scrolling_enabled"), "set_scrolling_enabled", "get_scrolling_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_to_rearrange_enabled"), "set_drag_to_rearrange_enabled", "get_drag_to_rearrange_enabled");
+ ADD_ARRAY_COUNT("Tabs", "tab_count", "set_tab_count", "get_tab_count", "tab_");
+
BIND_ENUM_CONSTANT(ALIGNMENT_LEFT);
BIND_ENUM_CONSTANT(ALIGNMENT_CENTER);
BIND_ENUM_CONSTANT(ALIGNMENT_RIGHT);
diff --git a/scene/gui/tab_bar.h b/scene/gui/tab_bar.h
index d9f9cca305..1741481b40 100644
--- a/scene/gui/tab_bar.h
+++ b/scene/gui/tab_bar.h
@@ -73,6 +73,10 @@ private:
Ref<Texture2D> right_button;
Rect2 rb_rect;
Rect2 cb_rect;
+
+ Tab() {
+ text_buf.instantiate();
+ }
};
int offset = 0;
@@ -112,6 +116,9 @@ private:
protected:
virtual void gui_input(const Ref<InputEvent> &p_event) override;
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_ret) const;
+ void _get_property_list(List<PropertyInfo> *p_list) const;
void _notification(int p_what);
static void _bind_methods();
@@ -140,7 +147,7 @@ public:
Ref<Texture2D> get_tab_icon(int p_tab) const;
void set_tab_disabled(int p_tab, bool p_disabled);
- bool get_tab_disabled(int p_tab) const;
+ bool is_tab_disabled(int p_tab) const;
void set_tab_right_button(int p_tab, const Ref<Texture2D> &p_right_button);
Ref<Texture2D> get_tab_right_button(int p_tab) const;
@@ -156,7 +163,9 @@ public:
void set_tab_close_display_policy(CloseButtonDisplayPolicy p_policy);
CloseButtonDisplayPolicy get_tab_close_display_policy() const;
+ void set_tab_count(int p_count);
int get_tab_count() const;
+
void set_current_tab(int p_current);
int get_current_tab() const;
int get_previous_tab() const;