diff --git a/doc/cookbook/Makefile.am b/doc/cookbook/Makefile.am index 15ce15a23..29512919a 100644 --- a/doc/cookbook/Makefile.am +++ b/doc/cookbook/Makefile.am @@ -41,6 +41,7 @@ IMAGE_FILES = \ images/textures-sub-texture.png \ images/layouts-stacking-diff-actor-sizes.png \ images/events-pointer-motion-stacking.png \ + images/layouts-bind-constraint-stage.png \ $(NULL) VIDEO_FILES = \ videos/animations-fading-out.ogv \ diff --git a/doc/cookbook/images/layouts-bind-constraint-stage.png b/doc/cookbook/images/layouts-bind-constraint-stage.png new file mode 100644 index 000000000..66d9d3690 Binary files /dev/null and b/doc/cookbook/images/layouts-bind-constraint-stage.png differ diff --git a/doc/cookbook/layouts.xml b/doc/cookbook/layouts.xml index 618f9dcf9..b96877fb3 100644 --- a/doc/cookbook/layouts.xml +++ b/doc/cookbook/layouts.xml @@ -587,4 +587,224 @@ clutter_actor_raise_top (text); +
+ Binding the size of one actor to the size of another + +
+ Problem + + You want one actor (the "target") to automatically change + its width or height (or both) when the size of another + actor (the "source") changes. + + Example use cases: + + + + Making an actor adjust itself to the size of the stage + (particularly when the stage is resizable). + + + Putting one actor on top of another and keeping their + sizes in sync. + + + +
+ +
+ Solution + + Create a ClutterBindConstraint bound to the + width and/or height of one actor (the "source"). Add that constraint + to an actor (the "target") whose size should follow the + size of the source. + + This short example shows how to create and add a constraint; + source and target can + be any two ClutterActors: + + + +ClutterConstraint *width_constraint; + +/* create a constraint which binds a target actor's width to 100px less than + * the width of the source actor (use CLUTTER_BIND_HEIGHT to create a + * constraint based on an actor's height) + * + * the third argument is a positive or negative offset from the actor's + * dimension, in pixels; this is added to the height or width of the source + * actor before the constraint is applied to the target actor + */ +width_constraint = clutter_bind_constraint_new (source, CLUTTER_BIND_WIDTH, -100); + +/* add the constraint to an actor */ +clutter_actor_add_constraint (target, width_constraint); + + + + Below is a full example, showing how to incorporate a + constraint into a Clutter application. + + + Constraining the size of a texture to + the size of the stage using <type>ClutterBindConstraint</type> + + + a code sample should be here... but isn't + + + + + The texture in this example is 100px smaller than the stage, + leaving a border of visible stage around the texture; and the texture + has a tiled image on it. The tiling changes as the texture changes + size. Also note that two ClutterAlignConstraints are + added to center the actor on the stage. + + The result looks like this: + + + + + + + + A texture bound to the height and width of the + stage using ClutterBindConstraint + + + + +
+ +
+ Discussion + + Sizing constraints are a good solution in these cases: + + + + Where you can't use a layout manager. For + example, you can't apply a layout manager to the stage + directly; so if you want to control the size of an actor + based on the size of the stage (as in + the example + above), constraints are a good substitute for a layout + manager . + + + + Where the layout of a UI is fairly simple (perhaps + up to half a dozen actors) and fairly static. An example + might be something like a text editor, where the arrangement + of the UI (menu bar, toolbar, editing panel, footer) changes + infrequently. Of course, it is possible to arrange top-level + components using constraints, but still use layout + managers inside individual components (e.g. a flow layout + manager to manage buttons in the toolbar). + + + + Where you have an actor whose size can change erratically, + but you still want to be able to track its size to control + another actor's size. An example might be an application like + a drawing program, where a user can create their own actors: + you might want the user to be able to describe loose, custom + constraints between actors like "keep these actors at the + same width", then allow those actors to be moved around and + resized in a free-form way as a group. In this situation, a + layout manager is too rigid and not appropriate; + but adding ClutterConstraints to actors + in response to user actions could work well. + + The sample + code in the appendix is the kind of thing you might include + in a drawing program: you can resize a texture with a key press + (+ to increase size, - to decrease), and + click on the actor to select/deselect it (a semi-transparent overlay is + toggled on the texture). The size of the overlay is bound and + aligned to the texture, so that it covers and slightly overlaps the + texture regardless of its size. + + + + + You can bind an actor to a single dimension (just height or + depth) of another actor: you don't have to bind both height + and width. Also, you don't have to bind both dimensions of the + target to the same source: for example, you could bind the target's + height to one source (actor A) and its width to another source + (actor B). + + A ClutterBindConstraint can also be used to + constrain a target actor's position on the x and + y axes to the position of a source actor. This is + covered in another recipe. + + +
+ Another way to bind actors' sizes together + + There is another way to control the size of a target + actor, based on the size of a source: you can create a handler + for the allocation-changed signal + of the source, emitted when its size and/or position + changes. This signal includes all the data + about the source's new allocation (height, width, x and y + coordindates), which the handler function can then use to + resize the target. + + Alternatively, if you're only interested in + a change to width or height, you can create a handler + for the notify::width or + notify::height signal (respectively), and modify + the target's width/height in the handler. + + This approach may be useful if you need a type of + control over alignment and size which is not possible using + constraints alone (e.g. one actor's size should be + a proportion of another's). See + the code in + this section for an example where the size + of one actor is dynamically set to 10% more than the + size of another. + + + This recipe + explains more about monitoring changes to an actor's size. + +
+ +
+ +
+ Full examples + + + Creating an automatically-resizing overlay for a + texture using <type>ClutterBindConstraint</type> + + + a code sample should be here... but isn't + + + + + + Using the <code>allocation-changed</code> + signal of one actor to trigger proportional size changes in + another + + + a code sample should be here... but isn't + + + + +
+ +
+