Fix T67265: Status bar is overlapped by workspace layout

The issue was that the screen geometry calculations scaled down the
areas, but the header would become too small. So it would be upscaled
again towards the lower screen edge (where the status-bar is at). Now we
do another pass over the geometry calculations, until all areas fit into
the screen, or until some rather arbitrary maximum is reached.

This fixes the issue for common cases. Extreme cases, with many
vertically stashed editors and a too small window to show all, are still
not too well supported. Blender keeps working but the status-bar is
still overlapped. We could deal with this better but what's there now
should be good enough.
This commit is contained in:
Julian Eisel 2020-09-05 17:57:00 +02:00
parent 7d8a252c17
commit 69377784f5
Notes: blender-bot 2023-02-14 05:53:42 +01:00
Referenced by issue #67265, UI: Header bar is overlaid
1 changed files with 41 additions and 17 deletions

View File

@ -147,23 +147,19 @@ ScrEdge *screen_geom_find_active_scredge(const wmWindow *win,
}
/**
* \brief Main screen-layout calculation function.
*
* * Scale areas nicely on window size and DPI changes.
* * Ensure areas have a minimum height.
* * Correctly set global areas to their fixed height.
* A single pass for moving all screen vertices to fit into \a screen_rect.
* \return true if another pass should be run.
*/
void screen_geom_vertices_scale(const wmWindow *win, bScreen *screen)
static bool screen_geom_vertices_scale_pass(const wmWindow *win,
const bScreen *screen,
const rcti *screen_rect)
{
rcti window_rect, screen_rect;
WM_window_rect_calc(win, &window_rect);
WM_window_screen_rect_calc(win, &screen_rect);
const int screen_size_x = BLI_rcti_size_x(&screen_rect);
const int screen_size_y = BLI_rcti_size_y(&screen_rect);
const int screen_size_x = BLI_rcti_size_x(screen_rect);
const int screen_size_y = BLI_rcti_size_y(screen_rect);
int screen_size_x_prev, screen_size_y_prev;
float min[2], max[2];
bool needs_another_pass = false;
/* calculate size */
min[0] = min[1] = 20000.0f;
@ -183,11 +179,11 @@ void screen_geom_vertices_scale(const wmWindow *win, bScreen *screen)
/* make sure it fits! */
LISTBASE_FOREACH (ScrVert *, sv, &screen->vertbase) {
sv->vec.x = screen_rect.xmin + round_fl_to_short((sv->vec.x - min[0]) * facx);
CLAMP(sv->vec.x, screen_rect.xmin, screen_rect.xmax - 1);
sv->vec.x = screen_rect->xmin + round_fl_to_short((sv->vec.x - min[0]) * facx);
CLAMP(sv->vec.x, screen_rect->xmin, screen_rect->xmax - 1);
sv->vec.y = screen_rect.ymin + round_fl_to_short((sv->vec.y - min[1]) * facy);
CLAMP(sv->vec.y, screen_rect.ymin, screen_rect.ymax - 1);
sv->vec.y = screen_rect->ymin + round_fl_to_short((sv->vec.y - min[1]) * facy);
CLAMP(sv->vec.y, screen_rect->ymin, screen_rect->ymax - 1);
}
/* test for collapsed areas. This could happen in some blender version... */
@ -198,7 +194,7 @@ void screen_geom_vertices_scale(const wmWindow *win, bScreen *screen)
if (facy > 1) {
/* Keep timeline small in video edit workspace. */
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
if (area->spacetype == SPACE_ACTION && area->v1->vec.y == screen_rect.ymin &&
if (area->spacetype == SPACE_ACTION && area->v1->vec.y == screen_rect->ymin &&
screen_geom_area_height(area) <= headery * facy + 1) {
ScrEdge *se = BKE_screen_find_edge(screen, area->v2, area->v3);
if (se) {
@ -212,6 +208,8 @@ void screen_geom_vertices_scale(const wmWindow *win, bScreen *screen)
if (sv != area->v1 && sv != area->v4) {
if (sv->flag) {
sv->vec.y = yval;
/* Changed size of a area. Run another pass to ensure everything still fits. */
needs_another_pass = true;
}
}
}
@ -236,6 +234,8 @@ void screen_geom_vertices_scale(const wmWindow *win, bScreen *screen)
if (sv != area->v2 && sv != area->v3) {
if (sv->flag) {
sv->vec.y = yval;
/* Changed size of a area. Run another pass to ensure everything still fits. */
needs_another_pass = true;
}
}
}
@ -245,6 +245,30 @@ void screen_geom_vertices_scale(const wmWindow *win, bScreen *screen)
}
}
return needs_another_pass;
}
/**
* \brief Main screen-layout calculation function.
*
* * Scale areas nicely on window size and DPI changes.
* * Ensure areas have a minimum height.
* * Correctly set global areas to their fixed height.
*/
void screen_geom_vertices_scale(const wmWindow *win, bScreen *screen)
{
rcti window_rect, screen_rect;
WM_window_rect_calc(win, &window_rect);
WM_window_screen_rect_calc(win, &screen_rect);
bool needs_another_pass;
int max_passes_left = 10; /* Avoids endless loop. Number is rather arbitrary. */
do {
needs_another_pass = screen_geom_vertices_scale_pass(win, screen, &screen_rect);
max_passes_left--;
} while (needs_another_pass && (max_passes_left > 0));
/* Global areas have a fixed size that only changes with the DPI.
* Here we ensure that exactly this size is set. */
LISTBASE_FOREACH (ScrArea *, area, &win->global_areas.areabase) {