diff options
-rw-r--r-- | editor/editor_themes.cpp | 10 | ||||
-rw-r--r-- | editor/icons/icon_GUI_mini_tab_menu.svg | 5 | ||||
-rw-r--r-- | editor/icons/icon_GUI_scroll_arrow_left_hl.svg | 3 | ||||
-rw-r--r-- | editor/icons/icon_GUI_scroll_arrow_right_hl.svg | 3 | ||||
-rw-r--r-- | editor/icons/icon_GUI_tab_menu_hl.svg | 5 | ||||
-rw-r--r-- | scene/gui/tab_container.cpp | 112 | ||||
-rw-r--r-- | scene/gui/tab_container.h | 4 | ||||
-rw-r--r-- | scene/gui/tabs.cpp | 18 | ||||
-rw-r--r-- | scene/gui/tabs.h | 4 |
9 files changed, 134 insertions, 30 deletions
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 42c55681ae..32b57e0d65 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -785,7 +785,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_color_fg", "Tabs", font_color); theme->set_color("font_color_bg", "Tabs", font_color_disabled); theme->set_icon("menu", "TabContainer", theme->get_icon("GuiTabMenu", "EditorIcons")); - theme->set_icon("menu_hl", "TabContainer", theme->get_icon("GuiTabMenu", "EditorIcons")); + theme->set_icon("menu_highlight", "TabContainer", theme->get_icon("GuiTabMenuHl", "EditorIcons")); theme->set_stylebox("SceneTabFG", "EditorStyles", style_tab_selected); theme->set_stylebox("SceneTabBG", "EditorStyles", style_tab_unselected); theme->set_icon("close", "Tabs", theme->get_icon("GuiClose", "EditorIcons")); @@ -795,10 +795,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("decrement", "TabContainer", theme->get_icon("GuiScrollArrowLeft", "EditorIcons")); theme->set_icon("increment", "Tabs", theme->get_icon("GuiScrollArrowRight", "EditorIcons")); theme->set_icon("decrement", "Tabs", theme->get_icon("GuiScrollArrowLeft", "EditorIcons")); - theme->set_icon("increment_highlight", "Tabs", theme->get_icon("GuiScrollArrowRight", "EditorIcons")); - theme->set_icon("decrement_highlight", "Tabs", theme->get_icon("GuiScrollArrowLeft", "EditorIcons")); - theme->set_icon("increment_highlight", "TabContainer", theme->get_icon("GuiScrollArrowRight", "EditorIcons")); - theme->set_icon("decrement_highlight", "TabContainer", theme->get_icon("GuiScrollArrowLeft", "EditorIcons")); + theme->set_icon("increment_highlight", "Tabs", theme->get_icon("GuiScrollArrowRightHl", "EditorIcons")); + theme->set_icon("decrement_highlight", "Tabs", theme->get_icon("GuiScrollArrowLeftHl", "EditorIcons")); + theme->set_icon("increment_highlight", "TabContainer", theme->get_icon("GuiScrollArrowRightHl", "EditorIcons")); + theme->set_icon("decrement_highlight", "TabContainer", theme->get_icon("GuiScrollArrowLeftHl", "EditorIcons")); theme->set_constant("hseparation", "Tabs", 4 * EDSCALE); // Content of each tab diff --git a/editor/icons/icon_GUI_mini_tab_menu.svg b/editor/icons/icon_GUI_mini_tab_menu.svg deleted file mode 100644 index 8aeb85277c..0000000000 --- a/editor/icons/icon_GUI_mini_tab_menu.svg +++ /dev/null @@ -1,5 +0,0 @@ -<svg width="6" height="16" version="1.1" viewBox="0 0 6 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m3 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm0 6a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm0 6a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2z" fill="#fff" fill-opacity=".39216"/> -</g> -</svg> diff --git a/editor/icons/icon_GUI_scroll_arrow_left_hl.svg b/editor/icons/icon_GUI_scroll_arrow_left_hl.svg new file mode 100644 index 0000000000..c4ce1c4432 --- /dev/null +++ b/editor/icons/icon_GUI_scroll_arrow_left_hl.svg @@ -0,0 +1,3 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<path d="m8 2a6 6 0 0 1 6 6 6 6 0 0 1-6 6 6 6 0 0 1-6-6 6 6 0 0 1 6-6zm1.0137 2a1 1 0 0 0-0.7207 0.29297l-3 3a1.0001 1.0001 0 0 0 0 1.4141l3 3a1 1 0 0 0 1.4141 0 1 1 0 0 0 0-1.4141l-2.293-2.293 2.293-2.293a1 1 0 0 0 0-1.4141 1 1 0 0 0-0.69336-0.29297z" fill="#e0e0e0" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/> +</svg> diff --git a/editor/icons/icon_GUI_scroll_arrow_right_hl.svg b/editor/icons/icon_GUI_scroll_arrow_right_hl.svg new file mode 100644 index 0000000000..0727b684eb --- /dev/null +++ b/editor/icons/icon_GUI_scroll_arrow_right_hl.svg @@ -0,0 +1,3 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<path d="m8 2a6 6 0 0 0-6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0-6-6zm-1.0137 2a1 1 0 0 1 0.7207 0.29297l3 3a1.0001 1.0001 0 0 1 0 1.4141l-3 3a1 1 0 0 1-1.4141 0 1 1 0 0 1 0-1.4141l2.293-2.293-2.293-2.293a1 1 0 0 1 0-1.4141 1 1 0 0 1 0.69336-0.29297z" fill="#e0e0e0" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/> +</svg> diff --git a/editor/icons/icon_GUI_tab_menu_hl.svg b/editor/icons/icon_GUI_tab_menu_hl.svg new file mode 100644 index 0000000000..e7be7c9154 --- /dev/null +++ b/editor/icons/icon_GUI_tab_menu_hl.svg @@ -0,0 +1,5 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<g transform="translate(0 -1036.4)" fill="#e0e0e0"> +<path transform="translate(0 1036.4)" d="m8 0a2 2 0 0 0-2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0-2-2zm0 6a2 2 0 0 0-2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0-2-2zm0 6a2 2 0 0 0-2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0-2-2z" fill="#e0e0e0"/> +</g> +</svg> diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index 292d80be9d..a29ba36bad 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -94,7 +94,7 @@ void TabContainer::_gui_input(const Ref<InputEvent> &p_event) { return; } - // Do not activate tabs when tabs is empty + // Do not activate tabs when tabs is empty. if (get_tab_count() == 0) return; @@ -140,6 +140,76 @@ void TabContainer::_gui_input(const Ref<InputEvent> &p_event) { pos.x -= tab_width; } } + + Ref<InputEventMouseMotion> mm = p_event; + + if (mm.is_valid()) { + + Point2 pos(mm->get_position().x, mm->get_position().y); + Size2 size = get_size(); + + // Mouse must be on tabs in the tab header area. + if (pos.x < tabs_ofs_cache || pos.y > _get_top_margin()) { + + if (menu_hovered || highlight_arrow > -1) { + menu_hovered = false; + highlight_arrow = -1; + update(); + } + return; + } + + Ref<Texture> menu = get_icon("menu"); + if (popup) { + + if (pos.x >= size.width - menu->get_width()) { + if (!menu_hovered) { + menu_hovered = true; + highlight_arrow = -1; + update(); + return; + } + } else if (menu_hovered) { + menu_hovered = false; + update(); + } + + if (menu_hovered) { + return; + } + } + + // Do not activate tabs when tabs is empty. + if ((get_tab_count() == 0 || !buttons_visible_cache) && menu_hovered) { + highlight_arrow = -1; + update(); + return; + } + + int popup_ofs = 0; + if (popup) { + popup_ofs = menu->get_width(); + } + + Ref<Texture> increment = get_icon("increment"); + Ref<Texture> decrement = get_icon("decrement"); + if (pos.x >= size.width - increment->get_width() - popup_ofs) { + + if (highlight_arrow != 1) { + highlight_arrow = 1; + update(); + } + } else if (pos.x >= size.width - increment->get_width() - decrement->get_width() - popup_ofs) { + + if (highlight_arrow != 0) { + highlight_arrow = 0; + update(); + } + } else if (highlight_arrow > -1) { + highlight_arrow = -1; + update(); + } + } } void TabContainer::_notification(int p_what) { @@ -203,9 +273,11 @@ void TabContainer::_notification(int p_what) { Ref<StyleBox> tab_fg = get_stylebox("tab_fg"); Ref<StyleBox> tab_disabled = get_stylebox("tab_disabled"); Ref<Texture> increment = get_icon("increment"); + Ref<Texture> increment_hl = get_icon("increment_highlight"); Ref<Texture> decrement = get_icon("decrement"); + Ref<Texture> decrement_hl = get_icon("decrement_highlight"); Ref<Texture> menu = get_icon("menu"); - Ref<Texture> menu_hl = get_icon("menu_hl"); + Ref<Texture> menu_hl = get_icon("menu_highlight"); Ref<Font> font = get_font("font"); Color font_color_fg = get_color("font_color_fg"); Color font_color_bg = get_color("font_color_bg"); @@ -332,7 +404,7 @@ void TabContainer::_notification(int p_what) { x = get_size().width; if (popup) { x -= menu->get_width(); - if (mouse_x_cache > x) + if (menu_hovered) menu_hl->draw(get_canvas_item(), Size2(x, (header_height - menu_hl->get_height()) / 2)); else menu->draw(get_canvas_item(), Size2(x, (header_height - menu->get_height()) / 2)); @@ -340,23 +412,26 @@ void TabContainer::_notification(int p_what) { // Draw the navigation buttons. if (buttons_visible_cache) { - int y_center = header_height / 2; x -= increment->get_width(); - increment->draw(canvas, - Point2(x, y_center - (increment->get_height() / 2)), - Color(1, 1, 1, last_tab_cache < tabs.size() - 1 ? 1.0 : 0.5)); + if (last_tab_cache < tabs.size() - 1) { + draw_texture(highlight_arrow == 1 ? increment_hl : increment, Point2(x, (header_height - increment->get_height()) / 2)); + } else { + draw_texture(increment, Point2(x, (header_height - increment->get_height()) / 2), Color(1, 1, 1, 0.5)); + } x -= decrement->get_width(); - decrement->draw(canvas, - Point2(x, y_center - (decrement->get_height() / 2)), - Color(1, 1, 1, first_tab_cache > 0 ? 1.0 : 0.5)); + if (first_tab_cache > 0) { + draw_texture(highlight_arrow == 0 ? decrement_hl : decrement, Point2(x, (header_height - decrement->get_height()) / 2)); + } else { + draw_texture(decrement, Point2(x, (header_height - decrement->get_height()) / 2), Color(1, 1, 1, 0.5)); + } } } break; case NOTIFICATION_THEME_CHANGED: { minimum_size_changed(); - call_deferred("_on_theme_changed"); //wait until all changed theme + call_deferred("_on_theme_changed"); // Wait until all changed theme. } break; } } @@ -367,6 +442,14 @@ void TabContainer::_on_theme_changed() { } } +void TabContainer::_on_mouse_exited() { + if (menu_hovered || highlight_arrow > -1) { + menu_hovered = false; + highlight_arrow = -1; + update(); + } +} + int TabContainer::_get_tab_width(int p_index) const { ERR_FAIL_INDEX_V(p_index, get_tab_count(), 0); @@ -894,6 +977,7 @@ void TabContainer::set_use_hidden_tabs_for_min_size(bool p_use_hidden_tabs) { bool TabContainer::get_use_hidden_tabs_for_min_size() const { return use_hidden_tabs_for_min_size; } + void TabContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("_gui_input"), &TabContainer::_gui_input); @@ -925,6 +1009,7 @@ void TabContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("_child_renamed_callback"), &TabContainer::_child_renamed_callback); ClassDB::bind_method(D_METHOD("_on_theme_changed"), &TabContainer::_on_theme_changed); + ClassDB::bind_method(D_METHOD("_on_mouse_exited"), &TabContainer::_on_mouse_exited); ClassDB::bind_method(D_METHOD("_update_current_tab"), &TabContainer::_update_current_tab); ADD_SIGNAL(MethodInfo("tab_changed", PropertyInfo(Variant::INT, "tab"))); @@ -947,14 +1032,17 @@ TabContainer::TabContainer() { first_tab_cache = 0; last_tab_cache = 0; buttons_visible_cache = false; + menu_hovered = false; + highlight_arrow = -1; tabs_ofs_cache = 0; current = 0; previous = 0; - mouse_x_cache = 0; align = ALIGN_CENTER; tabs_visible = true; popup = NULL; drag_to_rearrange_enabled = false; tabs_rearrange_group = -1; use_hidden_tabs_for_min_size = false; + + connect("mouse_exited", this, "_on_mouse_exited"); } diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h index 0314f86837..0c17ebc3ae 100644 --- a/scene/gui/tab_container.h +++ b/scene/gui/tab_container.h @@ -46,7 +46,6 @@ public: }; private: - int mouse_x_cache; int first_tab_cache; int tabs_ofs_cache; int last_tab_cache; @@ -54,6 +53,8 @@ private: int previous; bool tabs_visible; bool buttons_visible_cache; + bool menu_hovered; + int highlight_arrow; TabAlign align; Control *_get_tab(int p_idx) const; int _get_top_margin() const; @@ -65,6 +66,7 @@ private: Vector<Control *> _get_tabs() const; int _get_tab_width(int p_index) const; void _on_theme_changed(); + void _on_mouse_exited(); void _update_current_tab(); protected: diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index 7b0836cd28..93b091e8d0 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tabs.cpp @@ -226,12 +226,6 @@ void Tabs::_notification(int p_what) { minimum_size_changed(); update(); } break; - case NOTIFICATION_MOUSE_EXIT: { - rb_hover = -1; - cb_hover = -1; - hover = -1; - update(); - } break; case NOTIFICATION_RESIZED: { _update_cache(); _ensure_no_over_offset(); @@ -597,6 +591,15 @@ void Tabs::_update_cache() { } } +void Tabs::_on_mouse_exited() { + + rb_hover = -1; + cb_hover = -1; + hover = -1; + highlight_arrow = -1; + update(); +} + void Tabs::add_tab(const String &p_str, const Ref<Texture> &p_icon) { Tab t; @@ -948,6 +951,7 @@ void Tabs::_bind_methods() { ClassDB::bind_method(D_METHOD("_gui_input"), &Tabs::_gui_input); ClassDB::bind_method(D_METHOD("_update_hover"), &Tabs::_update_hover); + ClassDB::bind_method(D_METHOD("_on_mouse_exited"), &Tabs::_on_mouse_exited); ClassDB::bind_method(D_METHOD("get_tab_count"), &Tabs::get_tab_count); ClassDB::bind_method(D_METHOD("set_current_tab", "tab_idx"), &Tabs::set_current_tab); ClassDB::bind_method(D_METHOD("get_current_tab"), &Tabs::get_current_tab); @@ -1024,4 +1028,6 @@ Tabs::Tabs() { hover = -1; drag_to_rearrange_enabled = false; tabs_rearrange_group = -1; + + connect("mouse_exited", this, "_on_mouse_exited"); } diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h index 7c54f1acf2..a762b5b9cb 100644 --- a/scene/gui/tabs.h +++ b/scene/gui/tabs.h @@ -89,7 +89,7 @@ private: bool cb_pressing; CloseButtonDisplayPolicy cb_displaypolicy; - int hover; // hovered tab + int hover; // Hovered tab. int min_width; bool scrolling_enabled; bool drag_to_rearrange_enabled; @@ -101,6 +101,8 @@ private: void _update_hover(); void _update_cache(); + void _on_mouse_exited(); + protected: void _gui_input(const Ref<InputEvent> &p_event); void _notification(int p_what); |