Add middle-click removing for TabBars

Added a boolean option field to enable the firing of the "tab_close_pressed" signal when middle clicking on a tab.
This commit is contained in:
Cruglet
2025-02-18 21:08:10 -05:00
committed by PM
parent e2b2dce6c5
commit 1a1711f1ee
4 changed files with 24 additions and 7 deletions

View File

@ -245,6 +245,9 @@
<member name="clip_tabs" type="bool" setter="set_clip_tabs" getter="get_clip_tabs" default="true">
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.
</member>
<member name="close_with_middle_mouse" type="bool" setter="set_close_with_middle_mouse" getter="get_close_with_middle_mouse" default="true">
If [code]true[/code], middle clicking on the mouse will fire the [signal tab_close_pressed] signal.
</member>
<member name="current_tab" type="int" setter="set_current_tab" getter="get_current_tab" default="-1">
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.
</member>
@ -309,7 +312,7 @@
<signal name="tab_close_pressed">
<param index="0" name="tab" type="int" />
<description>
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]

View File

@ -116,15 +116,10 @@ void EditorSceneTabs::_scene_tab_exit() {
}
void EditorSceneTabs::_scene_tab_input(const Ref<InputEvent> &p_input) {
int tab_id = scene_tabs->get_hovered_tab();
Ref<InputEventMouseButton> 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();

View File

@ -203,6 +203,10 @@ void TabBar::gui_input(const Ref<InputEvent> &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");

View File

@ -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;