[Bf-blender-cvs] [7a9f64e6657] blender2.8: UI: better support for dynamically sized regions in topbar.

Brecht Van Lommel noreply at git.blender.org
Sun Apr 29 22:15:38 CEST 2018


Commit: 7a9f64e6657a231289f56b0a8c9949c8f7a23c59
Author: Brecht Van Lommel
Date:   Sun Apr 29 12:24:08 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB7a9f64e6657a231289f56b0a8c9949c8f7a23c59

UI: better support for dynamically sized regions in topbar.

Dynamically sized regions in the topbar were flickering due to only updating
their size after redraws. Now there is an optional layout() callback for
all regions in an area to do UI layout first, then refresh the region layout,
and then do the actual drawing for each region.

Task T54753

===================================================================

M	source/blender/blenkernel/BKE_screen.h
M	source/blender/editors/include/ED_screen.h
M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface.c
M	source/blender/editors/interface/interface_region_popup.c
M	source/blender/editors/screen/area.c
M	source/blender/editors/screen/screen_edit.c
M	source/blender/editors/space_topbar/space_topbar.c
M	source/blender/makesdna/DNA_screen_types.h
M	source/blender/windowmanager/intern/wm_draw.c

===================================================================

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
@@ -500,6 +500,27 @@ void ED_area_do_msg_notify_tag_refresh(
 	ED_area_tag_refresh(sa);
 }
 
+/* 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)
 {
@@ -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

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list