[Bf-blender-cvs] [51efeb68345] blender2.8: UI: Hide & shrink scroll-bars based on cursor position

Julian Eisel noreply at git.blender.org
Mon May 7 11:45:39 CEST 2018


Commit: 51efeb683451d896531baac949de65043edff0b6
Author: Julian Eisel
Date:   Mon May 7 01:31:18 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB51efeb683451d896531baac949de65043edff0b6

UI: Hide & shrink scroll-bars based on cursor position

Scroll-bars are now hidden unless the cursor approaches them, in which case they
smoothly grow and become more & more visible. Note that since 0d309144020168e55,
scroll-bars are drawn on top of editor contents. There's no more jumping of
buttons when scroll-bars appear.

Technical notes:
* AZones are used to adjust scrollbars based on mouse movements

  We may want to support screen level AZones if we want scrollbars to also
  smoothly appear when approaching them from a different area.
  I also plan to make further changes to AZones to clean up stuff a bit.
* Had to move AZone handling to a post ARegion init stage, since we need the
  updated View2D data from there.
* View2D masks and scroller rectangles are now updated on every redraw. It's
  cheap to do that though.

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

M	source/blender/blenloader/intern/readfile.c
M	source/blender/editors/include/ED_screen_types.h
M	source/blender/editors/include/UI_view2d.h
M	source/blender/editors/interface/view2d.c
M	source/blender/editors/screen/area.c
M	source/blender/editors/screen/screen_ops.c
M	source/blender/makesdna/DNA_view2d_types.h

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

diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index a042e42775b..96e3f4704d9 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6382,6 +6382,8 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
 	ar->v2d.tab_num = 0;
 	ar->v2d.tab_cur = 0;
 	ar->v2d.sms = NULL;
+	ar->v2d.alpha_hor = ar->v2d.alpha_vert = 0;
+	ar->v2d.size_hor = ar->v2d.size_vert = 0;
 	BLI_listbase_clear(&ar->panels_category);
 	BLI_listbase_clear(&ar->handlers);
 	BLI_listbase_clear(&ar->uiblocks);
diff --git a/source/blender/editors/include/ED_screen_types.h b/source/blender/editors/include/ED_screen_types.h
index 1c41b14a874..0fed5eb03fd 100644
--- a/source/blender/editors/include/ED_screen_types.h
+++ b/source/blender/editors/include/ED_screen_types.h
@@ -83,13 +83,22 @@ typedef enum {
 	AE_BOTTOM_TO_TOPLEFT    /* Region located at the top, _bottom_ edge is action zone. Region minimized to the top left */
 } AZEdge;
 
+typedef enum {
+	AZ_SCROLL_VERT,
+	AZ_SCROLL_HOR,
+} AZScrollDirection;
+
 /* for editing areas/regions */
 typedef struct AZone {
 	struct AZone *next, *prev;
 	ARegion *ar;
 	int type;
-	/* region-azone, which of the edges (only for AZONE_REGION) */
-	AZEdge edge;
+
+	union {
+		/* region-azone, which of the edges (only for AZONE_REGION) */
+		AZEdge edge;
+		AZScrollDirection direction;
+	};
 	/* for draw */
 	short x1, y1, x2, y2;
 	/* for clip */
@@ -99,8 +108,15 @@ typedef struct AZone {
 } AZone;
 
 /* actionzone type */
-#define AZONE_AREA      1  /* corner widgets for splitting areas */
-#define AZONE_REGION    2  /* when a region is collapsed, draw a handle to expose */
-#define AZONE_FULLSCREEN 3 /* when in editor fullscreen draw a corner to go to normal mode */
+enum {
+	/* corner widgets for splitting areas */
+	AZONE_AREA = 1,
+	/* when a region is collapsed, draw a handle to expose */
+	AZONE_REGION,
+	/* when in editor fullscreen draw a corner to go to normal mode */
+	AZONE_FULLSCREEN,
+	/* Hotspot azone around scrollbars to show/hide them. */
+	AZONE_REGION_SCROLL,
+};
 
 #endif /* __ED_SCREEN_TYPES_H__ */
diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h
index a19b2f05e2e..1f106e3f08d 100644
--- a/source/blender/editors/include/UI_view2d.h
+++ b/source/blender/editors/include/UI_view2d.h
@@ -103,6 +103,8 @@ enum eView2D_Gridlines {
 /* ------ Defines for Scrollers ----- */
 
 /* scroller area */
+#define V2D_SCROLL_HEIGHT_MIN  (0.25f * U.widget_unit)
+#define V2D_SCROLL_WIDTH_MIN   (0.25f * U.widget_unit)
 #define V2D_SCROLL_HEIGHT      (0.45f * U.widget_unit)
 #define V2D_SCROLL_WIDTH       (0.45f * U.widget_unit)
 /* For scrollers with scale markings (text written onto them) */
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index 8342387f956..2a687118eaa 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -152,10 +152,11 @@ static void view2d_masks(View2D *v2d, bool check_scrollers)
 	 *	- if they overlap, they must not occupy the corners (which are reserved for other widgets)
 	 */
 	if (scroll) {
-		const int scroll_width = (v2d->scroll & V2D_SCROLL_SCALE_VERTICAL) ?
-		                             V2D_SCROLL_WIDTH_TEXT : V2D_SCROLL_WIDTH;
-		const int scroll_height = (v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL) ?
-		                              V2D_SCROLL_HEIGHT_TEXT : V2D_SCROLL_HEIGHT;
+		int scroll_width  = (v2d->scroll & V2D_SCROLL_SCALE_VERTICAL) ?   V2D_SCROLL_WIDTH_TEXT  : v2d->size_vert;
+		int scroll_height = (v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL) ? V2D_SCROLL_HEIGHT_TEXT : v2d->size_hor;
+
+		CLAMP_MIN(scroll_width, V2D_SCROLL_WIDTH_MIN);
+		CLAMP_MIN(scroll_height, V2D_SCROLL_HEIGHT_MIN);
 
 		/* vertical scroller */
 		if (scroll & V2D_SCROLL_LEFT) {
@@ -357,6 +358,11 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
 	/* set masks (always do), but leave scroller scheck to totrect_set */
 	view2d_masks(v2d, 0);
 	
+	if (do_init) {
+		/* Visible by default. */
+		v2d->alpha_hor = v2d->alpha_vert = 255;
+	}
+	
 	/* set 'tot' rect before setting cur? */
 	/* XXX confusing stuff here still - I made this function not check scroller hide - that happens in totrect_set */
 	if (tot_changed)
@@ -1641,6 +1647,9 @@ View2DScrollers *UI_view2d_scrollers_calc(
 	/* scrollers is allocated here... */
 	scrollers = MEM_callocN(sizeof(View2DScrollers), "View2DScrollers");
 	
+	/* Always update before drawing (for dynamically sized scrollers). */
+	view2d_masks(v2d, false);
+	
 	vert = v2d->vert;
 	hor = v2d->hor;
 	
@@ -1804,9 +1813,11 @@ static void scroll_printstr(Scene *scene, float x, float y, float val, int power
 /* Draw scrollbars in the given 2d-region */
 void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *vs)
 {
+	bTheme *btheme = UI_GetTheme();
 	Scene *scene = CTX_data_scene(C);
 	rcti vert, hor;
-	int scroll = view2d_scroll_mapped(v2d->scroll);
+	const int scroll = view2d_scroll_mapped(v2d->scroll);
+	const char emboss_alpha = btheme->tui.widget_emboss[3];
 	unsigned char scrollers_back_color[4];
 
 	/* Color for scrollbar backs */
@@ -1818,8 +1829,8 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
 	
 	/* horizontal scrollbar */
 	if (scroll & V2D_SCROLL_HORIZONTAL) {
-		bTheme *btheme = UI_GetTheme();
 		uiWidgetColors wcol = btheme->tui.wcol_scroll;
+		const float alpha_fac = v2d->alpha_hor / 255.0f;
 		rcti slider;
 		int state;
 		
@@ -1830,6 +1841,11 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
 		
 		state = (v2d->scroll_ui & V2D_SCROLL_H_ACTIVE) ? UI_SCROLL_PRESSED : 0;
 		
+		wcol.inner[3]   *= alpha_fac;
+		wcol.item[3]    *= alpha_fac;
+		wcol.outline[3] *= alpha_fac;
+		btheme->tui.widget_emboss[3] *= alpha_fac; /* will be reset later */
+		
 		/* show zoom handles if:
 		 *	- zooming on x-axis is allowed (no scroll otherwise)
 		 *	- slider bubble is large enough (no overdraw confusion)
@@ -1916,9 +1932,9 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
 	
 	/* vertical scrollbar */
 	if (scroll & V2D_SCROLL_VERTICAL) {
-		bTheme *btheme = UI_GetTheme();
 		uiWidgetColors wcol = btheme->tui.wcol_scroll;
 		rcti slider;
+		const float alpha_fac = v2d->alpha_vert / 255.0f;
 		int state;
 		
 		slider.xmin = vert.xmin;
@@ -1928,6 +1944,11 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
 		
 		state = (v2d->scroll_ui & V2D_SCROLL_V_ACTIVE) ? UI_SCROLL_PRESSED : 0;
 		
+		wcol.inner[3]   *= alpha_fac;
+		wcol.item[3]    *= alpha_fac;
+		wcol.outline[3] *= alpha_fac;
+		btheme->tui.widget_emboss[3] *= alpha_fac; /* will be reset later */
+		
 		/* show zoom handles if:
 		 *	- zooming on y-axis is allowed (no scroll otherwise)
 		 *	- slider bubble is large enough (no overdraw confusion)
@@ -1990,6 +2011,8 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
 		}
 	}
 	
+	/* Was changed above, so reset. */
+	btheme->tui.widget_emboss[3] = emboss_alpha;
 }
 
 /* free temporary memory used for drawing scrollers */
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 58dbebd2b75..e86655ab2cf 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -203,6 +203,24 @@ void ED_area_azones_update(ScrArea *sa, const int mouse_xy[2])
 				break;
 			}
 		}
+		else if (az->type == AZONE_REGION_SCROLL) {
+			/* only if mouse is not hovering the azone */
+			if (BLI_rcti_isect_pt_v(&az->rect, mouse_xy) == false) {
+				View2D *v2d = &az->ar->v2d;
+
+				if (az->direction == AZ_SCROLL_VERT) {
+					az->alpha = v2d->alpha_vert = 0;
+					changed = true;
+				}
+				else if (az->direction == AZ_SCROLL_HOR) {
+					az->alpha = v2d->alpha_hor = 0;
+					changed = true;
+				}
+				else {
+					BLI_assert(0);
+				}
+			}
+		}
 	}
 
 	if (changed) {
@@ -464,6 +482,12 @@ static void region_draw_azones(ScrArea *sa, ARegion *ar)
 					area_azone_tag_update(sa);
 				}
 			}
+			else if (az->type == AZONE_REGION_SCROLL) {
+				if (az->alpha != 0.0f) {
+					area_azone_tag_update(sa);
+				}
+				/* Don't draw this azone. */
+			}
 		}
 	}
 
@@ -1043,7 +1067,7 @@ static void region_azone_tria(ScrArea *sa, AZone *az, ARegion *ar)
 }	
 
 
-static void region_azone_initialize(ScrArea *sa, ARegion *ar, AZEdge edge, const bool is_fullscreen)
+static void region_azone_edge_initialize(ScrArea *sa, ARegion *ar, AZEdge edge, const bool is_fullscreen)
 {
 	AZone *az = NULL;
 	const bool is_hidden = (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) == 0;
@@ -1074,21 +1098,76 @@ static void region_azone_initialize(ScrArea *sa, ARegion *ar, AZEdge edge, const
 	
 }
 
+static void region_azone_scrollbar_initialize(ScrArea *sa, ARegion *ar, AZScrollDirection direction)
+{
+	rcti scroller_vert = (direction == AZ_SCROLL_VERT) ? ar->v2d.vert : ar->v2d.hor;
+	AZone *az = MEM_callocN(sizeof(*az), __func__);
+
+	BLI_addtail(&sa->actionzones, az);
+	az->type = AZONE_REGION_SCROLL;
+	az->ar = ar;
+	az->direction = direction;
+
+	if (direction == AZ_SCROLL_VERT) {
+		az->ar->v2d.alpha_vert = 0;
+	}
+	else if (direction == AZ_SCROLL_HOR) {
+		az->ar->v2d.alpha_hor = 0;
+	}
+
+	BLI_rcti_translate(&scroller_vert, ar->winrct.xmin, ar->winrct.ymin);
+	az->x1 = scroller_vert.xmin - AZONEFADEIN;
+	az->y1 = scroller_vert.ymin - AZONEFADEIN;
+	az->x2 = scroller_vert.xmax + AZONEFADEIN;
+	az->y2 = scroller_vert.ymax + AZONEFADEIN;
+
+	BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2);
+}
+
+static void region_azones_scrollbars_initialize(ScrArea *sa, ARegion *ar)
+{
+	const View2D *v2d = &ar->v2d;
+
+	if ((v2d->scroll & V2D_SCROLL_VERTICAL)   && ((v2d->scroll & V2D_SCROLL_SCALE_VERTICAL)   == 0)) {
+		region_azone_scrollbar_initialize(sa, ar, AZ_SCROLL_VERT);
+	}
+	if ((v2d->scroll & V2D_SCROLL_HORIZONTAL) && ((v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL) == 0)) {
+		region_azone_scrollbar_initialize(sa, ar, AZ_SCROLL_HOR);
+	}
+}
+
 
 /* *******************************

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list