-
-
Notifications
You must be signed in to change notification settings - Fork 21k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add vertical_mode
toggle to TabBar
#63873
base: master
Are you sure you want to change the base?
Conversation
c48e058
to
58d8f48
Compare
Adds`VALignmentMode vertical_tab_alignment` to TabBar Adds vertical_tab_selected, vertical_tab_unselected, vertical_tab_disabled styleboxes to default theme Adds vertical_increment, vertical_increment_hight_light, vertical_decrement, and vertical_decrement_highlight to icons to default theme with corresponding svg files.
58d8f48
to
1d04764
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
theme->set_icon("vertical_increment", "TabBar", icons["scroll_button_down"]); | ||
theme->set_icon("vertical_increment_highlight", "TabBar", icons["scroll_button_down_hl"]); | ||
theme->set_icon("vertical_decrement", "TabBar", icons["scroll_button_up"]); | ||
theme->set_icon("vertical_decrement_highlight", "TabBar", icons["scroll_button_up_hl"]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar code has to be put into editor_themes.cpp
, else vertical mode can't be used correctly in the editor.
tabs.write[i].size_cache = get_tab_height(i); | ||
int tab_width = get_tab_width(i); | ||
|
||
if (max_width > 0 && tab_width > max_width) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really see the point of setting a max width for vertical tabs. For horizontal tabs, it allows saving space, but this is not the case with vertical tabs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be most effective in containers I would think, otherwise the vertical TabBar will have its minimum size set to the longest tab, it doesn't support a specific overflow behavior, but maximum width allows you to control this otherwise. (and I believe you could feasibly implement overflow behavior with this implementation in a script, but I haven't tested such yet)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't tried it in a container, but at least with anchor/offset positioning, it didn't limit the actual tab width, but only the text width (no matter whether clipping was on or off). But if it works like you say, it's indeed useful to have.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be fair it might be more suitable to name another property and call it tab_max_content_width
since it doesn't limit the right aligned elements, (since they don't follow the same content rules as the regular since it was too ugly to be visually useful imo) but given max_tab_width
is useless in vertical mode anyway, I had it perform that task, either renaming the property in the editor in vertical mode or using another property would likely be just as suitable.
@@ -471,40 +594,123 @@ void TabBar::_notification(int p_what) { | |||
} | |||
} | |||
|
|||
void TabBar::_draw_tab(Ref<StyleBox> &p_tab_style, Color &p_font_color, int p_index, float p_x) { | |||
void TabBar::_draw_tab(Ref<StyleBox> &p_tab_style, Color &p_font_color, int p_index, float p_tab_offset) { | |||
RID ci = get_canvas_item(); | |||
bool rtl = is_layout_rtl(); | |||
|
|||
Color font_outline_color = get_theme_color(SNAME("font_outline_color")); | |||
int outline_size = get_theme_constant(SNAME("outline_size")); | |||
int hseparation = get_theme_constant(SNAME("h_separation")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no corresponding v_separation
constant. (Even though hseparation does not work like I intuitively expected it to...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
h_separation
separates elements in the tab object, since it had no bearing on the TabBar as a whole I skipped it after realizing what it actually does, since the tabs are still horizontally aligned, the behavior for controlling that separation is actually in the style boxes (the separation for the tabs themselves normally just uses the borders and margins)
Adds `vertical_drop_mark` icon Fixes placement of drop mark in vertical mode Fixes close button positioning
686fa64
to
419861e
Compare
@@ -1174,8 +1174,13 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { | |||
theme->set_icon("decrement_highlight", "TabBar", theme->get_icon(SNAME("GuiScrollArrowLeftHl"), SNAME("EditorIcons"))); | |||
theme->set_icon("increment_highlight", "TabContainer", theme->get_icon(SNAME("GuiScrollArrowRightHl"), SNAME("EditorIcons"))); | |||
theme->set_icon("decrement_highlight", "TabContainer", theme->get_icon(SNAME("GuiScrollArrowLeftHl"), SNAME("EditorIcons"))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still missing the set_stylebox
calls for vertical_tab_*
.
For consistency, I think it would be better to add HTabBar/VTabBar instead of a vertical mode property to TabBar. Internally it can still use a vertical_mode bool that is set in the constructor (like the other nodes with H/V variations do), but it should be exposed in a way that matches all of the other control node types with horizontal and vertical variations. This would also remove the need for adding new enums, properties, and theme properties, as the H/V variants could use the same ones but with a different layout. |
This was the initial suggested approach godotengine/godot-proposals#5031 (comment) and the reason I deferred to implementing this in this way is mostly because it doesn't fit as much of the commonality of the other H/V nodes since it is considered default to use the horizontal tab layout, course I can change this to add H/VTabBar nodes, either is fine for me.
The theme elements I can agree with it would be cleaner, I'm still not sure the enum can be removed since that denotes a functionality by its name which without would contribute to confusion. (unless we renamed AlignmentMode's elements to Being/Start, Center, End but is doing that not a breaking change?) As for properties, outside of the two vertical properties, vertical_mode being in the least unavoidable here, the only strange things that may be found beyond common expectations is h_separation is a little odder in vertical mode as the tab button and close button are right aligned in vertical_mode, and max_tab_width only refers to the left align element sizes in vertical mode. I suppose how jank that might be as an approach would also be removed if made into a VTabBar node approach. If we have VTaBar, I suppose we could refurbish h_separation's documented use better, some properties could be added or to VTabBar that wouldn't mean anything in the horizontal version, tab_max_width would also optimally need to be renamed for VTabBar since it only refers to right aligned content in vertical mode and not the tab as a whole. |
Yeah I agree with having HTabBar and VTabBar. The TabBar could remain as a base class that allows to switch between layouts (see how BoxContainer handles this).
Enums are serialized as integers, so it would only affect the code that uses them. I think it's acceptable breakage. |
The SVGs have editor data from inkscape which is why the PR is 1000+ lines long :D They need to be optimized with svgcleaner I'd further suggest just copying the existing icons after rebasing, since I optimized them, and rotating them 90 degrees. You can get an optimized result for example by copying a SVG's text, pasting it here: https://www.svgviewer.dev/ |
If VTabBar and HTabBar are made then a corresponding VTabContainer and HTabContainer should probably be made as well to match. |
Closes godotengine/godot-proposals#5031
The additional theme elements were necessary to keep visual consistency in Godot and provide a more intuitive use case for this implementation.
Because of the appearance, reusing the existing algorithms didn't seem to work out as well as I thought it might, the right and close buttons will align on the right side (as would tend to be the result in horizontal tabs) but will still be separated with
h_separation
to preserve the functionality in the horizontal TabBar. (otherwise they just end up aligned right next to the text which looks off when the text of each tab is of different lengths)tab_alignment
andvertical_tab_alignment
will be hidden from the editor depending on whether the TabBar is in vertical mode or not.Exposed Additions
TabBar:
New Theme Elements
Styleboxes
Icons
Potential Considerations
vertical_mode
in this PR?