diff options
-rw-r--r-- | source/blender/editors/screen/screen_edit.c | 41 |
1 files changed, 18 insertions, 23 deletions
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 75aa709a5d1..554bfa6fd3f 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -534,7 +534,7 @@ int screen_area_join(bContext *C, bScreen *screen, ScrArea *sa1, ScrArea *sa2) return screen_area_join_ex(C, screen, sa1, sa2, false); } -/* Close a screen area, allowing any neighbor to take its place. */ +/* Close a screen area, allowing most-aligned neighbor to take its place. */ bool screen_area_close(struct bContext *C, bScreen *screen, ScrArea *area) { if (area == NULL) { @@ -542,32 +542,27 @@ bool screen_area_close(struct bContext *C, bScreen *screen, ScrArea *area) } ScrArea *sa2 = NULL; - - /* Find the most-aligned joinable area. Larger size breaks ties. */ - int min_alignment = INT_MAX; - int max_size = 0; - LISTBASE_FOREACH (ScrArea *, ar, &screen->areabase) { - int dir = area_getorientation(area, ar); - if (dir != -1) { - int offset1; - int offset2; - area_getoffsets(area, ar, dir, &offset1, &offset2); - int area_alignment = abs(offset1) + abs(offset2); - if (area_alignment < min_alignment) { - min_alignment = area_alignment; - max_size = ar->winx * ar->winy; - sa2 = ar; - } - else if (area_alignment == min_alignment) { - int area_size = ar->winx * ar->winy; - if (area_size > max_size) { - max_size = area_size; - sa2 = ar; - } + float best_alignment = 0.0f; + + LISTBASE_FOREACH (ScrArea *, neighbor, &screen->areabase) { + int dir = area_getorientation(area, neighbor); + /* Must at least partially share an edge and not be a global area. */ + if (dir != -1 && !neighbor->global) { + /* Winx/Winy might not be updated yet, so get lengths from verts. */ + int area_length = ELEM(dir, 1, 3) ? area->v3->vec.x - area->v1->vec.x : + area->v3->vec.y - area->v1->vec.y; + int ar_length = ELEM(dir, 1, 3) ? neighbor->v3->vec.x - neighbor->v1->vec.x : + neighbor->v3->vec.y - neighbor->v1->vec.y; + /* Calculate the ratio of the lengths of the shared edges. */ + float alignment = MIN2(area_length, ar_length) / (float)MAX2(area_length, ar_length); + if (alignment > best_alignment) { + best_alignment = alignment; + sa2 = neighbor; } } } + /* Join from neighbor into this area to close it. */ return screen_area_join_ex(C, screen, sa2, area, true); } |