diff --git a/doc/cookbook/events.xml b/doc/cookbook/events.xml
index 9b8050042..64d6a26d0 100644
--- a/doc/cookbook/events.xml
+++ b/doc/cookbook/events.xml
@@ -435,15 +435,225 @@ _scroll_event_cb (ClutterActor *actor,
events may also be emitted.
- Creating a full scrollable actor
+ Creating a scrolling viewport for an actorWhile the simple outline above explains the basics
of how to connect to scroll events, it doesn't do much to
- help with really implementing a scrollable actor. That's what
- we'll do in this section. The full code for the example we'll
- walk through here is available
- in this later
- section.
+ help with really implementing scrolling
+ over an actor. That's what we'll do in this section.
+
+
+ The full code for the example we'll walk through here is
+ available in this later
+ section.
+
+
+ Scrolling over an actor actually requires coordination
+ between two components:
+
+
+
+
+ Scrollable actor
+ An actor which is too large to fit on the stage
+ or inside the area of the UI assigned to it (otherwise
+ there's no need to scroll over it...).
+
+
+
+
+ Viewport
+ This displays a cropped view of part of the scrollable
+ actor, revealing different parts of it as scroll events
+ occur.
+
+
+
+
+ Here are the steps required to set up the two actors:
+
+
+
+ Create the scrollable actor; it should be larger
+ than the scrollview. This example uses a ClutterTexture,
+ but any ClutterActor will work:
+
+
+/* get image file path, set up stage etc. */
+
+ClutterActor *texture;
+texture = clutter_texture_new ();
+clutter_texture_set_keep_aspect_ratio (CLUTTER_TEXTURE (texture),
+ TRUE);
+
+/*
+ * set the texture's height so it's as tall as the stage
+ * (STAGE_HEIGHT is define'd at the top of the file);
+ * see this recipe
+ * for more about loading images into textures
+ */
+clutter_actor_set_request_mode (texture, CLUTTER_REQUEST_WIDTH_FOR_HEIGHT);
+clutter_actor_set_height (texture, STAGE_HEIGHT);
+
+/* load the image file */
+clutter_texture_set_from_file (CLUTTER_TEXTURE (texture),
+ image_file_path,
+ NULL);
+
+
+
+
+
+
+ Create the viewport. The simplest way to do
+ this is with a ClutterGroup:
+
+
+
+
+
+
+
+ The key here is calling
+ clutter_actor_set_clip_to_allocation (viewport, TRUE).
+ This configures the viewport group so
+ that any of its children are clipped: i.e. only the area of
+ the children which fits inside the group is visible. This
+ in turn requires setting an explicit size on the group,
+ rather than allowing it to size itself to fit its
+ children (the default).
+
+
+
+
+ Put the scrollable actor into the scroll view and
+ the scroll view into its container (in this case,
+ the default stage):
+
+
+
+clutter_container_add_actor (CLUTTER_CONTAINER (viewport), texture);
+
+clutter_container_add_actor (CLUTTER_CONTAINER (stage), viewport);
+
+
+
+
+
+
+ Create a callback handler for scroll event signals
+ emitted by the viewport:
+
+
+
+
+
+
+
+ The approach taken here is to move the scrollable
+ actor up, relative to the viewport. Initially, the
+ scrollable will have a y coordinate value
+ of 0.0 (it is aligned to the top of the viewport).
+ Scrolling up subtracts from the
+ y coordinate (down to a minumum of
+ viewport_height - scrollable_height). This moves
+ the top of the scrollable "outside" the clip area of the
+ viewport; simultaneously, more of the bottom part of the
+ scrollable moves into the clip area, becoming visible.
+
+ Scrolling down adds to the y coordinate
+ (but only up to a maximum value of 0.0).
+
+
+
+ Connect the callback handler to the signal; note
+ that we pass the scrollable (the texture) to the callback,
+ as we're moving the texture inside the viewport to
+ create the scrolling effect:
+
+
+
+g_signal_connect (viewport,
+ "scroll-event",
+ G_CALLBACK (_scroll_event_cb),
+ texture);
+
+
+
+
+
+
@@ -451,7 +661,7 @@ _scroll_event_cb (ClutterActor *actor,
Full example
- Mouse scrolling over ClutterActor
+ Mouse scrolling over a ClutterActora code sample should be here... but isn't
diff --git a/doc/cookbook/examples/events-mouse-scroll.c b/doc/cookbook/examples/events-mouse-scroll.c
index 71d66d5a2..08980f939 100644
--- a/doc/cookbook/examples/events-mouse-scroll.c
+++ b/doc/cookbook/examples/events-mouse-scroll.c
@@ -4,8 +4,6 @@
#define STAGE_WIDTH STAGE_HEIGHT
#define SCROLL_AMOUNT STAGE_HEIGHT * 0.125
-static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
-
static gboolean
_scroll_event_cb (ClutterActor *viewport,
ClutterEvent *event,
@@ -13,6 +11,13 @@ _scroll_event_cb (ClutterActor *viewport,
{
ClutterActor *scrollable = CLUTTER_ACTOR (user_data);
+ gfloat viewport_height = clutter_actor_get_height (viewport);
+ gfloat scrollable_height = clutter_actor_get_height (scrollable);
+
+ /* no need to scroll if the scrollable is shorter than the viewport */
+ if (scrollable_height < viewport_height)
+ return TRUE;
+
gfloat y = clutter_actor_get_y (scrollable);
ClutterScrollDirection direction;
@@ -26,14 +31,23 @@ _scroll_event_cb (ClutterActor *viewport,
case CLUTTER_SCROLL_DOWN:
y += SCROLL_AMOUNT;
break;
+
+ /* we're only interested in up and down */
case CLUTTER_SCROLL_LEFT:
case CLUTTER_SCROLL_RIGHT:
break;
}
+ /*
+ * the CLAMP macro returns a value for the first argument
+ * that falls within the range specified by the second and
+ * third arguments
+ *
+ * we allow the scrollable's y position to be decremented to the point
+ * where its base is aligned with the base of the viewport
+ */
y = CLAMP (y,
- clutter_actor_get_height (viewport)
- - clutter_actor_get_height (scrollable),
+ viewport_height - scrollable_height,
0.0);
clutter_actor_animate (scrollable,
@@ -48,6 +62,13 @@ _scroll_event_cb (ClutterActor *viewport,
int
main (int argc, char *argv[])
{
+ gchar *image_file_path = TESTS_DATA_DIR "/redhand.png";
+
+ if (argc > 1)
+ {
+ image_file_path = argv[1];
+ }
+
ClutterActor *stage;
ClutterActor *viewport;
ClutterActor *texture;
@@ -56,8 +77,6 @@ main (int argc, char *argv[])
stage = clutter_stage_get_default ();
clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT);
- clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
/* the scrollable actor */
texture = clutter_texture_new ();
@@ -69,7 +88,7 @@ main (int argc, char *argv[])
clutter_actor_set_height (texture, STAGE_HEIGHT);
clutter_texture_set_from_file (CLUTTER_TEXTURE (texture),
- TESTS_DATA_DIR "/redhand.png",
+ image_file_path,
NULL);
/* the viewport which the box is scrolled within */