From 968e1b3b10c7fb8c99d18e0ebcbffb5453d165af Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 15 Aug 2014 15:36:25 +0200 Subject: Fix T41427: Region overlap moves into wrong window. There was some fuzzyness in `region_overlap_fix()`, using an 'other side' region as ref to move current one in case their rect would intersect... New code is a bit more complex, but should handle nicely all situations, mostly ensuring we only translate an overlap if we find a previous one **on the same side**, and ensuring we also never have intersecting overlapping regions from different sides (since this does not work nice at all). --- source/blender/editors/screen/area.c | 55 +++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 17 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 583ecf7db43..05418d8d451 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -891,38 +891,59 @@ static int rct_fits(rcti *rect, char dir, int size) /* function checks if some overlapping region was defined before - on same place */ static void region_overlap_fix(ScrArea *sa, ARegion *ar) { - ARegion *ar1 = ar->prev; - + ARegion *ar1; + const int align = ar->alignment & ~RGN_SPLIT_PREV; + int align1 = 0; + /* find overlapping previous region on same place */ - while (ar1) { - if (ar1->overlap) { - if ((ar1->alignment & RGN_SPLIT_PREV) == 0) - if (BLI_rcti_isect(&ar1->winrct, &ar->winrct, NULL)) - break; + for (ar1 = ar->prev; ar1; ar1 = ar1->prev) { + if (ar1->overlap && ((ar1->alignment & RGN_SPLIT_PREV) == 0)) { + align1 = ar1->alignment; + if (BLI_rcti_isect(&ar1->winrct, &ar->winrct, NULL)) { + if (align1 != align) { + /* Left overlapping right or vice-versa, forbid this! */ + ar->flag |= RGN_FLAG_TOO_SMALL; + return; + } + /* Else, we have our previous region on same side. */ + break; + } } - ar1 = ar1->prev; } - + /* translate or close */ if (ar1) { - int align1 = ar1->alignment & ~RGN_SPLIT_PREV; - if (align1 == RGN_ALIGN_LEFT) { - if (ar->winrct.xmax + ar1->winx > sa->winx - U.widget_unit) + if (ar->winrct.xmax + ar1->winx > sa->winx - U.widget_unit) { ar->flag |= RGN_FLAG_TOO_SMALL; - else + return; + } + else { BLI_rcti_translate(&ar->winrct, ar1->winx, 0); + } } else if (align1 == RGN_ALIGN_RIGHT) { - if (ar->winrct.xmin - ar1->winx < U.widget_unit) + if (ar->winrct.xmin - ar1->winx < U.widget_unit) { ar->flag |= RGN_FLAG_TOO_SMALL; - else + return; + } + else { BLI_rcti_translate(&ar->winrct, -ar1->winx, 0); + } } } - - + /* At this point, 'ar' is in its final position and still open. + * Make a final check it does not overlap any previous 'other side' region. */ + for (ar1 = ar->prev; ar1; ar1 = ar1->prev) { + if (ar1->overlap && (ar1->alignment & RGN_SPLIT_PREV) == 0) { + if ((ar1->alignment != align) && BLI_rcti_isect(&ar1->winrct, &ar->winrct, NULL)) { + /* Left overlapping right or vice-versa, forbid this! */ + ar->flag |= RGN_FLAG_TOO_SMALL; + return; + } + } + } } /* overlapping regions only in the following restricted cases */ -- cgit v1.2.3