Fix #95709: Improve pulldown menu corner rounding #111554

Merged
Harley Acheson merged 7 commits from lone_noel/blender:menu-corner-rounding into main 2023-11-24 23:55:50 +01:00
2 changed files with 52 additions and 8 deletions

View File

@ -109,6 +109,21 @@ static void ui_popup_block_position(wmWindow *window,
}
}
/* Trim the popup and its contents to the width of the button if the size difference
* is small. This avoids cases where the rounded corner clips underneath the button. */
const int delta = BLI_rctf_size_x(&block->rect) - BLI_rctf_size_x(&butrct);
const float max_radius = (0.5f * U.widget_unit);
if (delta >= 0 && delta < max_radius) {
LISTBASE_FOREACH (uiBut *, bt, &block->buttons) {
/* Only trim the right most buttons in multi-column popovers. */
if (bt->rect.xmax == block->rect.xmax) {
bt->rect.xmax -= delta;
}
}
block->rect.xmax -= delta;
}
ui_block_to_window_rctf(butregion, but->block, &block->rect, &block->rect);
/* Compute direction relative to button, based on available space. */
@ -339,7 +354,26 @@ static void ui_popup_block_position(wmWindow *window,
block->safety.xmin = block->rect.xmin - s2;
}
}
block->direction = dir1;
const bool fully_aligned_with_button = BLI_rctf_size_x(&block->rect) <=
BLI_rctf_size_x(&butrct) + 1;
const bool off_screen_left = (block->rect.xmin < 0);
const bool off_screen_right = (block->rect.xmax > win_x);
if (fully_aligned_with_button) {
/* Popup is neither left or right from the button. */
dir2 &= ~(UI_DIR_LEFT | UI_DIR_RIGHT);
}
else if (off_screen_left || off_screen_right) {
/* Popup is both left and right from the button. */
dir2 |= (UI_DIR_LEFT | UI_DIR_RIGHT);
}
/* Popovers don't need secondary direction. Pulldowns to
* the left or right are currently not supported. */
const bool no_2nd_dir = (but->type == UI_BTYPE_POPOVER || ui_but_menu_draw_as_popover(but) ||
dir1 & (UI_DIR_RIGHT | UI_DIR_LEFT));
block->direction = no_2nd_dir ? dir1 : (dir1 | dir2);
}
/* Keep a list of these, needed for pull-down menus. */

View File

@ -2775,11 +2775,20 @@ static void widget_menu_back(
// rect->ymin -= 4.0;
// rect->ymax += 4.0;
}
else if (direction == UI_DIR_DOWN) {
roundboxalign = (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT);
}
else if (direction == UI_DIR_UP) {
roundboxalign = UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT;
else if (direction & (UI_DIR_DOWN | UI_DIR_UP)) {
if (direction & UI_DIR_DOWN) {
roundboxalign = (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT);
}
else {
roundboxalign = (UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
}
/* Corner rounding based on secondary direction. */
if (direction & UI_DIR_LEFT) {
roundboxalign |= (UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT);
}
if (direction & UI_DIR_RIGHT) {
roundboxalign |= (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
}
}
GPU_blend(GPU_BLEND_ALPHA);
@ -4742,10 +4751,11 @@ static int widget_roundbox_set(uiBut *but, rcti *rect)
if (but->active && (but->type != UI_BTYPE_POPOVER) && !ui_but_menu_draw_as_popover(but)) {
const int direction = ui_but_menu_direction(but);
if (direction == UI_DIR_UP) {
/* Pulldown menus that open above or below a button can have more than one direction. */
if (direction & UI_DIR_UP) {
roundbox &= ~(UI_CNR_TOP_RIGHT | UI_CNR_TOP_LEFT);
}
else if (direction == UI_DIR_DOWN) {
else if (direction & UI_DIR_DOWN) {
roundbox &= ~(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT);
}
else if (direction == UI_DIR_LEFT) {