Fix wrong usages of region align enumerations

`ARegion.alignment` unfortunately is a mixture of value and bitflag
enumerations. When checking for left/right/top/bottom region alignment,
the flags have to be masked out usually.
Most of the fixed cases here probably didn't cause issues in practice,
but could in fact break at any point when surrounding logic changes.

In fact the assert in #region_visible_rect_calc() failed in an older
file from https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=949035. This
fixes it.
This commit is contained in:
Julian Eisel
2020-01-16 15:55:49 +01:00
parent 5b8c2301d8
commit d52551401e
12 changed files with 56 additions and 40 deletions

View File

@@ -124,7 +124,7 @@ bool ui_but_can_align(const uiBut *but)
int ui_but_align_opposite_to_area_align_get(const ARegion *ar)
{
switch (ar->alignment) {
switch (RGN_ALIGN_ENUM_FROM_MASK(ar->alignment)) {
case RGN_ALIGN_TOP:
return UI_BUT_ALIGN_DOWN;
case RGN_ALIGN_BOTTOM:

View File

@@ -1886,11 +1886,13 @@ static bool ui_but_drag_init(bContext *C,
RGN_TYPE_HEADER,
RGN_TYPE_TOOL_HEADER,
RGN_TYPE_FOOTER)) {
const int ar_alignment = RGN_ALIGN_ENUM_FROM_MASK(data->region->alignment);
int lock_axis = -1;
if (ELEM(data->region->alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) {
if (ELEM(ar_alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) {
lock_axis = 0;
}
else if (ELEM(data->region->alignment, RGN_ALIGN_TOP, RGN_ALIGN_BOTTOM)) {
else if (ELEM(ar_alignment, RGN_ALIGN_TOP, RGN_ALIGN_BOTTOM)) {
lock_axis = 1;
}
if (lock_axis != -1) {

View File

@@ -1241,17 +1241,19 @@ static void ui_item_menu_hold(struct bContext *C, ARegion *butregion, uiBut *but
char direction = UI_DIR_DOWN;
if (!but->drawstr[0]) {
if (butregion->alignment == RGN_ALIGN_LEFT) {
switch (RGN_ALIGN_ENUM_FROM_MASK(butregion->alignment)) {
case RGN_ALIGN_LEFT:
direction = UI_DIR_RIGHT;
}
else if (butregion->alignment == RGN_ALIGN_RIGHT) {
break;
case RGN_ALIGN_RIGHT:
direction = UI_DIR_LEFT;
}
else if (butregion->alignment == RGN_ALIGN_BOTTOM) {
break;
case RGN_ALIGN_BOTTOM:
direction = UI_DIR_UP;
}
else {
break;
default:
direction = UI_DIR_DOWN;
break;
}
}
UI_block_direction_set(block, direction);

View File

@@ -1065,7 +1065,7 @@ static bool uiAlignPanelStep(ScrArea *sa, ARegion *ar, const float fac, const bo
ps->pa->ofsy = -get_panel_size_y(ps->pa);
if (has_category_tabs) {
if (align == BUT_VERTICAL && (ar->alignment != RGN_ALIGN_RIGHT)) {
if (align == BUT_VERTICAL && (RGN_ALIGN_ENUM_FROM_MASK(ar->alignment) != RGN_ALIGN_RIGHT)) {
ps->pa->ofsx += UI_PANEL_CATEGORY_MARGIN_WIDTH;
}
}
@@ -1913,7 +1913,7 @@ void UI_panel_category_draw_all(ARegion *ar, const char *category_id_active)
{
/* no tab outlines for */
// #define USE_FLAT_INACTIVE
const bool is_left = (ar->alignment != RGN_ALIGN_RIGHT);
const bool is_left = RGN_ALIGN_ENUM_FROM_MASK(ar->alignment != RGN_ALIGN_RIGHT);
View2D *v2d = &ar->v2d;
uiStyle *style = UI_style_get();
const uiFontStyle *fstyle = &style->widget;
@@ -2201,7 +2201,7 @@ static int ui_handle_panel_category_cycling(const wmEvent *event,
{
const bool is_mousewheel = ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE);
const bool inside_tabregion =
((ar->alignment != RGN_ALIGN_RIGHT) ?
((RGN_ALIGN_ENUM_FROM_MASK(ar->alignment) != RGN_ALIGN_RIGHT) ?
(event->mval[0] < ((PanelCategoryDyn *)ar->panels_category.first)->rect.xmax) :
(event->mval[0] > ((PanelCategoryDyn *)ar->panels_category.first)->rect.xmin));

View File

@@ -280,13 +280,13 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
ARegion *ar = CTX_wm_region(C);
if (sa && ar) {
if (ELEM(ar->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) {
if (ED_area_header_alignment(sa) == RGN_ALIGN_BOTTOM) {
if (RGN_ALIGN_ENUM_FROM_MASK(ED_area_header_alignment(sa)) == RGN_ALIGN_BOTTOM) {
UI_block_direction_set(block, UI_DIR_UP);
UI_block_order_flip(block);
}
}
if (ar->regiontype == RGN_TYPE_FOOTER) {
if (ED_area_footer_alignment(sa) == RGN_ALIGN_BOTTOM) {
if (RGN_ALIGN_ENUM_FROM_MASK(ED_area_footer_alignment(sa)) == RGN_ALIGN_BOTTOM) {
UI_block_direction_set(block, UI_DIR_UP);
UI_block_order_flip(block);
}

View File

@@ -189,12 +189,12 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v
/* Prefer popover from header to be positioned into the editor. */
else if (sa && ar) {
if (ELEM(ar->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) {
if (ED_area_header_alignment(sa) == RGN_ALIGN_BOTTOM) {
if (RGN_ALIGN_ENUM_FROM_MASK(ED_area_header_alignment(sa)) == RGN_ALIGN_BOTTOM) {
UI_block_direction_set(block, UI_DIR_UP | UI_DIR_CENTER_X);
}
}
if (ar->regiontype == RGN_TYPE_FOOTER) {
if (ED_area_footer_alignment(sa) == RGN_ALIGN_BOTTOM) {
if (RGN_ALIGN_ENUM_FROM_MASK(ED_area_footer_alignment(sa)) == RGN_ALIGN_BOTTOM) {
UI_block_direction_set(block, UI_DIR_UP | UI_DIR_CENTER_X);
}
}

View File

@@ -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) {
@@ -2585,7 +2588,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;
@@ -3347,7 +3350,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;
@@ -3358,7 +3363,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;
@@ -3367,7 +3372,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 {

View File

@@ -67,10 +67,12 @@ bool ED_region_panel_category_gutter_calc_rect(const ARegion *ar, rcti *r_ar_gut
if (UI_panel_category_is_visible(ar)) {
const int category_tabs_width = round_fl_to_int(UI_view2d_scale_get_x(&ar->v2d) *
UI_PANEL_CATEGORY_MARGIN_WIDTH);
if (ar->alignment == RGN_ALIGN_LEFT) {
const int alignment = RGN_ALIGN_ENUM_FROM_MASK(ar->alignment);
if (alignment == RGN_ALIGN_LEFT) {
r_ar_gutter->xmax = r_ar_gutter->xmin + category_tabs_width;
}
else if (ar->alignment == RGN_ALIGN_RIGHT) {
else if (alignment == RGN_ALIGN_RIGHT) {
r_ar_gutter->xmin = r_ar_gutter->xmax - category_tabs_width;
}
else {
@@ -141,14 +143,16 @@ bool ED_region_contains_xy(const ARegion *ar, const int event_xy[2])
else {
/* Side-bar & any other kind of overlapping region. */
const int alignment = RGN_ALIGN_ENUM_FROM_MASK(ar->alignment);
/* Check alignment to avoid region tabs being clipped out
* by only clipping a single axis for aligned regions. */
if (ELEM(ar->alignment, RGN_ALIGN_TOP, RGN_ALIGN_BOTTOM)) {
if (ELEM(alignment, RGN_ALIGN_TOP, RGN_ALIGN_BOTTOM)) {
if (!ED_region_overlap_isect_x_with_margin(ar, event_xy[0], overlap_margin)) {
return false;
}
}
else if (ELEM(ar->alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) {
else if (ELEM(alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) {
if (ED_region_panel_category_gutter_isect_xy(ar, event_xy)) {
/* pass */
}

View File

@@ -4114,7 +4114,8 @@ void ED_screens_header_tools_menu_create(bContext *C, uiLayout *layout, void *UN
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
const char *but_flip_str = (ar->alignment == RGN_ALIGN_TOP) ? IFACE_("Flip to Bottom") :
const char *but_flip_str = (RGN_ALIGN_ENUM_FROM_MASK(ar->alignment) == RGN_ALIGN_TOP) ?
IFACE_("Flip to Bottom") :
IFACE_("Flip to Top");
{
PointerRNA ptr;
@@ -4160,7 +4161,8 @@ void ED_screens_footer_tools_menu_create(bContext *C, uiLayout *layout, void *UN
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
const char *but_flip_str = (ar->alignment == RGN_ALIGN_TOP) ? IFACE_("Flip to Bottom") :
const char *but_flip_str = (RGN_ALIGN_ENUM_FROM_MASK(ar->alignment) == RGN_ALIGN_TOP) ?
IFACE_("Flip to Bottom") :
IFACE_("Flip to Top");
{
PointerRNA ptr;
@@ -4186,7 +4188,8 @@ void ED_screens_footer_tools_menu_create(bContext *C, uiLayout *layout, void *UN
void ED_screens_navigation_bar_tools_menu_create(bContext *C, uiLayout *layout, void *UNUSED(arg))
{
const ARegion *ar = CTX_wm_region(C);
const char *but_flip_str = (ar->alignment == RGN_ALIGN_LEFT) ? IFACE_("Flip to Right") :
const char *but_flip_str = (RGN_ALIGN_ENUM_FROM_MASK(ar->alignment) == RGN_ALIGN_LEFT) ?
IFACE_("Flip to Right") :
IFACE_("Flip to Left");
/* default is WM_OP_INVOKE_REGION_WIN, which we don't want here. */

View File

@@ -81,7 +81,7 @@ static SpaceLink *statusbar_duplicate(SpaceLink *sl)
/* add handlers, stuff you only do once or on area/region changes */
static void statusbar_header_region_init(wmWindowManager *UNUSED(wm), ARegion *region)
{
if (ELEM(region->alignment, RGN_ALIGN_RIGHT)) {
if (ELEM(RGN_ALIGN_ENUM_FROM_MASK(region->alignment), RGN_ALIGN_RIGHT)) {
region->flag |= RGN_FLAG_DYNAMIC_SIZE;
}
ED_region_header_init(region);

View File

@@ -103,7 +103,7 @@ static void topbar_main_region_init(wmWindowManager *wm, ARegion *region)
wmKeyMap *keymap;
/* force delayed UI_view2d_region_reinit call */
if (ELEM(region->alignment, RGN_ALIGN_RIGHT)) {
if (ELEM(RGN_ALIGN_ENUM_FROM_MASK(region->alignment), RGN_ALIGN_RIGHT)) {
region->flag |= RGN_FLAG_DYNAMIC_SIZE;
}
UI_view2d_region_reinit(&region->v2d, V2D_COMMONVIEW_HEADER, region->winx, region->winy);
@@ -123,7 +123,7 @@ static void topbar_keymap(struct wmKeyConfig *UNUSED(keyconf))
/* add handlers, stuff you only do once or on area/region changes */
static void topbar_header_region_init(wmWindowManager *UNUSED(wm), ARegion *ar)
{
if ((ar->alignment & ~RGN_SPLIT_PREV) == RGN_ALIGN_RIGHT) {
if (RGN_ALIGN_ENUM_FROM_MASK(ar->alignment) == RGN_ALIGN_RIGHT) {
ar->flag |= RGN_FLAG_DYNAMIC_SIZE;
}
ED_region_header_init(ar);

View File

@@ -514,12 +514,12 @@ void wm_draw_region_blend(ARegion *ar, int view, bool blend)
/* Slide vertical panels */
float ofs_x = BLI_rcti_size_x(&ar->winrct) * (1.0f - alpha_easing);
if (ar->alignment == RGN_ALIGN_RIGHT) {
if (RGN_ALIGN_ENUM_FROM_MASK(ar->alignment) == RGN_ALIGN_RIGHT) {
rect_geo.xmin += ofs_x;
rect_tex.xmax *= alpha_easing;
alpha = 1.0f;
}
else if (ar->alignment == RGN_ALIGN_LEFT) {
else if (RGN_ALIGN_ENUM_FROM_MASK(ar->alignment) == RGN_ALIGN_LEFT) {
rect_geo.xmax -= ofs_x;
rect_tex.xmin += 1.0f - alpha_easing;
alpha = 1.0f;