Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/screen/area.c')
-rw-r--r--source/blender/editors/screen/area.c59
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 {