mirror of
https://github.com/godotengine/godot.git
synced 2025-12-08 06:09:55 +00:00
Merge pull request #112545 from timothyqiu/compact-menu-gutter
PopupMenu: Add theme option for merging icon and checkbox gutters
This commit is contained in:
commit
31867abdaa
4 changed files with 47 additions and 26 deletions
|
|
@ -717,6 +717,9 @@
|
|||
<theme_item name="font_separator_outline_color" data_type="color" type="Color" default="Color(0, 0, 0, 1)">
|
||||
The tint of text outline of the labeled separator.
|
||||
</theme_item>
|
||||
<theme_item name="gutter_compact" data_type="constant" type="int" default="1">
|
||||
If not [code]0[/code], the icon gutter will be merged with the checkbox gutter when possible. This acts as a boolean.
|
||||
</theme_item>
|
||||
<theme_item name="h_separation" data_type="constant" type="int" default="4">
|
||||
The horizontal space between the item's elements.
|
||||
</theme_item>
|
||||
|
|
|
|||
|
|
@ -231,7 +231,8 @@ Size2 PopupMenu::_get_contents_minimum_size() const {
|
|||
real_t body_max_w = 0.0; // Indentation, text, and submenu arrow.
|
||||
real_t icon_max_w = 0.0;
|
||||
real_t accel_max_w = 0.0;
|
||||
bool has_check = false;
|
||||
bool has_check_gutter = false;
|
||||
bool gutter_compact = theme_cache.gutter_compact;
|
||||
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
_shape_item(i);
|
||||
|
|
@ -239,7 +240,10 @@ Size2 PopupMenu::_get_contents_minimum_size() const {
|
|||
icon_max_w = MAX(_get_item_icon_size(i).width, icon_max_w);
|
||||
|
||||
if (items[i].checkable_type && !items[i].separator) {
|
||||
has_check = true;
|
||||
has_check_gutter = true;
|
||||
if (items[i].icon.is_valid()) {
|
||||
gutter_compact = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (items[i].accel != Key::NONE || (items[i].shortcut.is_valid() && items[i].shortcut->has_valid_event())) {
|
||||
|
|
@ -258,12 +262,16 @@ Size2 PopupMenu::_get_contents_minimum_size() const {
|
|||
|
||||
minsize.width += theme_cache.item_start_padding + body_max_w + accel_max_w + theme_cache.item_end_padding;
|
||||
|
||||
if (icon_max_w > 0) {
|
||||
minsize.width += icon_max_w + theme_cache.h_separation;
|
||||
}
|
||||
if (has_check) {
|
||||
int check_w = MAX(theme_cache.checked->get_width(), theme_cache.radio_checked->get_width());
|
||||
minsize.width += check_w + theme_cache.h_separation;
|
||||
const int check_w = MAX(theme_cache.checked->get_width(), theme_cache.radio_checked->get_width());
|
||||
if (gutter_compact) {
|
||||
minsize.width += MAX(icon_max_w, check_w) + theme_cache.h_separation;
|
||||
} else {
|
||||
if (icon_max_w > 0) {
|
||||
minsize.width += icon_max_w + theme_cache.h_separation;
|
||||
}
|
||||
if (has_check_gutter) {
|
||||
minsize.width += check_w + theme_cache.h_separation;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_inside_tree()) {
|
||||
|
|
@ -801,31 +809,29 @@ void PopupMenu::_draw_items() {
|
|||
float display_width = control->get_size().width;
|
||||
|
||||
// Find the widest icon and whether any items have a checkbox, and store the offsets for each.
|
||||
float icon_ofs = 0.0;
|
||||
bool has_check = false;
|
||||
real_t icon_max_w = 0.0;
|
||||
real_t check_max_w = 0.0;
|
||||
bool has_check_gutter = false;
|
||||
bool gutter_compact = theme_cache.gutter_compact;
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
if (items[i].separator) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Size2 icon_size = _get_item_icon_size(i);
|
||||
icon_ofs = MAX(icon_size.width, icon_ofs);
|
||||
icon_max_w = MAX(_get_item_icon_size(i).width, icon_max_w);
|
||||
|
||||
if (items[i].checkable_type) {
|
||||
has_check = true;
|
||||
has_check_gutter = true;
|
||||
if (items[i].icon.is_valid()) {
|
||||
gutter_compact = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (icon_ofs > 0.0) {
|
||||
icon_ofs += theme_cache.h_separation;
|
||||
}
|
||||
|
||||
float check_ofs = 0.0;
|
||||
if (has_check) {
|
||||
if (has_check_gutter) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
check_ofs = MAX(check_ofs, check[i]->get_width());
|
||||
check_ofs = MAX(check_ofs, uncheck[i]->get_width());
|
||||
check_max_w = MAX(check_max_w, check[i]->get_width());
|
||||
check_max_w = MAX(check_max_w, uncheck[i]->get_width());
|
||||
}
|
||||
check_ofs += theme_cache.h_separation;
|
||||
}
|
||||
|
||||
Point2 ofs;
|
||||
|
|
@ -911,10 +917,11 @@ void PopupMenu::_draw_items() {
|
|||
separator_ofs += icon_size.width + theme_cache.h_separation;
|
||||
}
|
||||
} else {
|
||||
const real_t check_w = (gutter_compact || !has_check_gutter) ? 0 : (check_max_w + theme_cache.h_separation);
|
||||
if (rtl) {
|
||||
icon_pos = Size2(control->get_size().width - item_ofs.x - check_ofs - icon_size.width, item_ofs.y);
|
||||
icon_pos = Size2(control->get_size().width - item_ofs.x - check_w - icon_size.width, item_ofs.y);
|
||||
} else {
|
||||
icon_pos = item_ofs + Size2(check_ofs, 0);
|
||||
icon_pos = item_ofs + Size2(check_w, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -941,8 +948,16 @@ void PopupMenu::_draw_items() {
|
|||
items[i].text_buf->draw(ci, text_pos, theme_cache.font_separator_color);
|
||||
}
|
||||
} else {
|
||||
item_ofs.x += icon_ofs + check_ofs;
|
||||
|
||||
if (gutter_compact) {
|
||||
item_ofs.x += MAX(icon_max_w, check_max_w) + theme_cache.h_separation;
|
||||
} else {
|
||||
if (icon_max_w > 0) {
|
||||
item_ofs.x += icon_max_w + theme_cache.h_separation;
|
||||
}
|
||||
if (has_check_gutter) {
|
||||
item_ofs.x += check_max_w + theme_cache.h_separation;
|
||||
}
|
||||
}
|
||||
if (rtl) {
|
||||
Vector2 text_pos = Size2(control->get_size().width - items[i].text_buf->get_size().width - item_ofs.x, item_ofs.y) + Point2(0, Math::floor((h - items[i].text_buf->get_size().y) / 2.0));
|
||||
if (theme_cache.font_outline_size > 0 && theme_cache.font_outline_color.a > 0) {
|
||||
|
|
@ -3136,6 +3151,7 @@ void PopupMenu::_bind_methods() {
|
|||
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, PopupMenu, item_start_padding);
|
||||
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, PopupMenu, item_end_padding);
|
||||
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, PopupMenu, icon_max_width);
|
||||
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, PopupMenu, gutter_compact);
|
||||
|
||||
BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, PopupMenu, checked);
|
||||
BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, PopupMenu, checked_disabled);
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@ class PopupMenu : public Popup {
|
|||
int item_start_padding = 0;
|
||||
int item_end_padding = 0;
|
||||
int icon_max_width = 0;
|
||||
int gutter_compact = 0;
|
||||
|
||||
Ref<Texture2D> checked;
|
||||
Ref<Texture2D> checked_disabled;
|
||||
|
|
|
|||
|
|
@ -773,6 +773,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
|
|||
theme->set_constant("item_start_padding", "PopupMenu", Math::round(2 * scale));
|
||||
theme->set_constant("item_end_padding", "PopupMenu", Math::round(2 * scale));
|
||||
theme->set_constant("icon_max_width", "PopupMenu", 0);
|
||||
theme->set_constant("gutter_compact", "PopupMenu", 1);
|
||||
|
||||
// GraphNode
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue