From 84f46e2ee5c3eaf7536213b4d392c7647acf5b35 Mon Sep 17 00:00:00 2001 From: Leon Schittek Date: Sat, 26 Aug 2023 12:59:41 +0200 Subject: [PATCH 1/2] Fix #95709: Improve pulldown menu corner rounding Round all corners of pulldown menus that are not attached to the parent button. --- .../interface/interface_region_popup.cc | 36 ++++++++++++++++++- .../editors/interface/interface_widgets.cc | 28 ++++++++++----- 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/source/blender/editors/interface/interface_region_popup.cc b/source/blender/editors/interface/interface_region_popup.cc index e3e8aa8d1d1..ac34a24c792 100644 --- a/source/blender/editors/interface/interface_region_popup.cc +++ b/source/blender/editors/interface/interface_region_popup.cc @@ -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 too + * 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. */ @@ -349,7 +364,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. */ diff --git a/source/blender/editors/interface/interface_widgets.cc b/source/blender/editors/interface/interface_widgets.cc index 0720a23851c..a989ac8a5b0 100644 --- a/source/blender/editors/interface/interface_widgets.cc +++ b/source/blender/editors/interface/interface_widgets.cc @@ -2823,13 +2823,22 @@ 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); - rect->ymin -= 0.1f * U.widget_unit; - } - else if (direction == UI_DIR_UP) { - roundboxalign = UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT; - rect->ymax += 0.1f * U.widget_unit; + else if (direction & (UI_DIR_DOWN | UI_DIR_UP)) { + if (direction & UI_DIR_DOWN) { + roundboxalign = (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT); + rect->ymin -= 0.1f * U.widget_unit; + } + else { + roundboxalign = (UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT); + rect->ymax += 0.1f * U.widget_unit; + } + /* 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); @@ -4759,10 +4768,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) { -- 2.30.2 From b36422e374197c781801d12c258b9b60a6c8c689 Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Fri, 24 Nov 2023 14:21:59 -0800 Subject: [PATCH 2/2] Only comment changes. --- .../editors/interface/interface_region_popup.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/interface/interface_region_popup.cc b/source/blender/editors/interface/interface_region_popup.cc index 9913e39fe98..849963958fa 100644 --- a/source/blender/editors/interface/interface_region_popup.cc +++ b/source/blender/editors/interface/interface_region_popup.cc @@ -109,8 +109,8 @@ 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 too - * small. This avoids cases, where the rounded corner clips underneath the button. */ + /* 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); @@ -365,12 +365,12 @@ static void ui_popup_block_position(wmWindow *window, dir2 &= ~(UI_DIR_LEFT | UI_DIR_RIGHT); } else if (off_screen_left || off_screen_right) { - /* Popup is both left and right from the button */ + /* 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. */ + /* 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); -- 2.30.2