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
diff options
context:
space:
mode:
authorJulian Eisel <eiseljulian@gmail.com>2018-05-07 02:31:18 +0300
committerJulian Eisel <eiseljulian@gmail.com>2018-05-07 12:42:12 +0300
commit51efeb683451d896531baac949de65043edff0b6 (patch)
treea36b7c037205b77a78a0b0266a7e9ca4571a0a5a /source/blender/editors/screen/area.c
parent4ec467d3b52744ba2aa4f938973efa27202b23ee (diff)
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.
Diffstat (limited to 'source/blender/editors/screen/area.c')
-rw-r--r--source/blender/editors/screen/area.c136
1 files changed, 98 insertions, 38 deletions
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);
+ }
+}
+
/* *************************************************************** */
-static void region_azone_add(ScrArea *sa, ARegion *ar, const int alignment, const bool is_fullscreen)
+static void region_azones_add(const bScreen *screen, ScrArea *sa, ARegion *ar, const int alignment)
{
+ const bool is_fullscreen = screen->state == SCREENFULL;
+
/* edge code (t b l r) is along which area edge azone will be drawn */
-
- if (alignment == RGN_ALIGN_TOP)
- region_azone_initialize(sa, ar, AE_BOTTOM_TO_TOPLEFT, is_fullscreen);
+
+ if (ar->regiontype == RGN_TYPE_HEADER && ar->winy + 6 > sa->winy) {
+ /* The logic for this is: when the header takes up the full area,
+ * disallow hiding it to view the main window.
+ *
+ * Without this, you can drag down the file selectors header and hide it
+ * by accident very easily (highly annoying!), the value 6 is arbitrary
+ * but accounts for small common rounding problems when scaling the UI,
+ * must be minimum '4' */
+ }
+ else if (alignment == RGN_ALIGN_TOP)
+ region_azone_edge_initialize(sa, ar, AE_BOTTOM_TO_TOPLEFT, is_fullscreen);
else if (alignment == RGN_ALIGN_BOTTOM)
- region_azone_initialize(sa, ar, AE_TOP_TO_BOTTOMRIGHT, is_fullscreen);
+ region_azone_edge_initialize(sa, ar, AE_TOP_TO_BOTTOMRIGHT, is_fullscreen);
else if (alignment == RGN_ALIGN_RIGHT)
- region_azone_initialize(sa, ar, AE_LEFT_TO_TOPRIGHT, is_fullscreen);
+ region_azone_edge_initialize(sa, ar, AE_LEFT_TO_TOPRIGHT, is_fullscreen);
else if (alignment == RGN_ALIGN_LEFT)
- region_azone_initialize(sa, ar, AE_RIGHT_TO_TOPLEFT, is_fullscreen);
+ region_azone_edge_initialize(sa, ar, AE_RIGHT_TO_TOPLEFT, is_fullscreen);
+
+ if (is_fullscreen) {
+ fullscreen_azone_initialize(sa, ar);
+ }
+
+ region_azones_scrollbars_initialize(sa, ar);
}
/* dir is direction to check, not the splitting edge direction! */
@@ -1193,7 +1272,7 @@ static bool region_is_overlap(ScrArea *sa, ARegion *ar)
return 0;
}
-static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti *remainder, rcti *overlap_remainder, int quad, bool add_azones)
+static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti *remainder, rcti *overlap_remainder, int quad)
{
rcti *remainder_prev = remainder;
int prefsizex, prefsizey;
@@ -1421,30 +1500,8 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
if (!ar->overlap) {
*overlap_remainder = *remainder;
}
-
- /* in end, add azones, where appropriate */
- if (ar->regiontype == RGN_TYPE_HEADER && ar->winy + 6 > sa->winy) {
- /* The logic for this is: when the header takes up the full area,
- * disallow hiding it to view the main window.
- *
- * Without this, you can drag down the file selectors header and hide it
- * by accident very easily (highly annoying!), the value 6 is arbitrary
- * but accounts for small common rounding problems when scaling the UI,
- * must be minimum '4' */
- }
- else if (add_azones) {
- const bScreen *screen = WM_window_get_active_screen(win);
- if (ELEM(screen->state, SCREENNORMAL, SCREENMAXIMIZED)) {
- region_azone_add(sa, ar, alignment, false);
- }
- else {
- region_azone_add(sa, ar, alignment, true);
- fullscreen_azone_initialize(sa, ar);
- }
- }
-
- region_rect_recursive(win, sa, ar->next, remainder, overlap_remainder, quad, add_azones);
+ region_rect_recursive(win, sa, ar->next, remainder, overlap_remainder, quad);
}
static void area_calc_totrct(ScrArea *sa, int window_size_x, int window_size_y)
@@ -1574,7 +1631,7 @@ void ED_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *ar
/* region rect sizes */
rect = area->totrct;
overlap_rect = rect;
- region_rect_recursive(win, area, area->regionbase.first, &rect, &overlap_rect, 0, false);
+ region_rect_recursive(win, area, area->regionbase.first, &rect, &overlap_rect, 0);
for (ARegion *ar = area->regionbase.first; ar; ar = ar->next) {
region_subwindow(ar);
@@ -1615,13 +1672,10 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
/* area sizes */
area_calc_totrct(sa, window_size_x, window_size_y);
- /* clear all azones, add the area triange widgets */
- area_azone_initialize(win, screen, sa);
-
/* region rect sizes */
rect = sa->totrct;
overlap_rect = rect;
- region_rect_recursive(win, sa, sa->regionbase.first, &rect, &overlap_rect, 0, true);
+ region_rect_recursive(win, sa, sa->regionbase.first, &rect, &overlap_rect, 0);
sa->flag &= ~AREA_FLAG_REGION_SIZE_UPDATE;
/* default area handlers */
@@ -1629,7 +1683,10 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
/* checks spacedata, adds own handlers */
if (sa->type->init)
sa->type->init(wm, sa);
-
+
+ /* clear all azones, add the area triange widgets */
+ area_azone_initialize(win, screen, sa);
+
/* region windows, default and own handlers */
for (ar = sa->regionbase.first; ar; ar = ar->next) {
region_subwindow(ar);
@@ -1646,6 +1703,9 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
/* prevent uiblocks to run */
UI_blocklist_free(NULL, &ar->uiblocks);
}
+
+ /* Some AZones use View2D data which is only updated in region init, so call that first! */
+ region_azones_add(screen, sa, ar, ar->alignment & ~RGN_SPLIT_PREV);
}
}