From f568a68ee16ce7f59596bd1336f37eee1667b7a1 Mon Sep 17 00:00:00 2001 From: Elliot Smith Date: Wed, 11 Aug 2010 16:54:28 +0100 Subject: [PATCH] cookbook: Added walk through of code example for mouse scroll Modified the mouse scroll example to fit better with the tutorial walkthrough. Added a stepped walkthrough of the scrollable actor code example. --- doc/cookbook/events.xml | 224 +++++++++++++++++++- doc/cookbook/examples/events-mouse-scroll.c | 33 ++- 2 files changed, 243 insertions(+), 14 deletions(-) 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 actor While 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 <type>ClutterActor</type> + Mouse scrolling over a <type>ClutterActor</type> a 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 */