Add top and bottom shadows to app browser
Add a 'vshadow' property to StScrollView, which, when turned on, overlays gradient shadows on the top and bottom of the StScrollView. Turn this on for the StScrollView used for the app browser. https://bugzilla.gnome.org/show_bug.cgi?id=609604
This commit is contained in:
parent
d8800c095a
commit
fc39919856
@ -41,6 +41,22 @@ StScrollView
|
||||
scrollbar-height: 16px;
|
||||
}
|
||||
|
||||
StScrollView > .top-shadow
|
||||
{
|
||||
background-gradient-direction: vertical;
|
||||
background-gradient-start: rgba(0, 0, 0, 255);
|
||||
background-gradient-end: rgba(0, 0, 0, 0);
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
StScrollView > .bottom-shadow
|
||||
{
|
||||
background-gradient-direction: vertical;
|
||||
background-gradient-start: rgba(0, 0, 0, 0);
|
||||
background-gradient-end: rgba(0, 0, 0, 255);
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
StScrollBar {
|
||||
background-color: #080808;
|
||||
border: 1px solid #2d2d2d;
|
||||
|
@ -91,7 +91,10 @@ AllAppDisplay.prototype = {
|
||||
this.actor = new St.BoxLayout({ style_class: 'all-app', vertical: true });
|
||||
this.actor.hide();
|
||||
|
||||
let view = new St.ScrollView({ x_fill: true, y_fill: false, style_class: 'all-app-scroll-view' });
|
||||
let view = new St.ScrollView({ x_fill: true,
|
||||
y_fill: false,
|
||||
style_class: 'all-app-scroll-view',
|
||||
vshadows: true });
|
||||
this._scrollView = view;
|
||||
this.actor.add(bin);
|
||||
this.actor.add(view, { expand: true, y_fill: false, y_align: St.Align.START });
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "st-scroll-bar.h"
|
||||
#include "st-scrollable.h"
|
||||
#include <clutter/clutter.h>
|
||||
#include <math.h>
|
||||
|
||||
static void clutter_container_iface_init (ClutterContainerIface *iface);
|
||||
|
||||
@ -67,9 +68,13 @@ struct _StScrollViewPrivate
|
||||
GtkPolicyType hscroll_policy;
|
||||
GtkPolicyType vscroll_policy;
|
||||
|
||||
ClutterActor *top_shadow;
|
||||
ClutterActor *bottom_shadow;
|
||||
|
||||
gfloat row_size;
|
||||
gfloat column_size;
|
||||
|
||||
gboolean vshadows;
|
||||
gboolean row_size_set : 1;
|
||||
gboolean column_size_set : 1;
|
||||
guint mouse_scroll : 1;
|
||||
@ -82,7 +87,8 @@ enum {
|
||||
PROP_VSCROLL,
|
||||
PROP_HSCROLLBAR_POLICY,
|
||||
PROP_VSCROLLBAR_POLICY,
|
||||
PROP_MOUSE_SCROLL
|
||||
PROP_MOUSE_SCROLL,
|
||||
PROP_VSHADOWS
|
||||
};
|
||||
|
||||
static void
|
||||
@ -110,11 +116,67 @@ 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);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_shadow_visibility (GObject *gobject,
|
||||
GParamSpec *arg1,
|
||||
gpointer user_data)
|
||||
{
|
||||
StAdjustment *vadjust = ST_ADJUSTMENT (gobject);
|
||||
StScrollViewPrivate *priv = ST_SCROLL_VIEW (user_data)->priv;
|
||||
|
||||
gdouble value, lower, upper, page_size;
|
||||
|
||||
st_adjustment_get_values (vadjust, &value, &lower, &upper, NULL, NULL, &page_size);
|
||||
|
||||
if (fabs (value - lower) > 0.1 && priv->vshadows)
|
||||
clutter_actor_show (priv->top_shadow);
|
||||
else
|
||||
clutter_actor_hide (priv->top_shadow);
|
||||
|
||||
if (fabs (upper - value - page_size) > 0.1 && priv->vshadows)
|
||||
clutter_actor_show (priv->bottom_shadow);
|
||||
else
|
||||
clutter_actor_hide (priv->bottom_shadow);
|
||||
}
|
||||
|
||||
/**
|
||||
* st_scroll_view_set_vshadows:
|
||||
* @self: a #StScrollView
|
||||
* @vshadows: Whether to enable vertical shadows
|
||||
*
|
||||
* Sets whether to show shadows at the top and bottom of the area. Shadows
|
||||
* are omitted when fully scrolled to that edge.
|
||||
*/
|
||||
void
|
||||
st_scroll_view_set_vshadows (StScrollView *self,
|
||||
gboolean vshadows)
|
||||
{
|
||||
StAdjustment *vadjust;
|
||||
StScrollViewPrivate *priv = ST_SCROLL_VIEW (self)->priv;
|
||||
|
||||
vshadows = vshadows != FALSE;
|
||||
if (priv->vshadows == vshadows)
|
||||
return;
|
||||
|
||||
priv->vshadows = vshadows;
|
||||
|
||||
vadjust = st_scroll_bar_get_adjustment (ST_SCROLL_BAR(priv->vscroll));
|
||||
|
||||
if (!vadjust)
|
||||
return;
|
||||
|
||||
update_shadow_visibility (G_OBJECT (vadjust), NULL, self);
|
||||
g_object_notify (G_OBJECT (self), "vshadows");
|
||||
}
|
||||
|
||||
static void
|
||||
st_scroll_view_set_property (GObject *object,
|
||||
guint property_id,
|
||||
@ -126,6 +188,9 @@ st_scroll_view_set_property (GObject *object,
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_VSHADOWS:
|
||||
st_scroll_view_set_vshadows (self, g_value_get_boolean (value));
|
||||
break;
|
||||
case PROP_MOUSE_SCROLL:
|
||||
st_scroll_view_set_mouse_scrolling (self,
|
||||
g_value_get_boolean (value));
|
||||
@ -170,6 +235,11 @@ st_scroll_view_dispose (GObject *object)
|
||||
static void
|
||||
st_scroll_view_finalize (GObject *object)
|
||||
{
|
||||
StScrollViewPrivate *priv = ST_SCROLL_VIEW (object)->priv;
|
||||
|
||||
g_object_unref (priv->top_shadow);
|
||||
g_object_unref (priv->bottom_shadow);
|
||||
|
||||
G_OBJECT_CLASS (st_scroll_view_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@ -186,6 +256,11 @@ st_scroll_view_paint (ClutterActor *actor)
|
||||
clutter_actor_paint (priv->hscroll);
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (priv->vscroll))
|
||||
clutter_actor_paint (priv->vscroll);
|
||||
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (priv->top_shadow))
|
||||
clutter_actor_paint (priv->top_shadow);
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (priv->bottom_shadow))
|
||||
clutter_actor_paint (priv->bottom_shadow);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -202,6 +277,11 @@ st_scroll_view_pick (ClutterActor *actor,
|
||||
clutter_actor_paint (priv->hscroll);
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (priv->vscroll))
|
||||
clutter_actor_paint (priv->vscroll);
|
||||
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (priv->top_shadow))
|
||||
clutter_actor_paint (priv->top_shadow);
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (priv->bottom_shadow))
|
||||
clutter_actor_paint (priv->bottom_shadow);
|
||||
}
|
||||
|
||||
static double
|
||||
@ -372,6 +452,25 @@ st_scroll_view_allocate (ClutterActor *actor,
|
||||
|
||||
if (priv->child)
|
||||
clutter_actor_allocate (priv->child, &child_box, flags);
|
||||
|
||||
/*Shadows*/
|
||||
if (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 = MAX (child_box.y1, content_box.y1 + clutter_actor_get_height (priv->top_shadow));
|
||||
clutter_actor_allocate (priv->top_shadow, &child_box, flags);
|
||||
}
|
||||
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (priv->bottom_shadow))
|
||||
{
|
||||
child_box.x1 = content_box.x1;
|
||||
child_box.y1 = content_box.y2 - clutter_actor_get_height (priv->bottom_shadow);
|
||||
child_box.x2 = MAX (child_box.x1, content_box.x2 - sb_width);
|
||||
child_box.y2 = content_box.y2 + 1;
|
||||
clutter_actor_allocate (priv->bottom_shadow, &child_box, flags);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -382,6 +481,9 @@ st_scroll_view_style_changed (StWidget *widget)
|
||||
st_widget_style_changed (ST_WIDGET (priv->hscroll));
|
||||
st_widget_style_changed (ST_WIDGET (priv->vscroll));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -525,6 +627,14 @@ st_scroll_view_class_init (StScrollViewClass *klass)
|
||||
PROP_MOUSE_SCROLL,
|
||||
pspec);
|
||||
|
||||
pspec = g_param_spec_boolean ("vshadows",
|
||||
"Vertical Shadows",
|
||||
"Show shadows 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,
|
||||
pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -536,6 +646,9 @@ child_adjustment_changed_cb (StAdjustment *adjustment,
|
||||
|
||||
scroll = ST_SCROLL_VIEW (clutter_actor_get_parent (bar));
|
||||
|
||||
if (bar == scroll->priv->vscroll)
|
||||
update_shadow_visibility (G_OBJECT (adjustment), NULL, scroll);
|
||||
|
||||
/* Determine if this scroll-bar should be visible */
|
||||
st_adjustment_get_values (adjustment, NULL,
|
||||
&lower, &upper,
|
||||
@ -604,13 +717,16 @@ child_vadjustment_notify_cb (GObject *gobject,
|
||||
|
||||
vadjust = st_scroll_bar_get_adjustment (ST_SCROLL_BAR(priv->vscroll));
|
||||
if (vadjust)
|
||||
g_signal_handlers_disconnect_by_func (vadjust,
|
||||
child_adjustment_changed_cb,
|
||||
priv->vscroll);
|
||||
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (vadjust,
|
||||
update_shadow_visibility,
|
||||
user_data);
|
||||
g_signal_handlers_disconnect_by_func (vadjust,
|
||||
child_adjustment_changed_cb,
|
||||
priv->vscroll);
|
||||
}
|
||||
if (priv->vscroll_policy == GTK_POLICY_NEVER)
|
||||
return;
|
||||
|
||||
st_scrollable_get_adjustments (ST_SCROLLABLE(actor), NULL, &vadjust);
|
||||
if (vadjust)
|
||||
{
|
||||
@ -627,7 +743,10 @@ child_vadjustment_notify_cb (GObject *gobject,
|
||||
{
|
||||
g_signal_connect (vadjust, "changed", G_CALLBACK (
|
||||
child_adjustment_changed_cb), priv->vscroll);
|
||||
g_signal_connect (vadjust, "notify::value", G_CALLBACK (
|
||||
update_shadow_visibility), user_data);
|
||||
child_adjustment_changed_cb (vadjust, priv->vscroll);
|
||||
update_shadow_visibility (G_OBJECT (vadjust), NULL, user_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -646,6 +765,12 @@ st_scroll_view_init (StScrollView *self)
|
||||
clutter_actor_set_parent (priv->hscroll, CLUTTER_ACTOR (self));
|
||||
clutter_actor_set_parent (priv->vscroll, CLUTTER_ACTOR (self));
|
||||
|
||||
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);
|
||||
|
||||
clutter_actor_set_parent (priv->bottom_shadow, CLUTTER_ACTOR (self));
|
||||
clutter_actor_set_parent (priv->top_shadow, CLUTTER_ACTOR (self));
|
||||
|
||||
/* mouse scroll is enabled by default, so we also need to be reactive */
|
||||
priv->mouse_scroll = TRUE;
|
||||
g_object_set (G_OBJECT (self), "reactive", TRUE, NULL);
|
||||
@ -725,6 +850,9 @@ st_scroll_view_foreach_with_internals (ClutterContainer *container,
|
||||
|
||||
if (priv->vscroll != NULL)
|
||||
callback (priv->vscroll, user_data);
|
||||
|
||||
callback (priv->top_shadow, user_data);
|
||||
callback (priv->bottom_shadow, user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -88,6 +88,9 @@ void st_scroll_view_set_policy (StScrollView *scroll,
|
||||
GtkPolicyType hscroll,
|
||||
GtkPolicyType vscroll);
|
||||
|
||||
void st_scroll_view_set_vshadows (StScrollView *self,
|
||||
gboolean vshadows);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __ST_SCROLL_VIEW_H__ */
|
||||
|
Loading…
Reference in New Issue
Block a user