st/scroll-view: Make fade effect take ClutterMargin

Instead of taking just vertical/horizontal offsets, take a ClutterMargin
to allow us set the fade offsets on each direction specifically. Also,
handle negative values in margins, the fade effect will run in the negative
space left by the scrollview padding instead. Another difference now is
that areas outside the extents of the effect will be transparent, instead
of the effect ending abruptly past the given extents.

This will be used by the app grid, in order to selectively let see either
of next/prev pages while navigating.

While at it, fix code style issues in st_scroll_view_update_fade_effect(),
and clean up unused variables from the GLSL code.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1630>
This commit is contained in:
Carlos Garnacho 2021-02-03 12:07:34 +01:00 committed by Marge Bot
parent 8cb3825d48
commit f60a469a34
5 changed files with 89 additions and 105 deletions

View File

@ -264,7 +264,13 @@ var BaseAppView = GObject.registerClass({
return; return;
} }
this._scrollView.update_fade_effect(vOffset, hOffset); this._scrollView.update_fade_effect(
new Clutter.Margin({
left: hOffset,
right: hOffset,
top: vOffset,
bottom: vOffset,
}));
} }
_createGrid() { _createGrid() {

View File

@ -46,8 +46,7 @@ struct _StScrollViewFade
guint fade_edges : 1; guint fade_edges : 1;
float vfade_offset; ClutterMargin fade_margins;
float hfade_offset;
}; };
G_DEFINE_TYPE (StScrollViewFade, G_DEFINE_TYPE (StScrollViewFade,
@ -57,8 +56,7 @@ G_DEFINE_TYPE (StScrollViewFade,
enum { enum {
PROP_0, PROP_0,
PROP_VFADE_OFFSET, PROP_FADE_MARGINS,
PROP_HFADE_OFFSET,
PROP_FADE_EDGES, PROP_FADE_EDGES,
N_PROPS N_PROPS
@ -136,6 +134,15 @@ st_scroll_view_fade_paint_target (ClutterOffscreenEffect *effect,
if (h_scroll_visible) if (h_scroll_visible)
fade_area_bottomright[1] -= clutter_actor_get_height (hscroll); fade_area_bottomright[1] -= clutter_actor_get_height (hscroll);
if (self->fade_margins.left < 0)
fade_area_topleft[0] -= ABS (self->fade_margins.left);
if (self->fade_margins.right < 0)
fade_area_bottomright[0] += ABS (self->fade_margins.right);
if (self->fade_margins.top < 0)
fade_area_topleft[1] -= ABS (self->fade_margins.top);
if (self->fade_margins.bottom < 0)
fade_area_bottomright[1] += ABS (self->fade_margins.bottom);
st_adjustment_get_values (self->vadjustment, &value, &lower, &upper, NULL, NULL, &page_size); st_adjustment_get_values (self->vadjustment, &value, &lower, &upper, NULL, NULL, &page_size);
value = (value - lower) / (upper - page_size - lower); value = (value - lower) / (upper - page_size - lower);
clutter_shader_effect_set_uniform (shader, "fade_edges_top", G_TYPE_INT, 1, self->fade_edges ? value >= 0.0 : value > 0.0); clutter_shader_effect_set_uniform (shader, "fade_edges_top", G_TYPE_INT, 1, self->fade_edges ? value >= 0.0 : value > 0.0);
@ -146,8 +153,10 @@ st_scroll_view_fade_paint_target (ClutterOffscreenEffect *effect,
clutter_shader_effect_set_uniform (shader, "fade_edges_left", G_TYPE_INT, 1, self->fade_edges ? value >= 0.0 : value > 0.0); clutter_shader_effect_set_uniform (shader, "fade_edges_left", G_TYPE_INT, 1, self->fade_edges ? value >= 0.0 : value > 0.0);
clutter_shader_effect_set_uniform (shader, "fade_edges_right", G_TYPE_INT, 1, self->fade_edges ? value <= 1.0 : value < 1.0); clutter_shader_effect_set_uniform (shader, "fade_edges_right", G_TYPE_INT, 1, self->fade_edges ? value <= 1.0 : value < 1.0);
clutter_shader_effect_set_uniform (shader, "vfade_offset", G_TYPE_FLOAT, 1, self->vfade_offset); clutter_shader_effect_set_uniform (shader, "fade_offset_top", G_TYPE_FLOAT, 1, ABS (self->fade_margins.top));
clutter_shader_effect_set_uniform (shader, "hfade_offset", G_TYPE_FLOAT, 1, self->hfade_offset); clutter_shader_effect_set_uniform (shader, "fade_offset_bottom", G_TYPE_FLOAT, 1, ABS (self->fade_margins.bottom));
clutter_shader_effect_set_uniform (shader, "fade_offset_left", G_TYPE_FLOAT, 1, ABS (self->fade_margins.left));
clutter_shader_effect_set_uniform (shader, "fade_offset_right", G_TYPE_FLOAT, 1, ABS (self->fade_margins.right));
clutter_shader_effect_set_uniform (shader, "tex", G_TYPE_INT, 1, 0); clutter_shader_effect_set_uniform (shader, "tex", G_TYPE_INT, 1, 0);
clutter_shader_effect_set_uniform (shader, "height", G_TYPE_FLOAT, 1, clutter_actor_get_height (self->actor)); clutter_shader_effect_set_uniform (shader, "height", G_TYPE_FLOAT, 1, clutter_actor_get_height (self->actor));
clutter_shader_effect_set_uniform (shader, "width", G_TYPE_FLOAT, 1, clutter_actor_get_width (self->actor)); clutter_shader_effect_set_uniform (shader, "width", G_TYPE_FLOAT, 1, clutter_actor_get_width (self->actor));
@ -266,39 +275,21 @@ st_scroll_view_fade_dispose (GObject *gobject)
} }
static void static void
st_scroll_view_vfade_set_offset (StScrollViewFade *self, st_scroll_view_set_fade_margins (StScrollViewFade *self,
float fade_offset) ClutterMargin *fade_margins)
{ {
if (self->vfade_offset == fade_offset) if (self->fade_margins.left == fade_margins->left &&
self->fade_margins.right == fade_margins->right &&
self->fade_margins.top == fade_margins->top &&
self->fade_margins.bottom == fade_margins->bottom)
return; return;
g_object_freeze_notify (G_OBJECT (self)); self->fade_margins = *fade_margins;
self->vfade_offset = fade_offset;
if (self->actor != NULL) if (self->actor != NULL)
clutter_actor_queue_redraw (self->actor); clutter_actor_queue_redraw (self->actor);
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_VFADE_OFFSET]); g_object_notify_by_pspec (G_OBJECT (self), props[PROP_FADE_MARGINS]);
g_object_thaw_notify (G_OBJECT (self));
}
static void
st_scroll_view_hfade_set_offset (StScrollViewFade *self,
float fade_offset)
{
if (self->hfade_offset == fade_offset)
return;
g_object_freeze_notify (G_OBJECT (self));
self->hfade_offset = fade_offset;
if (self->actor != NULL)
clutter_actor_queue_redraw (self->actor);
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_HFADE_OFFSET]);
g_object_thaw_notify (G_OBJECT (self));
} }
static void static void
@ -329,11 +320,8 @@ st_scroll_view_fade_set_property (GObject *object,
switch (prop_id) switch (prop_id)
{ {
case PROP_VFADE_OFFSET: case PROP_FADE_MARGINS:
st_scroll_view_vfade_set_offset (self, g_value_get_float (value)); st_scroll_view_set_fade_margins (self, g_value_get_boxed (value));
break;
case PROP_HFADE_OFFSET:
st_scroll_view_hfade_set_offset (self, g_value_get_float (value));
break; break;
case PROP_FADE_EDGES: case PROP_FADE_EDGES:
st_scroll_view_fade_set_fade_edges (self, g_value_get_boolean (value)); st_scroll_view_fade_set_fade_edges (self, g_value_get_boolean (value));
@ -354,11 +342,8 @@ st_scroll_view_fade_get_property (GObject *object,
switch (prop_id) switch (prop_id)
{ {
case PROP_HFADE_OFFSET: case PROP_FADE_MARGINS:
g_value_set_float (value, self->hfade_offset); g_value_set_boxed (value, &self->fade_margins);
break;
case PROP_VFADE_OFFSET:
g_value_set_float (value, self->vfade_offset);
break; break;
case PROP_FADE_EDGES: case PROP_FADE_EDGES:
g_value_set_boolean (value, self->fade_edges); g_value_set_boolean (value, self->fade_edges);
@ -391,29 +376,15 @@ st_scroll_view_fade_class_init (StScrollViewFadeClass *klass)
offscreen_class->paint_target = st_scroll_view_fade_paint_target; offscreen_class->paint_target = st_scroll_view_fade_paint_target;
/** /**
* StScrollViewFade:vfade-offset: * StScrollViewFade:fade-margins:
* *
* The height of area which is faded at the top and bottom edges of the * The margins widths that are faded.
* #StScrollViewFade.
*/ */
props[PROP_VFADE_OFFSET] = props[PROP_FADE_MARGINS] =
g_param_spec_float ("vfade-offset", g_param_spec_boxed ("fade-margins",
"Vertical Fade Offset", "Fade margins",
"The height of the area which is faded at the edge", "The margin widths that are faded",
0.f, G_MAXFLOAT, DEFAULT_FADE_OFFSET, CLUTTER_TYPE_MARGIN,
ST_PARAM_READWRITE);
/**
* StScrollViewFade:hfade-offset:
*
* The height of area which is faded at the left and right edges of the
* #StScrollViewFade.
*/
props[PROP_HFADE_OFFSET] =
g_param_spec_float ("hfade-offset",
"Horizontal Fade Offset",
"The width of the area which is faded at the edge",
0.f, G_MAXFLOAT, DEFAULT_FADE_OFFSET,
ST_PARAM_READWRITE); ST_PARAM_READWRITE);
/** /**
@ -434,8 +405,12 @@ st_scroll_view_fade_class_init (StScrollViewFadeClass *klass)
static void static void
st_scroll_view_fade_init (StScrollViewFade *self) st_scroll_view_fade_init (StScrollViewFade *self)
{ {
self->vfade_offset = DEFAULT_FADE_OFFSET; self->fade_margins = (ClutterMargin) {
self->hfade_offset = DEFAULT_FADE_OFFSET; DEFAULT_FADE_OFFSET,
DEFAULT_FADE_OFFSET,
DEFAULT_FADE_OFFSET,
DEFAULT_FADE_OFFSET,
};
} }
/** /**

View File

@ -20,8 +20,10 @@
uniform sampler2D tex; uniform sampler2D tex;
uniform float height; uniform float height;
uniform float width; uniform float width;
uniform float vfade_offset; uniform float fade_offset_top;
uniform float hfade_offset; uniform float fade_offset_bottom;
uniform float fade_offset_left;
uniform float fade_offset_right;
uniform bool fade_edges_top; uniform bool fade_edges_top;
uniform bool fade_edges_right; uniform bool fade_edges_right;
uniform bool fade_edges_bottom; uniform bool fade_edges_bottom;
@ -37,23 +39,19 @@ void main ()
float y = height * cogl_tex_coord_in[0].y; float y = height * cogl_tex_coord_in[0].y;
float x = width * cogl_tex_coord_in[0].x; float x = width * cogl_tex_coord_in[0].x;
/*
* We cannot just return here due to a bug in llvmpipe see:
* https://bugzilla.freedesktop.org/show_bug.cgi?id=62357
*/
if (x > fade_area_topleft[0] && x < fade_area_bottomright[0] && if (x > fade_area_topleft[0] && x < fade_area_bottomright[0] &&
y > fade_area_topleft[1] && y < fade_area_bottomright[1]) { y > fade_area_topleft[1] && y < fade_area_bottomright[1])
{
float ratio = 1.0; float ratio = 1.0;
float fade_top_start = fade_area_topleft[1] + vfade_offset; float fade_top_start = fade_area_topleft[1] + fade_offset_top;
float fade_left_start = fade_area_topleft[0] + hfade_offset; float fade_left_start = fade_area_topleft[0] + fade_offset_left;
float fade_bottom_start = fade_area_bottomright[1] - vfade_offset; float fade_bottom_start = fade_area_bottomright[1] - fade_offset_bottom;
float fade_right_start = fade_area_bottomright[0] - hfade_offset; float fade_right_start = fade_area_bottomright[0] - fade_offset_right;
bool fade_top = y < vfade_offset && fade_edges_top; bool fade_top = y < fade_top_start && fade_edges_top;
bool fade_bottom = y > fade_bottom_start && fade_edges_bottom; bool fade_bottom = y > fade_bottom_start && fade_edges_bottom;
bool fade_left = x < fade_left_start && fade_edges_left; bool fade_left = x < fade_left_start && fade_edges_left;
bool fade_right = x > fade_right_start && fade_edges_right; bool fade_right = x > fade_right_start && fade_edges_right;
float vfade_scale = height / vfade_offset;
if (fade_top) { if (fade_top) {
ratio *= (fade_area_topleft[1] - y) / (fade_area_topleft[1] - fade_top_start); ratio *= (fade_area_topleft[1] - y) / (fade_area_topleft[1] - fade_top_start);
} }
@ -62,7 +60,6 @@ void main ()
ratio *= (fade_area_bottomright[1] - y) / (fade_area_bottomright[1] - fade_bottom_start); ratio *= (fade_area_bottomright[1] - y) / (fade_area_bottomright[1] - fade_bottom_start);
} }
float hfade_scale = width / hfade_offset;
if (fade_left) { if (fade_left) {
ratio *= (fade_area_topleft[0] - x) / (fade_area_topleft[0] - fade_left_start); ratio *= (fade_area_topleft[0] - x) / (fade_area_topleft[0] - fade_left_start);
} }
@ -72,5 +69,7 @@ void main ()
} }
cogl_color_out *= ratio; cogl_color_out *= ratio;
} else {
cogl_color_out *= 0;
} }
} }

View File

@ -164,23 +164,23 @@ st_scroll_view_get_property (GObject *object,
/** /**
* st_scroll_view_update_fade_effect: * st_scroll_view_update_fade_effect:
* @scroll: a #StScrollView * @scroll: a #StScrollView
* @vfade_offset: The length of the vertical fade effect, in pixels. * @fade_margins: a #ClutterMargin defining the vertical fade effects, in pixels.
* @hfade_offset: The length of the horizontal fade effect, in pixels.
* *
* Sets the height of the fade area area in pixels. A value of 0 * Sets the fade effects in all four edges of the view. A value of 0
* disables the effect. * disables the effect.
*/ */
void void
st_scroll_view_update_fade_effect (StScrollView *scroll, st_scroll_view_update_fade_effect (StScrollView *scroll,
float vfade_offset, ClutterMargin *fade_margins)
float hfade_offset)
{ {
StScrollViewPrivate *priv = ST_SCROLL_VIEW (scroll)->priv; StScrollViewPrivate *priv = ST_SCROLL_VIEW (scroll)->priv;
/* A fade amount of more than 0 enables the effect. */ /* A fade amount of other than 0 enables the effect. */
if (vfade_offset > 0. || hfade_offset > 0.) if (fade_margins->left != 0. || fade_margins->right != 0. ||
fade_margins->top != 0. || fade_margins->bottom != 0.)
{
if (priv->fade_effect == NULL)
{ {
if (priv->fade_effect == NULL) {
priv->fade_effect = g_object_new (ST_TYPE_SCROLL_VIEW_FADE, NULL); priv->fade_effect = g_object_new (ST_TYPE_SCROLL_VIEW_FADE, NULL);
clutter_actor_add_effect_with_name (CLUTTER_ACTOR (scroll), "fade", clutter_actor_add_effect_with_name (CLUTTER_ACTOR (scroll), "fade",
@ -188,16 +188,15 @@ st_scroll_view_update_fade_effect (StScrollView *scroll,
} }
g_object_set (priv->fade_effect, g_object_set (priv->fade_effect,
"vfade-offset", vfade_offset, "fade-margins", fade_margins,
NULL);
g_object_set (priv->fade_effect,
"hfade-offset", hfade_offset,
NULL); NULL);
} }
else else
{ {
if (priv->fade_effect != NULL) { if (priv->fade_effect != NULL)
clutter_actor_remove_effect (CLUTTER_ACTOR (scroll), CLUTTER_EFFECT (priv->fade_effect)); {
clutter_actor_remove_effect (CLUTTER_ACTOR (scroll),
CLUTTER_EFFECT (priv->fade_effect));
priv->fade_effect = NULL; priv->fade_effect = NULL;
} }
} }
@ -744,7 +743,13 @@ st_scroll_view_style_changed (StWidget *widget)
StThemeNode *theme_node = st_widget_get_theme_node (widget); StThemeNode *theme_node = st_widget_get_theme_node (widget);
gdouble vfade_offset = st_theme_node_get_length (theme_node, "-st-vfade-offset"); gdouble vfade_offset = st_theme_node_get_length (theme_node, "-st-vfade-offset");
gdouble hfade_offset = st_theme_node_get_length (theme_node, "-st-hfade-offset"); gdouble hfade_offset = st_theme_node_get_length (theme_node, "-st-hfade-offset");
st_scroll_view_update_fade_effect (self, vfade_offset, hfade_offset); st_scroll_view_update_fade_effect (self,
&(ClutterMargin) {
.top = vfade_offset,
.bottom = vfade_offset,
.left = hfade_offset,
.right = hfade_offset,
});
st_widget_style_changed (ST_WIDGET (priv->hscroll)); st_widget_style_changed (ST_WIDGET (priv->hscroll));
st_widget_style_changed (ST_WIDGET (priv->vscroll)); st_widget_style_changed (ST_WIDGET (priv->vscroll));

View File

@ -83,8 +83,7 @@ void st_scroll_view_set_policy (StScrollView *scroll,
StPolicyType hscroll, StPolicyType hscroll,
StPolicyType vscroll); StPolicyType vscroll);
void st_scroll_view_update_fade_effect (StScrollView *scroll, void st_scroll_view_update_fade_effect (StScrollView *scroll,
float vfade_offset, ClutterMargin *fade_margins);
float hfade_offset);
G_END_DECLS G_END_DECLS