diff options
Diffstat (limited to 'source/blender/editors/screen/area.c')
-rw-r--r-- | source/blender/editors/screen/area.c | 59 |
1 files changed, 43 insertions, 16 deletions
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index ef201603b30..7db634660af 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1141,6 +1141,9 @@ static void region_overlap_fix(ScrArea *sa, ARegion *ar) } } + /* Guard against flags slipping through that would have to be masked out in usages below. */ + BLI_assert(align1 == RGN_ALIGN_ENUM_FROM_MASK(align1)); + /* translate or close */ if (ar1) { if (align1 == RGN_ALIGN_LEFT) { @@ -1244,6 +1247,20 @@ static void region_rect_recursive( alignment = RGN_ALIGN_NONE; } + /* If both the ARegion.sizex/y and the prefsize are 0, the region is tagged as too small, even + * before the layout for dynamic regions is created. #wm_draw_window_offscreen() allows the + * layout to be created despite the RGN_FLAG_TOO_SMALL flag being set. But there may still be + * regions that don't have a separate ARegionType.layout callback. For those, set a default + * prefsize so they can become visible. */ + if ((ar->flag & RGN_FLAG_DYNAMIC_SIZE) && !(ar->type->layout)) { + if ((ar->sizex == 0) && (ar->type->prefsizex == 0)) { + ar->type->prefsizex = AREAMINX; + } + if ((ar->sizey == 0) && (ar->type->prefsizey == 0)) { + ar->type->prefsizey = HEADERY; + } + } + /* prefsize, taking into account DPI */ int prefsizex = UI_DPI_FAC * ((ar->sizex > 1) ? ar->sizex + 0.5f : ar->type->prefsizex); int prefsizey; @@ -1323,7 +1340,7 @@ static void region_rect_recursive( else if (alignment == RGN_ALIGN_TOP || alignment == RGN_ALIGN_BOTTOM) { rcti *winrct = (ar->overlap) ? overlap_remainder : remainder; - if (rct_fits(winrct, 'v', prefsizey) < 0) { + if ((prefsizey == 0) || (rct_fits(winrct, 'v', prefsizey) < 0)) { ar->flag |= RGN_FLAG_TOO_SMALL; } else { @@ -1348,7 +1365,7 @@ static void region_rect_recursive( else if (ELEM(alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) { rcti *winrct = (ar->overlap) ? overlap_remainder : remainder; - if (rct_fits(winrct, 'h', prefsizex) < 0) { + if ((prefsizex == 0) || (rct_fits(winrct, 'h', prefsizex) < 0)) { ar->flag |= RGN_FLAG_TOO_SMALL; } else { @@ -1438,9 +1455,8 @@ static void region_rect_recursive( } /* Fix any negative dimensions. This can happen when a quad split 3d view gets to small. (see - * T72200). BLI_rcti_init() sanitizes, making sure min values are <= max values. */ - BLI_rcti_init( - &ar->winrct, ar->winrct.xmin, ar->winrct.xmax, ar->winrct.ymin, ar->winrct.ymax); + * T72200). */ + BLI_rcti_sanitize(&ar->winrct); quad++; } @@ -1479,11 +1495,16 @@ static void region_rect_recursive( ar->winrct.xmin = ar->winrct.xmax; break; case RGN_ALIGN_LEFT: + ar->winrct.xmax = ar->winrct.xmin; + break; default: /* prevent winrct to be valid */ ar->winrct.xmax = ar->winrct.xmin; break; } + + /* Size on one axis is now 0, the other axis may still be invalid (negative) though. */ + BLI_rcti_sanitize(&ar->winrct); } /* restore prev-split exception */ @@ -1501,6 +1522,8 @@ static void region_rect_recursive( *overlap_remainder = *remainder; } + BLI_assert(BLI_rcti_is_valid(&ar->winrct)); + region_rect_recursive(sa, ar->next, remainder, overlap_remainder, quad); /* Tag for redraw if size changes. */ @@ -1599,11 +1622,6 @@ static void ed_default_handlers( WM_gizmomap_add_handlers(ar, ar->gizmo_map); } } - if (flag & ED_KEYMAP_TOOL) { - WM_event_add_keymap_handler_dynamic( - &ar->handlers, WM_event_get_keymap_from_toolsystem_fallback, sa); - WM_event_add_keymap_handler_dynamic(&ar->handlers, WM_event_get_keymap_from_toolsystem, sa); - } if (flag & ED_KEYMAP_VIEW2D) { /* 2d-viewport handling+manipulation */ wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "View2D", 0, 0); @@ -1624,6 +1642,11 @@ static void ed_default_handlers( keymap = WM_keymap_ensure(wm->defaultconf, "Animation", 0, 0); WM_event_add_keymap_handler(handlers, keymap); } + if (flag & ED_KEYMAP_TOOL) { + WM_event_add_keymap_handler_dynamic( + &ar->handlers, WM_event_get_keymap_from_toolsystem_fallback, sa); + WM_event_add_keymap_handler_dynamic(&ar->handlers, WM_event_get_keymap_from_toolsystem, sa); + } if (flag & ED_KEYMAP_FRAMES) { /* frame changing/jumping (for all spaces) */ wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Frames", 0, 0); @@ -1818,8 +1841,10 @@ void ED_region_update_rect(ARegion *ar) } /* externally called for floating regions like menus */ -void ED_region_init(ARegion *ar) +void ED_region_floating_initialize(ARegion *ar) { + BLI_assert(ar->alignment == RGN_ALIGN_FLOAT); + /* refresh can be called before window opened */ region_subwindow(ar); @@ -2321,7 +2346,7 @@ static void ed_panel_draw(const bContext *C, } } - UI_panel_end(block, w, h, open); + UI_panel_end(sa, ar, block, w, h, open); } /** @@ -2565,7 +2590,7 @@ void ED_region_panels_draw(const bContext *C, ARegion *ar) /* scrollers */ const rcti *mask = NULL; rcti mask_buf; - if (ar->runtime.category && (ar->alignment == RGN_ALIGN_RIGHT)) { + if (ar->runtime.category && (RGN_ALIGN_ENUM_FROM_MASK(ar->alignment) == RGN_ALIGN_RIGHT)) { UI_view2d_mask_from_win(v2d, &mask_buf); mask_buf.xmax -= UI_PANEL_CATEGORY_MARGIN_WIDTH; mask = &mask_buf; @@ -3327,7 +3352,9 @@ static void region_visible_rect_calc(ARegion *ar, rcti *rect) for (; arn; arn = arn->next) { if (ar != arn && arn->overlap) { if (BLI_rcti_isect(rect, &arn->winrct, NULL)) { - if (ELEM(arn->alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) { + int alignment = RGN_ALIGN_ENUM_FROM_MASK(arn->alignment); + + if (ELEM(alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) { /* Overlap left, also check 1 pixel offset (2 regions on one side). */ if (ABS(rect->xmin - arn->winrct.xmin) < 2) { rect->xmin = arn->winrct.xmax; @@ -3338,7 +3365,7 @@ static void region_visible_rect_calc(ARegion *ar, rcti *rect) rect->xmax = arn->winrct.xmin; } } - else if (ELEM(arn->alignment, RGN_ALIGN_TOP, RGN_ALIGN_BOTTOM)) { + else if (ELEM(alignment, RGN_ALIGN_TOP, RGN_ALIGN_BOTTOM)) { /* Same logic as above for vertical regions. */ if (ABS(rect->ymin - arn->winrct.ymin) < 2) { rect->ymin = arn->winrct.ymax; @@ -3347,7 +3374,7 @@ static void region_visible_rect_calc(ARegion *ar, rcti *rect) rect->ymax = arn->winrct.ymin; } } - else if (arn->alignment == RGN_ALIGN_FLOAT) { + else if (alignment == RGN_ALIGN_FLOAT) { /* Skip floating. */ } else { |