1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-04 12:00:25 +00:00

Merge pull request #103478 from KoBeWi/hover_witch

Add switch on hover to TabBar
This commit is contained in:
Thaddeus Crews
2025-10-21 19:09:29 -05:00
12 changed files with 110 additions and 8 deletions

View File

@@ -270,6 +270,9 @@
<member name="select_with_rmb" type="bool" setter="set_select_with_rmb" getter="get_select_with_rmb" default="false"> <member name="select_with_rmb" type="bool" setter="set_select_with_rmb" getter="get_select_with_rmb" default="false">
If [code]true[/code], enables selecting a tab with the right mouse button. If [code]true[/code], enables selecting a tab with the right mouse button.
</member> </member>
<member name="switch_on_drag_hover" type="bool" setter="set_switch_on_drag_hover" getter="get_switch_on_drag_hover" default="true">
If [code]true[/code], hovering over a tab while dragging something will switch to that tab. Does not have effect when hovering another tab to rearrange. The delay for when this happens is dictated by [theme_item hover_switch_wait_msec].
</member>
<member name="tab_alignment" type="int" setter="set_tab_alignment" getter="get_tab_alignment" enum="TabBar.AlignmentMode" default="0"> <member name="tab_alignment" type="int" setter="set_tab_alignment" getter="get_tab_alignment" enum="TabBar.AlignmentMode" default="0">
The position at which tabs will be placed. The position at which tabs will be placed.
</member> </member>
@@ -403,6 +406,9 @@
<theme_item name="h_separation" data_type="constant" type="int" default="4"> <theme_item name="h_separation" data_type="constant" type="int" default="4">
The horizontal separation between the elements inside tabs. The horizontal separation between the elements inside tabs.
</theme_item> </theme_item>
<theme_item name="hover_switch_wait_msec" data_type="constant" type="int" default="500">
During a drag-and-drop, this is how many milliseconds to wait before switching the tab.
</theme_item>
<theme_item name="icon_max_width" data_type="constant" type="int" default="0"> <theme_item name="icon_max_width" data_type="constant" type="int" default="0">
The maximum allowed width of the tab's icon. This limit is applied on top of the default size of the icon, but before the value set with [method set_tab_icon_max_width]. The height is adjusted according to the icon's ratio. The maximum allowed width of the tab's icon. This limit is applied on top of the default size of the icon, but before the value set with [method set_tab_icon_max_width]. The height is adjusted according to the icon's ratio.
</theme_item> </theme_item>

View File

@@ -223,6 +223,9 @@
<member name="drag_to_rearrange_enabled" type="bool" setter="set_drag_to_rearrange_enabled" getter="get_drag_to_rearrange_enabled" default="false"> <member name="drag_to_rearrange_enabled" type="bool" setter="set_drag_to_rearrange_enabled" getter="get_drag_to_rearrange_enabled" default="false">
If [code]true[/code], tabs can be rearranged with mouse drag. If [code]true[/code], tabs can be rearranged with mouse drag.
</member> </member>
<member name="switch_on_drag_hover" type="bool" setter="set_switch_on_drag_hover" getter="get_switch_on_drag_hover" default="true">
If [code]true[/code], hovering over a tab while dragging something will switch to that tab. Does not have effect when hovering another tab to rearrange.
</member>
<member name="tab_alignment" type="int" setter="set_tab_alignment" getter="get_tab_alignment" enum="TabBar.AlignmentMode" default="0"> <member name="tab_alignment" type="int" setter="set_tab_alignment" getter="get_tab_alignment" enum="TabBar.AlignmentMode" default="0">
The position at which tabs will be placed. The position at which tabs will be placed.
</member> </member>

View File

@@ -248,8 +248,12 @@ EditorDock *EditorDockManager::_get_dock_tab_dragged() {
Dictionary dock_drop_data = dock_slot[DOCK_SLOT_LEFT_BL]->get_viewport()->gui_get_drag_data(); Dictionary dock_drop_data = dock_slot[DOCK_SLOT_LEFT_BL]->get_viewport()->gui_get_drag_data();
// Check if we are dragging a dock. // Check if we are dragging a dock.
const String type = dock_drop_data.get("type", ""); if (dock_drop_data.get("type", "").operator String() != "tab") {
if (type == "tab_container_tab") { return nullptr;
}
const String tab_type = dock_drop_data.get("tab_type", "");
if (tab_type == "tab_container_tab") {
Node *source_tab_bar = EditorNode::get_singleton()->get_node(dock_drop_data["from_path"]); Node *source_tab_bar = EditorNode::get_singleton()->get_node(dock_drop_data["from_path"]);
if (!source_tab_bar) { if (!source_tab_bar) {
return nullptr; return nullptr;

View File

@@ -1017,6 +1017,7 @@ void EditorNode::_notification(int p_what) {
if (EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor")) { if (EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor")) {
theme->set_constant("dragging_unfold_wait_msec", "Tree", (float)EDITOR_GET("interface/editor/dragging_hover_wait_seconds") * 1000); theme->set_constant("dragging_unfold_wait_msec", "Tree", (float)EDITOR_GET("interface/editor/dragging_hover_wait_seconds") * 1000);
theme->set_constant("hover_switch_wait_msec", "TabBar", (float)EDITOR_GET("interface/editor/dragging_hover_wait_seconds") * 1000);
} }
if (EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/dock_tab_style")) { if (EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/dock_tab_style")) {

View File

@@ -3027,6 +3027,11 @@ bool EditorPropertyNodePath::is_drop_valid(const Dictionary &p_drag_data) const
return false; return false;
} }
Object *data_root = p_drag_data.get("scene_root", (Object *)nullptr);
if (data_root && get_tree()->get_edited_scene_root() != data_root) {
return false;
}
Node *dropped_node = get_tree()->get_edited_scene_root()->get_node(nodes[0]); Node *dropped_node = get_tree()->get_edited_scene_root()->get_node(nodes[0]);
ERR_FAIL_NULL_V(dropped_node, false); ERR_FAIL_NULL_V(dropped_node, false);

View File

@@ -1874,6 +1874,7 @@ Variant SceneTreeEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from
Dictionary drag_data; Dictionary drag_data;
drag_data["type"] = "nodes"; drag_data["type"] = "nodes";
drag_data["nodes"] = objs; drag_data["nodes"] = objs;
drag_data["scene_root"] = get_tree()->get_edited_scene_root();
tree->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN | Tree::DROP_MODE_ON_ITEM); tree->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN | Tree::DROP_MODE_ON_ITEM);
emit_signal(SNAME("nodes_dragged")); emit_signal(SNAME("nodes_dragged"));
@@ -1895,6 +1896,11 @@ bool SceneTreeEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_d
return false; return false;
} }
Object *data_root = d.get("scene_root", (Object *)nullptr);
if (data_root && get_tree()->get_edited_scene_root() != data_root) {
return false;
}
TreeItem *item = (p_point == Vector2(Math::INF, Math::INF)) ? tree->get_selected() : tree->get_item_at_position(p_point); TreeItem *item = (p_point == Vector2(Math::INF, Math::INF)) ? tree->get_selected() : tree->get_item_at_position(p_point);
if (!item) { if (!item) {
return false; return false;

View File

@@ -1204,6 +1204,7 @@ void EditorThemeManager::_populate_standard_styles(const Ref<EditorTheme> &p_the
p_theme->set_constant("outline_size", "TabContainer", 0); p_theme->set_constant("outline_size", "TabContainer", 0);
p_theme->set_constant("h_separation", "TabBar", 4 * EDSCALE); p_theme->set_constant("h_separation", "TabBar", 4 * EDSCALE);
p_theme->set_constant("outline_size", "TabBar", 0); p_theme->set_constant("outline_size", "TabBar", 0);
p_theme->set_constant("hover_switch_wait_msec", "TabBar", (float)EDITOR_GET("interface/editor/dragging_hover_wait_seconds") * 1000);
} }
// Separators. // Separators.

View File

@@ -33,6 +33,7 @@
#include "scene/gui/box_container.h" #include "scene/gui/box_container.h"
#include "scene/gui/label.h" #include "scene/gui/label.h"
#include "scene/gui/texture_rect.h" #include "scene/gui/texture_rect.h"
#include "scene/main/timer.h"
#include "scene/main/viewport.h" #include "scene/main/viewport.h"
#include "scene/theme/theme_db.h" #include "scene/theme/theme_db.h"
@@ -501,6 +502,13 @@ void TabBar::_notification(int p_what) {
dragging_valid_tab = false; dragging_valid_tab = false;
queue_redraw(); queue_redraw();
} }
[[fallthrough]];
}
case NOTIFICATION_MOUSE_EXIT: {
if (!hover_switch_delay->is_stopped()) {
hover_switch_delay->stop();
}
} break; } break;
case NOTIFICATION_DRAW: { case NOTIFICATION_DRAW: {
@@ -1285,6 +1293,10 @@ void TabBar::_update_cache(bool p_update_hover) {
} }
} }
void TabBar::_hover_switch_timeout() {
set_current_tab(hover);
}
void TabBar::_on_mouse_exited() { void TabBar::_on_mouse_exited() {
rb_hover = -1; rb_hover = -1;
cb_hover = -1; cb_hover = -1;
@@ -1424,6 +1436,10 @@ Variant TabBar::get_drag_data(const Point2 &p_point) {
} }
bool TabBar::can_drop_data(const Point2 &p_point, const Variant &p_data) const { bool TabBar::can_drop_data(const Point2 &p_point, const Variant &p_data) const {
if (switch_on_drag_hover) {
_handle_switch_on_hover(p_data);
}
bool drop_override = Control::can_drop_data(p_point, p_data); bool drop_override = Control::can_drop_data(p_point, p_data);
if (drop_override) { if (drop_override) {
return drop_override; return drop_override;
@@ -1470,7 +1486,8 @@ Variant TabBar::_handle_get_drag_data(const String &p_type, const Point2 &p_poin
set_drag_preview(drag_preview); set_drag_preview(drag_preview);
Dictionary drag_data; Dictionary drag_data;
drag_data["type"] = p_type; drag_data["type"] = "tab";
drag_data["tab_type"] = p_type;
drag_data["tab_index"] = tab_over; drag_data["tab_index"] = tab_over;
drag_data["from_path"] = get_path(); drag_data["from_path"] = get_path();
@@ -1479,11 +1496,12 @@ Variant TabBar::_handle_get_drag_data(const String &p_type, const Point2 &p_poin
bool TabBar::_handle_can_drop_data(const String &p_type, const Point2 &p_point, const Variant &p_data) const { bool TabBar::_handle_can_drop_data(const String &p_type, const Point2 &p_point, const Variant &p_data) const {
Dictionary d = p_data; Dictionary d = p_data;
if (!d.has("type")) { if (d.get("type", "").operator String() != "tab") {
return false; return false;
} }
if (String(d["type"]) == p_type) { const String tab_type = d.get("tab_type", "");
if (tab_type == p_type) {
NodePath from_path = d["from_path"]; NodePath from_path = d["from_path"];
NodePath to_path = get_path(); NodePath to_path = get_path();
if (from_path == to_path) { if (from_path == to_path) {
@@ -1497,17 +1515,17 @@ bool TabBar::_handle_can_drop_data(const String &p_type, const Point2 &p_point,
} }
} }
} }
return false; return false;
} }
void TabBar::_handle_drop_data(const String &p_type, const Point2 &p_point, const Variant &p_data, const Callable &p_move_tab_callback, const Callable &p_move_tab_from_other_callback) { void TabBar::_handle_drop_data(const String &p_type, const Point2 &p_point, const Variant &p_data, const Callable &p_move_tab_callback, const Callable &p_move_tab_from_other_callback) {
Dictionary d = p_data; Dictionary d = p_data;
if (!d.has("type")) { if (d.get("type", "").operator String() != "tab") {
return; return;
} }
if (String(d["type"]) == p_type) { const String tab_type = d.get("tab_type", "");
if (tab_type == p_type) {
int tab_from_id = d["tab_index"]; int tab_from_id = d["tab_index"];
int hover_now = (p_point == Vector2(Math::INF, Math::INF)) ? current : get_closest_tab_idx_to_point(p_point); int hover_now = (p_point == Vector2(Math::INF, Math::INF)) ? current : get_closest_tab_idx_to_point(p_point);
NodePath from_path = d["from_path"]; NodePath from_path = d["from_path"];
@@ -1565,6 +1583,22 @@ void TabBar::_handle_drop_data(const String &p_type, const Point2 &p_point, cons
} }
} }
void TabBar::_handle_switch_on_hover(const Variant &p_data) const {
Dictionary d = p_data;
if (d.get("type", "").operator String() == "tab") {
// Dragging a tab shouldn't switch on hover.
return;
}
if (hover > -1 && hover != current) {
if (hover_switch_delay->is_stopped()) {
const_cast<TabBar *>(this)->hover_switch_delay->start(theme_cache.hover_switch_wait_msec * 0.001);
}
} else if (!hover_switch_delay->is_stopped()) {
hover_switch_delay->stop();
}
}
void TabBar::_move_tab_from(TabBar *p_from_tabbar, int p_from_index, int p_to_index) { void TabBar::_move_tab_from(TabBar *p_from_tabbar, int p_from_index, int p_to_index) {
Tab moving_tab = p_from_tabbar->tabs[p_from_index]; Tab moving_tab = p_from_tabbar->tabs[p_from_index];
moving_tab.accessibility_item_element = RID(); moving_tab.accessibility_item_element = RID();
@@ -1983,6 +2017,14 @@ bool TabBar::get_scroll_to_selected() const {
return scroll_to_selected; return scroll_to_selected;
} }
void TabBar::set_switch_on_drag_hover(bool p_enabled) {
switch_on_drag_hover = p_enabled;
}
bool TabBar::get_switch_on_drag_hover() const {
return switch_on_drag_hover;
}
void TabBar::set_select_with_rmb(bool p_enabled) { void TabBar::set_select_with_rmb(bool p_enabled) {
select_with_rmb = p_enabled; select_with_rmb = p_enabled;
} }
@@ -2055,6 +2097,8 @@ void TabBar::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_scrolling_enabled"), &TabBar::get_scrolling_enabled); ClassDB::bind_method(D_METHOD("get_scrolling_enabled"), &TabBar::get_scrolling_enabled);
ClassDB::bind_method(D_METHOD("set_drag_to_rearrange_enabled", "enabled"), &TabBar::set_drag_to_rearrange_enabled); ClassDB::bind_method(D_METHOD("set_drag_to_rearrange_enabled", "enabled"), &TabBar::set_drag_to_rearrange_enabled);
ClassDB::bind_method(D_METHOD("get_drag_to_rearrange_enabled"), &TabBar::get_drag_to_rearrange_enabled); ClassDB::bind_method(D_METHOD("get_drag_to_rearrange_enabled"), &TabBar::get_drag_to_rearrange_enabled);
ClassDB::bind_method(D_METHOD("set_switch_on_drag_hover", "enabled"), &TabBar::set_switch_on_drag_hover);
ClassDB::bind_method(D_METHOD("get_switch_on_drag_hover"), &TabBar::get_switch_on_drag_hover);
ClassDB::bind_method(D_METHOD("set_tabs_rearrange_group", "group_id"), &TabBar::set_tabs_rearrange_group); ClassDB::bind_method(D_METHOD("set_tabs_rearrange_group", "group_id"), &TabBar::set_tabs_rearrange_group);
ClassDB::bind_method(D_METHOD("get_tabs_rearrange_group"), &TabBar::get_tabs_rearrange_group); ClassDB::bind_method(D_METHOD("get_tabs_rearrange_group"), &TabBar::get_tabs_rearrange_group);
ClassDB::bind_method(D_METHOD("set_scroll_to_selected", "enabled"), &TabBar::set_scroll_to_selected); ClassDB::bind_method(D_METHOD("set_scroll_to_selected", "enabled"), &TabBar::set_scroll_to_selected);
@@ -2082,6 +2126,7 @@ void TabBar::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_tab_width", PROPERTY_HINT_RANGE, "0,99999,1,suffix:px"), "set_max_tab_width", "get_max_tab_width"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_tab_width", PROPERTY_HINT_RANGE, "0,99999,1,suffix:px"), "set_max_tab_width", "get_max_tab_width");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scrolling_enabled"), "set_scrolling_enabled", "get_scrolling_enabled"); 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_PROPERTY(PropertyInfo(Variant::BOOL, "drag_to_rearrange_enabled"), "set_drag_to_rearrange_enabled", "get_drag_to_rearrange_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "switch_on_drag_hover"), "set_switch_on_drag_hover", "get_switch_on_drag_hover");
ADD_PROPERTY(PropertyInfo(Variant::INT, "tabs_rearrange_group"), "set_tabs_rearrange_group", "get_tabs_rearrange_group"); ADD_PROPERTY(PropertyInfo(Variant::INT, "tabs_rearrange_group"), "set_tabs_rearrange_group", "get_tabs_rearrange_group");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_to_selected"), "set_scroll_to_selected", "get_scroll_to_selected"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_to_selected"), "set_scroll_to_selected", "get_scroll_to_selected");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "select_with_rmb"), "set_select_with_rmb", "get_select_with_rmb"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "select_with_rmb"), "set_select_with_rmb", "get_select_with_rmb");
@@ -2102,6 +2147,7 @@ void TabBar::_bind_methods() {
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, TabBar, h_separation); BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, TabBar, h_separation);
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, TabBar, tab_separation); BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, TabBar, tab_separation);
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, TabBar, icon_max_width); BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, TabBar, icon_max_width);
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, TabBar, hover_switch_wait_msec);
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, TabBar, tab_unselected_style, "tab_unselected"); BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, TabBar, tab_unselected_style, "tab_unselected");
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, TabBar, tab_hovered_style, "tab_hovered"); BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, TabBar, tab_hovered_style, "tab_hovered");
@@ -2152,5 +2198,10 @@ TabBar::TabBar() {
set_focus_mode(FOCUS_ALL); set_focus_mode(FOCUS_ALL);
connect(SceneStringName(mouse_exited), callable_mp(this, &TabBar::_on_mouse_exited)); connect(SceneStringName(mouse_exited), callable_mp(this, &TabBar::_on_mouse_exited));
hover_switch_delay = memnew(Timer);
hover_switch_delay->connect("timeout", callable_mp(this, &TabBar::_hover_switch_timeout));
hover_switch_delay->set_one_shot(true);
add_child(hover_switch_delay, false, INTERNAL_MODE_FRONT);
property_helper.setup_for_instance(base_property_helper, this); property_helper.setup_for_instance(base_property_helper, this);
} }

View File

@@ -34,6 +34,8 @@
#include "scene/property_list_helper.h" #include "scene/property_list_helper.h"
#include "scene/resources/text_line.h" #include "scene/resources/text_line.h"
class Timer;
class TabBar : public Control { class TabBar : public Control {
GDCLASS(TabBar, Control); GDCLASS(TabBar, Control);
@@ -130,6 +132,7 @@ private:
bool dragging_valid_tab = false; bool dragging_valid_tab = false;
bool scroll_to_selected = true; bool scroll_to_selected = true;
int tabs_rearrange_group = -1; int tabs_rearrange_group = -1;
bool switch_on_drag_hover = true;
static const int CURRENT_TAB_UNINITIALIZED = -2; static const int CURRENT_TAB_UNINITIALIZED = -2;
bool initialized = false; bool initialized = false;
@@ -143,6 +146,7 @@ private:
int h_separation = 0; int h_separation = 0;
int tab_separation = 0; int tab_separation = 0;
int icon_max_width = 0; int icon_max_width = 0;
int hover_switch_wait_msec = 500;
Ref<StyleBox> tab_unselected_style; Ref<StyleBox> tab_unselected_style;
Ref<StyleBox> tab_hovered_style; Ref<StyleBox> tab_hovered_style;
@@ -177,6 +181,8 @@ private:
Ref<StyleBox> button_hl_style; Ref<StyleBox> button_hl_style;
} theme_cache; } theme_cache;
Timer *hover_switch_delay = nullptr;
int get_tab_width(int p_idx) const; int get_tab_width(int p_idx) const;
Size2 _get_tab_icon_size(int p_idx) const; Size2 _get_tab_icon_size(int p_idx) const;
void _ensure_no_over_offset(); void _ensure_no_over_offset();
@@ -184,6 +190,7 @@ private:
void _update_hover(); void _update_hover();
void _update_cache(bool p_update_hover = true); void _update_cache(bool p_update_hover = true);
void _hover_switch_timeout();
void _on_mouse_exited(); void _on_mouse_exited();
@@ -218,6 +225,7 @@ public:
bool _handle_can_drop_data(const String &p_type, const Point2 &p_point, const Variant &p_data) const; bool _handle_can_drop_data(const String &p_type, const Point2 &p_point, const Variant &p_data) const;
void _handle_drop_data(const String &p_type, const Point2 &p_point, const Variant &p_data, const Callable &p_move_tab_callback, const Callable &p_move_tab_from_other_callback); void _handle_drop_data(const String &p_type, const Point2 &p_point, const Variant &p_data, const Callable &p_move_tab_callback, const Callable &p_move_tab_from_other_callback);
void _draw_tab_drop(RID p_canvas_item); void _draw_tab_drop(RID p_canvas_item);
void _handle_switch_on_hover(const Variant &p_data) const;
void add_tab(const String &p_str = "", const Ref<Texture2D> &p_icon = Ref<Texture2D>()); void add_tab(const String &p_str = "", const Ref<Texture2D> &p_icon = Ref<Texture2D>());
@@ -307,6 +315,9 @@ public:
void set_scroll_to_selected(bool p_enabled); void set_scroll_to_selected(bool p_enabled);
bool get_scroll_to_selected() const; bool get_scroll_to_selected() const;
void set_switch_on_drag_hover(bool p_enabled);
bool get_switch_on_drag_hover() const;
void set_select_with_rmb(bool p_enabled); void set_select_with_rmb(bool p_enabled);
bool get_select_with_rmb() const; bool get_select_with_rmb() const;

View File

@@ -1025,6 +1025,14 @@ Popup *TabContainer::get_popup() const {
return nullptr; return nullptr;
} }
void TabContainer::set_switch_on_drag_hover(bool p_enabled) {
tab_bar->set_switch_on_drag_hover(p_enabled);
}
bool TabContainer::get_switch_on_drag_hover() const {
return tab_bar->get_switch_on_drag_hover();
}
void TabContainer::set_drag_to_rearrange_enabled(bool p_enabled) { void TabContainer::set_drag_to_rearrange_enabled(bool p_enabled) {
drag_to_rearrange_enabled = p_enabled; drag_to_rearrange_enabled = p_enabled;
} }
@@ -1102,6 +1110,8 @@ void TabContainer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_tab_idx_from_control", "control"), &TabContainer::get_tab_idx_from_control); ClassDB::bind_method(D_METHOD("get_tab_idx_from_control", "control"), &TabContainer::get_tab_idx_from_control);
ClassDB::bind_method(D_METHOD("set_popup", "popup"), &TabContainer::set_popup); ClassDB::bind_method(D_METHOD("set_popup", "popup"), &TabContainer::set_popup);
ClassDB::bind_method(D_METHOD("get_popup"), &TabContainer::get_popup); ClassDB::bind_method(D_METHOD("get_popup"), &TabContainer::get_popup);
ClassDB::bind_method(D_METHOD("set_switch_on_drag_hover", "enabled"), &TabContainer::set_switch_on_drag_hover);
ClassDB::bind_method(D_METHOD("get_switch_on_drag_hover"), &TabContainer::get_switch_on_drag_hover);
ClassDB::bind_method(D_METHOD("set_drag_to_rearrange_enabled", "enabled"), &TabContainer::set_drag_to_rearrange_enabled); ClassDB::bind_method(D_METHOD("set_drag_to_rearrange_enabled", "enabled"), &TabContainer::set_drag_to_rearrange_enabled);
ClassDB::bind_method(D_METHOD("get_drag_to_rearrange_enabled"), &TabContainer::get_drag_to_rearrange_enabled); ClassDB::bind_method(D_METHOD("get_drag_to_rearrange_enabled"), &TabContainer::get_drag_to_rearrange_enabled);
ClassDB::bind_method(D_METHOD("set_tabs_rearrange_group", "group_id"), &TabContainer::set_tabs_rearrange_group); ClassDB::bind_method(D_METHOD("set_tabs_rearrange_group", "group_id"), &TabContainer::set_tabs_rearrange_group);
@@ -1127,6 +1137,7 @@ void TabContainer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_tabs"), "set_clip_tabs", "get_clip_tabs"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_tabs"), "set_clip_tabs", "get_clip_tabs");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "tabs_visible"), "set_tabs_visible", "are_tabs_visible"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "tabs_visible"), "set_tabs_visible", "are_tabs_visible");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "all_tabs_in_front"), "set_all_tabs_in_front", "is_all_tabs_in_front"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "all_tabs_in_front"), "set_all_tabs_in_front", "is_all_tabs_in_front");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "switch_on_drag_hover"), "set_switch_on_drag_hover", "get_switch_on_drag_hover");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_to_rearrange_enabled"), "set_drag_to_rearrange_enabled", "get_drag_to_rearrange_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_to_rearrange_enabled"), "set_drag_to_rearrange_enabled", "get_drag_to_rearrange_enabled");
ADD_PROPERTY(PropertyInfo(Variant::INT, "tabs_rearrange_group"), "set_tabs_rearrange_group", "get_tabs_rearrange_group"); ADD_PROPERTY(PropertyInfo(Variant::INT, "tabs_rearrange_group"), "set_tabs_rearrange_group", "get_tabs_rearrange_group");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_hidden_tabs_for_min_size"), "set_use_hidden_tabs_for_min_size", "get_use_hidden_tabs_for_min_size"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_hidden_tabs_for_min_size"), "set_use_hidden_tabs_for_min_size", "get_use_hidden_tabs_for_min_size");

View File

@@ -207,6 +207,8 @@ public:
void move_tab_from_tab_container(TabContainer *p_from, int p_from_index, int p_to_index = -1); void move_tab_from_tab_container(TabContainer *p_from, int p_from_index, int p_to_index = -1);
void set_switch_on_drag_hover(bool p_enabled);
bool get_switch_on_drag_hover() const;
void set_drag_to_rearrange_enabled(bool p_enabled); void set_drag_to_rearrange_enabled(bool p_enabled);
bool get_drag_to_rearrange_enabled() const; bool get_drag_to_rearrange_enabled() const;
void set_tabs_rearrange_group(int p_group_id); void set_tabs_rearrange_group(int p_group_id);

View File

@@ -1040,6 +1040,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("h_separation", "TabBar", Math::round(4 * scale)); theme->set_constant("h_separation", "TabBar", Math::round(4 * scale));
theme->set_constant("icon_max_width", "TabBar", 0); theme->set_constant("icon_max_width", "TabBar", 0);
theme->set_constant("outline_size", "TabBar", 0); theme->set_constant("outline_size", "TabBar", 0);
theme->set_constant("hover_switch_wait_msec", "TabBar", 500);
// Separators // Separators