Fix a number of small errors in area coordinate handling

For example collapsing the lower part of the topbar with 2x interface scale
would hide the top-bar header region. There were also more asserts when changing
window size and moving area edges afterwards (same assert as in T55298).
Fixes are similar to e626998a26.

With all the recent fixes I've done, area geometry handling should be stable
again. Let's hope I'm right :)
This commit is contained in:
Severin 2018-06-30 00:42:19 +02:00
parent 48ad67ef82
commit a55b00b53b
5 changed files with 50 additions and 12 deletions

View File

@ -150,6 +150,8 @@ void ED_area_swapspace(struct bContext *C, ScrArea *sa1, ScrArea *sa2);
int ED_area_headersize(void);
int ED_area_header_alignment(const ScrArea *area);
int ED_area_global_size_y(const ScrArea *area);
int ED_area_global_min_size_y(const ScrArea *area);
int ED_area_global_max_size_y(const ScrArea *area);
bool ED_area_is_global(const ScrArea *area);
int ED_region_global_size_y(void);
void ED_area_update_region_sizes(struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *area);

View File

@ -2362,6 +2362,16 @@ int ED_area_global_size_y(const ScrArea *area)
BLI_assert(ED_area_is_global(area));
return round_fl_to_int(area->global->cur_fixed_height * UI_DPI_FAC);
}
int ED_area_global_min_size_y(const ScrArea *area)
{
BLI_assert(ED_area_is_global(area));
return round_fl_to_int(area->global->size_min * UI_DPI_FAC);
}
int ED_area_global_max_size_y(const ScrArea *area)
{
BLI_assert(ED_area_is_global(area));
return round_fl_to_int(area->global->size_max * UI_DPI_FAC);
}
bool ED_area_is_global(const ScrArea *area)
{

View File

@ -718,7 +718,7 @@ static void screen_vertices_scale(
/* adjust headery if verts are along the edge of window */
if (sa->v1->vec.y > window_rect->ymin)
headery += U.pixelsize;
if (sa->v2->vec.y < window_rect->ymax)
if (sa->v2->vec.y < (window_rect->ymax - 1))
headery += U.pixelsize;
if (area_geometry_height(sa) < headery) {
@ -744,21 +744,32 @@ static void screen_vertices_scale(
/* Global areas have a fixed size that only changes with the DPI. Here we ensure that exactly this size is set. */
for (ScrArea *area = win->global_areas.areabase.first; area; area = area->next) {
int height = ED_area_global_size_y(area) - 1;
if (area->global->flag & GLOBAL_AREA_IS_HIDDEN) {
continue;
}
if (area->v1->vec.y > window_rect->ymin) {
height += U.pixelsize;
}
if (area->v2->vec.y < (window_rect->ymax - 1)) {
height += U.pixelsize;
}
/* width */
area->v1->vec.x = area->v2->vec.x = window_rect->xmin;
area->v3->vec.x = area->v4->vec.x = window_rect->xmax - 1;
/* height */
area->v1->vec.y = area->v4->vec.y = window_rect->ymin;
area->v2->vec.y = area->v3->vec.y = window_rect->ymax - 1;
switch (area->global->align) {
case GLOBAL_AREA_ALIGN_TOP:
area->v1->vec.y = area->v4->vec.y = area->v2->vec.y - ED_area_global_size_y(area);
area->v1->vec.y = area->v4->vec.y = area->v2->vec.y - height;
break;
case GLOBAL_AREA_ALIGN_BOTTOM:
area->v2->vec.y = area->v3->vec.y = area->v1->vec.y + ED_area_global_size_y(area);
area->v2->vec.y = area->v3->vec.y = area->v1->vec.y + height;
break;
}
}

View File

@ -1235,8 +1235,8 @@ static void area_move_set_limits(
if (use_bigger_smaller_snap != NULL) {
*use_bigger_smaller_snap = false;
for (ScrArea *area = win->global_areas.areabase.first; area; area = area->next) {
const int size_min = round_fl_to_int(area->global->size_min * UI_DPI_FAC);
const int size_max = round_fl_to_int(area->global->size_max * UI_DPI_FAC);
const int size_min = ED_area_global_min_size_y(area) - 1;
const int size_max = ED_area_global_max_size_y(area) - 1;
/* logic here is only tested for lower edge :) */
/* left edge */

View File

@ -2013,22 +2013,37 @@ void WM_window_rect_calc(const wmWindow *win, rcti *r_rect)
*/
void WM_window_screen_rect_calc(const wmWindow *win, rcti *r_rect)
{
rcti rect;
rcti window_rect, screen_rect;
BLI_rcti_init(&rect, 0, WM_window_pixels_x(win), 0, WM_window_pixels_y(win));
WM_window_rect_calc(win, &window_rect);
screen_rect = window_rect;
/* Substract global areas from screen rectangle. */
for (ScrArea *global_area = win->global_areas.areabase.first; global_area; global_area = global_area->next) {
int height = ED_area_global_size_y(global_area) - 1;
if (global_area->global->flag & GLOBAL_AREA_IS_HIDDEN) {
continue;
}
switch (global_area->global->align) {
case GLOBAL_AREA_ALIGN_TOP:
rect.ymax -= ED_area_global_size_y(global_area);
if ((screen_rect.ymax - height) > window_rect.ymin) {
height += U.pixelsize;
}
if (screen_rect.ymax < (window_rect.ymax - 1)) {
height += U.pixelsize;
}
screen_rect.ymax -= height;
break;
case GLOBAL_AREA_ALIGN_BOTTOM:
rect.ymin += ED_area_global_size_y(global_area);
if (screen_rect.ymin > window_rect.ymin) {
height += U.pixelsize;
}
if ((screen_rect.ymin + height) < (window_rect.ymax - 1)) {
height += U.pixelsize;
}
screen_rect.ymin += height;
break;
default:
BLI_assert(0);
@ -2036,9 +2051,9 @@ void WM_window_screen_rect_calc(const wmWindow *win, rcti *r_rect)
}
}
BLI_assert(rect.xmin < rect.xmax);
BLI_assert(rect.ymin < rect.ymax);
*r_rect = rect;
BLI_assert(screen_rect.xmin < screen_rect.xmax);
BLI_assert(screen_rect.ymin < screen_rect.ymax);
*r_rect = screen_rect;
}
bool WM_window_is_fullscreen(wmWindow *win)