From 248b32289619c94ecce2c1b98c2e16d50719087e Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Mon, 3 Jul 2023 13:06:38 +0200 Subject: [PATCH] UI: Improve how region size snapping respects the maximum size Previously, a region that used size snapping could be dragged to a snapped size (say 3 times a column width), but then would be clamped to an unsnapped size (say 2.7 times a column width) to make it fit the available space. Instead clamp the size before snapping, so that snapping respects the available width/height (resulting in 2 times a column width for example). Put differently, the region will not be made taller if there's not enough space to fit the region up to the next snapping point. Implemented as part of #104831. Pull Request: https://projects.blender.org/blender/blender/pulls/109027 --- source/blender/editors/screen/screen_ops.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 33264214141..5af001b5321 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2836,14 +2836,20 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event) const int size_no_snap = rmd->origval + delta; rmd->region->sizex = size_no_snap; + /* Clamp before snapping, so the snapping doesn't use a size that's invalid anyway. It will + * check for and respect the max-width too. */ + CLAMP(rmd->region->sizex, 0, rmd->maxsize); if (rmd->region->type->snap_size) { short sizex_test = rmd->region->type->snap_size(rmd->region, rmd->region->sizex, 0); - if (abs(rmd->region->sizex - sizex_test) < snap_size_threshold) { + if ((abs(rmd->region->sizex - sizex_test) < snap_size_threshold) && + /* Don't snap to a new size if that would exceed the maximum width. */ + sizex_test <= rmd->maxsize) + { rmd->region->sizex = sizex_test; } } - CLAMP(rmd->region->sizex, 0, rmd->maxsize); + BLI_assert(rmd->region->sizex <= rmd->maxsize); if (size_no_snap < UI_UNIT_X / aspect) { rmd->region->sizex = rmd->origval; @@ -2869,14 +2875,20 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event) const int size_no_snap = rmd->origval + delta; rmd->region->sizey = size_no_snap; + /* Clamp before snapping, so the snapping doesn't use a size that's invalid anyway. It will + * check for and respect the max-height too. */ + CLAMP(rmd->region->sizey, 0, rmd->maxsize); if (rmd->region->type->snap_size) { short sizey_test = rmd->region->type->snap_size(rmd->region, rmd->region->sizey, 1); - if (abs(rmd->region->sizey - sizey_test) < snap_size_threshold) { + if ((abs(rmd->region->sizey - sizey_test) < snap_size_threshold) && + /* Don't snap to a new size if that would exceed the maximum height. */ + (sizey_test <= rmd->maxsize)) + { rmd->region->sizey = sizey_test; } } - CLAMP(rmd->region->sizey, 0, rmd->maxsize); + BLI_assert(rmd->region->sizey <= rmd->maxsize); /* NOTE: `UI_UNIT_Y / 4` means you need to drag the footer and execute region * almost all the way down for it to become hidden, this is done