Better handle icons and checkboxes with separators in PopupMenu
This commit is contained in:
parent
9d1626b4d7
commit
989caab0ad
@ -67,7 +67,7 @@ Size2 PopupMenu::_get_contents_minimum_size() const {
|
|||||||
|
|
||||||
size.width += items[i].h_ofs;
|
size.width += items[i].h_ofs;
|
||||||
|
|
||||||
if (items[i].checkable_type) {
|
if (items[i].checkable_type && !items[i].separator) {
|
||||||
has_check = true;
|
has_check = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ int PopupMenu::_get_item_height(int p_item) const {
|
|||||||
ERR_FAIL_COND_V(p_item < 0, 0);
|
ERR_FAIL_COND_V(p_item < 0, 0);
|
||||||
|
|
||||||
int icon_height = items[p_item].get_icon_size().height;
|
int icon_height = items[p_item].get_icon_size().height;
|
||||||
if (items[p_item].checkable_type) {
|
if (items[p_item].checkable_type && !items[p_item].separator) {
|
||||||
icon_height = MAX(icon_height, MAX(get_theme_icon(SNAME("checked"))->get_height(), get_theme_icon(SNAME("radio_checked"))->get_height()));
|
icon_height = MAX(icon_height, MAX(get_theme_icon(SNAME("checked"))->get_height(), get_theme_icon(SNAME("radio_checked"))->get_height()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -495,7 +495,7 @@ void PopupMenu::_draw_items() {
|
|||||||
bool rtl = control->is_layout_rtl();
|
bool rtl = control->is_layout_rtl();
|
||||||
Ref<StyleBox> style = get_theme_stylebox(SNAME("panel"));
|
Ref<StyleBox> style = get_theme_stylebox(SNAME("panel"));
|
||||||
Ref<StyleBox> hover = get_theme_stylebox(SNAME("hover"));
|
Ref<StyleBox> hover = get_theme_stylebox(SNAME("hover"));
|
||||||
// In Item::checkable_type enum order (less the non-checkable member)
|
// In Item::checkable_type enum order (less the non-checkable member).
|
||||||
Ref<Texture2D> check[] = { get_theme_icon(SNAME("checked")), get_theme_icon(SNAME("radio_checked")) };
|
Ref<Texture2D> check[] = { get_theme_icon(SNAME("checked")), get_theme_icon(SNAME("radio_checked")) };
|
||||||
Ref<Texture2D> uncheck[] = { get_theme_icon(SNAME("unchecked")), get_theme_icon(SNAME("radio_unchecked")) };
|
Ref<Texture2D> uncheck[] = { get_theme_icon(SNAME("unchecked")), get_theme_icon(SNAME("radio_unchecked")) };
|
||||||
Ref<Texture2D> submenu;
|
Ref<Texture2D> submenu;
|
||||||
@ -524,6 +524,10 @@ void PopupMenu::_draw_items() {
|
|||||||
float icon_ofs = 0.0;
|
float icon_ofs = 0.0;
|
||||||
bool has_check = false;
|
bool has_check = false;
|
||||||
for (int i = 0; i < items.size(); i++) {
|
for (int i = 0; i < items.size(); i++) {
|
||||||
|
if (items[i].separator) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
icon_ofs = MAX(items[i].get_icon_size().width, icon_ofs);
|
icon_ofs = MAX(items[i].get_icon_size().width, icon_ofs);
|
||||||
|
|
||||||
if (items[i].checkable_type) {
|
if (items[i].checkable_type) {
|
||||||
@ -567,29 +571,33 @@ void PopupMenu::_draw_items() {
|
|||||||
if (items[i].separator) {
|
if (items[i].separator) {
|
||||||
int sep_h = separator->get_center_size().height + separator->get_minimum_size().height;
|
int sep_h = separator->get_center_size().height + separator->get_minimum_size().height;
|
||||||
int sep_ofs = Math::floor((h - sep_h) / 2.0);
|
int sep_ofs = Math::floor((h - sep_h) / 2.0);
|
||||||
if (!text.is_empty()) {
|
if (!text.is_empty() || !items[i].icon.is_null()) {
|
||||||
int text_size = items[i].text_buf->get_size().width;
|
int content_size = items[i].text_buf->get_size().width;
|
||||||
int text_center = display_width / 2;
|
if (!items[i].icon.is_null()) {
|
||||||
int text_left = text_center - text_size / 2;
|
content_size += icon_size.width + hseparation;
|
||||||
int text_right = text_center + text_size / 2;
|
|
||||||
if (text_left > item_ofs.x) {
|
|
||||||
labeled_separator_left->draw(ci, Rect2(item_ofs + Point2(0, sep_ofs), Size2(MAX(0, text_left - item_ofs.x), sep_h)));
|
|
||||||
}
|
}
|
||||||
if (text_right < display_width) {
|
|
||||||
labeled_separator_right->draw(ci, Rect2(Point2(text_right, item_ofs.y + sep_ofs), Size2(MAX(0, display_width - text_right), sep_h)));
|
int content_center = display_width / 2;
|
||||||
|
int content_left = content_center - content_size / 2;
|
||||||
|
int content_right = content_center + content_size / 2;
|
||||||
|
if (content_left > item_ofs.x) {
|
||||||
|
labeled_separator_left->draw(ci, Rect2(item_ofs + Point2(0, sep_ofs), Size2(MAX(0, content_left - item_ofs.x), sep_h)));
|
||||||
|
}
|
||||||
|
if (content_right < display_width) {
|
||||||
|
labeled_separator_right->draw(ci, Rect2(Point2(content_right, item_ofs.y + sep_ofs), Size2(MAX(0, display_width - content_right), sep_h)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
separator->draw(ci, Rect2(item_ofs + Point2(0, sep_ofs), Size2(display_width, sep_h)));
|
separator->draw(ci, Rect2(item_ofs + Point2(0, sep_ofs), Size2(display_width, sep_h)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Color icon_color(1, 1, 1, items[i].disabled ? 0.5 : 1);
|
Color icon_color(1, 1, 1, items[i].disabled && !items[i].separator ? 0.5 : 1);
|
||||||
|
|
||||||
// For non-separator items, add some padding for the content.
|
// For non-separator items, add some padding for the content.
|
||||||
item_ofs.x += item_start_padding;
|
item_ofs.x += item_start_padding;
|
||||||
|
|
||||||
// Checkboxes
|
// Checkboxes
|
||||||
if (items[i].checkable_type) {
|
if (items[i].checkable_type && !items[i].separator) {
|
||||||
Texture2D *icon = (items[i].checked ? check[items[i].checkable_type - 1] : uncheck[items[i].checkable_type - 1]).ptr();
|
Texture2D *icon = (items[i].checked ? check[items[i].checkable_type - 1] : uncheck[items[i].checkable_type - 1]).ptr();
|
||||||
if (rtl) {
|
if (rtl) {
|
||||||
icon->draw(ci, Size2(control->get_size().width - item_ofs.x - icon->get_width(), item_ofs.y) + Point2(0, Math::floor((h - icon->get_height()) / 2.0)), icon_color);
|
icon->draw(ci, Size2(control->get_size().width - item_ofs.x - icon->get_width(), item_ofs.y) + Point2(0, Math::floor((h - icon->get_height()) / 2.0)), icon_color);
|
||||||
@ -598,16 +606,28 @@ void PopupMenu::_draw_items() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int separator_ofs = (display_width - items[i].text_buf->get_size().width) / 2;
|
||||||
|
|
||||||
// Icon
|
// Icon
|
||||||
if (!items[i].icon.is_null()) {
|
if (!items[i].icon.is_null()) {
|
||||||
|
if (items[i].separator) {
|
||||||
|
separator_ofs -= (icon_size.width + hseparation) / 2;
|
||||||
|
|
||||||
|
if (rtl) {
|
||||||
|
items[i].icon->draw(ci, Size2(control->get_size().width - item_ofs.x - separator_ofs - icon_size.width, item_ofs.y) + Point2(0, Math::floor((h - icon_size.height) / 2.0)), icon_color);
|
||||||
|
} else {
|
||||||
|
items[i].icon->draw(ci, item_ofs + Size2(separator_ofs, 0) + Point2(0, Math::floor((h - icon_size.height) / 2.0)), icon_color);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (rtl) {
|
if (rtl) {
|
||||||
items[i].icon->draw(ci, Size2(control->get_size().width - item_ofs.x - check_ofs - icon_size.width, item_ofs.y) + Point2(0, Math::floor((h - icon_size.height) / 2.0)), icon_color);
|
items[i].icon->draw(ci, Size2(control->get_size().width - item_ofs.x - check_ofs - icon_size.width, item_ofs.y) + Point2(0, Math::floor((h - icon_size.height) / 2.0)), icon_color);
|
||||||
} else {
|
} else {
|
||||||
items[i].icon->draw(ci, item_ofs + Size2(check_ofs, 0) + Point2(0, Math::floor((h - icon_size.height) / 2.0)), icon_color);
|
items[i].icon->draw(ci, item_ofs + Size2(check_ofs, 0) + Point2(0, Math::floor((h - icon_size.height) / 2.0)), icon_color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Submenu arrow on right hand side
|
// Submenu arrow on right hand side.
|
||||||
if (!items[i].submenu.is_empty()) {
|
if (!items[i].submenu.is_empty()) {
|
||||||
if (rtl) {
|
if (rtl) {
|
||||||
submenu->draw(ci, Point2(scroll_width + style->get_margin(SIDE_LEFT) + item_end_padding, item_ofs.y + Math::floor(h - submenu->get_height()) / 2), icon_color);
|
submenu->draw(ci, Point2(scroll_width + style->get_margin(SIDE_LEFT) + item_end_padding, item_ofs.y + Math::floor(h - submenu->get_height()) / 2), icon_color);
|
||||||
@ -621,8 +641,11 @@ void PopupMenu::_draw_items() {
|
|||||||
int outline_size = get_theme_constant(SNAME("outline_size"));
|
int outline_size = get_theme_constant(SNAME("outline_size"));
|
||||||
if (items[i].separator) {
|
if (items[i].separator) {
|
||||||
if (!text.is_empty()) {
|
if (!text.is_empty()) {
|
||||||
int center = (display_width - items[i].text_buf->get_size().width) / 2;
|
Vector2 text_pos = Point2(separator_ofs, item_ofs.y + Math::floor((h - items[i].text_buf->get_size().y) / 2.0));
|
||||||
Vector2 text_pos = Point2(center, item_ofs.y + Math::floor((h - items[i].text_buf->get_size().y) / 2.0));
|
if (!items[i].icon.is_null()) {
|
||||||
|
text_pos.x = rtl ? text_pos.x - (icon_size.width + hseparation) : text_pos.x + icon_size.width + hseparation;
|
||||||
|
}
|
||||||
|
|
||||||
if (outline_size > 0 && font_outline_color.a > 0) {
|
if (outline_size > 0 && font_outline_color.a > 0) {
|
||||||
items[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color);
|
items[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color);
|
||||||
}
|
}
|
||||||
@ -659,7 +682,7 @@ void PopupMenu::_draw_items() {
|
|||||||
items[i].accel_text_buf->draw(ci, text_pos, i == mouse_over ? font_hover_color : font_accelerator_color);
|
items[i].accel_text_buf->draw(ci, text_pos, i == mouse_over ? font_hover_color : font_accelerator_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache the item vertical offset from the first item and the height
|
// Cache the item vertical offset from the first item and the height.
|
||||||
items.write[i]._ofs_cache = ofs.y;
|
items.write[i]._ofs_cache = ofs.y;
|
||||||
items.write[i]._height_cache = h;
|
items.write[i]._height_cache = h;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user