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
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_screen.h4
-rw-r--r--source/blender/editors/include/ED_screen.h4
-rw-r--r--source/blender/editors/include/UI_interface.h2
-rw-r--r--source/blender/editors/interface/interface.c63
-rw-r--r--source/blender/editors/interface/interface_region_popup.c2
-rw-r--r--source/blender/editors/screen/area.c107
-rw-r--r--source/blender/editors/screen/screen_edit.c33
-rw-r--r--source/blender/editors/space_topbar/space_topbar.c16
-rw-r--r--source/blender/makesdna/DNA_screen_types.h5
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c21
10 files changed, 153 insertions, 104 deletions
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 17cca92c1fc..36708cb11a4 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -140,8 +140,8 @@ typedef struct ARegionType {
void (*exit)(struct wmWindowManager *, struct ARegion *);
/* draw entirely, view changes should be handled here */
void (*draw)(const struct bContext *, struct ARegion *);
- /* optional, refresh popup before drawing */
- void (*refresh)(const struct bContext *, struct ARegion *);
+ /* optional, compute button layout before drawing for dynamic size */
+ void (*layout)(const struct bContext *, struct ARegion *);
/* snap the size of the region (can be NULL for no snapping). */
int (*snap_size)(const struct ARegion *ar, int size, int axis);
/* contextual changes should be handled here */
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index b5f1d947076..a1c429043cc 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -65,6 +65,7 @@ struct wmMsgSubscribeValue;
void ED_region_do_listen(
struct bScreen *sc, struct ScrArea *sa, struct ARegion *ar,
struct wmNotifier *note, const Scene *scene);
+void ED_region_do_layout(struct bContext *C, struct ARegion *ar);
void ED_region_do_draw(struct bContext *C, struct ARegion *ar);
void ED_region_exit(struct bContext *C, struct ARegion *ar);
void ED_region_pixelspace(struct ARegion *ar);
@@ -81,6 +82,8 @@ void ED_region_panels(
const bool vertical);
void ED_region_header_init(struct ARegion *ar);
void ED_region_header(const struct bContext *C, struct ARegion *ar);
+void ED_region_header_layout(const struct bContext *C, struct ARegion *ar);
+void ED_region_header_draw(const struct bContext *C, struct ARegion *ar);
void ED_region_cursor_set(struct wmWindow *win, struct ScrArea *sa, struct ARegion *ar);
void ED_region_toggle_hidden(struct bContext *C, struct ARegion *ar);
void ED_region_visibility_change_update(struct bContext *C, struct ARegion *ar);
@@ -135,6 +138,7 @@ int ED_area_headersize(void);
int ED_area_global_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);
ScrArea *ED_screen_areas_iter_first(const struct wmWindow *win, const bScreen *screen);
ScrArea *ED_screen_areas_iter_next(const bScreen *screen, const ScrArea *area);
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 7fd48ce081c..20c4552e6b2 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -475,6 +475,8 @@ uiBlock *UI_block_begin(const struct bContext *C, struct ARegion *region, const
void UI_block_end_ex(const struct bContext *C, uiBlock *block, const int xy[2], int r_xy[2]);
void UI_block_end(const struct bContext *C, uiBlock *block);
void UI_block_draw(const struct bContext *C, struct uiBlock *block);
+void UI_blocklist_update_window_matrix(const struct bContext *C, const struct ListBase *lb);
+void UI_blocklist_draw(const struct bContext *C, const struct ListBase *lb);
void UI_block_update_from_old(const struct bContext *C, struct uiBlock *block);
uiBlock *UI_block_find_in_region(const char *name, struct ARegion *ar);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index eb69ccef2e4..99387a47670 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -224,6 +224,26 @@ void ui_region_to_window(const ARegion *ar, int *x, int *y)
*y += ar->winrct.ymin;
}
+static void ui_update_window_matrix(const wmWindow *window, const ARegion *region, uiBlock *block)
+{
+ /* window matrix and aspect */
+ if (region && region->visible) {
+ /* Get projection matrix which includes View2D translation and zoom. */
+ gpuGetProjectionMatrix(block->winmat);
+ block->aspect = 2.0f / fabsf(region->winx * block->winmat[0][0]);
+ }
+ else {
+ /* No subwindow created yet, for menus for example, so we use the main
+ * window instead, since buttons are created there anyway. */
+ int width = WM_window_pixels_x(window);
+ int height = WM_window_pixels_y(window);
+ rcti winrct = {0, width - 1, 0, height - 1};
+
+ wmGetProjectionMatrix(block->winmat, &winrct);
+ block->aspect = 2.0f / fabsf(width * block->winmat[0][0]);
+ }
+}
+
/**
* Popups will add a margin to #ARegion.winrct for shadow,
* for interactivity (point-inside tests for eg), we want the winrct without the margin added.
@@ -2670,6 +2690,27 @@ void UI_block_free(const bContext *C, uiBlock *block)
MEM_freeN(block);
}
+void UI_blocklist_update_window_matrix(const bContext *C, const ListBase *lb)
+{
+ ARegion *region = CTX_wm_region(C);
+ wmWindow *window = CTX_wm_window(C);
+
+ for (uiBlock *block = lb->first; block; block = block->next) {
+ if (block->active) {
+ ui_update_window_matrix(window, region, block);
+ }
+ }
+}
+
+void UI_blocklist_draw(const bContext *C, const ListBase *lb)
+{
+ for (uiBlock *block = lb->first; block; block = block->next) {
+ if (block->active) {
+ UI_block_draw(C, block);
+ }
+ }
+}
+
/* can be called with C==NULL */
void UI_blocklist_free(const bContext *C, ListBase *lb)
{
@@ -2755,25 +2796,13 @@ uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, sh
if (region)
UI_block_region_set(block, region);
- /* window matrix and aspect */
- if (region && region->visible) {
- gpuGetProjectionMatrix(block->winmat);
+ /* Set window matrix and aspect for region and OpenGL state. */
+ ui_update_window_matrix(window, region, block);
- block->aspect = 2.0f / fabsf(region->winx * block->winmat[0][0]);
- }
- else {
- /* no subwindow created yet, for menus for example, so we
- * use the main window instead, since buttons are created
- * there anyway */
- int width = WM_window_pixels_x(window);
- int height = WM_window_pixels_y(window);
- rcti winrct = {0, width -1, 0, height - 1};
-
- wmGetProjectionMatrix(block->winmat, &winrct);
-
- block->aspect = 2.0f / fabsf(width * block->winmat[0][0]);
+ /* Tag as popup menu if not created within a region. */
+ if (!(region && region->visible)) {
block->auto_open = true;
- block->flag |= UI_BLOCK_LOOP; /* tag as menu */
+ block->flag |= UI_BLOCK_LOOP;
}
return block;
diff --git a/source/blender/editors/interface/interface_region_popup.c b/source/blender/editors/interface/interface_region_popup.c
index f397c62920b..4f8e9090a4a 100644
--- a/source/blender/editors/interface/interface_region_popup.c
+++ b/source/blender/editors/interface/interface_region_popup.c
@@ -682,7 +682,7 @@ uiPopupBlockHandle *ui_popup_block_create(
memset(&type, 0, sizeof(ARegionType));
type.draw = ui_block_region_draw;
- type.refresh = ui_block_region_refresh;
+ type.layout = ui_block_region_refresh;
type.regionid = RGN_TYPE_TEMPORARY;
ar->type = &type;
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 6e45b184478..5e68ad1218d 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -501,6 +501,27 @@ void ED_area_do_msg_notify_tag_refresh(
}
/* only exported for WM */
+void ED_region_do_layout(bContext *C, ARegion *ar)
+{
+ /* This is optional, only needed for dynamically sized regions. */
+ ScrArea *sa = CTX_wm_area(C);
+ ARegionType *at = ar->type;
+
+ if (!at->layout) {
+ return;
+ }
+
+ if (at->do_lock) {
+ return;
+ }
+
+ ar->do_draw |= RGN_DRAWING;
+
+ UI_SetTheme(sa ? sa->spacetype : 0, at->regionid);
+ at->layout(C, ar);
+}
+
+/* only exported for WM */
void ED_region_do_draw(bContext *C, ARegion *ar)
{
wmWindow *win = CTX_wm_window(C);
@@ -1187,9 +1208,8 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
if (ar->next == NULL && alignment != RGN_ALIGN_QSPLIT)
alignment = RGN_ALIGN_NONE;
- /* prefsize, for header we stick to exception (prevent dpi rounding error) */
- const float sizex_dpi_fac = (ar->flag & RGN_SIZEX_DPI_APPLIED) ? 1.0f : UI_DPI_FAC;
- prefsizex = sizex_dpi_fac * ((ar->sizex > 1) ? ar->sizex + 0.5f : ar->type->prefsizex);
+ /* prefsize, taking into account DPI */
+ prefsizex = UI_DPI_FAC * ((ar->sizex > 1) ? ar->sizex + 0.5f : ar->type->prefsizex);
if (ar->regiontype == RGN_TYPE_HEADER) {
prefsizey = ED_area_headersize();
@@ -1514,8 +1534,12 @@ static void ed_default_handlers(wmWindowManager *wm, ScrArea *sa, ListBase *hand
}
}
-void screen_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *area)
+void ED_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *area)
{
+ if (!(area->flag & AREA_FLAG_REGION_SIZE_UPDATE)) {
+ return;
+ }
+
const int size_x = WM_window_pixels_x(win);
const int size_y = WM_window_pixels_y(win);
rcti rect;
@@ -1898,6 +1922,23 @@ static ThemeColorID region_background_color_id(const bContext *C, const ARegion
}
}
+static void region_clear_color(const bContext *C, const ARegion *ar, ThemeColorID colorid)
+{
+ if (ar->overlap) {
+ /* view should be in pixelspace */
+ UI_view2d_view_restore(C);
+
+ float back[4];
+ UI_GetThemeColor4fv(colorid, back);
+ glClearColor(back[3] * back[0], back[3] * back[1], back[3] * back[2], back[3]);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+ else {
+ UI_ThemeClearColor(colorid);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+}
+
void ED_region_panels(const bContext *C, ARegion *ar, const char *context, int contextnr, const bool vertical)
{
const WorkSpace *workspace = CTX_wm_workspace(C);
@@ -2124,20 +2165,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, const char *context, int c
}
}
- /* clear */
- if (ar->overlap) {
- /* view should be in pixelspace */
- UI_view2d_view_restore(C);
-
- float back[4];
- UI_GetThemeColor4fv((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK, back);
- glClearColor(back[3] * back[0], back[3] * back[1], back[3] * back[2], back[3]);
- glClear(GL_COLOR_BUFFER_BIT);
- }
- else {
- UI_ThemeClearColor((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK);
- glClear(GL_COLOR_BUFFER_BIT);
- }
+ region_clear_color(C, ar, (ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK);
/* reset line width for drawing tabs */
glLineWidth(1.0f);
@@ -2171,7 +2199,7 @@ void ED_region_panels_init(wmWindowManager *wm, ARegion *ar)
WM_event_add_keymap_handler(&ar->handlers, keymap);
}
-void ED_region_header(const bContext *C, ARegion *ar)
+void ED_region_header_layout(const bContext *C, ARegion *ar)
{
uiStyle *style = UI_style_get_dpi();
uiBlock *block;
@@ -2183,10 +2211,6 @@ void ED_region_header(const bContext *C, ARegion *ar)
const int start_ofs = 0.4f * UI_UNIT_X;
bool region_layout_based = ar->flag & RGN_FLAG_DYNAMIC_SIZE;
- /* clear */
- UI_ThemeClearColor(region_background_color_id(C, ar));
- glClear(GL_COLOR_BUFFER_BIT);
-
/* set view2d view matrix for scrolling (without scrollers) */
UI_view2d_view_ortho(&ar->v2d);
@@ -2221,27 +2245,50 @@ void ED_region_header(const bContext *C, ARegion *ar)
if (xco > maxco)
maxco = xco;
- if (region_layout_based && (ar->sizex != (maxco + start_ofs))) {
+ int new_sizex = (maxco + start_ofs) / UI_DPI_FAC;
+
+ if (region_layout_based && (ar->sizex != new_sizex)) {
/* region size is layout based and needs to be updated */
ScrArea *sa = CTX_wm_area(C);
- ar->sizex = maxco + start_ofs;
- UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->sizex, ar->winy);
-
+ ar->sizex = new_sizex;
sa->flag |= AREA_FLAG_REGION_SIZE_UPDATE;
- ar->flag |= RGN_SIZEX_DPI_APPLIED;
}
+
UI_block_end(C, block);
- UI_block_draw(C, block);
}
/* always as last */
UI_view2d_totRect_set(&ar->v2d, maxco + (region_layout_based ? 0 : UI_UNIT_X + 80), headery);
- /* restore view matrix? */
+ /* restore view matrix */
+ UI_view2d_view_restore(C);
+}
+
+void ED_region_header_draw(const bContext *C, ARegion *ar)
+{
+ UI_view2d_view_ortho(&ar->v2d);
+
+ /* clear */
+ region_clear_color(C, ar, region_background_color_id(C, ar));
+
+ /* View2D matrix might have changed due to dynamic sized regions. */
+ UI_blocklist_update_window_matrix(C, &ar->uiblocks);
+
+ /* draw blocks */
+ UI_blocklist_draw(C, &ar->uiblocks);
+
+ /* restore view matrix */
UI_view2d_view_restore(C);
}
+void ED_region_header(const bContext *C, ARegion *ar)
+{
+ /* TODO: remove? */
+ ED_region_header_layout(C, ar);
+ ED_region_header_draw(C, ar);
+}
+
void ED_region_header_init(ARegion *ar)
{
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index c7d1605cbbf..1cadefadd5c 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -835,36 +835,6 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
screen->context = ed_screen_context;
}
-static bool screen_regions_need_size_refresh(
- const wmWindow *win, const bScreen *screen)
-{
- ED_screen_areas_iter(win, screen, area) {
- if (area->flag & AREA_FLAG_REGION_SIZE_UPDATE) {
- return true;
- }
- }
-
- return false;
-}
-
-static void screen_refresh_region_sizes_only(
- wmWindowManager *wm, wmWindow *win,
- bScreen *screen)
-{
- const int window_size_x = WM_window_pixels_x(win);
- const int window_size_y = WM_window_pixels_y(win);
- const int screen_size_x = WM_window_screen_pixels_x(win);
- const int screen_size_y = WM_window_screen_pixels_y(win);
-
- screen_vertices_scale(win, screen, window_size_x, window_size_y, screen_size_x, screen_size_y);
-
- ED_screen_areas_iter(win, screen, area) {
- screen_area_update_region_sizes(wm, win, area);
- /* XXX hack to force drawing */
- ED_area_tag_redraw(area);
- }
-}
-
/* file read, set all screens, ... */
void ED_screens_initialize(wmWindowManager *wm)
{
@@ -887,9 +857,6 @@ void ED_screen_ensure_updated(wmWindowManager *wm, wmWindow *win, bScreen *scree
if (screen->do_refresh) {
ED_screen_refresh(wm, win);
}
- else if (screen_regions_need_size_refresh(win, screen)) {
- screen_refresh_region_sizes_only(wm, win, screen);
- }
}
diff --git a/source/blender/editors/space_topbar/space_topbar.c b/source/blender/editors/space_topbar/space_topbar.c
index f2824b3bf70..fc76fd9c638 100644
--- a/source/blender/editors/space_topbar/space_topbar.c
+++ b/source/blender/editors/space_topbar/space_topbar.c
@@ -132,11 +132,6 @@ static void topbar_main_region_init(wmWindowManager *wm, ARegion *region)
WM_event_add_keymap_handler(&region->handlers, keymap);
}
-static void topbar_main_region_draw(const bContext *C, ARegion *region)
-{
- ED_region_header(C, region);
-}
-
static void topbar_operatortypes(void)
{
@@ -156,11 +151,6 @@ static void topbar_header_region_init(wmWindowManager *UNUSED(wm), ARegion *ar)
ED_region_header_init(ar);
}
-static void topbar_header_region_draw(const bContext *C, ARegion *ar)
-{
- ED_region_header(C, ar);
-}
-
static void topbar_main_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
wmNotifier *wmn, const Scene *UNUSED(scene))
{
@@ -263,7 +253,8 @@ void ED_spacetype_topbar(void)
art = MEM_callocN(sizeof(ARegionType), "spacetype topbar main region");
art->regionid = RGN_TYPE_WINDOW;
art->init = topbar_main_region_init;
- art->draw = topbar_main_region_draw;
+ art->layout = ED_region_header_layout;
+ art->draw = ED_region_header_draw;
art->listener = topbar_main_region_listener;
art->prefsizex = UI_UNIT_X * 5; /* Mainly to avoid glitches */
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_HEADER;
@@ -279,7 +270,8 @@ void ED_spacetype_topbar(void)
art->listener = topbar_header_listener;
art->message_subscribe = topbar_header_region_message_subscribe;
art->init = topbar_header_region_init;
- art->draw = topbar_header_region_draw;
+ art->layout = ED_region_header_layout;
+ art->draw = ED_region_header_draw;
BLI_addhead(&st->regiontypes, art);
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index 18986206b23..4274f348b2d 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -464,11 +464,6 @@ enum {
* just big enough to show all its content (if enough space is available).
* Note that only ED_region_header supports this right now. */
RGN_FLAG_DYNAMIC_SIZE = (1 << 2),
- /* The region width stored in ARegion.sizex already has the DPI
- * factor applied, skip applying it again (in region_rect_recursive).
- * XXX Not nice at all. Leaving for now as temporary solution, but
- * it might cause issues if we change how ARegion.sizex is used... */
- RGN_SIZEX_DPI_APPLIED = (1 << 3),
};
/* region do_draw */
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index f111bc3e2d1..685e6f7e216 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -489,12 +489,25 @@ GPUViewport *WM_draw_region_get_bound_viewport(ARegion *ar)
static void wm_draw_window_offscreen(bContext *C, wmWindow *win, bool stereo)
{
+ wmWindowManager *wm = CTX_wm_manager(C);
bScreen *screen = WM_window_get_active_screen(win);
/* Draw screen areas into own frame buffer. */
ED_screen_areas_iter(win, screen, sa) {
CTX_wm_area_set(C, sa);
+ /* Compute UI layouts for dynamically size regions. */
+ for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) {
+ if (ar->visible && ar->do_draw && ar->type && ar->type->layout) {
+ CTX_wm_region_set(C, ar);
+ ED_region_do_layout(C, ar);
+ CTX_wm_region_set(C, NULL);
+ }
+ }
+
+ ED_area_update_region_sizes(wm, win, sa);
+
+ /* Then do actual drawing of regions. */
for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) {
if (ar->visible && ar->do_draw) {
CTX_wm_region_set(C, ar);
@@ -539,11 +552,11 @@ static void wm_draw_window_offscreen(bContext *C, wmWindow *win, bool stereo)
if (ar->visible) {
CTX_wm_menu_set(C, ar);
- if (ar->type && ar->type->refresh) {
- /* UI code reads the OpenGL state, but we have to
- * refresh beforehand in case the menu size changes. */
+ if (ar->type && ar->type->layout) {
+ /* UI code reads the OpenGL state, but we have to refesh
+ * the UI layout beforehand in case the menu size changes. */
wmViewport(&ar->winrct);
- ar->type->refresh(C, ar);
+ ar->type->layout(C, ar);
}
wm_draw_region_buffer_create(ar, false, false);