You've already forked godot
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:
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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")) {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user