diff --git a/doc/classes/TabBar.xml b/doc/classes/TabBar.xml
index d080294c1a4..1634e80b718 100644
--- a/doc/classes/TabBar.xml
+++ b/doc/classes/TabBar.xml
@@ -245,6 +245,9 @@
If [code]true[/code], tabs overflowing this node's width will be hidden, displaying two navigation buttons instead. Otherwise, this node's minimum size is updated so that all tabs are visible.
+
+ If [code]true[/code], middle clicking on the mouse will fire the [signal tab_close_pressed] signal.
+
The index of the current selected tab. A value of [code]-1[/code] means that no tab is selected and can only be set when [member deselect_enabled] is [code]true[/code] or if all tabs are hidden or disabled.
@@ -309,7 +312,7 @@
- Emitted when a tab's close button is pressed.
+ Emitted when a tab's close button is pressed or when middle-clicking on a tab, if [member close_with_middle_mouse] is enabled.
[b]Note:[/b] Tabs are not removed automatically once the close button is pressed, this behavior needs to be programmed manually. For example:
[codeblocks]
[gdscript]
diff --git a/editor/gui/editor_scene_tabs.cpp b/editor/gui/editor_scene_tabs.cpp
index 77d020f7ab3..2563e581e0d 100644
--- a/editor/gui/editor_scene_tabs.cpp
+++ b/editor/gui/editor_scene_tabs.cpp
@@ -116,15 +116,10 @@ void EditorSceneTabs::_scene_tab_exit() {
}
void EditorSceneTabs::_scene_tab_input(const Ref &p_input) {
- int tab_id = scene_tabs->get_hovered_tab();
Ref mb = p_input;
if (mb.is_valid()) {
- if (tab_id >= 0) {
- if (mb->get_button_index() == MouseButton::MIDDLE && mb->is_pressed()) {
- _scene_tab_closed(tab_id);
- }
- } else if (mb->get_button_index() == MouseButton::LEFT && mb->is_double_click()) {
+ if (mb->get_button_index() == MouseButton::LEFT && mb->is_double_click()) {
int tab_buttons = 0;
if (scene_tabs->get_offset_buttons_visible()) {
tab_buttons = get_theme_icon(SNAME("increment"), SNAME("TabBar"))->get_width() + get_theme_icon(SNAME("decrement"), SNAME("TabBar"))->get_width();
diff --git a/scene/gui/tab_bar.cpp b/scene/gui/tab_bar.cpp
index 65e3d23c0bf..02cda2a466e 100644
--- a/scene/gui/tab_bar.cpp
+++ b/scene/gui/tab_bar.cpp
@@ -203,6 +203,10 @@ void TabBar::gui_input(const Ref &p_event) {
queue_redraw();
}
+ if (close_with_middle_mouse && mb->is_pressed() && mb->get_button_index() == MouseButton::MIDDLE) {
+ emit_signal(SNAME("tab_close_pressed"), hover);
+ }
+
if (mb->is_pressed() && (mb->get_button_index() == MouseButton::LEFT || (select_with_rmb && mb->get_button_index() == MouseButton::RIGHT))) {
Point2 pos = mb->get_position();
@@ -1654,6 +1658,14 @@ Rect2 TabBar::get_tab_rect(int p_tab) const {
}
}
+void TabBar::set_close_with_middle_mouse(bool p_scroll_close) {
+ close_with_middle_mouse = p_scroll_close;
+}
+
+bool TabBar::get_close_with_middle_mouse() const {
+ return close_with_middle_mouse;
+}
+
void TabBar::set_tab_close_display_policy(CloseButtonDisplayPolicy p_policy) {
ERR_FAIL_INDEX(p_policy, CLOSE_BUTTON_MAX);
@@ -1795,6 +1807,8 @@ void TabBar::_bind_methods() {
ClassDB::bind_method(D_METHOD("ensure_tab_visible", "idx"), &TabBar::ensure_tab_visible);
ClassDB::bind_method(D_METHOD("get_tab_rect", "tab_idx"), &TabBar::get_tab_rect);
ClassDB::bind_method(D_METHOD("move_tab", "from", "to"), &TabBar::move_tab);
+ ClassDB::bind_method(D_METHOD("set_close_with_middle_mouse", "enabled"), &TabBar::set_close_with_middle_mouse);
+ ClassDB::bind_method(D_METHOD("get_close_with_middle_mouse"), &TabBar::get_close_with_middle_mouse);
ClassDB::bind_method(D_METHOD("set_tab_close_display_policy", "policy"), &TabBar::set_tab_close_display_policy);
ClassDB::bind_method(D_METHOD("get_tab_close_display_policy"), &TabBar::get_tab_close_display_policy);
ClassDB::bind_method(D_METHOD("set_max_tab_width", "width"), &TabBar::set_max_tab_width);
@@ -1825,6 +1839,7 @@ void TabBar::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE, "-1,4096,1"), "set_current_tab", "get_current_tab");
ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_tab_alignment", "get_tab_alignment");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_tabs"), "set_clip_tabs", "get_clip_tabs");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "close_with_middle_mouse"), "set_close_with_middle_mouse", "get_close_with_middle_mouse");
ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_close_display_policy", PROPERTY_HINT_ENUM, "Show Never,Show Active Only,Show Always"), "set_tab_close_display_policy", "get_tab_close_display_policy");
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");
diff --git a/scene/gui/tab_bar.h b/scene/gui/tab_bar.h
index f5ae75de51f..e9781101c0e 100644
--- a/scene/gui/tab_bar.h
+++ b/scene/gui/tab_bar.h
@@ -108,6 +108,7 @@ private:
int cb_hover = -1;
bool cb_pressing = false;
CloseButtonDisplayPolicy cb_displaypolicy = CLOSE_BUTTON_SHOW_NEVER;
+ bool close_with_middle_mouse = true;
int hover = -1; // Hovered tab.
int max_width = 0;
@@ -239,6 +240,9 @@ public:
void set_tab_close_display_policy(CloseButtonDisplayPolicy p_policy);
CloseButtonDisplayPolicy get_tab_close_display_policy() const;
+ void set_close_with_middle_mouse(bool p_scroll_close);
+ bool get_close_with_middle_mouse() const;
+
void set_tab_count(int p_count);
int get_tab_count() const;