From 00ba93717141ce149e1708594bdb24b12a7653c3 Mon Sep 17 00:00:00 2001 From: Adel Gadllah Date: Thu, 20 Jan 2011 20:25:21 +0100 Subject: [PATCH] StScrollView: Implement real fade effect Implement an edge fade effect (top/bottom) using a ClutterOffscreenEffect subclass, replacing the former shadow hack. https://bugzilla.gnome.org/show_bug.cgi?id=639460 --- js/ui/appDisplay.js | 2 +- js/ui/messageTray.js | 2 +- js/ui/searchDisplay.js | 2 +- src/Makefile-st.am | 8 +- src/Makefile.am | 2 +- src/st/st-scroll-view-fade.c | 348 ++++++++++++++++++++++++ src/st/st-scroll-view-fade.h | 40 +++ src/st/st-scroll-view.c | 179 +++--------- src/st/st-scroll-view.h | 4 +- tests/interactive/scroll-view-sizing.js | 18 +- 10 files changed, 446 insertions(+), 159 deletions(-) create mode 100644 src/st/st-scroll-view-fade.c create mode 100644 src/st/st-scroll-view-fade.h diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js index 4b460fcc0..f1d44ebe7 100644 --- a/js/ui/appDisplay.js +++ b/js/ui/appDisplay.js @@ -40,7 +40,7 @@ AlphabeticalView.prototype = { this.actor = new St.ScrollView({ x_fill: true, y_fill: false, y_align: St.Align.START, - vshadows: true }); + vfade: true }); this.actor.add_actor(box); this.actor.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC); }, diff --git a/js/ui/messageTray.js b/js/ui/messageTray.js index c158c037a..073b87acc 100644 --- a/js/ui/messageTray.js +++ b/js/ui/messageTray.js @@ -386,7 +386,7 @@ Notification.prototype = { this._scrollArea = new St.ScrollView({ name: 'notification-scrollview', vscrollbar_policy: Gtk.PolicyType.AUTOMATIC, hscrollbar_policy: Gtk.PolicyType.NEVER, - vshadows: true }); + vfade: true }); this.actor.add(this._scrollArea, { row: 1, col: 1 }); this._contentArea = new St.BoxLayout({ name: 'notification-body', diff --git a/js/ui/searchDisplay.js b/js/ui/searchDisplay.js index fe6c76072..f85eb6714 100644 --- a/js/ui/searchDisplay.js +++ b/js/ui/searchDisplay.js @@ -166,7 +166,7 @@ SearchResults.prototype = { let scrollView = new St.ScrollView({ x_fill: true, y_fill: false, - vshadows: true }); + vfade: true }); scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC); scrollView.add_actor(this._content); diff --git a/src/Makefile-st.am b/src/Makefile-st.am index 225ff5bc2..cb54ef4ba 100644 --- a/src/Makefile-st.am +++ b/src/Makefile-st.am @@ -159,11 +159,17 @@ st_source_c = \ st/st-widget.c \ $(NULL) +st_non_gir_sources = \ + st/st-scroll-view-fade.c \ + st/st-scroll-view-fade.h \ + $(NULL) + noinst_LTLIBRARIES += libst-1.0.la libst_1_0_la_LIBADD = -lm $(ST_LIBS) libst_1_0_la_SOURCES = \ - $(st_source_c) \ + $(st_source_c) \ + $(st_non_gir_sources) \ $(st_source_private_h) \ $(st_source_private_c) \ $(st_source_h) \ diff --git a/src/Makefile.am b/src/Makefile.am index f252e5bc1..5bfa8c764 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -262,7 +262,7 @@ St-1.0.gir: $(mutter) $(G_IR_SCANNER) libst-1.0.la Makefile --libtool="$(LIBTOOL)" \ --library=libst-1.0.la \ -DST_COMPILATION \ - $(filter-out %-private.h, $(addprefix $(srcdir)/,$(st_source_h))) \ + $(filter-out %-private.h $(st_non_gir_sources), $(addprefix $(srcdir)/,$(st_source_h))) \ $(addprefix $(srcdir)/,$(st_source_c)) \ $(srcdir)/st-enum-types.h \ $(st_cflags) \ diff --git a/src/st/st-scroll-view-fade.c b/src/st/st-scroll-view-fade.c new file mode 100644 index 000000000..050cea5a7 --- /dev/null +++ b/src/st/st-scroll-view-fade.c @@ -0,0 +1,348 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * st-scroll-view-fade.h: Edge fade effect for StScrollView + * + * Copyright 2010 Intel Corporation. + * Copyright 2011 Adel Gadllah + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU Lesser General Public License, + * version 2.1, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + * more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + + +#define ST_SCROLL_VIEW_FADE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ST_TYPE_SCROLL_VIEW_FADE, StScrollViewFadeClass)) +#define ST_IS_SCROLL_VIEW_FADE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ST_TYPE_SCROLL_VIEW_FADE)) +#define ST_SCROLL_VIEW_FADE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ST_TYPE_SCROLL_VIEW_FADE, StScrollViewFadeClass)) + +#include "st-scroll-view-fade.h" +#include "st-scroll-view.h" +#include "st-scroll-bar.h" +#include "st-scrollable.h" + +#include +#include + +typedef struct _StScrollViewFadeClass StScrollViewFadeClass; + +#define FADE_OFFSET 68.0f + +static const gchar *fade_glsl_shader = +"uniform sampler2D tex;\n" +"uniform float height;\n" +"uniform float width;\n" +"uniform float scrollbar_width;\n" +"uniform float offset_bottom;\n" +"uniform float offset_top;\n" +"\n" +"void main ()\n" +"{\n" +" vec4 color = cogl_color_in * texture2D (tex, vec2 (cogl_tex_coord_in[0].xy));\n" +" float y = height * cogl_tex_coord_in[0].y;\n" +" float x = width * cogl_tex_coord_in[0].x;\n" +" float ratio = 0.0;\n" +" float fade_bottom_start = height - offset_bottom;\n" +" \n" +" if (offset_top != 0.0 && y < offset_top && x < (width - scrollbar_width)) {\n" +" ratio = y / offset_top;\n" +" cogl_color_out = color * ratio;\n" +" }\n" +" else if (offset_bottom != 0.0 && y > fade_bottom_start && x < (width - scrollbar_width)) {\n" +" ratio = (height - y)/(height - fade_bottom_start);\n" +" cogl_color_out = color * ratio;\n" +" }\n" +" else { \n" +" cogl_color_out = color;\n" +" }\n" +"}\n"; + +struct _StScrollViewFade +{ + ClutterOffscreenEffect parent_instance; + + /* a back pointer to our actor, so that we can query it */ + ClutterActor *actor; + + CoglHandle shader; + CoglHandle program; + + gint tex_uniform; + gint height_uniform; + gint width_uniform; + gint scrollbar_width_uniform; + gint offset_top_uniform; + gint offset_bottom_uniform; + + StAdjustment *vadjustment; + + guint is_attached : 1; +}; + +struct _StScrollViewFadeClass +{ + ClutterOffscreenEffectClass parent_class; +}; + +G_DEFINE_TYPE (StScrollViewFade, + st_scroll_view_fade, + CLUTTER_TYPE_OFFSCREEN_EFFECT); + +static gboolean +st_scroll_view_fade_pre_paint (ClutterEffect *effect) +{ + StScrollViewFade *self = ST_SCROLL_VIEW_FADE (effect); + ClutterEffectClass *parent_class; + + if (self->shader == COGL_INVALID_HANDLE) + return FALSE; + + if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect))) + return FALSE; + + if (self->actor == NULL) + return FALSE; + + if (self->program == COGL_INVALID_HANDLE) + self->program = cogl_create_program (); + + if (!self->is_attached) + { + g_assert (self->shader != COGL_INVALID_HANDLE); + g_assert (self->program != COGL_INVALID_HANDLE); + + cogl_program_attach_shader (self->program, self->shader); + cogl_program_link (self->program); + + cogl_handle_unref (self->shader); + + self->is_attached = TRUE; + + self->tex_uniform = + cogl_program_get_uniform_location (self->program, "tex"); + self->height_uniform = + cogl_program_get_uniform_location (self->program, "height"); + self->width_uniform = + cogl_program_get_uniform_location (self->program, "width"); + self->scrollbar_width_uniform = + cogl_program_get_uniform_location (self->program, "scrollbar_width"); + self->offset_top_uniform = + cogl_program_get_uniform_location (self->program, "offset_top"); + self->offset_bottom_uniform = + cogl_program_get_uniform_location (self->program, "offset_bottom"); + } + + parent_class = CLUTTER_EFFECT_CLASS (st_scroll_view_fade_parent_class); + return parent_class->pre_paint (effect); +} + +static CoglHandle +st_scroll_view_fade_create_texture (ClutterOffscreenEffect *effect, + gfloat min_width, + gfloat min_height) +{ + return cogl_texture_new_with_size (min_width, + min_height, + COGL_TEXTURE_NO_SLICING, + COGL_PIXEL_FORMAT_RGBA_8888_PRE); +} + +static void +st_scroll_view_fade_paint_target (ClutterOffscreenEffect *effect) +{ + StScrollViewFade *self = ST_SCROLL_VIEW_FADE (effect); + ClutterOffscreenEffectClass *parent; + CoglHandle material; + + gdouble value, lower, upper, page_size; + ClutterActor *vscroll = st_scroll_view_get_vscroll_bar (ST_SCROLL_VIEW (self->actor)); + + if (self->program == COGL_INVALID_HANDLE) + goto out; + + st_adjustment_get_values (self->vadjustment, &value, &lower, &upper, NULL, NULL, &page_size); + + if (self->offset_top_uniform > -1) { + if (value > lower + 0.1) + cogl_program_set_uniform_1f (self->program, self->offset_top_uniform, FADE_OFFSET); + else + cogl_program_set_uniform_1f (self->program, self->offset_top_uniform, 0.0f); + } + + if (self->offset_bottom_uniform > -1) { + if (value < upper - page_size - 0.1) + cogl_program_set_uniform_1f (self->program, self->offset_bottom_uniform, FADE_OFFSET); + else + cogl_program_set_uniform_1f (self->program, self->offset_bottom_uniform, 0.0f); + } + + if (self->tex_uniform > -1) + cogl_program_set_uniform_1i (self->program, self->tex_uniform, 0); + if (self->height_uniform > -1) + cogl_program_set_uniform_1f (self->program, self->height_uniform, clutter_actor_get_height (self->actor)); + if (self->width_uniform > -1) + cogl_program_set_uniform_1f (self->program, self->width_uniform, clutter_actor_get_width (self->actor)); + if (self->scrollbar_width_uniform > -1) + cogl_program_set_uniform_1f (self->program, self->scrollbar_width_uniform, clutter_actor_get_width (vscroll)); + + material = clutter_offscreen_effect_get_target (effect); + cogl_material_set_user_program (material, self->program); + +out: + parent = CLUTTER_OFFSCREEN_EFFECT_CLASS (st_scroll_view_fade_parent_class); + parent->paint_target (effect); +} + +static void +on_vadjustment_changed (StAdjustment *adjustment, + ClutterEffect *effect) +{ + gdouble value, lower, upper, page_size; + gboolean needs_fade; + + st_adjustment_get_values (adjustment, &value, &lower, &upper, NULL, NULL, &page_size); + needs_fade = (value > lower + 0.1) || (value < upper - page_size - 0.1); + + clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (effect), needs_fade); +} + +static void +st_scroll_view_fade_set_actor (ClutterActorMeta *meta, + ClutterActor *actor) +{ + StScrollViewFade *self = ST_SCROLL_VIEW_FADE (meta); + ClutterActorMetaClass *parent; + + g_return_if_fail (actor == NULL || ST_IS_SCROLL_VIEW (actor)); + + if (self->shader == COGL_INVALID_HANDLE) + { + clutter_actor_meta_set_enabled (meta, FALSE); + return; + } + + if (self->vadjustment) + { + g_signal_handlers_disconnect_by_func (self->vadjustment, + (gpointer)on_vadjustment_changed, + self); + self->vadjustment = NULL; + } + + if (actor) + { + StScrollView *scroll_view = ST_SCROLL_VIEW (actor); + StScrollBar *vscroll = ST_SCROLL_BAR (st_scroll_view_get_vscroll_bar (scroll_view)); + self->vadjustment = ST_ADJUSTMENT (st_scroll_bar_get_adjustment (vscroll)); + + g_signal_connect (self->vadjustment, "changed", + G_CALLBACK (on_vadjustment_changed), + self); + + on_vadjustment_changed (self->vadjustment, CLUTTER_EFFECT (self)); + } + + parent = CLUTTER_ACTOR_META_CLASS (st_scroll_view_fade_parent_class); + parent->set_actor (meta, actor); + + /* we keep a back pointer here, to avoid going through the ActorMeta */ + self->actor = clutter_actor_meta_get_actor (meta); +} + +static void +st_scroll_view_fade_dispose (GObject *gobject) +{ + StScrollViewFade *self = ST_SCROLL_VIEW_FADE (gobject); + + if (self->program != COGL_INVALID_HANDLE) + { + cogl_handle_unref (self->program); + + self->program = COGL_INVALID_HANDLE; + self->shader = COGL_INVALID_HANDLE; + } + + if (self->vadjustment) + { + g_signal_handlers_disconnect_by_func (self->vadjustment, + (gpointer)on_vadjustment_changed, + self); + self->vadjustment = NULL; + } + + self->actor = NULL; + + G_OBJECT_CLASS (st_scroll_view_fade_parent_class)->dispose (gobject); +} + +static void +st_scroll_view_fade_class_init (StScrollViewFadeClass *klass) +{ + ClutterEffectClass *effect_class = CLUTTER_EFFECT_CLASS (klass); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + ClutterOffscreenEffectClass *offscreen_class; + ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); + + gobject_class->dispose = st_scroll_view_fade_dispose; + + meta_class->set_actor = st_scroll_view_fade_set_actor; + + effect_class->pre_paint = st_scroll_view_fade_pre_paint; + + offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); + offscreen_class->create_texture = st_scroll_view_fade_create_texture; + offscreen_class->paint_target = st_scroll_view_fade_paint_target; +} + + +static void +st_scroll_view_fade_init (StScrollViewFade *self) +{ + static CoglHandle shader = COGL_INVALID_HANDLE; + + if (shader == COGL_INVALID_HANDLE) + { + if (clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL)) + { + shader = cogl_create_shader (COGL_SHADER_TYPE_FRAGMENT); + cogl_shader_source (shader, fade_glsl_shader); + cogl_shader_compile (shader); + if (!cogl_shader_is_compiled (shader)) + { + gchar *log_buf = cogl_shader_get_info_log (shader); + + g_warning (G_STRLOC ": Unable to compile the fade shader: %s", + log_buf); + g_free (log_buf); + + cogl_handle_unref (shader); + shader = COGL_INVALID_HANDLE; + } + } + } + + self->shader = shader; + self->is_attached = FALSE; + self->tex_uniform = -1; + self->height_uniform = -1; + self->width_uniform = -1; + self->scrollbar_width_uniform = -1; + self->offset_top_uniform = -1; + self->offset_bottom_uniform = -1; + + if (shader != COGL_INVALID_HANDLE) + cogl_handle_ref (self->shader); +} + +ClutterEffect * +st_scroll_view_fade_new (void) +{ + return g_object_new (ST_TYPE_SCROLL_VIEW_FADE, NULL); +} diff --git a/src/st/st-scroll-view-fade.h b/src/st/st-scroll-view-fade.h new file mode 100644 index 000000000..f8ec2d5a2 --- /dev/null +++ b/src/st/st-scroll-view-fade.h @@ -0,0 +1,40 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * st-scroll-view-fade.h: Edge fade effect for StScrollView + * + * Copyright 2010 Intel Corporation. + * Copyright 2011 Adel Gadllah + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU Lesser General Public License, + * version 2.1, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + * more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef __ST_SCROLL_VIEW_FADE_H__ +#define __ST_SCROLL_VIEW_FADE_H__ + +#include + +G_BEGIN_DECLS + +#define ST_TYPE_SCROLL_VIEW_FADE (st_scroll_view_fade_get_type ()) +#define ST_SCROLL_VIEW_FADE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ST_TYPE_SCROLL_VIEW_FADE, StScrollViewFade)) +#define ST_IS_SCROLL_VIEW_FADE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ST_TYPE_SCROLL_VIEW_FADE)) + +typedef struct _StScrollViewFade StScrollViewFade; + +GType st_scroll_view_fade_get_type (void) G_GNUC_CONST; + +ClutterEffect *st_scroll_view_fade_new (void); + +G_END_DECLS + +#endif /* __ST_SCROLL_VIEW_FADE_H__ */ diff --git a/src/st/st-scroll-view.c b/src/st/st-scroll-view.c index 14df6005b..c56182e11 100644 --- a/src/st/st-scroll-view.c +++ b/src/st/st-scroll-view.c @@ -62,6 +62,7 @@ #include "st-marshal.h" #include "st-scroll-bar.h" #include "st-scrollable.h" +#include "st-scroll-view-fade.h" #include #include @@ -93,20 +94,17 @@ struct _StScrollViewPrivate GtkPolicyType hscrollbar_policy; GtkPolicyType vscrollbar_policy; - ClutterActor *top_shadow; - ClutterActor *bottom_shadow; - gfloat row_size; gfloat column_size; - gboolean vshadows; + gboolean vfade; + StScrollViewFade *vfade_effect; + gboolean row_size_set : 1; gboolean column_size_set : 1; guint mouse_scroll : 1; guint hscrollbar_visible : 1; guint vscrollbar_visible : 1; - guint top_shadow_visible : 1; - guint bottom_shadow_visible : 1; }; enum { @@ -117,7 +115,7 @@ enum { PROP_HSCROLLBAR_POLICY, PROP_VSCROLLBAR_POLICY, PROP_MOUSE_SCROLL, - PROP_VSHADOWS + PROP_VFADE }; static void @@ -145,80 +143,50 @@ st_scroll_view_get_property (GObject *object, case PROP_MOUSE_SCROLL: g_value_set_boolean (value, priv->mouse_scroll); break; - case PROP_VSHADOWS: - g_value_set_boolean (value, priv->vshadows); + case PROP_VFADE: + g_value_set_boolean (value, priv->vfade); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } -static void -update_shadow_visibility (StScrollView *scroll) -{ - StScrollViewPrivate *priv = scroll->priv; - - if (priv->vshadows) - { - gdouble value, lower, upper, page_size; - - st_adjustment_get_values (priv->vadjustment, &value, &lower, &upper, NULL, NULL, &page_size); - - priv->top_shadow_visible = value > lower + 0.1; - priv->bottom_shadow_visible = value < upper - page_size - 0.1; - } - else - { - priv->top_shadow_visible = FALSE; - priv->bottom_shadow_visible = FALSE; - } -} - /** - * st_scroll_view_set_vshadows: + * st_scroll_view_set_vfade: * @self: a #StScrollView - * @vshadows: Whether to enable vertical shadows + * @vfade: Whether to enable the vertical fade effect * - * Sets whether to show shadows at the top and bottom of the area. Shadows - * are omitted when fully scrolled to that edge. + * Sets whether to fade the content at the top and bottom of the area when not + * fully scrolled to that edge. */ void -st_scroll_view_set_vshadows (StScrollView *self, - gboolean vshadows) +st_scroll_view_set_vfade (StScrollView *self, + gboolean vfade) { StScrollViewPrivate *priv = ST_SCROLL_VIEW (self)->priv; - vshadows = vshadows != FALSE; - if (priv->vshadows == vshadows) + vfade = vfade != FALSE; + if (priv->vfade == vfade) return; - priv->vshadows = vshadows; + priv->vfade = vfade; - if (vshadows) + if (vfade) { - if (priv->top_shadow) - { - clutter_actor_show (priv->top_shadow); - clutter_actor_show (priv->bottom_shadow); - } - else - { - priv->top_shadow = g_object_new (ST_TYPE_BIN, "style-class", "top-shadow", NULL); - priv->bottom_shadow = g_object_new (ST_TYPE_BIN, "style-class", "bottom-shadow", NULL); + if (priv->vfade_effect == NULL) + priv->vfade_effect = g_object_new (ST_TYPE_SCROLL_VIEW_FADE, NULL); - clutter_actor_set_parent (priv->bottom_shadow, CLUTTER_ACTOR (self)); - clutter_actor_set_parent (priv->top_shadow, CLUTTER_ACTOR (self)); - } + clutter_actor_add_effect (CLUTTER_ACTOR (self), CLUTTER_EFFECT (priv->vfade_effect)); } - else + else { - clutter_actor_hide (priv->top_shadow); - clutter_actor_hide (priv->bottom_shadow); + clutter_actor_remove_effect (CLUTTER_ACTOR (self), CLUTTER_EFFECT (priv->vfade_effect)); + priv->vfade_effect = NULL; } - update_shadow_visibility (self); + clutter_actor_queue_redraw (CLUTTER_ACTOR (self)); - g_object_notify (G_OBJECT (self), "vshadows"); + g_object_notify (G_OBJECT (self), "vfade"); } static void @@ -232,8 +200,8 @@ st_scroll_view_set_property (GObject *object, switch (property_id) { - case PROP_VSHADOWS: - st_scroll_view_set_vshadows (self, g_value_get_boolean (value)); + case PROP_VFADE: + st_scroll_view_set_vfade (self, g_value_get_boolean (value)); break; case PROP_MOUSE_SCROLL: st_scroll_view_set_mouse_scrolling (self, @@ -259,6 +227,12 @@ st_scroll_view_dispose (GObject *object) { StScrollViewPrivate *priv = ST_SCROLL_VIEW (object)->priv; + if (priv->vfade_effect) + { + clutter_actor_remove_effect (CLUTTER_ACTOR (object), CLUTTER_EFFECT (priv->vfade_effect)); + priv->vfade_effect = NULL; + } + if (priv->vscroll) clutter_actor_destroy (priv->vscroll); @@ -284,20 +258,6 @@ st_scroll_view_dispose (GObject *object) priv->vadjustment = NULL; } - /* since it's impossible to get a handle to these actors, we can - * just directly unparent them and not go through destroy/remove */ - if (priv->top_shadow) - { - clutter_actor_unparent (priv->top_shadow); - priv->top_shadow = NULL; - } - - if (priv->bottom_shadow) - { - clutter_actor_unparent (priv->bottom_shadow); - priv->bottom_shadow = NULL; - } - G_OBJECT_CLASS (st_scroll_view_parent_class)->dispose (object); } @@ -314,11 +274,6 @@ st_scroll_view_paint (ClutterActor *actor) clutter_actor_paint (priv->hscroll); if (priv->vscrollbar_visible && CLUTTER_ACTOR_IS_VISIBLE (priv->vscroll)) clutter_actor_paint (priv->vscroll); - - if (priv->top_shadow_visible) - clutter_actor_paint (priv->top_shadow); - if (priv->bottom_shadow_visible) - clutter_actor_paint (priv->bottom_shadow); } static void @@ -532,18 +487,6 @@ st_scroll_view_get_preferred_height (ClutterActor *actor, st_theme_node_adjust_preferred_height (theme_node, min_height_p, natural_height_p); } -static gfloat -get_shadow_height (ClutterActor *shadow) -{ - gfloat natural_height; - - /* The shadows are empty StBin and have no height-for-width behavior */ - - clutter_actor_get_preferred_height (shadow, -1, NULL, &natural_height); - - return natural_height; -} - static void st_scroll_view_allocate (ClutterActor *actor, const ClutterActorBox *box, @@ -688,25 +631,6 @@ st_scroll_view_allocate (ClutterActor *actor, if (priv->child) clutter_actor_allocate (priv->child, &child_box, flags); - /* Shadows */ - if (priv->top_shadow && CLUTTER_ACTOR_IS_VISIBLE (priv->top_shadow)) - { - child_box.x1 = content_box.x1; - child_box.y1 = content_box.y1; - child_box.x2 = MAX (child_box.x1, content_box.x2 - sb_width); - child_box.y2 = content_box.y1 + get_shadow_height (priv->top_shadow); - clutter_actor_allocate (priv->top_shadow, &child_box, flags); - } - - if (priv->bottom_shadow && CLUTTER_ACTOR_IS_VISIBLE (priv->bottom_shadow)) - { - child_box.x1 = content_box.x1; - child_box.y1 = content_box.y2 - sb_height - get_shadow_height (priv->bottom_shadow); - child_box.x2 = MAX (content_box.x1, content_box.x2 - sb_width); - child_box.y2 = content_box.y2 - sb_height; - clutter_actor_allocate (priv->bottom_shadow, &child_box, flags); - } - priv->hscrollbar_visible = hscrollbar_visible; priv->vscrollbar_visible = vscrollbar_visible; } @@ -719,12 +643,6 @@ st_scroll_view_style_changed (StWidget *widget) st_widget_style_changed (ST_WIDGET (priv->hscroll)); st_widget_style_changed (ST_WIDGET (priv->vscroll)); - if (priv->top_shadow) - { - st_widget_style_changed (ST_WIDGET (priv->top_shadow)); - st_widget_style_changed (ST_WIDGET (priv->bottom_shadow)); - } - ST_WIDGET_CLASS (st_scroll_view_parent_class)->style_changed (widget); } @@ -857,31 +775,16 @@ st_scroll_view_class_init (StScrollViewClass *klass) PROP_MOUSE_SCROLL, pspec); - pspec = g_param_spec_boolean ("vshadows", + pspec = g_param_spec_boolean ("vfade", "Vertical Shadows", - "Show shadows at the top and and bottom of the area unless fully scrolled to that edge", + "Fade the content at the top and and bottom of the area unless fully scrolled to that edge", FALSE, G_PARAM_READWRITE); g_object_class_install_property (object_class, - PROP_VSHADOWS, + PROP_VFADE, pspec); } -static void -child_adjustment_changed_cb (StAdjustment *adjustment, - StScrollView *scroll) -{ - update_shadow_visibility (scroll); -} - -static void -child_adjustment_notify_value (GObject *gobject, - GParamSpec *pspec, - StScrollView *scroll) -{ - update_shadow_visibility (scroll); -} - static void st_scroll_view_init (StScrollView *self) { @@ -897,10 +800,6 @@ st_scroll_view_init (StScrollView *self) NULL); priv->vadjustment = g_object_new (ST_TYPE_ADJUSTMENT, NULL); - g_signal_connect (priv->vadjustment, "changed", - G_CALLBACK (child_adjustment_changed_cb), self); - g_signal_connect (priv->vadjustment, "notify::value", - G_CALLBACK (child_adjustment_notify_value), self); priv->vscroll = g_object_new (ST_TYPE_SCROLL_BAR, "adjustment", priv->vadjustment, "vertical", TRUE, @@ -988,12 +887,6 @@ st_scroll_view_foreach_with_internals (ClutterContainer *container, if (priv->vscroll != NULL) callback (priv->vscroll, user_data); - - if (priv->top_shadow) - { - callback (priv->top_shadow, user_data); - callback (priv->bottom_shadow, user_data); - } } static void diff --git a/src/st/st-scroll-view.h b/src/st/st-scroll-view.h index ddb1ebb7d..f0a03fe9d 100644 --- a/src/st/st-scroll-view.h +++ b/src/st/st-scroll-view.h @@ -84,8 +84,8 @@ void st_scroll_view_set_policy (StScrollView *scroll, GtkPolicyType hscroll, GtkPolicyType vscroll); -void st_scroll_view_set_vshadows (StScrollView *self, - gboolean vshadows); +void st_scroll_view_set_vfade (StScrollView *self, + gboolean vfade); G_END_DECLS diff --git a/tests/interactive/scroll-view-sizing.js b/tests/interactive/scroll-view-sizing.js index c7c8c9541..4ea5b8a58 100644 --- a/tests/interactive/scroll-view-sizing.js +++ b/tests/interactive/scroll-view-sizing.js @@ -319,17 +319,17 @@ function togglePolicy(button) { hpolicy.connect('clicked', function() { togglePolicy(hpolicy); }); vpolicy.connect('clicked', function() { togglePolicy(vpolicy); }); -let shadowsBox = new St.BoxLayout({ vertical: false }); -mainBox.add(shadowsBox); +let fadeBox = new St.BoxLayout({ vertical: false }); +mainBox.add(fadeBox); spacer = new St.Bin(); -shadowsBox.add(spacer, { expand: true }); +fadeBox.add(spacer, { expand: true }); -shadowsBox.add(new St.Label({ text: 'Vertical Shadows: '})); -let vshadows = new St.Button({ label: 'No', style: 'text-decoration: underline; color: #4444ff;' }); -shadowsBox.add(vshadows); +fadeBox.add(new St.Label({ text: 'Vertical Fade: '})); +let vfade = new St.Button({ label: 'No', style: 'text-decoration: underline; color: #4444ff;' }); +fadeBox.add(vfade); -function toggleShadows(button) { +function toggleFade(button) { switch(button.label) { case 'No': button.label = 'Yes'; @@ -338,10 +338,10 @@ function toggleShadows(button) { button.label = 'No'; break; } - scrollView.set_vshadows(vshadows.label == 'Yes'); + scrollView.set_vfade(vfade.label == 'Yes'); } -vshadows.connect('clicked', function() { toggleShadows(vshadows); }); +vfade.connect('clicked', function() { toggleFade(vfade); }); stage.show(); Clutter.main();