From 262c68512f07582cae82ba201206e30d21529c3d Mon Sep 17 00:00:00 2001 From: Guillermo Venegas Date: Tue, 2 Jul 2024 13:29:14 +1000 Subject: [PATCH] Fix #123807: layout panels can't be collapsed on scaled regions In `ui_popup_block_position` popup blocks are scaled with the owner button region scale which wasn't being done for layout panel bounds. This applies the scale applied to the popup block to layout panels bodies and headers. Also when calculating layout-panels headers and bodies the offset `layout_panel_y_offset` is applied in place, this because this value can also be affected by this scale. This solves the original issue described in #122411 and reverts the regression #123807. Ref !123980 --- .../editors/interface/interface_layout.cc | 13 +++++++---- .../editors/interface/interface_panel.cc | 23 ++++++++----------- .../regions/interface_region_popup.cc | 13 +++++++++++ 3 files changed, 30 insertions(+), 19 deletions(-) diff --git a/source/blender/editors/interface/interface_layout.cc b/source/blender/editors/interface/interface_layout.cc index 4cf7f987d5a..947ce7109fe 100644 --- a/source/blender/editors/interface/interface_layout.cc +++ b/source/blender/editors/interface/interface_layout.cc @@ -4152,9 +4152,9 @@ static void ui_litem_layout_panel_header(uiLayout *litem) ui_item_size(item, &w, &h); litem->y -= h; ui_item_position(item, litem->x, litem->y, litem->w, h); - - panel->runtime->layout_panels.headers.append({float(litem->y), - float(litem->y + litem->h), + const float offset = UI_style_get_dpi()->panelspace; + panel->runtime->layout_panels.headers.append({float(litem->y) - offset, + float(litem->y + litem->h) - offset, header_litem->open_prop_owner, header_litem->open_prop_name}); } @@ -4169,8 +4169,11 @@ static void ui_litem_layout_panel_body(uiLayout *litem) { Panel *panel = litem->root->block->panel; ui_litem_layout_column(litem, false, false); - panel->runtime->layout_panels.bodies.append( - {float(litem->y - litem->space), float(litem->y + litem->h + litem->space)}); + const float offset = UI_style_get_dpi()->panelspace; + panel->runtime->layout_panels.bodies.append({ + float(litem->y - litem->space) - offset, + float(litem->y + litem->h + litem->space) - offset, + }); } /* box layout */ diff --git a/source/blender/editors/interface/interface_panel.cc b/source/blender/editors/interface/interface_panel.cc index 75c43f099f8..4056c4ee7f1 100644 --- a/source/blender/editors/interface/interface_panel.cc +++ b/source/blender/editors/interface/interface_panel.cc @@ -1195,23 +1195,21 @@ static void panel_draw_aligned_widgets(const uiStyle *style, } } -static int layout_panel_y_offset() -{ - return UI_style_get_dpi()->panelspace; -} - void ui_draw_layout_panels_backdrop(const ARegion *region, const Panel *panel, const float radius, float subpanel_backcolor[4]) { /* Draw backdrops for layout panels. */ + const float aspect = ui_block_is_popup_any(panel->runtime->block) ? + panel->runtime->block->aspect : + 1.0f; + for (const LayoutPanelBody &body : panel->runtime->layout_panels.bodies) { rctf panel_blockspace = panel->runtime->block->rect; panel_blockspace.ymax = panel->runtime->block->rect.ymax + body.end_y; panel_blockspace.ymin = panel->runtime->block->rect.ymax + body.start_y; - BLI_rctf_translate(&panel_blockspace, 0, -layout_panel_y_offset()); if (panel_blockspace.ymax <= panel->runtime->block->rect.ymin) { /* Layout panels no longer fits in block rectangle, stop drawing backdrops. */ @@ -1222,7 +1220,8 @@ void ui_draw_layout_panels_backdrop(const ARegion *region, continue; } /* If the layout panel is at the end of the root panel, it's bottom corners are rounded. */ - const bool is_main_panel_end = panel_blockspace.ymin - panel->runtime->block->rect.ymin < 10; + const bool is_main_panel_end = panel_blockspace.ymin - panel->runtime->block->rect.ymin < + (10.0f / aspect); if (is_main_panel_end) { panel_blockspace.ymin = panel->runtime->block->rect.ymin; UI_draw_roundbox_corner_set(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT); @@ -1997,12 +1996,8 @@ static void ui_do_drag(const bContext *C, const wmEvent *event, Panel *panel) LayoutPanelHeader *ui_layout_panel_header_under_mouse(const Panel &panel, const int my) { - const float aspect = panel.runtime->block->aspect; for (LayoutPanelHeader &header : panel.runtime->layout_panels.headers) { - if (IN_RANGE(float(my - panel.runtime->block->rect.ymax + layout_panel_y_offset()) * aspect, - header.start_y, - header.end_y)) - { + if (IN_RANGE(float(my - panel.runtime->block->rect.ymax), header.start_y, header.end_y)) { return &header; } } @@ -2071,8 +2066,8 @@ static void ui_panel_drag_collapse(const bContext *C, for (LayoutPanelHeader &header : panel->runtime->layout_panels.headers) { rctf rect = block->rect; - rect.ymin = block->rect.ymax + header.start_y + layout_panel_y_offset(); - rect.ymax = block->rect.ymax + header.end_y + layout_panel_y_offset(); + rect.ymin = block->rect.ymax + header.start_y; + rect.ymax = block->rect.ymax + header.end_y; if (BLI_rctf_isect_segment(&rect, xy_a_block, xy_b_block)) { RNA_boolean_set( diff --git a/source/blender/editors/interface/regions/interface_region_popup.cc b/source/blender/editors/interface/regions/interface_region_popup.cc index 7886b4d24ae..9c8f9566dc2 100644 --- a/source/blender/editors/interface/regions/interface_region_popup.cc +++ b/source/blender/editors/interface/regions/interface_region_popup.cc @@ -126,6 +126,19 @@ static void ui_popup_block_position(wmWindow *window, ui_block_to_window_rctf(butregion, but->block, &block->rect, &block->rect); + /* `block->rect` is already scaled with `butregion->winrct`, + * apply this scale to layout panels too. */ + if (Panel *panel = block->panel) { + for (LayoutPanelBody &body : panel->runtime->layout_panels.bodies) { + body.start_y /= block->aspect; + body.end_y /= block->aspect; + } + for (LayoutPanelHeader &header : panel->runtime->layout_panels.headers) { + header.start_y /= block->aspect; + header.end_y /= block->aspect; + } + } + /* Compute direction relative to button, based on available space. */ const int size_x = BLI_rctf_size_x(&block->rect) + 0.2f * UI_UNIT_X; /* 4 for shadow */ const int size_y = BLI_rctf_size_y(&block->rect) + 0.2f * UI_UNIT_Y;