2008-06-10 Emmanuele Bassi <ebassi@openedhand.com>
Bug #815 - Split up request, allocation, and paint box * clutter/clutter-actor.[ch]: Rework the size allocation, request and paint area. Now ::request_coords() is called ::allocate(), and ::query_coords() has been split into ::get_preferred_width() and ::get_preferred_height(). See the documentation and the layout test on how to implement a container and layout manager with the new API. (#915, based on a patch by Havoc Pennington, Lucas Rocha and Johan Bilien) * clutter/clutter-clone-texture.c: Port CloneTexture to the new size negotiation API; it just means forwarding the requests to the parent texture. * clutter/clutter-deprecated.h: Add deprecated and replaced API. * clutter/clutter-entry.c: Port Entry to the new size negotiation API. * clutter/clutter-group.c: Port Group to the new size negotiation API; the semantics of the Group actor do not change. * clutter/clutter-label.c: Port Label to the new size negotiation API, and vastly simplify the code. * clutter/clutter-main.[ch]: Add API for executing a relayout when needed. * clutter/clutter-private.h: Add new Stage private API. * clutter/clutter-rectangle.c: Update the get_abs_opacity() call to get_paint_opacity(). * clutter/clutter-stage.c: (clutter_stage_get_preferred_width), (clutter_stage_get_preferred_height), (clutter_stage_allocate), (clutter_stage_class_init): Port Stage to the new size negotiation API. * clutter/clutter-texture.c: Port Texture to the new size negotiation API. * clutter/clutter-types.h: Add ClutterRequestMode enumeration. * clutter/x11/clutter-stage-x11.c: Port the X11 stage implementation to the new size negotiation API. * tests/Makefile.am: Add the layout manager test case. * tests/test-opacity.c: Update. * tests/test-project.c: Update. * tests/test-layout.c: Test case for a layout manager implemented using the new size negotiation API; the layout manager handles both transformed and untransformed children.
This commit is contained in:
parent
fb613411c8
commit
473d0e9fc3
63
ChangeLog
63
ChangeLog
@ -1,3 +1,66 @@
|
||||
2008-06-10 Emmanuele Bassi <ebassi@openedhand.com>
|
||||
|
||||
Bug #815 - Split up request, allocation, and paint box
|
||||
|
||||
* clutter/clutter-actor.[ch]: Rework the size allocation,
|
||||
request and paint area. Now ::request_coords() is called
|
||||
::allocate(), and ::query_coords() has been split into
|
||||
::get_preferred_width() and ::get_preferred_height(). See
|
||||
the documentation and the layout test on how to implement
|
||||
a container and layout manager with the new API. (#915,
|
||||
based on a patch by Havoc Pennington, Lucas Rocha and Johan
|
||||
Bilien)
|
||||
|
||||
* clutter/clutter-clone-texture.c: Port CloneTexture to
|
||||
the new size negotiation API; it just means forwarding
|
||||
the requests to the parent texture.
|
||||
|
||||
* clutter/clutter-deprecated.h: Add deprecated and replaced
|
||||
API.
|
||||
|
||||
* clutter/clutter-entry.c: Port Entry to the new size
|
||||
negotiation API.
|
||||
|
||||
* clutter/clutter-group.c: Port Group to the new size
|
||||
negotiation API; the semantics of the Group actor do not
|
||||
change.
|
||||
|
||||
* clutter/clutter-label.c: Port Label to the new size
|
||||
negotiation API, and vastly simplify the code.
|
||||
|
||||
* clutter/clutter-main.[ch]: Add API for executing a
|
||||
relayout when needed.
|
||||
|
||||
* clutter/clutter-private.h: Add new Stage private API.
|
||||
|
||||
* clutter/clutter-rectangle.c: Update the get_abs_opacity()
|
||||
call to get_paint_opacity().
|
||||
|
||||
* clutter/clutter-stage.c:
|
||||
(clutter_stage_get_preferred_width),
|
||||
(clutter_stage_get_preferred_height),
|
||||
(clutter_stage_allocate),
|
||||
(clutter_stage_class_init): Port Stage to the new size
|
||||
negotiation API.
|
||||
|
||||
* clutter/clutter-texture.c: Port Texture to the new size
|
||||
negotiation API.
|
||||
|
||||
* clutter/clutter-types.h: Add ClutterRequestMode enumeration.
|
||||
|
||||
* clutter/x11/clutter-stage-x11.c: Port the X11 stage
|
||||
implementation to the new size negotiation API.
|
||||
|
||||
* tests/Makefile.am: Add the layout manager test case.
|
||||
|
||||
* tests/test-opacity.c: Update.
|
||||
|
||||
* tests/test-project.c: Update.
|
||||
|
||||
* tests/test-layout.c: Test case for a layout manager implemented
|
||||
using the new size negotiation API; the layout manager handles
|
||||
both transformed and untransformed children.
|
||||
|
||||
2008-06-10 Emmanuele Bassi <ebassi@openedhand.com>
|
||||
|
||||
* Makefile.am: Add the po/ directory to the build.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -157,13 +157,13 @@ struct _ClutterActor
|
||||
|
||||
/**
|
||||
* ClutterActorClass:
|
||||
* @show: signal class handler for ClutterActor::show; it must chain
|
||||
* @show: signal class handler for #ClutterActor::show; it must chain
|
||||
* up to the parent's implementation
|
||||
* @show_all: virtual function for containers and composite actors, to
|
||||
* determine which children should be shown when calling
|
||||
* clutter_actor_show_all() on the actor. Defaults to calling
|
||||
* clutter_actor_show().
|
||||
* @hide: signal class handler for ClutterActor::hide; it must chain
|
||||
* @hide: signal class handler for #ClutterActor::hide; it must chain
|
||||
* up to the parent's implementation
|
||||
* @hide_all: virtual function for containers and composite actors, to
|
||||
* determine which children should be shown when calling
|
||||
@ -172,31 +172,36 @@ struct _ClutterActor
|
||||
* @realize: virtual function, used to allocate resources for the actor;
|
||||
* it should chain up to the parent's implementation
|
||||
* @unrealize: virtual function, used to deallocate resources allocated
|
||||
* in ::realized; it should chain up to the parent's implementation
|
||||
* in ::realize; it should chain up to the parent's implementation
|
||||
* @paint: virtual function, used to paint the actor
|
||||
* @request_coords: virtual function, used when setting the coordinates
|
||||
* of an actor
|
||||
* @query_coords: virtual function, used when querying the actor for
|
||||
* its coordinates; it must chain up to the parent's implementation
|
||||
* @parent_set: signal class closure for the ClutterActor::parent-set
|
||||
* @destroy: signal class closure for ClutterActor::destroy
|
||||
* @get_preferred_width: virtual function, used when querying the minimum and
|
||||
* natural widths of an actor
|
||||
* @get_preferred_height: virtual function, used when querying the minimum and
|
||||
* natural heights of an actor
|
||||
* @allocate: virtual function, used when settings the coordinates of an
|
||||
* actor
|
||||
* @get_paint_area: virtual function, used when querying the untrasformed
|
||||
* bounding box of an actor; it's used internally by
|
||||
* clutter_actor_get_stage_area()
|
||||
* @parent_set: signal class closure for the #ClutterActor::parent-set
|
||||
* @destroy: signal class closure for #ClutterActor::destroy
|
||||
* @pick: virtual function, used to draw an outline of the actor with
|
||||
* the given colour
|
||||
* @event: signal class closure for ClutterActor::event
|
||||
* the given color
|
||||
* @event: signal class closure for #ClutterActor::event
|
||||
* @button_press_event: signal class closure for
|
||||
* ClutterActor::button-press-event
|
||||
* #ClutterActor::button-press-event
|
||||
* @button_release_event: signal class closure for
|
||||
* ClutterActor::button-release-event
|
||||
* @scroll_event: signal class closure for ClutterActor::scroll-event
|
||||
* @key_press_event: signal class closure for ClutterActor::key-press-event
|
||||
* #ClutterActor::button-release-event
|
||||
* @scroll_event: signal class closure for #ClutterActor::scroll-event
|
||||
* @key_press_event: signal class closure for #ClutterActor::key-press-event
|
||||
* @key_release_event: signal class closure for
|
||||
* ClutterActor::key-release-event
|
||||
* @motion_event: signal class closure for ClutterActor::motion-event
|
||||
* @enter_event: signal class closure for ClutterActor::enter-event
|
||||
* @leave_event: signal class closure for ClutterActor::leave-event
|
||||
* @captured_event: signal class closure for ClutterActor::captured-event
|
||||
* @focus_in: signal class closure for ClutterActor::focus-in
|
||||
* @focus_out: signal class closure for ClutterActor::focus-out
|
||||
* #ClutterActor::key-release-event
|
||||
* @motion_event: signal class closure for #ClutterActor::motion-event
|
||||
* @enter_event: signal class closure for #ClutterActor::enter-event
|
||||
* @leave_event: signal class closure for #ClutterActor::leave-event
|
||||
* @captured_event: signal class closure for #ClutterActor::captured-event
|
||||
* @focus_in: signal class closure for #ClutterActor::focus-in
|
||||
* @focus_out: signal class closure for #ClutterActor::focus-out
|
||||
*
|
||||
* Base class for actors.
|
||||
*/
|
||||
@ -206,23 +211,34 @@ struct _ClutterActorClass
|
||||
GInitiallyUnownedClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
void (* show) (ClutterActor *actor);
|
||||
void (* show_all) (ClutterActor *actor);
|
||||
void (* hide) (ClutterActor *actor);
|
||||
void (* hide_all) (ClutterActor *actor);
|
||||
void (* realize) (ClutterActor *actor);
|
||||
void (* unrealize) (ClutterActor *actor);
|
||||
void (* paint) (ClutterActor *actor);
|
||||
void (* request_coords) (ClutterActor *actor,
|
||||
ClutterActorBox *box);
|
||||
void (* query_coords) (ClutterActor *actor,
|
||||
ClutterActorBox *box);
|
||||
void (* parent_set) (ClutterActor *actor,
|
||||
ClutterActor *old_parent);
|
||||
void (* show) (ClutterActor *actor);
|
||||
void (* show_all) (ClutterActor *actor);
|
||||
void (* hide) (ClutterActor *actor);
|
||||
void (* hide_all) (ClutterActor *actor);
|
||||
void (* realize) (ClutterActor *actor);
|
||||
void (* unrealize) (ClutterActor *actor);
|
||||
void (* paint) (ClutterActor *actor);
|
||||
void (* parent_set) (ClutterActor *actor,
|
||||
ClutterActor *old_parent);
|
||||
|
||||
void (* destroy) (ClutterActor *actor);
|
||||
void (* pick) (ClutterActor *actor,
|
||||
const ClutterColor *color);
|
||||
void (* destroy) (ClutterActor *actor);
|
||||
void (* pick) (ClutterActor *actor,
|
||||
const ClutterColor *color);
|
||||
|
||||
/* size negotiation */
|
||||
void (* get_preferred_width) (ClutterActor *actor,
|
||||
ClutterUnit for_height,
|
||||
ClutterUnit *min_width_p,
|
||||
ClutterUnit *natural_width_p);
|
||||
void (* get_preferred_height) (ClutterActor *actor,
|
||||
ClutterUnit for_width,
|
||||
ClutterUnit *min_height_p,
|
||||
ClutterUnit *natural_height_p);
|
||||
void (* allocate) (ClutterActor *actor,
|
||||
const ClutterActorBox *box,
|
||||
gboolean absolute_origin_changed);
|
||||
void (* get_paint_area) (ClutterActor *actor,
|
||||
ClutterActorBox *box);
|
||||
|
||||
/* event signals */
|
||||
gboolean (* event) (ClutterActor *actor,
|
||||
@ -253,216 +269,246 @@ struct _ClutterActorClass
|
||||
gpointer _padding_dummy[32];
|
||||
};
|
||||
|
||||
GType clutter_actor_get_type (void) G_GNUC_CONST;
|
||||
GType clutter_actor_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void clutter_actor_show (ClutterActor *self);
|
||||
void clutter_actor_show_all (ClutterActor *self);
|
||||
void clutter_actor_hide (ClutterActor *self);
|
||||
void clutter_actor_hide_all (ClutterActor *self);
|
||||
void clutter_actor_realize (ClutterActor *self);
|
||||
void clutter_actor_unrealize (ClutterActor *self);
|
||||
void clutter_actor_paint (ClutterActor *self);
|
||||
void clutter_actor_pick (ClutterActor *self,
|
||||
const ClutterColor *color);
|
||||
void clutter_actor_queue_redraw (ClutterActor *self);
|
||||
void clutter_actor_destroy (ClutterActor *self);
|
||||
void clutter_actor_show (ClutterActor *self);
|
||||
void clutter_actor_show_all (ClutterActor *self);
|
||||
void clutter_actor_hide (ClutterActor *self);
|
||||
void clutter_actor_hide_all (ClutterActor *self);
|
||||
void clutter_actor_realize (ClutterActor *self);
|
||||
void clutter_actor_unrealize (ClutterActor *self);
|
||||
void clutter_actor_paint (ClutterActor *self);
|
||||
void clutter_actor_pick (ClutterActor *self,
|
||||
const ClutterColor *color);
|
||||
void clutter_actor_queue_redraw (ClutterActor *self);
|
||||
void clutter_actor_queue_relayout (ClutterActor *self);
|
||||
void clutter_actor_destroy (ClutterActor *self);
|
||||
|
||||
void clutter_actor_request_coords (ClutterActor *self,
|
||||
ClutterActorBox *box);
|
||||
void clutter_actor_query_coords (ClutterActor *self,
|
||||
ClutterActorBox *box);
|
||||
void clutter_actor_set_geometry (ClutterActor *self,
|
||||
const ClutterGeometry *geometry);
|
||||
void clutter_actor_get_geometry (ClutterActor *self,
|
||||
ClutterGeometry *geometry);
|
||||
void clutter_actor_get_coords (ClutterActor *self,
|
||||
gint *x_1,
|
||||
gint *y_1,
|
||||
gint *x_2,
|
||||
gint *y_2);
|
||||
void clutter_actor_set_size (ClutterActor *self,
|
||||
gint width,
|
||||
gint height);
|
||||
void clutter_actor_set_sizeu (ClutterActor *self,
|
||||
ClutterUnit width,
|
||||
ClutterUnit height);
|
||||
void clutter_actor_get_size (ClutterActor *self,
|
||||
guint *width,
|
||||
guint *height);
|
||||
void clutter_actor_get_sizeu (ClutterActor *self,
|
||||
ClutterUnit *width,
|
||||
ClutterUnit *height);
|
||||
void clutter_actor_get_abs_size (ClutterActor *self,
|
||||
guint *width,
|
||||
guint *height);
|
||||
void clutter_actor_set_position (ClutterActor *self,
|
||||
gint x,
|
||||
gint y);
|
||||
void clutter_actor_set_positionu (ClutterActor *self,
|
||||
ClutterUnit x,
|
||||
ClutterUnit y);
|
||||
void clutter_actor_get_position (ClutterActor *self,
|
||||
gint *x,
|
||||
gint *y);
|
||||
void clutter_actor_get_positionu (ClutterActor *self,
|
||||
ClutterUnit *x,
|
||||
ClutterUnit *y);
|
||||
void clutter_actor_get_abs_position (ClutterActor *self,
|
||||
gint *x,
|
||||
gint *y);
|
||||
guint clutter_actor_get_width (ClutterActor *self);
|
||||
ClutterUnit clutter_actor_get_widthu (ClutterActor *self);
|
||||
guint clutter_actor_get_height (ClutterActor *self);
|
||||
ClutterUnit clutter_actor_get_heightu (ClutterActor *self);
|
||||
void clutter_actor_set_width (ClutterActor *self,
|
||||
guint width);
|
||||
void clutter_actor_set_widthu (ClutterActor *self,
|
||||
ClutterUnit width);
|
||||
void clutter_actor_set_height (ClutterActor *self,
|
||||
guint height);
|
||||
void clutter_actor_set_heightu (ClutterActor *self,
|
||||
ClutterUnit height);
|
||||
gint clutter_actor_get_x (ClutterActor *self);
|
||||
ClutterUnit clutter_actor_get_xu (ClutterActor *self);
|
||||
gint clutter_actor_get_y (ClutterActor *self);
|
||||
ClutterUnit clutter_actor_get_yu (ClutterActor *self);
|
||||
void clutter_actor_set_x (ClutterActor *self,
|
||||
gint x);
|
||||
void clutter_actor_set_xu (ClutterActor *self,
|
||||
ClutterUnit x);
|
||||
void clutter_actor_set_y (ClutterActor *self,
|
||||
gint y);
|
||||
void clutter_actor_set_yu (ClutterActor *self,
|
||||
ClutterUnit y);
|
||||
void clutter_actor_set_rotation (ClutterActor *self,
|
||||
ClutterRotateAxis axis,
|
||||
gdouble angle,
|
||||
gint x,
|
||||
gint y,
|
||||
gint z);
|
||||
void clutter_actor_set_rotationx (ClutterActor *self,
|
||||
ClutterRotateAxis axis,
|
||||
ClutterFixed angle,
|
||||
gint x,
|
||||
gint y,
|
||||
gint z);
|
||||
void clutter_actor_set_rotationu (ClutterActor *self,
|
||||
ClutterRotateAxis axis,
|
||||
gdouble angle,
|
||||
ClutterUnit x,
|
||||
ClutterUnit y,
|
||||
ClutterUnit z);
|
||||
gdouble clutter_actor_get_rotation (ClutterActor *self,
|
||||
ClutterRotateAxis axis,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gint *z);
|
||||
ClutterFixed clutter_actor_get_rotationx (ClutterActor *self,
|
||||
ClutterRotateAxis axis,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gint *z);
|
||||
gdouble clutter_actor_get_rotationu (ClutterActor *self,
|
||||
ClutterRotateAxis axis,
|
||||
ClutterUnit *x,
|
||||
ClutterUnit *y,
|
||||
ClutterUnit *z);
|
||||
/* size negotiation */
|
||||
void clutter_actor_get_preferred_width (ClutterActor *self,
|
||||
ClutterUnit for_height,
|
||||
ClutterUnit *min_width_p,
|
||||
ClutterUnit *natural_width_p);
|
||||
void clutter_actor_get_preferred_height (ClutterActor *self,
|
||||
ClutterUnit for_width,
|
||||
ClutterUnit *min_height_p,
|
||||
ClutterUnit *natural_height_p);
|
||||
void clutter_actor_get_preferred_size (ClutterActor *self,
|
||||
ClutterUnit *min_width_p,
|
||||
ClutterUnit *min_height_p,
|
||||
ClutterUnit *natural_width_p,
|
||||
ClutterUnit *natural_height_p);
|
||||
void clutter_actor_allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
gboolean absolute_origin_changed);
|
||||
void clutter_actor_get_allocation_coords (ClutterActor *self,
|
||||
gint *x1,
|
||||
gint *y1,
|
||||
gint *x2,
|
||||
gint *y2);
|
||||
void clutter_actor_get_allocation_box (ClutterActor *self,
|
||||
ClutterActorBox *box);
|
||||
void clutter_actor_get_allocation_geometry (ClutterActor *self,
|
||||
ClutterGeometry *geom);
|
||||
void clutter_actor_get_allocation_vertices (ClutterActor *self,
|
||||
ClutterActor *ancestor,
|
||||
ClutterVertex verts[4]);
|
||||
void clutter_actor_get_paint_area (ClutterActor *self,
|
||||
ClutterActorBox *box);
|
||||
|
||||
void clutter_actor_set_opacity (ClutterActor *self,
|
||||
guint8 opacity);
|
||||
guint8 clutter_actor_get_opacity (ClutterActor *self);
|
||||
guint8 clutter_actor_get_abs_opacity (ClutterActor *self);
|
||||
void clutter_actor_set_name (ClutterActor *self,
|
||||
const gchar *name);
|
||||
G_CONST_RETURN gchar *clutter_actor_get_name (ClutterActor *self);
|
||||
guint32 clutter_actor_get_gid (ClutterActor *self);
|
||||
void clutter_actor_set_clip (ClutterActor *self,
|
||||
gint xoff,
|
||||
gint yoff,
|
||||
gint width,
|
||||
gint height);
|
||||
void clutter_actor_set_clipu (ClutterActor *self,
|
||||
ClutterUnit xoff,
|
||||
ClutterUnit yoff,
|
||||
ClutterUnit width,
|
||||
ClutterUnit height);
|
||||
void clutter_actor_remove_clip (ClutterActor *self);
|
||||
gboolean clutter_actor_has_clip (ClutterActor *self);
|
||||
void clutter_actor_get_clip (ClutterActor *self,
|
||||
gint *xoff,
|
||||
gint *yoff,
|
||||
gint *width,
|
||||
gint *height);
|
||||
void clutter_actor_get_clipu (ClutterActor *self,
|
||||
ClutterUnit *xoff,
|
||||
ClutterUnit *yoff,
|
||||
ClutterUnit *width,
|
||||
ClutterUnit *height);
|
||||
void clutter_actor_set_parent (ClutterActor *self,
|
||||
ClutterActor *parent);
|
||||
ClutterActor * clutter_actor_get_parent (ClutterActor *self);
|
||||
void clutter_actor_reparent (ClutterActor *self,
|
||||
ClutterActor *new_parent);
|
||||
void clutter_actor_unparent (ClutterActor *self);
|
||||
void clutter_actor_raise (ClutterActor *self,
|
||||
ClutterActor *below);
|
||||
void clutter_actor_lower (ClutterActor *self,
|
||||
ClutterActor *above);
|
||||
void clutter_actor_raise_top (ClutterActor *self);
|
||||
void clutter_actor_lower_bottom (ClutterActor *self);
|
||||
void clutter_actor_set_depth (ClutterActor *self,
|
||||
gint depth);
|
||||
gint clutter_actor_get_depth (ClutterActor *self);
|
||||
void clutter_actor_set_depthu (ClutterActor *self,
|
||||
ClutterUnit depth);
|
||||
ClutterUnit clutter_actor_get_depthu (ClutterActor *self);
|
||||
void clutter_actor_set_reactive (ClutterActor *actor,
|
||||
gboolean reactive);
|
||||
gboolean clutter_actor_get_reactive (ClutterActor *actor);
|
||||
void clutter_actor_set_scalex (ClutterActor *self,
|
||||
ClutterFixed scale_x,
|
||||
ClutterFixed scale_y);
|
||||
void clutter_actor_set_scale (ClutterActor *self,
|
||||
gdouble scale_x,
|
||||
gdouble scale_y);
|
||||
void clutter_actor_get_scalex (ClutterActor *self,
|
||||
ClutterFixed *scale_x,
|
||||
ClutterFixed *scale_y);
|
||||
void clutter_actor_get_scale (ClutterActor *self,
|
||||
gdouble *scale_x,
|
||||
gdouble *scale_y);
|
||||
void clutter_actor_set_geometry (ClutterActor *self,
|
||||
const ClutterGeometry *geometry);
|
||||
void clutter_actor_get_geometry (ClutterActor *self,
|
||||
ClutterGeometry *geometry);
|
||||
void clutter_actor_set_size (ClutterActor *self,
|
||||
gint width,
|
||||
gint height);
|
||||
void clutter_actor_set_sizeu (ClutterActor *self,
|
||||
ClutterUnit width,
|
||||
ClutterUnit height);
|
||||
void clutter_actor_get_size (ClutterActor *self,
|
||||
guint *width,
|
||||
guint *height);
|
||||
void clutter_actor_get_sizeu (ClutterActor *self,
|
||||
ClutterUnit *width,
|
||||
ClutterUnit *height);
|
||||
void clutter_actor_get_transformed_size (ClutterActor *self,
|
||||
guint *width,
|
||||
guint *height);
|
||||
void clutter_actor_get_transformed_sizeu (ClutterActor *self,
|
||||
ClutterUnit *width,
|
||||
ClutterUnit *height);
|
||||
void clutter_actor_set_position (ClutterActor *self,
|
||||
gint x,
|
||||
gint y);
|
||||
void clutter_actor_set_positionu (ClutterActor *self,
|
||||
ClutterUnit x,
|
||||
ClutterUnit y);
|
||||
void clutter_actor_get_position (ClutterActor *self,
|
||||
gint *x,
|
||||
gint *y);
|
||||
void clutter_actor_get_positionu (ClutterActor *self,
|
||||
ClutterUnit *x,
|
||||
ClutterUnit *y);
|
||||
void clutter_actor_get_transformed_position (ClutterActor *self,
|
||||
gint *x,
|
||||
gint *y);
|
||||
void clutter_actor_get_transformed_positionu (ClutterActor *self,
|
||||
ClutterUnit *x,
|
||||
ClutterUnit *y);
|
||||
|
||||
void clutter_actor_move_by (ClutterActor *self,
|
||||
gint dx,
|
||||
gint dy);
|
||||
void clutter_actor_move_byu (ClutterActor *self,
|
||||
ClutterUnit dx,
|
||||
ClutterUnit dy);
|
||||
void clutter_actor_get_vertices (ClutterActor *self,
|
||||
ClutterVertex verts[4]);
|
||||
void clutter_actor_get_relative_vertices (ClutterActor *self,
|
||||
ClutterActor *ancestor,
|
||||
ClutterVertex verts[4]);
|
||||
void clutter_actor_apply_transform_to_point (ClutterActor *self,
|
||||
ClutterVertex *point,
|
||||
ClutterVertex *vertex);
|
||||
void clutter_actor_apply_relative_transform_to_point (ClutterActor *self,
|
||||
ClutterActor *ancestor,
|
||||
ClutterVertex *point,
|
||||
ClutterVertex *vertex);
|
||||
gboolean clutter_actor_event (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gboolean capture);
|
||||
ClutterActor * clutter_get_actor_by_gid (guint32 id);
|
||||
gboolean clutter_actor_get_fixed_position_set (ClutterActor *self);
|
||||
void clutter_actor_set_fixed_position_set (ClutterActor *self,
|
||||
gboolean is_set);
|
||||
|
||||
gboolean clutter_actor_should_pick_paint (ClutterActor *self);
|
||||
guint clutter_actor_get_width (ClutterActor *self);
|
||||
ClutterUnit clutter_actor_get_widthu (ClutterActor *self);
|
||||
guint clutter_actor_get_height (ClutterActor *self);
|
||||
ClutterUnit clutter_actor_get_heightu (ClutterActor *self);
|
||||
void clutter_actor_set_width (ClutterActor *self,
|
||||
guint width);
|
||||
void clutter_actor_set_widthu (ClutterActor *self,
|
||||
ClutterUnit width);
|
||||
void clutter_actor_set_height (ClutterActor *self,
|
||||
guint height);
|
||||
void clutter_actor_set_heightu (ClutterActor *self,
|
||||
ClutterUnit height);
|
||||
gint clutter_actor_get_x (ClutterActor *self);
|
||||
ClutterUnit clutter_actor_get_xu (ClutterActor *self);
|
||||
gint clutter_actor_get_y (ClutterActor *self);
|
||||
ClutterUnit clutter_actor_get_yu (ClutterActor *self);
|
||||
void clutter_actor_set_x (ClutterActor *self,
|
||||
gint x);
|
||||
void clutter_actor_set_xu (ClutterActor *self,
|
||||
ClutterUnit x);
|
||||
void clutter_actor_set_y (ClutterActor *self,
|
||||
gint y);
|
||||
void clutter_actor_set_yu (ClutterActor *self,
|
||||
ClutterUnit y);
|
||||
void clutter_actor_set_rotation (ClutterActor *self,
|
||||
ClutterRotateAxis axis,
|
||||
gdouble angle,
|
||||
gint x,
|
||||
gint y,
|
||||
gint z);
|
||||
void clutter_actor_set_rotationx (ClutterActor *self,
|
||||
ClutterRotateAxis axis,
|
||||
ClutterFixed angle,
|
||||
gint x,
|
||||
gint y,
|
||||
gint z);
|
||||
void clutter_actor_set_rotationu (ClutterActor *self,
|
||||
ClutterRotateAxis axis,
|
||||
gdouble angle,
|
||||
ClutterUnit x,
|
||||
ClutterUnit y,
|
||||
ClutterUnit z);
|
||||
gdouble clutter_actor_get_rotation (ClutterActor *self,
|
||||
ClutterRotateAxis axis,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gint *z);
|
||||
ClutterFixed clutter_actor_get_rotationx (ClutterActor *self,
|
||||
ClutterRotateAxis axis,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gint *z);
|
||||
gdouble clutter_actor_get_rotationu (ClutterActor *self,
|
||||
ClutterRotateAxis axis,
|
||||
ClutterUnit *x,
|
||||
ClutterUnit *y,
|
||||
ClutterUnit *z);
|
||||
|
||||
gboolean clutter_actor_set_shader (ClutterActor *self,
|
||||
ClutterShader *shader);
|
||||
ClutterShader * clutter_actor_get_shader (ClutterActor *self);
|
||||
void clutter_actor_set_shader_param (ClutterActor *self,
|
||||
const gchar *param,
|
||||
gfloat value);
|
||||
void clutter_actor_set_opacity (ClutterActor *self,
|
||||
guint8 opacity);
|
||||
guint8 clutter_actor_get_opacity (ClutterActor *self);
|
||||
guint8 clutter_actor_get_paint_opacity (ClutterActor *self);
|
||||
|
||||
void clutter_actor_set_name (ClutterActor *self,
|
||||
const gchar *name);
|
||||
G_CONST_RETURN gchar *clutter_actor_get_name (ClutterActor *self);
|
||||
|
||||
guint32 clutter_actor_get_gid (ClutterActor *self);
|
||||
void clutter_actor_set_clip (ClutterActor *self,
|
||||
gint xoff,
|
||||
gint yoff,
|
||||
gint width,
|
||||
gint height);
|
||||
void clutter_actor_set_clipu (ClutterActor *self,
|
||||
ClutterUnit xoff,
|
||||
ClutterUnit yoff,
|
||||
ClutterUnit width,
|
||||
ClutterUnit height);
|
||||
void clutter_actor_remove_clip (ClutterActor *self);
|
||||
gboolean clutter_actor_has_clip (ClutterActor *self);
|
||||
void clutter_actor_get_clip (ClutterActor *self,
|
||||
gint *xoff,
|
||||
gint *yoff,
|
||||
gint *width,
|
||||
gint *height);
|
||||
void clutter_actor_get_clipu (ClutterActor *self,
|
||||
ClutterUnit *xoff,
|
||||
ClutterUnit *yoff,
|
||||
ClutterUnit *width,
|
||||
ClutterUnit *height);
|
||||
|
||||
void clutter_actor_set_parent (ClutterActor *self,
|
||||
ClutterActor *parent);
|
||||
ClutterActor * clutter_actor_get_parent (ClutterActor *self);
|
||||
void clutter_actor_reparent (ClutterActor *self,
|
||||
ClutterActor *new_parent);
|
||||
void clutter_actor_unparent (ClutterActor *self);
|
||||
ClutterActor* clutter_actor_get_stage (ClutterActor *actor);
|
||||
|
||||
void clutter_actor_raise (ClutterActor *self,
|
||||
ClutterActor *below);
|
||||
void clutter_actor_lower (ClutterActor *self,
|
||||
ClutterActor *above);
|
||||
void clutter_actor_raise_top (ClutterActor *self);
|
||||
void clutter_actor_lower_bottom (ClutterActor *self);
|
||||
void clutter_actor_set_depth (ClutterActor *self,
|
||||
gint depth);
|
||||
gint clutter_actor_get_depth (ClutterActor *self);
|
||||
void clutter_actor_set_depthu (ClutterActor *self,
|
||||
ClutterUnit depth);
|
||||
ClutterUnit clutter_actor_get_depthu (ClutterActor *self);
|
||||
|
||||
void clutter_actor_set_scalex (ClutterActor *self,
|
||||
ClutterFixed scale_x,
|
||||
ClutterFixed scale_y);
|
||||
void clutter_actor_set_scale (ClutterActor *self,
|
||||
gdouble scale_x,
|
||||
gdouble scale_y);
|
||||
void clutter_actor_get_scalex (ClutterActor *self,
|
||||
ClutterFixed *scale_x,
|
||||
ClutterFixed *scale_y);
|
||||
void clutter_actor_get_scale (ClutterActor *self,
|
||||
gdouble *scale_x,
|
||||
gdouble *scale_y);
|
||||
|
||||
void clutter_actor_move_by (ClutterActor *self,
|
||||
gint dx,
|
||||
gint dy);
|
||||
void clutter_actor_move_byu (ClutterActor *self,
|
||||
ClutterUnit dx,
|
||||
ClutterUnit dy);
|
||||
|
||||
void clutter_actor_set_reactive (ClutterActor *actor,
|
||||
gboolean reactive);
|
||||
gboolean clutter_actor_get_reactive (ClutterActor *actor);
|
||||
|
||||
gboolean clutter_actor_event (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gboolean capture);
|
||||
|
||||
ClutterActor * clutter_get_actor_by_gid (guint32 id);
|
||||
|
||||
gboolean clutter_actor_set_shader (ClutterActor *self,
|
||||
ClutterShader *shader);
|
||||
ClutterShader * clutter_actor_get_shader (ClutterActor *self);
|
||||
void clutter_actor_set_shader_param (ClutterActor *self,
|
||||
const gchar *param,
|
||||
gfloat value);
|
||||
|
||||
void clutter_actor_set_anchor_point (ClutterActor *self,
|
||||
gint anchor_x,
|
||||
@ -484,9 +530,9 @@ void clutter_actor_get_anchor_pointu (ClutterActor *self,
|
||||
ClutterUnit *anchor_y);
|
||||
void clutter_actor_set_anchor_point_from_gravity (ClutterActor *self,
|
||||
ClutterGravity gravity);
|
||||
|
||||
void clutter_actor_move_anchor_point_from_gravity (ClutterActor *self,
|
||||
ClutterGravity gravity);
|
||||
|
||||
gboolean clutter_actor_transform_stage_point (ClutterActor *self,
|
||||
ClutterUnit x,
|
||||
ClutterUnit y,
|
||||
@ -494,12 +540,21 @@ gboolean clutter_actor_transform_stage_point (ClutterActor *self,
|
||||
ClutterUnit *y_out);
|
||||
gboolean clutter_actor_is_rotated (ClutterActor *self);
|
||||
gboolean clutter_actor_is_scaled (ClutterActor *self);
|
||||
gboolean clutter_actor_should_pick_paint (ClutterActor *self);
|
||||
|
||||
void clutter_actor_box_get_from_vertices (ClutterVertex vtx[4],
|
||||
ClutterActorBox *box);
|
||||
|
||||
ClutterActor* clutter_actor_get_stage (ClutterActor *actor);
|
||||
void clutter_actor_get_abs_allocation_vertices (ClutterActor *self,
|
||||
ClutterVertex verts[4]);
|
||||
|
||||
void clutter_actor_apply_transform_to_point (ClutterActor *self,
|
||||
ClutterVertex *point,
|
||||
ClutterVertex *vertex);
|
||||
void clutter_actor_apply_relative_transform_to_point (ClutterActor *self,
|
||||
ClutterActor *ancestor,
|
||||
ClutterVertex *point,
|
||||
ClutterVertex *vertex);
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* _HAVE_CLUTTER_ACTOR_H */
|
||||
|
@ -68,6 +68,74 @@ struct _ClutterCloneTexturePrivate
|
||||
guint repeat_y : 1;
|
||||
};
|
||||
|
||||
static void
|
||||
clutter_clone_texture_get_preferred_width (ClutterActor *self,
|
||||
ClutterUnit for_height,
|
||||
ClutterUnit *min_width_p,
|
||||
ClutterUnit *natural_width_p)
|
||||
{
|
||||
ClutterCloneTexturePrivate *priv = CLUTTER_CLONE_TEXTURE (self)->priv;
|
||||
ClutterActor *parent_texture;
|
||||
ClutterActorClass *parent_texture_class;
|
||||
|
||||
/* Note that by calling the get_width_request virtual method directly
|
||||
* and skipping the clutter_actor_get_preferred_width() wrapper, we
|
||||
* are ignoring any size request override set on the parent texture
|
||||
* and just getting the normal size of the parent texture.
|
||||
*/
|
||||
parent_texture = CLUTTER_ACTOR (priv->parent_texture);
|
||||
if (!parent_texture)
|
||||
{
|
||||
if (min_width_p)
|
||||
*min_width_p = 0;
|
||||
|
||||
if (natural_width_p)
|
||||
*natural_width_p = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
parent_texture_class = CLUTTER_ACTOR_GET_CLASS (parent_texture);
|
||||
parent_texture_class->get_preferred_width (parent_texture,
|
||||
for_height,
|
||||
min_width_p,
|
||||
natural_width_p);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_clone_texture_get_preferred_height (ClutterActor *self,
|
||||
ClutterUnit for_width,
|
||||
ClutterUnit *min_height_p,
|
||||
ClutterUnit *natural_height_p)
|
||||
{
|
||||
ClutterCloneTexturePrivate *priv = CLUTTER_CLONE_TEXTURE (self)->priv;
|
||||
ClutterActor *parent_texture;
|
||||
ClutterActorClass *parent_texture_class;
|
||||
|
||||
/* Note that by calling the get_height_request virtual method directly
|
||||
* and skipping the clutter_actor_get_preferred_height() wrapper, we
|
||||
* are ignoring any size request override set on the parent texture and
|
||||
* just getting the normal size of the parent texture.
|
||||
*/
|
||||
parent_texture = CLUTTER_ACTOR (priv->parent_texture);
|
||||
if (!parent_texture)
|
||||
{
|
||||
if (min_height_p)
|
||||
*min_height_p = 0;
|
||||
|
||||
if (natural_height_p)
|
||||
*natural_height_p = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
parent_texture_class = CLUTTER_ACTOR_GET_CLASS (parent_texture);
|
||||
parent_texture_class->get_preferred_height (parent_texture,
|
||||
for_width,
|
||||
min_height_p,
|
||||
natural_height_p);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_clone_texture_paint (ClutterActor *self)
|
||||
{
|
||||
@ -99,10 +167,10 @@ clutter_clone_texture_paint (ClutterActor *self)
|
||||
|
||||
cogl_push_matrix ();
|
||||
|
||||
col.alpha = clutter_actor_get_abs_opacity (self);
|
||||
col.alpha = clutter_actor_get_paint_opacity (self);
|
||||
cogl_color (&col);
|
||||
|
||||
clutter_actor_get_coords (self, &x_1, &y_1, &x_2, &y_2);
|
||||
clutter_actor_get_allocation_coords (self, &x_1, &y_1, &x_2, &y_2);
|
||||
|
||||
CLUTTER_NOTE (PAINT, "paint to x1: %i, y1: %i x2: %i, y2: %i "
|
||||
"opacity: %i",
|
||||
@ -156,14 +224,8 @@ set_parent_texture (ClutterCloneTexture *ctexture,
|
||||
|
||||
if (texture)
|
||||
{
|
||||
gint width, height;
|
||||
|
||||
priv->parent_texture = g_object_ref (texture);
|
||||
|
||||
/* Sync up the size to parent texture base pixbuf size. */
|
||||
clutter_texture_get_base_size (texture, &width, &height);
|
||||
clutter_actor_set_size (actor, width, height);
|
||||
|
||||
/* queue a redraw if the cloned texture is already visible */
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (priv->parent_texture) &&
|
||||
was_visible)
|
||||
@ -171,6 +233,8 @@ set_parent_texture (ClutterCloneTexture *ctexture,
|
||||
clutter_actor_show (actor);
|
||||
clutter_actor_queue_redraw (actor);
|
||||
}
|
||||
|
||||
clutter_actor_queue_relayout (actor);
|
||||
}
|
||||
|
||||
}
|
||||
@ -265,7 +329,12 @@ clutter_clone_texture_class_init (ClutterCloneTextureClass *klass)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
|
||||
actor_class->paint = clutter_clone_texture_paint;
|
||||
actor_class->paint =
|
||||
clutter_clone_texture_paint;
|
||||
actor_class->get_preferred_width =
|
||||
clutter_clone_texture_get_preferred_width;
|
||||
actor_class->get_preferred_height =
|
||||
clutter_clone_texture_get_preferred_height;
|
||||
|
||||
gobject_class->finalize = clutter_clone_texture_finalize;
|
||||
gobject_class->dispose = clutter_clone_texture_dispose;
|
||||
|
@ -45,4 +45,11 @@
|
||||
#define clutter_texture_new_from_pixbuf clutter_texture_new_from_pixbuf_DEPRECATED_BY_clutter_texture_new_from_file_OR_clutter_texture_new_AND_clutter_texture_set_from_rgb_data
|
||||
#define clutter_texture_set_pixbuf clutter_texture_set_pixbuf+DEPRECATED_BY_clutter_texture_set_from_rgb_data
|
||||
|
||||
#define clutter_actor_query_coords clutter_actor_query_coords_REPLACED_BY_clutter_actor_get_width_request_AND_clutter_actor_get_height_request
|
||||
#define clutter_actor_request_coords clutter_actor_request_coords_REPLACED_BY_clutter_actor_allocate
|
||||
|
||||
#define clutter_actor_get_abs_position clutter_actor_get_abs_position_REPLACED_BY_clutter_actor_get_transformed_position
|
||||
#define clutter_actor_get_abs_size clutter_actor_get_abs_size_REPLACED_BY_clutter_actor_get_transformed_size
|
||||
#define clutter_actor_get_abs_opacity clutter_actor_get_abs_opacity_REPLACED_BY_clutter_actor_get_paint_opacity
|
||||
|
||||
#endif /* CLUTTER_DEPRECATED_H */
|
||||
|
@ -473,7 +473,7 @@ clutter_entry_paint (ClutterActor *self)
|
||||
}
|
||||
|
||||
memcpy (&color, &priv->fgcol, sizeof (ClutterColor));
|
||||
color.alpha = clutter_actor_get_abs_opacity (self);
|
||||
color.alpha = clutter_actor_get_paint_opacity (self);
|
||||
|
||||
pango_clutter_render_layout (priv->layout,
|
||||
priv->text_x + priv->entry_padding, 0,
|
||||
@ -484,8 +484,9 @@ clutter_entry_paint (ClutterActor *self)
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_entry_request_coords (ClutterActor *self,
|
||||
ClutterActorBox *box)
|
||||
clutter_entry_allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
gboolean absolute_origin_changed)
|
||||
{
|
||||
ClutterEntry *entry = CLUTTER_ENTRY (self);
|
||||
ClutterEntryPrivate *priv = entry->priv;
|
||||
@ -501,7 +502,7 @@ clutter_entry_request_coords (ClutterActor *self,
|
||||
priv->width = width;
|
||||
}
|
||||
|
||||
CLUTTER_ACTOR_CLASS (clutter_entry_parent_class)->request_coords (self, box);
|
||||
CLUTTER_ACTOR_CLASS (clutter_entry_parent_class)->allocate (self, box, absolute_origin_changed);
|
||||
}
|
||||
|
||||
static inline void
|
||||
@ -633,13 +634,13 @@ clutter_entry_finalize (GObject *object)
|
||||
static void
|
||||
clutter_entry_class_init (ClutterEntryClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
|
||||
klass->paint_cursor = clutter_entry_paint_cursor;
|
||||
|
||||
actor_class->paint = clutter_entry_paint;
|
||||
actor_class->request_coords = clutter_entry_request_coords;
|
||||
actor_class->allocate = clutter_entry_allocate;
|
||||
actor_class->key_press_event = clutter_entry_key_press;
|
||||
|
||||
gobject_class->finalize = clutter_entry_finalize;
|
||||
|
@ -33,7 +33,7 @@
|
||||
* rotating and clipping of the group will apply to the child actors.
|
||||
*
|
||||
* A #ClutterGroup's size is defined by the size and position of its children.
|
||||
* Resize requests via parent #ClutterActor API will be ignored.
|
||||
* Resize requests via the #ClutterActor API will be ignored.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -83,14 +83,14 @@ struct _ClutterGroupPrivate
|
||||
static void
|
||||
clutter_group_paint (ClutterActor *actor)
|
||||
{
|
||||
ClutterGroup *self = CLUTTER_GROUP(actor);
|
||||
GList *child_item;
|
||||
ClutterGroupPrivate *priv = CLUTTER_GROUP (actor)->priv;
|
||||
GList *child_item;
|
||||
|
||||
CLUTTER_NOTE (PAINT, "ClutterGroup paint enter");
|
||||
|
||||
cogl_push_matrix();
|
||||
cogl_push_matrix ();
|
||||
|
||||
for (child_item = self->priv->children;
|
||||
for (child_item = priv->children;
|
||||
child_item != NULL;
|
||||
child_item = child_item->next)
|
||||
{
|
||||
@ -102,7 +102,7 @@ clutter_group_paint (ClutterActor *actor)
|
||||
clutter_actor_paint (child);
|
||||
}
|
||||
|
||||
cogl_pop_matrix();
|
||||
cogl_pop_matrix ();
|
||||
|
||||
CLUTTER_NOTE (PAINT, "ClutterGroup paint leave");
|
||||
}
|
||||
@ -137,91 +137,286 @@ clutter_group_pick (ClutterActor *actor,
|
||||
clutter_group_paint (actor);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
clutter_group_request_coords (ClutterActor *self,
|
||||
ClutterActorBox *box)
|
||||
clutter_fixed_layout_get_preferred_width (GList *children,
|
||||
ClutterUnit *min_width_p,
|
||||
ClutterUnit *natural_width_p)
|
||||
{
|
||||
ClutterActorBox cbox;
|
||||
GList *l;
|
||||
ClutterUnit min_left, min_right;
|
||||
ClutterUnit natural_left, natural_right;
|
||||
|
||||
clutter_actor_query_coords (self, &cbox);
|
||||
min_left = 0;
|
||||
min_right = 0;
|
||||
natural_left = 0;
|
||||
natural_right = 0;
|
||||
|
||||
/* Only positioning works.
|
||||
* Sizing requests fail, use scale() instead
|
||||
*/
|
||||
box->x2 = box->x1 + (cbox.x2 - cbox.x1);
|
||||
box->y2 = box->y1 + (cbox.y2 - cbox.y1);
|
||||
for (l = children; l != NULL; l = l->next)
|
||||
{
|
||||
ClutterActor *child = l->data;
|
||||
ClutterUnit child_x, child_min, child_natural;
|
||||
|
||||
CLUTTER_ACTOR_CLASS (clutter_group_parent_class)->request_coords (self, box);
|
||||
child_x = clutter_actor_get_xu (child);
|
||||
|
||||
clutter_actor_get_preferred_size (child,
|
||||
&child_min, NULL,
|
||||
&child_natural, NULL);
|
||||
|
||||
if (l == children)
|
||||
{
|
||||
/* First child */
|
||||
min_left = child_x;
|
||||
natural_left = child_x;
|
||||
min_right = min_left + child_min;
|
||||
natural_right = natural_left + child_natural;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Union of extents with previous children */
|
||||
if (child_x < min_left)
|
||||
min_left = child_x;
|
||||
|
||||
if (child_x < natural_left)
|
||||
natural_left = child_x;
|
||||
|
||||
if (child_x + child_min > min_right)
|
||||
min_right = child_x + child_min;
|
||||
|
||||
if (child_x + child_natural > natural_right)
|
||||
natural_right = child_x + child_natural;
|
||||
}
|
||||
}
|
||||
|
||||
/* The preferred size is defined as the width and height we want starting
|
||||
* from our origin, since our allocation will set the origin; so we now
|
||||
* need to remove any part of the request that is to the left of the origin.
|
||||
*/
|
||||
if (min_left < 0)
|
||||
min_left = 0;
|
||||
|
||||
if (natural_left < 0)
|
||||
natural_left = 0;
|
||||
|
||||
if (min_right < 0)
|
||||
min_right = 0;
|
||||
|
||||
if (natural_right < 0)
|
||||
natural_right = 0;
|
||||
|
||||
g_assert (min_right >= min_left);
|
||||
g_assert (natural_right >= natural_left);
|
||||
|
||||
if (min_width_p)
|
||||
*min_width_p = min_right - min_left;
|
||||
|
||||
if (natural_width_p)
|
||||
*natural_width_p = natural_right - min_left;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_group_query_coords (ClutterActor *self,
|
||||
ClutterActorBox *box)
|
||||
clutter_fixed_layout_get_preferred_height (GList *children,
|
||||
ClutterUnit *min_height_p,
|
||||
ClutterUnit *natural_height_p)
|
||||
{
|
||||
ClutterGroupPrivate *priv;
|
||||
GList *child_item;
|
||||
GList *l;
|
||||
ClutterUnit min_top, min_bottom;
|
||||
ClutterUnit natural_top, natural_bottom;
|
||||
|
||||
priv = CLUTTER_GROUP(self)->priv;
|
||||
min_top = 0;
|
||||
min_bottom = 0;
|
||||
natural_top = 0;
|
||||
natural_bottom = 0;
|
||||
|
||||
child_item = priv->children;
|
||||
|
||||
/* FIXME: Cache these values */
|
||||
box->x2 = box->x1;
|
||||
box->y2 = box->y1;
|
||||
|
||||
if (child_item)
|
||||
for (l = children; l != NULL; l = l->next)
|
||||
{
|
||||
do
|
||||
{
|
||||
ClutterActor *child = CLUTTER_ACTOR(child_item->data);
|
||||
ClutterActorBox cbox;
|
||||
ClutterActor *child = l->data;
|
||||
ClutterUnit child_y, child_min, child_natural;
|
||||
|
||||
#if 0 /* XXX - Leave this post 0.6 ??? */
|
||||
if (clutter_actor_is_scaled (child) ||
|
||||
clutter_actor_is_rotated (child))
|
||||
{
|
||||
ClutterVertex vtx[4];
|
||||
child_y = clutter_actor_get_yu (child);
|
||||
|
||||
clutter_actor_get_relative_vertices (child, self, vtx);
|
||||
clutter_actor_box_get_from_vertices (vtx, &cbox);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
gint anchor_x;
|
||||
gint anchor_y;
|
||||
clutter_actor_get_preferred_size (child,
|
||||
NULL, &child_min,
|
||||
NULL, &child_natural);
|
||||
|
||||
clutter_actor_query_coords (child, &cbox);
|
||||
if (l == children)
|
||||
{
|
||||
/* First child */
|
||||
min_top = child_y;
|
||||
natural_top = child_y;
|
||||
min_bottom = min_top + child_min;
|
||||
natural_bottom = natural_top + child_natural;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Union of extents with previous children */
|
||||
if (child_y < min_top)
|
||||
min_top = child_y;
|
||||
|
||||
/*
|
||||
* Must adjust these by the anchor point, as we need the box
|
||||
* to be relative to the top-left corner of the parent
|
||||
*/
|
||||
clutter_actor_get_anchor_pointu (child, &anchor_x, &anchor_y);
|
||||
if (child_y < natural_top)
|
||||
natural_top = child_y;
|
||||
|
||||
cbox.x1 -= anchor_x;
|
||||
cbox.x2 -= anchor_x;
|
||||
cbox.y1 -= anchor_y;
|
||||
cbox.y2 -= anchor_y;
|
||||
}
|
||||
if (child_y + child_min > min_bottom)
|
||||
min_bottom = child_y + child_min;
|
||||
|
||||
/* FIXME: now that we go into the trouble of working out the
|
||||
* projected sizes, we should do better than this (probably resize
|
||||
* the box in all direction as required).
|
||||
*
|
||||
* Ignore any children with offscreen ( negaive )
|
||||
* positions.
|
||||
*
|
||||
* Also x1 and x2 will be set by parent caller.
|
||||
*/
|
||||
if (box->x2 - box->x1 < cbox.x2)
|
||||
box->x2 = cbox.x2 + box->x1;
|
||||
if (child_y + child_natural > natural_bottom)
|
||||
natural_bottom = child_y + child_natural;
|
||||
}
|
||||
}
|
||||
|
||||
if (box->y2 - box->y1 < cbox.y2)
|
||||
box->y2 = cbox.y2 + box->y1;
|
||||
}
|
||||
while ((child_item = g_list_next(child_item)) != NULL);
|
||||
/* The preferred size is defined as the width and height we want starting
|
||||
* from our origin, since our allocation will set the origin; so we now
|
||||
* need to remove any part of the request that is above the origin.
|
||||
*/
|
||||
if (min_top < 0)
|
||||
min_top = 0;
|
||||
|
||||
if (natural_top < 0)
|
||||
natural_top = 0;
|
||||
|
||||
if (min_bottom < 0)
|
||||
min_bottom = 0;
|
||||
|
||||
if (natural_bottom < 0)
|
||||
natural_bottom = 0;
|
||||
|
||||
g_assert (min_bottom >= min_top);
|
||||
g_assert (natural_bottom >= natural_top);
|
||||
|
||||
if (min_height_p)
|
||||
*min_height_p = min_bottom - min_top;
|
||||
|
||||
if (natural_height_p)
|
||||
*natural_height_p = natural_bottom - min_top;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_fixed_layout_allocate (GList *children,
|
||||
gboolean absolute_origin_changed)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = children; l != NULL; l = l->next)
|
||||
{
|
||||
ClutterActor *child = l->data;
|
||||
ClutterUnit child_x, child_y;
|
||||
ClutterUnit natural_width, natural_height;
|
||||
ClutterActorBox child_box;
|
||||
|
||||
child_x = clutter_actor_get_xu (child);
|
||||
child_y = clutter_actor_get_yu (child);
|
||||
|
||||
/* All children get their position and natural size (the
|
||||
* container's allocation is flat-out ignored).
|
||||
*/
|
||||
clutter_actor_get_preferred_size (child,
|
||||
NULL, NULL,
|
||||
&natural_width,
|
||||
&natural_height);
|
||||
|
||||
child_box.x1 = child_x;
|
||||
child_box.y1 = child_y;
|
||||
child_box.x2 = child_box.x1 + natural_width;
|
||||
child_box.y2 = child_box.y1 + natural_height;
|
||||
|
||||
clutter_actor_allocate (child, &child_box, absolute_origin_changed);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_group_get_preferred_width (ClutterActor *self,
|
||||
ClutterUnit for_height,
|
||||
ClutterUnit *min_width_p,
|
||||
ClutterUnit *natural_width_p)
|
||||
{
|
||||
ClutterGroupPrivate *priv = CLUTTER_GROUP (self)->priv;
|
||||
|
||||
/* for_height is irrelevant to the fixed layout, so it's not used */
|
||||
clutter_fixed_layout_get_preferred_width (priv->children,
|
||||
min_width_p,
|
||||
natural_width_p);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_group_get_preferred_height (ClutterActor *self,
|
||||
ClutterUnit for_width,
|
||||
ClutterUnit *min_height_p,
|
||||
ClutterUnit *natural_height_p)
|
||||
{
|
||||
ClutterGroupPrivate *priv = CLUTTER_GROUP (self)->priv;
|
||||
|
||||
/* for_width is irrelevant to the fixed layout, so it's not used */
|
||||
clutter_fixed_layout_get_preferred_height (priv->children,
|
||||
min_height_p,
|
||||
natural_height_p);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_group_allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
gboolean origin_changed)
|
||||
{
|
||||
ClutterGroupPrivate *priv = CLUTTER_GROUP (self)->priv;
|
||||
|
||||
/* chain up to set actor->allocation */
|
||||
CLUTTER_ACTOR_CLASS (clutter_group_parent_class)->allocate (self, box,
|
||||
origin_changed);
|
||||
|
||||
/* Note that fixed-layout allocation of children does not care what
|
||||
* allocation the container received, so "box" is not passed in
|
||||
* here. We do not require that children's allocations are completely
|
||||
* contained by our own.
|
||||
*/
|
||||
clutter_fixed_layout_allocate (priv->children, origin_changed);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_group_get_paint_area (ClutterActor *self,
|
||||
ClutterActorBox *box)
|
||||
{
|
||||
ClutterGroupPrivate *priv = CLUTTER_GROUP (self)->priv;
|
||||
|
||||
/* Our area is the union of all child boxes. */
|
||||
if (!priv->children)
|
||||
{
|
||||
/* Only get our allocation if no children;
|
||||
* if we do have children, we don't want this
|
||||
* because the allocation is based on the children's
|
||||
* untransformed layout, and we want the union of
|
||||
* their transformed boxes (their paint boxes).
|
||||
*/
|
||||
clutter_actor_get_allocation_box (self, box);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClutterActorBox all_box = { 0, }; /* initialize to silence gcc */
|
||||
GList *l;
|
||||
|
||||
for (l = priv->children; l != NULL; l = l->next)
|
||||
{
|
||||
ClutterActor *child = l->data;
|
||||
ClutterActorBox child_box = { 0, };
|
||||
|
||||
clutter_actor_get_paint_area (child, &child_box);
|
||||
|
||||
if (l == priv->children)
|
||||
all_box = child_box;
|
||||
else
|
||||
{
|
||||
if (child_box.x1 < all_box.x1)
|
||||
all_box.x1 = child_box.x1;
|
||||
|
||||
if (child_box.y1 < all_box.y1)
|
||||
all_box.y1 = child_box.y1;
|
||||
|
||||
if (child_box.x2 > all_box.x2)
|
||||
all_box.x2 = child_box.x2;
|
||||
|
||||
if (child_box.y2 > all_box.y2)
|
||||
all_box.y2 = child_box.y2;
|
||||
}
|
||||
}
|
||||
|
||||
*box = all_box;
|
||||
}
|
||||
}
|
||||
|
||||
@ -234,6 +429,8 @@ clutter_group_dispose (GObject *object)
|
||||
if (priv->children)
|
||||
{
|
||||
g_list_foreach (priv->children, (GFunc) clutter_actor_destroy, NULL);
|
||||
g_list_free (priv->children);
|
||||
|
||||
priv->children = NULL;
|
||||
}
|
||||
|
||||
@ -277,6 +474,11 @@ clutter_group_real_add (ClutterContainer *container,
|
||||
priv->children = g_list_append (priv->children, actor);
|
||||
clutter_actor_set_parent (actor, CLUTTER_ACTOR (group));
|
||||
|
||||
/* queue a relayout, to get the correct positioning inside
|
||||
* the ::actor-added signal handlers
|
||||
*/
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (group));
|
||||
|
||||
g_signal_emit_by_name (container, "actor-added", actor);
|
||||
|
||||
clutter_group_sort_depth_order (group);
|
||||
@ -303,6 +505,11 @@ clutter_group_real_remove (ClutterContainer *container,
|
||||
priv->children = g_list_remove (priv->children, actor);
|
||||
clutter_actor_unparent (actor);
|
||||
|
||||
/* queue a relayout, to get the correct positioning inside
|
||||
* the ::actor-removed signal handlers
|
||||
*/
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (group));
|
||||
|
||||
/* at this point, the actor passed to the "actor-removed" signal
|
||||
* handlers is not parented anymore to the container but since we
|
||||
* are holding a reference on it, it's still valid
|
||||
@ -459,11 +666,14 @@ clutter_group_class_init (ClutterGroupClass *klass)
|
||||
actor_class->pick = clutter_group_pick;
|
||||
actor_class->show_all = clutter_group_real_show_all;
|
||||
actor_class->hide_all = clutter_group_real_hide_all;
|
||||
actor_class->request_coords = clutter_group_request_coords;
|
||||
actor_class->query_coords = clutter_group_query_coords;
|
||||
actor_class->realize = clutter_group_realize;
|
||||
actor_class->unrealize = clutter_group_unrealize;
|
||||
|
||||
actor_class->get_preferred_width = clutter_group_get_preferred_width;
|
||||
actor_class->get_preferred_height = clutter_group_get_preferred_height;
|
||||
actor_class->allocate = clutter_group_allocate;
|
||||
actor_class->get_paint_area = clutter_group_get_paint_area;
|
||||
|
||||
/**
|
||||
* ClutterGroup::add:
|
||||
* @group: the #ClutterGroup that received the signal
|
||||
|
@ -48,7 +48,7 @@
|
||||
G_DEFINE_TYPE (ClutterLabel, clutter_label, CLUTTER_TYPE_ACTOR)
|
||||
|
||||
/* Probably move into main */
|
||||
static PangoContext *_context = NULL;
|
||||
static PangoContext *_context = NULL;
|
||||
|
||||
enum
|
||||
{
|
||||
@ -75,8 +75,6 @@ struct _ClutterLabelPrivate
|
||||
|
||||
ClutterColor fgcol;
|
||||
|
||||
ClutterActorBox allocation;
|
||||
|
||||
gchar *text;
|
||||
gchar *font_name;
|
||||
|
||||
@ -95,194 +93,83 @@ struct _ClutterLabelPrivate
|
||||
PangoAttrList *attrs;
|
||||
PangoAttrList *effective_attrs;
|
||||
PangoLayout *layout;
|
||||
gint width_chars;
|
||||
gint wrap_width;
|
||||
};
|
||||
|
||||
static gint
|
||||
get_label_char_width (ClutterLabel *label)
|
||||
/*
|
||||
* clutter_label_create_layout:
|
||||
* @label: a #ClutterLabel
|
||||
* @allocation_width: the width of the layout, or -1
|
||||
*
|
||||
* Creates a new #PangoLayout for the given @allocation_width, using
|
||||
* the layout properties of the @label.
|
||||
*/
|
||||
static PangoLayout *
|
||||
clutter_label_create_layout (ClutterLabel *label,
|
||||
ClutterUnit allocation_width)
|
||||
{
|
||||
ClutterLabelPrivate *priv = label->priv;
|
||||
PangoContext *context;
|
||||
PangoFontMetrics *metrics;
|
||||
gint char_width, digit_width, char_pixels, w;
|
||||
|
||||
context = pango_layout_get_context (priv->layout);
|
||||
metrics = pango_context_get_metrics (context, priv->font_desc,
|
||||
pango_context_get_language (context));
|
||||
char_width = pango_font_metrics_get_approximate_char_width (metrics);
|
||||
digit_width = pango_font_metrics_get_approximate_digit_width (metrics);
|
||||
char_pixels = MAX (char_width, digit_width);
|
||||
pango_font_metrics_unref (metrics);
|
||||
PangoLayout *layout;
|
||||
|
||||
if (priv->width_chars < 0)
|
||||
layout = pango_layout_new (_context);
|
||||
|
||||
if (priv->effective_attrs)
|
||||
pango_layout_set_attributes (layout, priv->effective_attrs);
|
||||
|
||||
pango_layout_set_alignment (layout, priv->alignment);
|
||||
pango_layout_set_single_paragraph_mode (layout, priv->single_line_mode);
|
||||
|
||||
pango_layout_set_font_description (layout, priv->font_desc);
|
||||
pango_layout_set_justify (layout, priv->justify);
|
||||
|
||||
if (priv->text)
|
||||
{
|
||||
PangoRectangle rect;
|
||||
|
||||
pango_layout_set_width (priv->layout, -1);
|
||||
pango_layout_get_extents (priv->layout, NULL, &rect);
|
||||
|
||||
w = char_pixels * 5;
|
||||
w = MIN (rect.width, w);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* enforce minimum width for ellipsized labels at ~5 chars */
|
||||
w = char_pixels * MAX (priv->width_chars, 5);
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static gint
|
||||
get_label_wrap_width (ClutterLabel *label)
|
||||
{
|
||||
ClutterLabelPrivate *priv = label->priv;
|
||||
|
||||
if (priv->wrap_width < 0)
|
||||
{
|
||||
if (priv->width_chars > 0)
|
||||
priv->wrap_width = get_label_char_width (label);
|
||||
if (!priv->use_markup)
|
||||
pango_layout_set_text (layout, priv->text, -1);
|
||||
else
|
||||
{
|
||||
PangoLayout *tmp;
|
||||
|
||||
tmp = pango_layout_new (_context);
|
||||
pango_layout_set_font_description (tmp, priv->font_desc);
|
||||
pango_layout_set_text (tmp, "This is a very long string, which "
|
||||
"should be enough for a wrap width.",
|
||||
-1);
|
||||
pango_layout_get_size (tmp, &priv->wrap_width, NULL);
|
||||
g_object_unref (tmp);
|
||||
}
|
||||
pango_layout_set_markup (layout, priv->text, -1);
|
||||
}
|
||||
|
||||
return priv->wrap_width;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_label_ensure_layout (ClutterLabel *label)
|
||||
{
|
||||
ClutterLabelPrivate *priv;
|
||||
ClutterUnit raw_width;
|
||||
gint width;
|
||||
|
||||
priv = label->priv;
|
||||
|
||||
/* use the last size requested, if any */
|
||||
raw_width = priv->allocation.x2 - priv->allocation.x1;
|
||||
width = CLUTTER_UNITS_TO_DEVICE (raw_width);
|
||||
|
||||
if (!priv->layout)
|
||||
if (allocation_width > 0)
|
||||
{
|
||||
priv->layout = pango_layout_new (_context);
|
||||
int layout_width, layout_height;
|
||||
|
||||
if (priv->effective_attrs)
|
||||
pango_layout_set_attributes (priv->layout, priv->effective_attrs);
|
||||
|
||||
pango_layout_set_alignment (priv->layout, priv->alignment);
|
||||
pango_layout_set_ellipsize (priv->layout, priv->ellipsize);
|
||||
pango_layout_set_single_paragraph_mode (priv->layout,
|
||||
priv->single_line_mode);
|
||||
|
||||
pango_layout_set_font_description (priv->layout, priv->font_desc);
|
||||
pango_layout_set_justify (priv->layout, priv->justify);
|
||||
|
||||
if (priv->text)
|
||||
{
|
||||
if (!priv->use_markup)
|
||||
pango_layout_set_text (priv->layout, priv->text, -1);
|
||||
else
|
||||
pango_layout_set_markup (priv->layout, priv->text, -1);
|
||||
}
|
||||
|
||||
if (priv->ellipsize != PANGO_ELLIPSIZE_NONE)
|
||||
pango_layout_set_width (priv->layout, raw_width > 0 ? CLUTTER_UNITS_TO_PANGO_UNIT (raw_width)
|
||||
: -1);
|
||||
else if (priv->wrap)
|
||||
pango_layout_get_size (layout, &layout_width, &layout_height);
|
||||
|
||||
/* No need to set ellipsize or wrap if we already have enough
|
||||
* space, since we don't want to make the layout wider than it
|
||||
* would be otherwise.
|
||||
*/
|
||||
|
||||
if (CLUTTER_UNITS_FROM_PANGO_UNIT (layout_width) > allocation_width)
|
||||
{
|
||||
pango_layout_set_wrap (priv->layout, priv->wrap_mode);
|
||||
|
||||
if (width > 0)
|
||||
pango_layout_set_width (priv->layout, CLUTTER_UNITS_TO_PANGO_UNIT (raw_width));
|
||||
else
|
||||
if (priv->ellipsize != PANGO_ELLIPSIZE_NONE)
|
||||
{
|
||||
/* this was adapted from the GtkLabel code */
|
||||
ClutterActor *stage = clutter_stage_get_default ();
|
||||
gint stage_width = clutter_actor_get_width (stage);
|
||||
gint longest_paragraph, height, wrap_width;
|
||||
PangoRectangle logical_rect;
|
||||
gint width;
|
||||
|
||||
pango_layout_set_width (priv->layout, -1);
|
||||
pango_layout_get_extents (priv->layout, NULL, &logical_rect);
|
||||
width = allocation_width > 0
|
||||
? CLUTTER_UNITS_TO_PANGO_UNIT (allocation_width)
|
||||
: -1;
|
||||
|
||||
width = logical_rect.width;
|
||||
|
||||
longest_paragraph = width;
|
||||
|
||||
wrap_width = get_label_wrap_width (label);
|
||||
width = MAX (width, wrap_width);
|
||||
width = MIN (width, PANGO_SCALE * (stage_width + 1) / 2);
|
||||
|
||||
pango_layout_set_width (priv->layout, width);
|
||||
pango_layout_get_extents (priv->layout, NULL, &logical_rect);
|
||||
width = logical_rect.width;
|
||||
height = logical_rect.height;
|
||||
|
||||
if (longest_paragraph > 0)
|
||||
{
|
||||
gint n_lines, perfect_width;
|
||||
|
||||
n_lines = pango_layout_get_line_count (priv->layout);
|
||||
perfect_width = (longest_paragraph + n_lines - 1) / n_lines;
|
||||
|
||||
if (perfect_width < width)
|
||||
{
|
||||
pango_layout_set_width (priv->layout, perfect_width);
|
||||
pango_layout_get_extents (priv->layout, NULL,
|
||||
&logical_rect);
|
||||
|
||||
if (logical_rect.height <= height)
|
||||
width = logical_rect.width = width;
|
||||
else
|
||||
{
|
||||
gint mid_width = (perfect_width + width) / 2;
|
||||
|
||||
if (mid_width > perfect_width)
|
||||
{
|
||||
pango_layout_set_width (priv->layout, mid_width);
|
||||
pango_layout_get_extents (priv->layout, NULL,
|
||||
&logical_rect);
|
||||
|
||||
if (logical_rect.height <= height);
|
||||
width = logical_rect.width;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pango_layout_set_width (priv->layout, width);
|
||||
pango_layout_set_ellipsize (layout, priv->ellipsize);
|
||||
pango_layout_set_width (layout, width);
|
||||
}
|
||||
}
|
||||
else
|
||||
pango_layout_set_width (priv->layout, raw_width > 0 ? CLUTTER_UNITS_TO_PANGO_UNIT (raw_width)
|
||||
: -1);
|
||||
else if (priv->wrap)
|
||||
{
|
||||
gint width;
|
||||
|
||||
/* Prime the glyph cache */
|
||||
pango_clutter_ensure_glyph_cache_for_layout (priv->layout);
|
||||
width = allocation_width > 0
|
||||
? CLUTTER_UNITS_TO_PANGO_UNIT (allocation_width)
|
||||
: -1;
|
||||
|
||||
pango_layout_set_wrap (layout, priv->wrap_mode);
|
||||
pango_layout_set_width (layout, width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CLUTTER_NOTE (ACTOR, "Label width set to %d pixels", width);
|
||||
}
|
||||
pango_clutter_ensure_glyph_cache_for_layout (layout);
|
||||
|
||||
static void
|
||||
clutter_label_clear_layout (ClutterLabel *label)
|
||||
{
|
||||
if (label->priv->layout)
|
||||
{
|
||||
g_object_unref (label->priv->layout);
|
||||
label->priv->layout = NULL;
|
||||
}
|
||||
return layout;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -294,8 +181,7 @@ clutter_label_paint (ClutterActor *self)
|
||||
|
||||
if (priv->font_desc == NULL || priv->text == NULL)
|
||||
{
|
||||
CLUTTER_NOTE (ACTOR, "layout: %p, desc: %p, text %p",
|
||||
priv->layout,
|
||||
CLUTTER_NOTE (ACTOR, "desc: %p, text %p",
|
||||
priv->font_desc ? priv->font_desc : 0x0,
|
||||
priv->text ? priv->text : 0x0);
|
||||
return;
|
||||
@ -303,85 +189,115 @@ clutter_label_paint (ClutterActor *self)
|
||||
|
||||
CLUTTER_NOTE (PAINT, "painting label (text:`%s')", priv->text);
|
||||
|
||||
clutter_label_ensure_layout (label);
|
||||
/* XXX - this should never happen, as the layout is always
|
||||
* recreated when the label allocation changes
|
||||
*/
|
||||
if (G_UNLIKELY (!priv->layout))
|
||||
{
|
||||
ClutterActorBox alloc = { 0, };
|
||||
|
||||
clutter_actor_get_allocation_box (self, &alloc);
|
||||
priv->layout = clutter_label_create_layout (label, alloc.x2 - alloc.x1);
|
||||
}
|
||||
|
||||
memcpy (&color, &priv->fgcol, sizeof (ClutterColor));
|
||||
color.alpha = clutter_actor_get_abs_opacity (self);
|
||||
color.alpha = clutter_actor_get_paint_opacity (self);
|
||||
|
||||
pango_clutter_render_layout (priv->layout, 0, 0, &color, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_label_query_coords (ClutterActor *self,
|
||||
ClutterActorBox *box)
|
||||
{
|
||||
ClutterLabel *label = CLUTTER_LABEL(self);
|
||||
ClutterLabelPrivate *priv;
|
||||
ClutterActorBox layout_box = { 0, };
|
||||
PangoRectangle logical_rect;
|
||||
clutter_label_get_preferred_width (ClutterActor *self,
|
||||
ClutterUnit for_height,
|
||||
ClutterUnit *min_width_p,
|
||||
ClutterUnit *natural_width_p)
|
||||
{
|
||||
ClutterLabel *label = CLUTTER_LABEL (self);
|
||||
ClutterLabelPrivate *priv = label->priv;
|
||||
PangoRectangle logical_rect = { 0, };
|
||||
PangoLayout *layout;
|
||||
|
||||
priv = label->priv;
|
||||
/* we create a layout to compute the width request; we ignore the
|
||||
* passed height because ClutterLabel is a height-for-width actor
|
||||
*/
|
||||
layout = clutter_label_create_layout (label, -1);
|
||||
|
||||
if (priv->wrap)
|
||||
clutter_label_clear_layout (label);
|
||||
pango_layout_get_extents (layout, NULL, &logical_rect);
|
||||
|
||||
clutter_label_ensure_layout (label);
|
||||
|
||||
pango_layout_get_extents (priv->layout, NULL, &logical_rect);
|
||||
|
||||
layout_box.x1 = box->x1;
|
||||
layout_box.x2 = box->x1 + CLUTTER_UNITS_FROM_PANGO_UNIT (logical_rect.width);
|
||||
layout_box.y1 = box->y1;
|
||||
layout_box.y2 = box->y1 + CLUTTER_UNITS_FROM_PANGO_UNIT (logical_rect.height);
|
||||
|
||||
if ((priv->allocation.x2 - priv->allocation.x1) > 0)
|
||||
if (min_width_p)
|
||||
{
|
||||
ClutterUnit alloc_width, alloc_height;
|
||||
|
||||
alloc_width = priv->allocation.x2 - priv->allocation.x1;
|
||||
alloc_height = priv->allocation.y2 - priv->allocation.y1;
|
||||
|
||||
if ((alloc_width >= (layout_box.x2 - layout_box.x1)) &&
|
||||
(alloc_height >= (layout_box.y2 - layout_box.y1)))
|
||||
*box = priv->allocation;
|
||||
if (priv->wrap || priv->ellipsize)
|
||||
*min_width_p = 1;
|
||||
else
|
||||
*box = layout_box;
|
||||
|
||||
return;
|
||||
*min_width_p = CLUTTER_UNITS_FROM_PANGO_UNIT (logical_rect.width);
|
||||
}
|
||||
else
|
||||
*box = layout_box;
|
||||
|
||||
if (natural_width_p)
|
||||
*natural_width_p = CLUTTER_UNITS_FROM_PANGO_UNIT (logical_rect.width);
|
||||
|
||||
g_object_unref (layout);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_label_request_coords (ClutterActor *self,
|
||||
ClutterActorBox *box)
|
||||
clutter_label_get_preferred_height (ClutterActor *self,
|
||||
ClutterUnit for_width,
|
||||
ClutterUnit *min_height_p,
|
||||
ClutterUnit *natural_height_p)
|
||||
{
|
||||
ClutterLabel *label = CLUTTER_LABEL (self);
|
||||
|
||||
if (for_width == 0)
|
||||
{
|
||||
if (min_height_p)
|
||||
*min_height_p = 0;
|
||||
|
||||
if (natural_height_p)
|
||||
*natural_height_p = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
PangoLayout *layout;
|
||||
PangoRectangle logical_rect = { 0, };
|
||||
ClutterUnit height;
|
||||
|
||||
/* we create a new layout to compute the height for the
|
||||
* given width and then discard it
|
||||
*/
|
||||
layout = clutter_label_create_layout (label, for_width);
|
||||
|
||||
pango_layout_get_extents (layout, NULL, &logical_rect);
|
||||
height = CLUTTER_UNITS_FROM_PANGO_UNIT (logical_rect.height);
|
||||
|
||||
if (min_height_p)
|
||||
*min_height_p = height;
|
||||
|
||||
if (natural_height_p)
|
||||
*natural_height_p = height;
|
||||
|
||||
g_object_unref (layout);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_label_allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
gboolean origin_changed)
|
||||
{
|
||||
ClutterLabel *label = CLUTTER_LABEL (self);
|
||||
ClutterLabelPrivate *priv = label->priv;
|
||||
ClutterActorClass *parent_class;
|
||||
|
||||
if (priv->ellipsize)
|
||||
/* the allocation was changed, so we must recreate the layout */
|
||||
if (priv->layout)
|
||||
{
|
||||
if (priv->layout)
|
||||
{
|
||||
gint width;
|
||||
PangoRectangle logical;
|
||||
|
||||
width = CLUTTER_UNITS_TO_PANGO_UNIT (box->x2 - box->x1);
|
||||
|
||||
pango_layout_set_width (priv->layout, -1);
|
||||
pango_layout_get_extents (priv->layout, NULL, &logical);
|
||||
|
||||
if (logical.width > width)
|
||||
pango_layout_set_width (priv->layout, width);
|
||||
}
|
||||
g_object_unref (priv->layout);
|
||||
priv->layout = NULL;
|
||||
}
|
||||
else
|
||||
clutter_label_clear_layout (label);
|
||||
|
||||
priv->allocation = *box;
|
||||
priv->layout = clutter_label_create_layout (label, box->x2 - box->x1);
|
||||
|
||||
CLUTTER_ACTOR_CLASS (clutter_label_parent_class)->request_coords (self, box);
|
||||
parent_class = CLUTTER_ACTOR_CLASS (clutter_label_parent_class);
|
||||
parent_class->allocate (self, box, origin_changed);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -532,9 +448,10 @@ clutter_label_class_init (ClutterLabelClass *klass)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
|
||||
actor_class->paint = clutter_label_paint;
|
||||
actor_class->request_coords = clutter_label_request_coords;
|
||||
actor_class->query_coords = clutter_label_query_coords;
|
||||
actor_class->paint = clutter_label_paint;
|
||||
actor_class->get_preferred_width = clutter_label_get_preferred_width;
|
||||
actor_class->get_preferred_height = clutter_label_get_preferred_height;
|
||||
actor_class->allocate = clutter_label_allocate;
|
||||
|
||||
gobject_class->finalize = clutter_label_finalize;
|
||||
gobject_class->dispose = clutter_label_dispose;
|
||||
@ -667,9 +584,6 @@ clutter_label_init (ClutterLabel *self)
|
||||
priv->text = NULL;
|
||||
priv->attrs = NULL;
|
||||
|
||||
priv->width_chars = -1;
|
||||
priv->wrap_width = -1;
|
||||
|
||||
priv->fgcol.red = 0;
|
||||
priv->fgcol.green = 0;
|
||||
priv->fgcol.blue = 0;
|
||||
@ -768,21 +682,12 @@ clutter_label_set_text (ClutterLabel *label,
|
||||
|
||||
priv = label->priv;
|
||||
|
||||
g_object_ref (label);
|
||||
|
||||
g_free (priv->text);
|
||||
priv->text = g_strdup (text);
|
||||
|
||||
clutter_label_clear_layout (label);
|
||||
/* Recreate the layout now so that the glyph cache will be primed
|
||||
outside of the paint run */
|
||||
clutter_label_ensure_layout (label);
|
||||
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (CLUTTER_ACTOR(label)))
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR(label));
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (label));
|
||||
|
||||
g_object_notify (G_OBJECT (label), "text");
|
||||
g_object_unref (label);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -841,8 +746,6 @@ clutter_label_set_font_name (ClutterLabel *label,
|
||||
return;
|
||||
}
|
||||
|
||||
g_object_ref (label);
|
||||
|
||||
g_free (priv->font_name);
|
||||
priv->font_name = g_strdup (font_name);
|
||||
|
||||
@ -850,21 +753,11 @@ clutter_label_set_font_name (ClutterLabel *label,
|
||||
pango_font_description_free (priv->font_desc);
|
||||
|
||||
priv->font_desc = desc;
|
||||
priv->wrap_width = -1;
|
||||
|
||||
if (label->priv->text && label->priv->text[0] != '\0')
|
||||
{
|
||||
clutter_label_clear_layout (label);
|
||||
/* Recreate the layout now so that the glyph cache will be
|
||||
primed outside of the paint run */
|
||||
clutter_label_ensure_layout (label);
|
||||
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (label))
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (label));
|
||||
}
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (label));
|
||||
|
||||
g_object_notify (G_OBJECT (label), "font-name");
|
||||
g_object_unref (label);
|
||||
}
|
||||
|
||||
|
||||
@ -953,20 +846,11 @@ clutter_label_set_ellipsize (ClutterLabel *label,
|
||||
|
||||
if ((PangoEllipsizeMode) priv->ellipsize != mode)
|
||||
{
|
||||
g_object_ref (label);
|
||||
|
||||
priv->ellipsize = mode;
|
||||
|
||||
clutter_label_clear_layout (label);
|
||||
/* Recreate the layout now so that the glyph cache will be
|
||||
primed outside of the paint run */
|
||||
clutter_label_ensure_layout (label);
|
||||
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (CLUTTER_ACTOR(label)))
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR(label));
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (label));
|
||||
|
||||
g_object_notify (G_OBJECT (label), "ellipsize");
|
||||
g_object_unref (label);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1015,17 +899,11 @@ clutter_label_set_line_wrap (ClutterLabel *label,
|
||||
|
||||
if (priv->wrap != wrap)
|
||||
{
|
||||
g_object_ref (label);
|
||||
|
||||
priv->wrap = wrap;
|
||||
|
||||
clutter_label_clear_layout (label);
|
||||
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (CLUTTER_ACTOR (label)))
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (label));
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (label));
|
||||
|
||||
g_object_notify (G_OBJECT (label), "wrap");
|
||||
g_object_unref (label);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1071,17 +949,11 @@ clutter_label_set_line_wrap_mode (ClutterLabel *label,
|
||||
|
||||
if (priv->wrap_mode != wrap_mode)
|
||||
{
|
||||
g_object_ref (label);
|
||||
|
||||
priv->wrap_mode = wrap_mode;
|
||||
|
||||
clutter_label_clear_layout (label);
|
||||
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (CLUTTER_ACTOR (label)))
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (label));
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (label));
|
||||
|
||||
g_object_notify (G_OBJECT (label), "wrap-mode");
|
||||
g_object_unref (label);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1118,13 +990,11 @@ clutter_label_get_line_wrap_mode (ClutterLabel *label)
|
||||
*
|
||||
* Since: 0.2
|
||||
**/
|
||||
PangoLayout*
|
||||
PangoLayout *
|
||||
clutter_label_get_layout (ClutterLabel *label)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_LABEL (label), NULL);
|
||||
|
||||
clutter_label_ensure_layout (label);
|
||||
|
||||
return label->priv->layout;
|
||||
}
|
||||
|
||||
@ -1136,8 +1006,6 @@ clutter_label_set_attributes_internal (ClutterLabel *label,
|
||||
|
||||
priv = label->priv;
|
||||
|
||||
g_object_ref (label);
|
||||
|
||||
if (attrs)
|
||||
pango_attr_list_ref (attrs);
|
||||
|
||||
@ -1148,6 +1016,7 @@ clutter_label_set_attributes_internal (ClutterLabel *label,
|
||||
{
|
||||
if (attrs)
|
||||
pango_attr_list_ref (attrs);
|
||||
|
||||
if (priv->effective_attrs)
|
||||
pango_attr_list_unref (priv->effective_attrs);
|
||||
priv->effective_attrs = attrs;
|
||||
@ -1155,7 +1024,6 @@ clutter_label_set_attributes_internal (ClutterLabel *label,
|
||||
|
||||
label->priv->attrs = attrs;
|
||||
g_object_notify (G_OBJECT (label), "attributes");
|
||||
g_object_unref (label);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1178,10 +1046,7 @@ clutter_label_set_attributes (ClutterLabel *label,
|
||||
|
||||
clutter_label_set_attributes_internal (label, attrs);
|
||||
|
||||
clutter_label_clear_layout (label);
|
||||
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (CLUTTER_ACTOR(label)))
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR(label));
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (label));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1224,19 +1089,11 @@ clutter_label_set_use_markup (ClutterLabel *label,
|
||||
|
||||
if (priv->use_markup != setting)
|
||||
{
|
||||
g_object_ref (label);
|
||||
|
||||
priv->use_markup = setting;
|
||||
clutter_label_clear_layout (label);
|
||||
/* Recreate the layout now so that the glyph cache will be
|
||||
primed outside of the paint run */
|
||||
clutter_label_ensure_layout (label);
|
||||
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (CLUTTER_ACTOR (label)))
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (label));
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (label));
|
||||
|
||||
g_object_notify (G_OBJECT (label), "use-markup");
|
||||
g_object_unref (label);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1277,16 +1134,11 @@ clutter_label_set_alignment (ClutterLabel *label,
|
||||
|
||||
if (priv->alignment != alignment)
|
||||
{
|
||||
g_object_ref (label);
|
||||
|
||||
priv->alignment = alignment;
|
||||
clutter_label_clear_layout (label);
|
||||
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (CLUTTER_ACTOR (label)))
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (label));
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (label));
|
||||
|
||||
g_object_notify (G_OBJECT (label), "alignment");
|
||||
g_object_unref (label);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1333,10 +1185,7 @@ clutter_label_set_justify (ClutterLabel *label,
|
||||
{
|
||||
priv->justify = justify;
|
||||
|
||||
clutter_label_clear_layout (label);
|
||||
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (label))
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (label));
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (label));
|
||||
|
||||
g_object_notify (G_OBJECT (label), "justify");
|
||||
}
|
||||
|
@ -106,8 +106,41 @@ clutter_get_show_fps (void)
|
||||
return clutter_show_fps;
|
||||
}
|
||||
|
||||
static inline void
|
||||
clutter_maybe_setup_viewport (ClutterStage *stage)
|
||||
void
|
||||
_clutter_stage_maybe_relayout (ClutterActor *stage)
|
||||
{
|
||||
ClutterUnit natural_width, natural_height;
|
||||
ClutterActorBox box = { 0, };
|
||||
|
||||
/* avoid reentrancy */
|
||||
if (!(CLUTTER_PRIVATE_FLAGS (stage) & CLUTTER_ACTOR_IN_RELAYOUT))
|
||||
{
|
||||
CLUTTER_NOTE (ACTOR, "Recomputing layout");
|
||||
|
||||
CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_IN_RELAYOUT);
|
||||
|
||||
natural_width = natural_height = 0;
|
||||
clutter_actor_get_preferred_size (stage,
|
||||
NULL, NULL,
|
||||
&natural_width, &natural_height);
|
||||
|
||||
box.x1 = 0;
|
||||
box.y1 = 0;
|
||||
box.x2 = natural_width;
|
||||
box.y2 = natural_height;
|
||||
|
||||
CLUTTER_NOTE (ACTOR, "Allocating (0, 0 - %d, %d) for the stage",
|
||||
CLUTTER_UNITS_TO_DEVICE (natural_width),
|
||||
CLUTTER_UNITS_TO_DEVICE (natural_height));
|
||||
|
||||
clutter_actor_allocate (stage, &box, FALSE);
|
||||
|
||||
CLUTTER_UNSET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_IN_RELAYOUT);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_stage_maybe_setup_viewport (ClutterStage *stage)
|
||||
{
|
||||
if (CLUTTER_PRIVATE_FLAGS (stage) & CLUTTER_ACTOR_SYNC_MATRICES)
|
||||
{
|
||||
@ -148,6 +181,9 @@ clutter_redraw (ClutterStage *stage)
|
||||
CLUTTER_NOTE (PAINT, " Redraw enter for stage:%p", stage);
|
||||
CLUTTER_NOTE (MULTISTAGE, "Redraw called for stage:%p", stage);
|
||||
|
||||
/* Before we can paint, we have to be sure we have the latest layout */
|
||||
_clutter_stage_maybe_relayout (CLUTTER_ACTOR (stage));
|
||||
|
||||
_clutter_backend_ensure_context (ctx->backend, stage);
|
||||
|
||||
/* Setup FPS count - not currently across *all* stages rather than per */
|
||||
@ -160,7 +196,7 @@ clutter_redraw (ClutterStage *stage)
|
||||
/* The code below can't go in stage paint as base actor_paint
|
||||
* will get called before it (and break picking, etc)
|
||||
*/
|
||||
clutter_maybe_setup_viewport (stage);
|
||||
_clutter_stage_maybe_setup_viewport (stage);
|
||||
|
||||
/* Call through to the actual backend to do the painting down from
|
||||
* the stage. It will likely need to swap buffers, vblank sync etc
|
||||
@ -322,7 +358,7 @@ _clutter_do_pick (ClutterStage *stage,
|
||||
_clutter_backend_ensure_context (context->backend, stage);
|
||||
|
||||
/* needed for when a context switch happens */
|
||||
clutter_maybe_setup_viewport (stage);
|
||||
_clutter_stage_maybe_setup_viewport (stage);
|
||||
|
||||
cogl_paint_init (&white);
|
||||
|
||||
@ -2118,3 +2154,27 @@ clutter_set_use_mipmapped_text (gboolean value)
|
||||
pango_clutter_font_map_set_use_mipmapping (CLUTTER_CONTEXT ()->font_map,
|
||||
value);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_get_use_mipmapped_text:
|
||||
*
|
||||
* Gets whether mipmapped textures are used in text operations.
|
||||
* See clutter_set_use_mipmapped_text().
|
||||
*
|
||||
* Return value: %TRUE if text operations should use mipmapped
|
||||
* textures
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
gboolean
|
||||
clutter_get_use_mipmapped_text (void)
|
||||
{
|
||||
PangoClutterFontMap *font_map = NULL;
|
||||
|
||||
font_map = CLUTTER_CONTEXT ()->font_map;
|
||||
|
||||
if (font_map)
|
||||
return pango_clutter_font_map_get_use_mipmapping (font_map);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -129,6 +129,7 @@ ClutterActor * clutter_get_keyboard_grab (void);
|
||||
|
||||
void clutter_clear_glyph_cache (void);
|
||||
void clutter_set_use_mipmapped_text (gboolean value);
|
||||
gboolean clutter_get_use_mipmapped_text (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -59,7 +59,8 @@ typedef enum {
|
||||
* viewport / perspective etc
|
||||
* needs (re)setting.
|
||||
*/
|
||||
CLUTTER_ACTOR_IN_PAINT = 1 << 4 /* Used to avoid recursion */
|
||||
CLUTTER_ACTOR_IN_PAINT = 1 << 4, /* Used to avoid recursion */
|
||||
CLUTTER_ACTOR_IN_RELAYOUT = 1 << 5 /* Used to avoid recursion */
|
||||
} ClutterPrivateFlags;
|
||||
|
||||
typedef enum {
|
||||
@ -142,10 +143,12 @@ void _clutter_stage_manager_remove_stage (ClutterStageManager *stage_manager,
|
||||
|
||||
/* stage */
|
||||
|
||||
void _clutter_stage_set_window (ClutterStage *stage,
|
||||
ClutterStageWindow *stage_window);
|
||||
ClutterStageWindow *_clutter_stage_get_window (ClutterStage *stage);
|
||||
ClutterStageWindow *_clutter_stage_get_default_window (void);
|
||||
void _clutter_stage_set_window (ClutterStage *stage,
|
||||
ClutterStageWindow *stage_window);
|
||||
ClutterStageWindow *_clutter_stage_get_window (ClutterStage *stage);
|
||||
ClutterStageWindow *_clutter_stage_get_default_window (void);
|
||||
void _clutter_stage_maybe_setup_viewport (ClutterStage *stage);
|
||||
void _clutter_stage_maybe_relayout (ClutterActor *stage);
|
||||
|
||||
/* vfuncs implemented by backend */
|
||||
GType _clutter_backend_impl_get_type (void);
|
||||
|
@ -84,7 +84,7 @@ clutter_rectangle_paint (ClutterActor *self)
|
||||
: "unknown");
|
||||
cogl_push_matrix();
|
||||
|
||||
clutter_actor_get_geometry (self, &geom);
|
||||
clutter_actor_get_allocation_geometry (self, &geom);
|
||||
|
||||
/* parent paint call will have translated us into position so
|
||||
* paint from 0, 0
|
||||
@ -94,8 +94,9 @@ clutter_rectangle_paint (ClutterActor *self)
|
||||
tmp_col.red = priv->border_color.red;
|
||||
tmp_col.green = priv->border_color.green;
|
||||
tmp_col.blue = priv->border_color.blue;
|
||||
tmp_col.alpha = (clutter_actor_get_abs_opacity (self) *
|
||||
priv->border_color.alpha) / 0xff;
|
||||
tmp_col.alpha = clutter_actor_get_paint_opacity (self)
|
||||
* priv->border_color.alpha
|
||||
/ 255;
|
||||
|
||||
cogl_color (&tmp_col);
|
||||
|
||||
@ -120,13 +121,13 @@ clutter_rectangle_paint (ClutterActor *self)
|
||||
tmp_col.red = priv->color.red;
|
||||
tmp_col.green = priv->color.green;
|
||||
tmp_col.blue = priv->color.blue;
|
||||
tmp_col.alpha = (clutter_actor_get_abs_opacity (self) *
|
||||
priv->color.alpha) / 0xff;
|
||||
tmp_col.alpha = clutter_actor_get_paint_opacity (self)
|
||||
* priv->color.alpha
|
||||
/ 255;
|
||||
|
||||
cogl_color (&tmp_col);
|
||||
|
||||
cogl_rectangle (priv->border_width,
|
||||
priv->border_width,
|
||||
cogl_rectangle (priv->border_width, priv->border_width,
|
||||
geom.width - priv->border_width * 2,
|
||||
geom.height - priv->border_width * 2);
|
||||
}
|
||||
@ -135,8 +136,9 @@ clutter_rectangle_paint (ClutterActor *self)
|
||||
tmp_col.red = priv->color.red;
|
||||
tmp_col.green = priv->color.green;
|
||||
tmp_col.blue = priv->color.blue;
|
||||
tmp_col.alpha = (clutter_actor_get_abs_opacity (self) *
|
||||
priv->color.alpha) / 0xff;
|
||||
tmp_col.alpha = clutter_actor_get_paint_opacity (self)
|
||||
* priv->color.alpha
|
||||
/ 255;
|
||||
|
||||
cogl_color (&tmp_col);
|
||||
|
||||
|
@ -121,25 +121,52 @@ enum
|
||||
static guint stage_signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
static void
|
||||
clutter_stage_request_coords (ClutterActor *self,
|
||||
ClutterActorBox *box)
|
||||
clutter_stage_get_preferred_width (ClutterActor *self,
|
||||
ClutterUnit for_height,
|
||||
ClutterUnit *min_width_p,
|
||||
ClutterUnit *natural_width_p)
|
||||
{
|
||||
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
|
||||
|
||||
g_assert (priv->impl != NULL);
|
||||
CLUTTER_ACTOR_GET_CLASS (priv->impl)->request_coords (priv->impl, box);
|
||||
|
||||
CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->request_coords (self, box);
|
||||
CLUTTER_ACTOR_GET_CLASS (priv->impl)->get_preferred_width (priv->impl,
|
||||
for_height,
|
||||
min_width_p,
|
||||
natural_width_p);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_query_coords (ClutterActor *self,
|
||||
ClutterActorBox *box)
|
||||
clutter_stage_get_preferred_height (ClutterActor *self,
|
||||
ClutterUnit for_width,
|
||||
ClutterUnit *min_height_p,
|
||||
ClutterUnit *natural_height_p)
|
||||
{
|
||||
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
|
||||
|
||||
g_assert (priv->impl != NULL);
|
||||
CLUTTER_ACTOR_GET_CLASS (priv->impl)->query_coords (priv->impl, box);
|
||||
|
||||
CLUTTER_ACTOR_GET_CLASS (priv->impl)->get_preferred_height (priv->impl,
|
||||
for_width,
|
||||
min_height_p,
|
||||
natural_height_p);
|
||||
}
|
||||
static void
|
||||
clutter_stage_allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
gboolean origin_changed)
|
||||
{
|
||||
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
|
||||
|
||||
g_assert (priv->impl != NULL);
|
||||
|
||||
CLUTTER_ACTOR_GET_CLASS (priv->impl)->allocate (priv->impl,
|
||||
box,
|
||||
origin_changed);
|
||||
|
||||
CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->allocate (self,
|
||||
box,
|
||||
origin_changed);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -242,6 +269,32 @@ clutter_stage_hide (ClutterActor *self)
|
||||
CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->hide (self);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_real_fullscreen (ClutterStage *stage)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
ClutterUnit natural_width, natural_height;
|
||||
ClutterActorBox box;
|
||||
|
||||
/* we need to force an allocation here because the size
|
||||
* of the stage might have been changed by the backend
|
||||
*
|
||||
* this is a really bad solution to the issues caused by
|
||||
* the fact that fullscreening the stage on the X11 backends
|
||||
* is really an asynchronous operation
|
||||
*/
|
||||
clutter_actor_get_preferred_size (CLUTTER_ACTOR (priv->impl),
|
||||
NULL, NULL,
|
||||
&natural_width, &natural_height);
|
||||
|
||||
box.x1 = 0;
|
||||
box.y1 = 0;
|
||||
box.x2 = natural_width;
|
||||
box.y2 = natural_height;
|
||||
|
||||
clutter_actor_allocate (CLUTTER_ACTOR (stage), &box, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
@ -404,8 +457,9 @@ clutter_stage_class_init (ClutterStageClass *klass)
|
||||
gobject_class->dispose = clutter_stage_dispose;
|
||||
gobject_class->finalize = clutter_stage_finalize;
|
||||
|
||||
actor_class->request_coords = clutter_stage_request_coords;
|
||||
actor_class->query_coords = clutter_stage_query_coords;
|
||||
actor_class->allocate = clutter_stage_allocate;
|
||||
actor_class->get_preferred_width = clutter_stage_get_preferred_width;
|
||||
actor_class->get_preferred_height = clutter_stage_get_preferred_height;
|
||||
actor_class->paint = clutter_stage_paint;
|
||||
actor_class->pick = clutter_stage_pick;
|
||||
actor_class->realize = clutter_stage_realize;
|
||||
@ -518,7 +572,7 @@ clutter_stage_class_init (ClutterStageClass *klass)
|
||||
stage_signals[FULLSCREEN] =
|
||||
g_signal_new ("fullscreen",
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (ClutterStageClass, fullscreen),
|
||||
NULL, NULL,
|
||||
clutter_marshal_VOID__VOID,
|
||||
@ -575,6 +629,8 @@ clutter_stage_class_init (ClutterStageClass *klass)
|
||||
clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
klass->fullscreen = clutter_stage_real_fullscreen;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (ClutterStagePrivate));
|
||||
}
|
||||
|
||||
|
@ -40,10 +40,10 @@
|
||||
* This process allows basic management of commonly limited available texture
|
||||
* memory.
|
||||
*
|
||||
* Note: a ClutterTexture will scale its contents to fit the bounding box
|
||||
* requested using clutter_actor_request_coords() and its wrappers. To
|
||||
* display an area of a texture without scaling, you should set the clip
|
||||
* area using clutter_actor_set_clip().
|
||||
* Note: a ClutterTexture will scale its contents to fit the bounding
|
||||
* box requested using clutter_actor_set_size(). To display an area of
|
||||
* a texture without scaling, you should set the clip area using
|
||||
* clutter_actor_set_clip().
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -318,6 +318,64 @@ clutter_texture_realize (ClutterActor *actor)
|
||||
CLUTTER_NOTE (TEXTURE, "Texture realized");
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_texture_get_preferred_width (ClutterActor *self,
|
||||
ClutterUnit for_height,
|
||||
ClutterUnit *min_width_p,
|
||||
ClutterUnit *natural_width_p)
|
||||
{
|
||||
ClutterTexture *texture = CLUTTER_TEXTURE (self);
|
||||
ClutterTexturePrivate *priv = texture->priv;
|
||||
|
||||
/* FIXME If we wanted to be clever here, we could set the natural
|
||||
* width to preserve aspect ratio considering for_height
|
||||
*/
|
||||
|
||||
/* Min request is always 0 since we can scale down or clip */
|
||||
if (min_width_p)
|
||||
*min_width_p = 0;
|
||||
|
||||
if (priv->sync_actor_size)
|
||||
{
|
||||
if (natural_width_p)
|
||||
*natural_width_p = CLUTTER_UNITS_FROM_DEVICE (priv->width);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (natural_width_p)
|
||||
*natural_width_p = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_texture_get_preferred_height (ClutterActor *self,
|
||||
ClutterUnit for_width,
|
||||
ClutterUnit *min_height_p,
|
||||
ClutterUnit *natural_height_p)
|
||||
{
|
||||
ClutterTexture *texture = CLUTTER_TEXTURE (self);
|
||||
ClutterTexturePrivate *priv = texture->priv;
|
||||
|
||||
/* FIXME If we wanted to be clever here, we could set the natural
|
||||
* height to preserve aspect ratio considering for_width
|
||||
*/
|
||||
|
||||
/* Min request is always 0 since we can scale down or clip */
|
||||
if (min_height_p)
|
||||
*min_height_p = 0;
|
||||
|
||||
if (priv->sync_actor_size)
|
||||
{
|
||||
if (natural_height_p)
|
||||
*natural_height_p = CLUTTER_UNITS_FROM_DEVICE (priv->height);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (natural_height_p)
|
||||
*natural_height_p = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_texture_paint (ClutterActor *self)
|
||||
{
|
||||
@ -370,10 +428,10 @@ clutter_texture_paint (ClutterActor *self)
|
||||
: "unknown");
|
||||
cogl_push_matrix ();
|
||||
|
||||
col.alpha = clutter_actor_get_abs_opacity (self);
|
||||
col.alpha = clutter_actor_get_paint_opacity (self);
|
||||
cogl_color (&col);
|
||||
|
||||
clutter_actor_get_coords (self, &x_1, &y_1, &x_2, &y_2);
|
||||
clutter_actor_get_allocation_coords (self, &x_1, &y_1, &x_2, &y_2);
|
||||
|
||||
CLUTTER_NOTE (PAINT, "paint to x1: %i, y1: %i x2: %i, y2: %i "
|
||||
"opacity: %i",
|
||||
@ -400,23 +458,6 @@ clutter_texture_paint (ClutterActor *self)
|
||||
cogl_pop_matrix ();
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_texture_request_coords (ClutterActor *self,
|
||||
ClutterActorBox *box)
|
||||
{
|
||||
ClutterTexture *texture = CLUTTER_TEXTURE (self);
|
||||
ClutterActorBox old_request;
|
||||
|
||||
clutter_actor_query_coords (self, &old_request);
|
||||
|
||||
if (((box->x2 - box->x1) != (old_request.x2 - old_request.x1)) ||
|
||||
((box->y2 - box->y1) != (old_request.y2 - old_request.y1)))
|
||||
texture->priv->sync_actor_size = FALSE;
|
||||
|
||||
CLUTTER_ACTOR_CLASS (clutter_texture_parent_class)
|
||||
->request_coords (self, box);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_texture_dispose (GObject *object)
|
||||
{
|
||||
@ -457,6 +498,7 @@ clutter_texture_set_property (GObject *object,
|
||||
break;
|
||||
case PROP_SYNC_SIZE:
|
||||
priv->sync_actor_size = g_value_get_boolean (value);
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (texture));
|
||||
break;
|
||||
case PROP_REPEAT_X:
|
||||
if (priv->repeat_x != g_value_get_boolean (value))
|
||||
@ -557,7 +599,9 @@ clutter_texture_class_init (ClutterTextureClass *klass)
|
||||
actor_class->paint = clutter_texture_paint;
|
||||
actor_class->realize = clutter_texture_realize;
|
||||
actor_class->unrealize = clutter_texture_unrealize;
|
||||
actor_class->request_coords = clutter_texture_request_coords;
|
||||
|
||||
actor_class->get_preferred_width = clutter_texture_get_preferred_width;
|
||||
actor_class->get_preferred_height = clutter_texture_get_preferred_height;
|
||||
|
||||
gobject_class->dispose = clutter_texture_dispose;
|
||||
gobject_class->set_property = clutter_texture_set_property;
|
||||
@ -920,18 +964,11 @@ clutter_texture_set_cogl_texture (ClutterTexture *texture,
|
||||
|
||||
if (size_change)
|
||||
{
|
||||
g_signal_emit (texture, texture_signals[SIZE_CHANGE],
|
||||
0, priv->width, priv->height);
|
||||
g_signal_emit (texture, texture_signals[SIZE_CHANGE], 0,
|
||||
priv->width,
|
||||
priv->height);
|
||||
|
||||
if (priv->sync_actor_size)
|
||||
{
|
||||
clutter_actor_set_size (CLUTTER_ACTOR(texture),
|
||||
priv->width,
|
||||
priv->height);
|
||||
/* The above call will clear sync_actor_size because the
|
||||
size has changed so we need to put it back */
|
||||
priv->sync_actor_size = TRUE;
|
||||
}
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (texture));
|
||||
}
|
||||
|
||||
/* rename signal */
|
||||
@ -1493,7 +1530,7 @@ on_fbo_source_size_change (GObject *object,
|
||||
ClutterTexturePrivate *priv = texture->priv;
|
||||
guint w, h;
|
||||
|
||||
clutter_actor_get_abs_size (priv->fbo_source, &w, &h);
|
||||
clutter_actor_get_transformed_size (priv->fbo_source, &w, &h);
|
||||
|
||||
if (w != priv->width || h != priv->height)
|
||||
{
|
||||
@ -1616,7 +1653,7 @@ clutter_texture_new_from_actor (ClutterActor *actor)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
clutter_actor_get_abs_size (actor, &w, &h);
|
||||
clutter_actor_get_transformed_size (actor, &w, &h);
|
||||
|
||||
if (w == 0 || h == 0)
|
||||
return NULL;
|
||||
|
@ -94,16 +94,26 @@ clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11)
|
||||
if (stage_x11->xwin != None && stage_x11->is_foreign_xwin == FALSE)
|
||||
{
|
||||
XSizeHints *size_hints;
|
||||
ClutterUnit min_width, min_height;
|
||||
|
||||
size_hints = XAllocSizeHints();
|
||||
|
||||
clutter_actor_get_preferred_width (CLUTTER_ACTOR (stage_x11),
|
||||
-1,
|
||||
&min_width, NULL);
|
||||
clutter_actor_get_preferred_height (CLUTTER_ACTOR (stage_x11),
|
||||
min_width,
|
||||
&min_height, NULL);
|
||||
|
||||
size_hints->min_width = CLUTTER_UNITS_TO_DEVICE (min_width);
|
||||
size_hints->min_height = CLUTTER_UNITS_TO_DEVICE (min_height);
|
||||
size_hints->flags = PMinSize;
|
||||
|
||||
if (!resize)
|
||||
{
|
||||
size_hints->max_width = size_hints->min_width =
|
||||
stage_x11->xwin_width;
|
||||
size_hints->max_height = size_hints->min_height =
|
||||
stage_x11->xwin_height;
|
||||
size_hints->flags = PMinSize|PMaxSize;
|
||||
size_hints->max_width = size_hints->min_width;
|
||||
size_hints->max_height = size_hints->min_height;
|
||||
size_hints->flags |= PMaxSize;
|
||||
}
|
||||
|
||||
XSetWMNormalHints (stage_x11->xdpy, stage_x11->xwin, size_hints);
|
||||
@ -117,18 +127,18 @@ clutter_stage_x11_show (ClutterActor *actor)
|
||||
{
|
||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (actor);
|
||||
|
||||
CLUTTER_ACTOR_CLASS (clutter_stage_x11_parent_class)->show (actor);
|
||||
|
||||
if (stage_x11->xwin)
|
||||
{
|
||||
/* Fire off a redraw to avoid flicker on first map.
|
||||
* Appears not to work perfectly on intel drivers at least.
|
||||
*/
|
||||
*/
|
||||
clutter_redraw (stage_x11->wrapper);
|
||||
|
||||
XSync (stage_x11->xdpy, FALSE);
|
||||
XMapWindow (stage_x11->xdpy, stage_x11->xwin);
|
||||
}
|
||||
|
||||
CLUTTER_ACTOR_SET_FLAGS (actor, CLUTTER_ACTOR_MAPPED);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -136,8 +146,6 @@ clutter_stage_x11_hide (ClutterActor *actor)
|
||||
{
|
||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (actor);
|
||||
|
||||
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_MAPPED);
|
||||
|
||||
if (stage_x11->xwin)
|
||||
XUnmapWindow (stage_x11->xdpy, stage_x11->xwin);
|
||||
}
|
||||
@ -156,41 +164,108 @@ clutter_stage_x11_set_wm_protocols (ClutterStageX11 *stage_x11)
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_x11_query_coords (ClutterActor *self,
|
||||
ClutterActorBox *box)
|
||||
clutter_stage_x11_get_preferred_width (ClutterActor *self,
|
||||
ClutterUnit for_height,
|
||||
ClutterUnit *min_width_p,
|
||||
ClutterUnit *natural_width_p)
|
||||
{
|
||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (self);
|
||||
gboolean resize;
|
||||
|
||||
box->x1 = box->y1 = 0;
|
||||
box->x2 = box->x1 + CLUTTER_UNITS_FROM_INT (stage_x11->xwin_width);
|
||||
box->y2 = box->y1 + CLUTTER_UNITS_FROM_INT (stage_x11->xwin_height);
|
||||
if (stage_x11->fullscreen_on_map)
|
||||
{
|
||||
int width;
|
||||
|
||||
width = DisplayWidth (stage_x11->xdpy, stage_x11->xscreen);
|
||||
|
||||
if (min_width_p)
|
||||
*min_width_p = CLUTTER_UNITS_FROM_DEVICE (width);
|
||||
|
||||
if (natural_width_p)
|
||||
*natural_width_p = CLUTTER_UNITS_FROM_DEVICE (width);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
resize = clutter_stage_get_user_resizable (stage_x11->wrapper);
|
||||
|
||||
if (min_width_p)
|
||||
{
|
||||
/* FIXME need API to set this */
|
||||
if (resize)
|
||||
*min_width_p = CLUTTER_UNITS_FROM_DEVICE (1);
|
||||
else
|
||||
*min_width_p = CLUTTER_UNITS_FROM_DEVICE (stage_x11->xwin_width);
|
||||
}
|
||||
|
||||
if (natural_width_p)
|
||||
*natural_width_p = CLUTTER_UNITS_FROM_DEVICE (stage_x11->xwin_width);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_x11_request_coords (ClutterActor *self,
|
||||
ClutterActorBox *box)
|
||||
clutter_stage_x11_get_preferred_height (ClutterActor *self,
|
||||
ClutterUnit for_width,
|
||||
ClutterUnit *min_height_p,
|
||||
ClutterUnit *natural_height_p)
|
||||
{
|
||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (self);
|
||||
gboolean resize;
|
||||
|
||||
if (stage_x11->fullscreen_on_map)
|
||||
{
|
||||
int height;
|
||||
|
||||
height = DisplayHeight (stage_x11->xdpy, stage_x11->xscreen);
|
||||
|
||||
if (min_height_p)
|
||||
*min_height_p = CLUTTER_UNITS_FROM_DEVICE (height);
|
||||
|
||||
if (natural_height_p)
|
||||
*natural_height_p = CLUTTER_UNITS_FROM_DEVICE (height);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
resize = clutter_stage_get_user_resizable (stage_x11->wrapper);
|
||||
|
||||
if (min_height_p)
|
||||
{
|
||||
if (resize)
|
||||
*min_height_p = CLUTTER_UNITS_FROM_DEVICE (1); /* FIXME need API
|
||||
* to set this
|
||||
*/
|
||||
else
|
||||
*min_height_p = CLUTTER_UNITS_FROM_DEVICE (stage_x11->xwin_height);
|
||||
}
|
||||
|
||||
if (natural_height_p)
|
||||
*natural_height_p = CLUTTER_UNITS_FROM_DEVICE (stage_x11->xwin_height);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_x11_allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
gboolean origin_changed)
|
||||
{
|
||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (self);
|
||||
ClutterActorClass *parent_class;
|
||||
gint new_width, new_height;
|
||||
|
||||
new_width = ABS (CLUTTER_UNITS_TO_INT (box->x2 - box->x1));
|
||||
new_height = ABS (CLUTTER_UNITS_TO_INT (box->y2 - box->y1));
|
||||
new_height = ABS (CLUTTER_UNITS_TO_INT (box->y2 - box->y1));
|
||||
|
||||
/* X cant resize to 0 dimentions */
|
||||
if (new_height == 0)
|
||||
if (new_width == 0 || new_height == 0)
|
||||
{
|
||||
box->y2 = box->y1 + 1;
|
||||
/* Should not happen, if this turns up we need to debug it and
|
||||
* determine the cleanest way to fix.
|
||||
*/
|
||||
g_warning ("X11 stage not allowed to have 0 width or height");
|
||||
new_width = 1;
|
||||
new_height = 1;
|
||||
}
|
||||
|
||||
if (new_width == 0)
|
||||
{
|
||||
box->x2 = box->x1 + 1;
|
||||
new_width = 1;
|
||||
}
|
||||
|
||||
if (new_width != stage_x11->xwin_width
|
||||
|| new_height != stage_x11->xwin_height)
|
||||
if (new_width != stage_x11->xwin_width ||
|
||||
new_height != stage_x11->xwin_height)
|
||||
{
|
||||
stage_x11->xwin_width = new_width;
|
||||
stage_x11->xwin_height = new_height;
|
||||
@ -210,13 +285,13 @@ clutter_stage_x11_request_coords (ClutterActor *self,
|
||||
if (stage_x11->xwin != None
|
||||
&& !stage_x11->is_foreign_xwin
|
||||
&& !stage_x11->handling_configure)
|
||||
XResizeWindow (stage_x11->xdpy,
|
||||
XResizeWindow (stage_x11->xdpy,
|
||||
stage_x11->xwin,
|
||||
stage_x11->xwin_width,
|
||||
stage_x11->xwin_height);
|
||||
|
||||
clutter_stage_x11_fix_window_size (stage_x11);
|
||||
|
||||
|
||||
if (stage_x11->xpixmap != None)
|
||||
{
|
||||
/* Need to recreate to resize */
|
||||
@ -228,16 +303,9 @@ clutter_stage_x11_request_coords (ClutterActor *self,
|
||||
CLUTTER_ACTOR_SYNC_MATRICES);
|
||||
}
|
||||
|
||||
if (stage_x11->xwin != None
|
||||
&& !stage_x11->is_foreign_xwin
|
||||
&& !stage_x11->handling_configure) /* Do we want to bother ? */
|
||||
XMoveWindow (stage_x11->xdpy,
|
||||
stage_x11->xwin,
|
||||
CLUTTER_UNITS_TO_INT (box->x1),
|
||||
CLUTTER_UNITS_TO_INT (box->y1));
|
||||
|
||||
CLUTTER_ACTOR_CLASS (clutter_stage_x11_parent_class)->request_coords (self,
|
||||
box);
|
||||
/* chain up to fill in actor->priv->allocation */
|
||||
parent_class = CLUTTER_ACTOR_CLASS (clutter_stage_x11_parent_class);
|
||||
parent_class->allocate (self, box, origin_changed);
|
||||
}
|
||||
|
||||
static inline void
|
||||
@ -331,8 +399,26 @@ clutter_stage_x11_set_fullscreen (ClutterStageWindow *stage_window,
|
||||
|
||||
if (is_fullscreen)
|
||||
{
|
||||
int width, height;
|
||||
|
||||
width = DisplayWidth (stage_x11->xdpy, stage_x11->xscreen);
|
||||
height = DisplayHeight (stage_x11->xdpy, stage_x11->xscreen);
|
||||
|
||||
/* we force the stage to the screen size here, in order to
|
||||
* get the fullscreen stage size right after the call to
|
||||
* clutter_stage_fullscreen(). XXX this might break in case
|
||||
* the stage is not fullscreened, but if that does not happen
|
||||
* we are massively screwed anyway
|
||||
*/
|
||||
stage_x11->xwin_width = width;
|
||||
stage_x11->xwin_height = height;
|
||||
|
||||
clutter_actor_set_size (CLUTTER_ACTOR (stage), width, height);
|
||||
|
||||
if (stage_x11->xwin != None)
|
||||
{
|
||||
stage_x11->fullscreen_on_map = TRUE;
|
||||
|
||||
/* if the actor is not mapped we resize the stage window to match
|
||||
* the size of the screen; this is useful for e.g. EGLX to avoid
|
||||
* a resize when calling clutter_stage_fullscreen() before showing
|
||||
@ -340,14 +426,6 @@ clutter_stage_x11_set_fullscreen (ClutterStageWindow *stage_window,
|
||||
*/
|
||||
if (!CLUTTER_ACTOR_IS_MAPPED (stage_x11))
|
||||
{
|
||||
gint width, height;
|
||||
|
||||
width = DisplayWidth (stage_x11->xdpy, stage_x11->xscreen);
|
||||
height = DisplayHeight (stage_x11->xdpy, stage_x11->xscreen);
|
||||
|
||||
clutter_actor_set_size (CLUTTER_ACTOR (stage_x11),
|
||||
width, height);
|
||||
|
||||
/* FIXME: This wont work if we support more states */
|
||||
XChangeProperty (stage_x11->xdpy,
|
||||
stage_x11->xwin,
|
||||
@ -365,12 +443,10 @@ clutter_stage_x11_set_fullscreen (ClutterStageWindow *stage_window,
|
||||
else
|
||||
clutter_stage_set_user_resizable (stage, TRUE);
|
||||
|
||||
send_wmspec_change_state(backend_x11, stage_x11->xwin,
|
||||
backend_x11->atom_NET_WM_STATE_FULLSCREEN,
|
||||
TRUE);
|
||||
send_wmspec_change_state (backend_x11, stage_x11->xwin,
|
||||
backend_x11->atom_NET_WM_STATE_FULLSCREEN,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
stage_x11->fullscreen_on_map = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -388,10 +464,10 @@ clutter_stage_x11_set_fullscreen (ClutterStageWindow *stage_window,
|
||||
{
|
||||
clutter_stage_set_user_resizable (stage, TRUE);
|
||||
|
||||
send_wmspec_change_state(backend_x11,
|
||||
stage_x11->xwin,
|
||||
backend_x11->atom_NET_WM_STATE_FULLSCREEN,
|
||||
FALSE);
|
||||
send_wmspec_change_state (backend_x11,
|
||||
stage_x11->xwin,
|
||||
backend_x11->atom_NET_WM_STATE_FULLSCREEN,
|
||||
FALSE);
|
||||
|
||||
/* reset the windows state - this isn't fun - see above */
|
||||
if (!was_resizeable)
|
||||
@ -414,7 +490,6 @@ clutter_stage_x11_set_cursor_visible (ClutterStageWindow *stage_window,
|
||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
||||
|
||||
stage_x11->is_cursor_visible = (cursor_visible == TRUE);
|
||||
|
||||
set_cursor_visible (stage_x11);
|
||||
}
|
||||
|
||||
@ -426,7 +501,6 @@ clutter_stage_x11_set_title (ClutterStageWindow *stage_window,
|
||||
|
||||
g_free (stage_x11->title);
|
||||
stage_x11->title = g_strdup (title);
|
||||
|
||||
set_wm_title (stage_x11);
|
||||
}
|
||||
|
||||
@ -478,8 +552,10 @@ clutter_stage_x11_class_init (ClutterStageX11Class *klass)
|
||||
actor_class->realize = clutter_stage_x11_realize;
|
||||
actor_class->show = clutter_stage_x11_show;
|
||||
actor_class->hide = clutter_stage_x11_hide;
|
||||
actor_class->request_coords = clutter_stage_x11_request_coords;
|
||||
actor_class->query_coords = clutter_stage_x11_query_coords;
|
||||
|
||||
actor_class->get_preferred_width = clutter_stage_x11_get_preferred_width;
|
||||
actor_class->get_preferred_height = clutter_stage_x11_get_preferred_height;
|
||||
actor_class->allocate = clutter_stage_x11_allocate;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -681,7 +757,7 @@ clutter_stage_x11_map (ClutterStageX11 *stage_x11)
|
||||
else
|
||||
clutter_stage_unfullscreen (CLUTTER_STAGE (stage_x11->wrapper));
|
||||
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage_x11->wrapper));
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (stage_x11->wrapper));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -13,7 +13,7 @@ noinst_PROGRAMS = test-textures test-events test-offscreen test-scale \
|
||||
test-cogl-tex-getset test-cogl-offscreen \
|
||||
test-cogl-tex-polygon test-stage-read-pixels \
|
||||
test-random-text test-clip test-paint-wrapper \
|
||||
test-texture-quality test-entry-auto
|
||||
test-texture-quality test-entry-auto test-layout
|
||||
|
||||
if X11_TESTS
|
||||
noinst_PROGRAMS += test-pixmap
|
||||
@ -24,22 +24,22 @@ LDADD = $(top_builddir)/clutter/libclutter-@CLUTTER_FLAVOUR@-@CLUTTER_MAJORMINOR
|
||||
AM_CFLAGS = $(CLUTTER_CFLAGS)
|
||||
AM_LDFLAGS = $(CLUTTER_LIBS)
|
||||
|
||||
test_textures_SOURCES = test-textures.c
|
||||
test_events_SOURCES = test-events.c
|
||||
test_offscreen_SOURCES = test-offscreen.c
|
||||
test_scale_SOURCES = test-scale.c
|
||||
test_actors_SOURCES = test-actors.c
|
||||
test_grab_SOURCES = test-grab.c
|
||||
test_behave_SOURCES = test-behave.c
|
||||
test_text_SOURCES = test-text.c
|
||||
test_entry_SOURCES = test-entry.c
|
||||
test_project_SOURCES = test-project.c
|
||||
test_unproject_SOURCES = test-unproject.c
|
||||
test_perspective_SOURCES = test-perspective.c
|
||||
test_rotate_SOURCES = test-rotate.c
|
||||
test_depth_SOURCES = test-depth.c
|
||||
test_threads_SOURCES = test-threads.c
|
||||
test_timeline_SOURCES = test-timeline.c
|
||||
test_textures_SOURCES = test-textures.c
|
||||
test_events_SOURCES = test-events.c
|
||||
test_offscreen_SOURCES = test-offscreen.c
|
||||
test_scale_SOURCES = test-scale.c
|
||||
test_actors_SOURCES = test-actors.c
|
||||
test_grab_SOURCES = test-grab.c
|
||||
test_behave_SOURCES = test-behave.c
|
||||
test_text_SOURCES = test-text.c
|
||||
test_entry_SOURCES = test-entry.c
|
||||
test_project_SOURCES = test-project.c
|
||||
test_unproject_SOURCES = test-unproject.c
|
||||
test_perspective_SOURCES = test-perspective.c
|
||||
test_rotate_SOURCES = test-rotate.c
|
||||
test_depth_SOURCES = test-depth.c
|
||||
test_threads_SOURCES = test-threads.c
|
||||
test_timeline_SOURCES = test-timeline.c
|
||||
test_timeline_dup_frames_SOURCES = test-timeline-dup-frames.c
|
||||
test_timeline_interpolate_SOURCES = test-timeline-interpolate.c
|
||||
test_timeline_rewind_SOURCES = test-timeline-rewind.c
|
||||
@ -67,5 +67,6 @@ test_random_text_SOURCES = test-random-text.c
|
||||
test_paint_wrapper_SOURCES = test-paint-wrapper.c
|
||||
test_texture_quality_SOURCES = test-texture-quality.c
|
||||
test_entry_auto_SOURCES = test-entry-auto.c
|
||||
test_layout_SOURCES = test-layout.c
|
||||
|
||||
EXTRA_DIST = redhand.png test-script.json
|
||||
|
785
tests/test-layout.c
Normal file
785
tests/test-layout.c
Normal file
@ -0,0 +1,785 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
/* layout actor, by Lucas Rocha */
|
||||
|
||||
#define MY_TYPE_THING (my_thing_get_type ())
|
||||
#define MY_THING(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MY_TYPE_THING, MyThing))
|
||||
#define MY_IS_THING(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MY_TYPE_THING))
|
||||
#define MY_THING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MY_TYPE_THING, MyThingClass))
|
||||
#define MY_IS_THING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MY_TYPE_THING))
|
||||
#define MY_THING_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MY_TYPE_THING, MyThingClass))
|
||||
|
||||
typedef struct _MyThing MyThing;
|
||||
typedef struct _MyThingPrivate MyThingPrivate;
|
||||
typedef struct _MyThingClass MyThingClass;
|
||||
|
||||
struct _MyThing
|
||||
{
|
||||
ClutterActor parent_instance;
|
||||
|
||||
MyThingPrivate *priv;
|
||||
};
|
||||
|
||||
struct _MyThingClass
|
||||
{
|
||||
ClutterActorClass parent_class;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_SPACING,
|
||||
PROP_PADDING,
|
||||
PROP_USE_TRANSFORMED_BOX
|
||||
};
|
||||
|
||||
static void clutter_container_iface_init (ClutterContainerIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (MyThing,
|
||||
my_thing,
|
||||
CLUTTER_TYPE_ACTOR,
|
||||
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER,
|
||||
clutter_container_iface_init));
|
||||
|
||||
#define MY_THING_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), MY_TYPE_THING, MyThingPrivate))
|
||||
|
||||
struct _MyThingPrivate
|
||||
{
|
||||
GList *children;
|
||||
|
||||
ClutterUnit spacing;
|
||||
ClutterUnit padding;
|
||||
|
||||
guint use_transformed_box : 1;
|
||||
};
|
||||
|
||||
/* Add, remove, foreach, copied from ClutterGroup code. */
|
||||
|
||||
static void
|
||||
my_thing_real_add (ClutterContainer *container,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
MyThing *group = MY_THING (container);
|
||||
MyThingPrivate *priv = group->priv;
|
||||
|
||||
g_object_ref (actor);
|
||||
|
||||
priv->children = g_list_append (priv->children, actor);
|
||||
clutter_actor_set_parent (actor, CLUTTER_ACTOR (group));
|
||||
|
||||
g_signal_emit_by_name (container, "actor-added", actor);
|
||||
|
||||
/* queue relayout to allocate new item */
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (group));
|
||||
|
||||
g_object_unref (actor);
|
||||
}
|
||||
|
||||
static void
|
||||
my_thing_real_remove (ClutterContainer *container,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
MyThing *group = MY_THING (container);
|
||||
MyThingPrivate *priv = group->priv;
|
||||
|
||||
g_object_ref (actor);
|
||||
|
||||
priv->children = g_list_remove (priv->children, actor);
|
||||
clutter_actor_unparent (actor);
|
||||
|
||||
/* At this point, the actor passed to the "actor-removed" signal
|
||||
* handlers is not parented anymore to the container but since we
|
||||
* are holding a reference on it, it's still valid
|
||||
*/
|
||||
g_signal_emit_by_name (container, "actor-removed", actor);
|
||||
|
||||
/* queue relayout to re-allocate children without the
|
||||
removed item */
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (group));
|
||||
|
||||
g_object_unref (actor);
|
||||
}
|
||||
|
||||
static void
|
||||
my_thing_real_foreach (ClutterContainer *container,
|
||||
ClutterCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
MyThingPrivate *priv = MY_THING (container)->priv;
|
||||
GList *l;
|
||||
|
||||
for (l = priv->children; l; l = l->next)
|
||||
(* callback) (CLUTTER_ACTOR (l->data), user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_container_iface_init (ClutterContainerIface *iface)
|
||||
{
|
||||
iface->add = my_thing_real_add;
|
||||
iface->remove = my_thing_real_remove;
|
||||
iface->foreach = my_thing_real_foreach;
|
||||
}
|
||||
|
||||
static void
|
||||
my_thing_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MyThingPrivate *priv = MY_THING (gobject)->priv;
|
||||
gboolean needs_relayout = TRUE;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SPACING:
|
||||
priv->spacing = clutter_value_get_unit (value);
|
||||
break;
|
||||
|
||||
case PROP_PADDING:
|
||||
priv->padding = clutter_value_get_unit (value);
|
||||
break;
|
||||
|
||||
case PROP_USE_TRANSFORMED_BOX:
|
||||
priv->use_transformed_box = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
needs_relayout = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* setting spacing or padding queues a relayout
|
||||
because they are supposed to change the internal
|
||||
allocation of children */
|
||||
if (needs_relayout)
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (gobject));
|
||||
}
|
||||
|
||||
static void
|
||||
my_thing_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MyThingPrivate *priv = MY_THING (gobject)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SPACING:
|
||||
clutter_value_set_unit (value, priv->spacing);
|
||||
break;
|
||||
|
||||
case PROP_PADDING:
|
||||
clutter_value_set_unit (value, priv->padding);
|
||||
break;
|
||||
|
||||
case PROP_USE_TRANSFORMED_BOX:
|
||||
g_value_set_boolean (value, priv->use_transformed_box);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
my_thing_finalize (GObject *gobject)
|
||||
{
|
||||
G_OBJECT_CLASS (my_thing_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
my_thing_dispose (GObject *gobject)
|
||||
{
|
||||
MyThing *self = MY_THING (gobject);
|
||||
MyThingPrivate *priv = self->priv;
|
||||
|
||||
if (priv->children)
|
||||
{
|
||||
g_list_foreach (priv->children, (GFunc) clutter_actor_destroy, NULL);
|
||||
priv->children = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (my_thing_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
my_thing_get_preferred_width (ClutterActor *self,
|
||||
ClutterUnit for_height,
|
||||
ClutterUnit *min_width_p,
|
||||
ClutterUnit *natural_width_p)
|
||||
{
|
||||
MyThingPrivate *priv;
|
||||
GList *l;
|
||||
ClutterUnit min_left, min_right;
|
||||
ClutterUnit natural_left, natural_right;
|
||||
|
||||
priv = MY_THING (self)->priv;
|
||||
|
||||
min_left = 0;
|
||||
min_right = 0;
|
||||
natural_left = 0;
|
||||
natural_right = 0;
|
||||
|
||||
for (l = priv->children; l != NULL; l = l->next)
|
||||
{
|
||||
ClutterActor *child;
|
||||
ClutterUnit child_x, child_min, child_natural;
|
||||
|
||||
child = l->data;
|
||||
|
||||
child_x = clutter_actor_get_xu (child);
|
||||
|
||||
clutter_actor_get_preferred_size (child,
|
||||
&child_min, NULL,
|
||||
&child_natural, NULL);
|
||||
|
||||
if (l == priv->children)
|
||||
{
|
||||
/* First child */
|
||||
min_left = child_x;
|
||||
natural_left = child_x;
|
||||
min_right = min_left + child_min;
|
||||
natural_right = natural_left + child_natural;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Union of extents with previous children */
|
||||
if (child_x < min_left)
|
||||
min_left = child_x;
|
||||
|
||||
if (child_x < natural_left)
|
||||
natural_left = child_x;
|
||||
|
||||
if (child_x + child_min > min_right)
|
||||
min_right = child_x + child_min;
|
||||
|
||||
if (child_x + child_natural > natural_right)
|
||||
natural_right = child_x + child_natural;
|
||||
}
|
||||
}
|
||||
|
||||
if (min_left < 0)
|
||||
min_left = 0;
|
||||
|
||||
if (natural_left < 0)
|
||||
natural_left = 0;
|
||||
|
||||
if (min_right < 0)
|
||||
min_right = 0;
|
||||
|
||||
if (natural_right < 0)
|
||||
natural_right = 0;
|
||||
|
||||
g_assert (min_right >= min_left);
|
||||
g_assert (natural_right >= natural_left);
|
||||
|
||||
if (min_width_p)
|
||||
*min_width_p = min_right - min_left;
|
||||
|
||||
if (natural_width_p)
|
||||
*natural_width_p = natural_right - min_left;
|
||||
}
|
||||
|
||||
static void
|
||||
my_thing_get_preferred_height (ClutterActor *self,
|
||||
ClutterUnit for_width,
|
||||
ClutterUnit *min_height_p,
|
||||
ClutterUnit *natural_height_p)
|
||||
{
|
||||
MyThingPrivate *priv;
|
||||
GList *l;
|
||||
ClutterUnit min_top, min_bottom;
|
||||
ClutterUnit natural_top, natural_bottom;
|
||||
|
||||
priv = MY_THING (self)->priv;
|
||||
|
||||
min_top = 0;
|
||||
min_bottom = 0;
|
||||
natural_top = 0;
|
||||
natural_bottom = 0;
|
||||
|
||||
for (l = priv->children; l != NULL; l = l->next)
|
||||
{
|
||||
ClutterActor *child;
|
||||
ClutterUnit child_y, child_min, child_natural;
|
||||
|
||||
child = l->data;
|
||||
|
||||
child_y = clutter_actor_get_yu (child);
|
||||
|
||||
clutter_actor_get_preferred_size (child,
|
||||
NULL, &child_min,
|
||||
NULL, &child_natural);
|
||||
|
||||
if (l == priv->children)
|
||||
{
|
||||
/* First child */
|
||||
min_top = child_y;
|
||||
natural_top = child_y;
|
||||
min_bottom = min_top + child_min;
|
||||
natural_bottom = natural_top + child_natural;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Union of extents with previous children */
|
||||
if (child_y < min_top)
|
||||
min_top = child_y;
|
||||
|
||||
if (child_y < natural_top)
|
||||
natural_top = child_y;
|
||||
|
||||
if (child_y + child_min > min_bottom)
|
||||
min_bottom = child_y + child_min;
|
||||
|
||||
if (child_y + child_natural > natural_bottom)
|
||||
natural_bottom = child_y + child_natural;
|
||||
}
|
||||
}
|
||||
|
||||
if (min_top < 0)
|
||||
min_top = 0;
|
||||
|
||||
if (natural_top < 0)
|
||||
natural_top = 0;
|
||||
|
||||
if (min_bottom < 0)
|
||||
min_bottom = 0;
|
||||
|
||||
if (natural_bottom < 0)
|
||||
natural_bottom = 0;
|
||||
|
||||
g_assert (min_bottom >= min_top);
|
||||
g_assert (natural_bottom >= natural_top);
|
||||
|
||||
if (min_height_p)
|
||||
*min_height_p = min_bottom - min_top;
|
||||
|
||||
if (natural_height_p)
|
||||
*natural_height_p = natural_bottom - min_top;
|
||||
}
|
||||
|
||||
static void
|
||||
my_thing_allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
gboolean absolute_origin_changed)
|
||||
{
|
||||
MyThingPrivate *priv;
|
||||
ClutterUnit current_x, current_y, max_row_height;
|
||||
GList *l;
|
||||
|
||||
/* chain up to set actor->allocation */
|
||||
CLUTTER_ACTOR_CLASS (my_thing_parent_class)->allocate (self, box,
|
||||
absolute_origin_changed);
|
||||
|
||||
priv = MY_THING (self)->priv;
|
||||
|
||||
current_x = priv->padding;
|
||||
current_y = priv->padding;
|
||||
max_row_height = 0;
|
||||
|
||||
/* The allocation logic here is to horizontally place children
|
||||
* side-by-side and reflow into a new row when we run out of
|
||||
* space
|
||||
*/
|
||||
for (l = priv->children; l != NULL; l = l->next)
|
||||
{
|
||||
ClutterActor *child;
|
||||
ClutterUnit natural_width, natural_height;
|
||||
ClutterActorBox child_box;
|
||||
|
||||
child = l->data;
|
||||
|
||||
clutter_actor_get_preferred_size (child,
|
||||
NULL, NULL,
|
||||
&natural_width, &natural_height);
|
||||
|
||||
/* if it fits in the current row, keep it there; otherwise
|
||||
* reflow into another row
|
||||
*/
|
||||
if (current_x + natural_width > box->x2 - box->x1 - priv->padding)
|
||||
{
|
||||
current_x = priv->padding;
|
||||
current_y += max_row_height + priv->spacing;
|
||||
max_row_height = 0;
|
||||
}
|
||||
|
||||
child_box.x1 = current_x;
|
||||
child_box.y1 = current_y;
|
||||
child_box.x2 = child_box.x1 + natural_width;
|
||||
child_box.y2 = child_box.y1 + natural_height;
|
||||
|
||||
clutter_actor_allocate (child, &child_box, absolute_origin_changed);
|
||||
|
||||
/* if we take into account the transformation of the children
|
||||
* then we first check if it's transformed; then we get the
|
||||
* onscreen coordinates of the two points of the bounding box
|
||||
* of the actor (origin(x, y) and (origin + size)(x,y)) and
|
||||
* we update the coordinates and area given to the next child
|
||||
*/
|
||||
if (priv->use_transformed_box)
|
||||
{
|
||||
if (clutter_actor_is_scaled (child) ||
|
||||
clutter_actor_is_rotated (child))
|
||||
{
|
||||
ClutterVertex v1 = { 0, }, v2 = { 0, };
|
||||
ClutterActorBox box = { 0, };
|
||||
|
||||
/* origin */
|
||||
v1.x = 0;
|
||||
v1.y = 0;
|
||||
clutter_actor_apply_transform_to_point (child, &v1, &v2);
|
||||
box.x1 = v2.x;
|
||||
box.y1 = v2.y;
|
||||
|
||||
/* size */
|
||||
v1.x = natural_width;
|
||||
v1.y = natural_height;
|
||||
clutter_actor_apply_transform_to_point (child, &v1, &v2);
|
||||
box.x2 = v2.x;
|
||||
box.y2 = v2.y;
|
||||
|
||||
natural_width = box.x2 - box.x1;
|
||||
natural_height = box.y2 - box.y1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Record the maximum child height on current row to know
|
||||
* what's the increment that should be used for the next
|
||||
* row
|
||||
*/
|
||||
if (natural_height > max_row_height)
|
||||
max_row_height = natural_height;
|
||||
|
||||
current_x += natural_width + priv->spacing;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
my_thing_paint (ClutterActor *actor)
|
||||
{
|
||||
MyThing *self = MY_THING (actor);
|
||||
GList *c;
|
||||
|
||||
cogl_push_matrix();
|
||||
|
||||
/* paint all visible children */
|
||||
for (c = self->priv->children;
|
||||
c != NULL;
|
||||
c = c->next)
|
||||
{
|
||||
ClutterActor *child = c->data;
|
||||
|
||||
g_assert (child != NULL);
|
||||
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (child))
|
||||
clutter_actor_paint (child);
|
||||
}
|
||||
|
||||
cogl_pop_matrix();
|
||||
}
|
||||
|
||||
#define MIN_SIZE 24
|
||||
#define MAX_SIZE 64
|
||||
|
||||
static void
|
||||
my_thing_class_init (MyThingClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
|
||||
gobject_class->set_property = my_thing_set_property;
|
||||
gobject_class->get_property = my_thing_get_property;
|
||||
gobject_class->dispose = my_thing_dispose;
|
||||
gobject_class->finalize = my_thing_finalize;
|
||||
|
||||
actor_class->get_preferred_width = my_thing_get_preferred_width;
|
||||
actor_class->get_preferred_height = my_thing_get_preferred_height;
|
||||
actor_class->allocate = my_thing_allocate;
|
||||
actor_class->paint = my_thing_paint;
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_SPACING,
|
||||
clutter_param_spec_unit ("spacing",
|
||||
"Spacing",
|
||||
"Spacing of the thing",
|
||||
0, CLUTTER_MAXUNIT,
|
||||
0,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_PADDING,
|
||||
clutter_param_spec_unit ("padding",
|
||||
"Padding",
|
||||
"Padding around the thing",
|
||||
0, CLUTTER_MAXUNIT,
|
||||
0,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_USE_TRANSFORMED_BOX,
|
||||
g_param_spec_boolean ("use-transformed-box",
|
||||
"Use Transformed Box",
|
||||
"Use transformed box when allocating",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_type_class_add_private (klass, sizeof (MyThingPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
my_thing_init (MyThing *thing)
|
||||
{
|
||||
thing->priv = MY_THING_GET_PRIVATE (thing);
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
my_thing_new (gint padding,
|
||||
gint spacing)
|
||||
{
|
||||
return g_object_new (MY_TYPE_THING,
|
||||
"padding", CLUTTER_UNITS_FROM_DEVICE (padding),
|
||||
"spacing", CLUTTER_UNITS_FROM_DEVICE (spacing),
|
||||
NULL);
|
||||
|
||||
}
|
||||
|
||||
/* test code */
|
||||
|
||||
static ClutterActor *stage = NULL;
|
||||
static ClutterActor *box = NULL;
|
||||
static ClutterActor *icon = NULL;
|
||||
static ClutterTimeline *timeline = NULL;
|
||||
static ClutterBehaviour *behaviour = NULL;
|
||||
|
||||
static ClutterColor bg_color;
|
||||
|
||||
static void
|
||||
toggle_property_value (ClutterActor *actor,
|
||||
const gchar *property_name)
|
||||
{
|
||||
gboolean value;
|
||||
|
||||
g_object_get (G_OBJECT (actor),
|
||||
property_name, &value,
|
||||
NULL);
|
||||
|
||||
value = !value;
|
||||
|
||||
g_object_set (G_OBJECT (box),
|
||||
property_name, value,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
increase_property_value (ClutterActor *actor,
|
||||
const char *property_name)
|
||||
{
|
||||
ClutterUnit value;
|
||||
|
||||
g_object_get (G_OBJECT (actor),
|
||||
property_name, &value,
|
||||
NULL);
|
||||
|
||||
value = value + CLUTTER_UNITS_FROM_DEVICE (10);
|
||||
|
||||
g_object_set (G_OBJECT (box),
|
||||
property_name, value,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
decrease_property_value (ClutterActor *actor,
|
||||
const char *property_name)
|
||||
{
|
||||
ClutterUnit value;
|
||||
|
||||
g_object_get (G_OBJECT (actor),
|
||||
property_name, &value,
|
||||
NULL);
|
||||
|
||||
value = MAX (0, value - CLUTTER_UNITS_FROM_DEVICE (10));
|
||||
|
||||
g_object_set (G_OBJECT (box),
|
||||
property_name, value,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static ClutterActor *
|
||||
create_item()
|
||||
{
|
||||
ClutterActor *clone =
|
||||
clutter_clone_texture_new (CLUTTER_TEXTURE (icon));
|
||||
|
||||
gint32 size = g_random_int_range (MIN_SIZE, MAX_SIZE);
|
||||
|
||||
clutter_actor_set_size (clone, size, size);
|
||||
|
||||
clutter_behaviour_apply (behaviour, clone);
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
keypress_cb (ClutterStage *stage,
|
||||
ClutterKeyEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
switch (clutter_key_event_symbol (event))
|
||||
{
|
||||
case CLUTTER_q:
|
||||
{
|
||||
clutter_main_quit ();
|
||||
}
|
||||
|
||||
case CLUTTER_a:
|
||||
{
|
||||
if (icon != NULL)
|
||||
{
|
||||
ClutterActor *clone = create_item ();
|
||||
|
||||
/* Add one item to container */
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (box), clone);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CLUTTER_d:
|
||||
{
|
||||
GList *children =
|
||||
clutter_container_get_children (CLUTTER_CONTAINER (box));
|
||||
|
||||
if (children)
|
||||
{
|
||||
GList *last = g_list_last (children);
|
||||
|
||||
/* Remove last item on container */
|
||||
clutter_container_remove_actor (CLUTTER_CONTAINER (box),
|
||||
CLUTTER_ACTOR (last->data));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CLUTTER_w:
|
||||
{
|
||||
decrease_property_value (box, "padding");
|
||||
break;
|
||||
}
|
||||
|
||||
case CLUTTER_e:
|
||||
{
|
||||
increase_property_value (box, "padding");
|
||||
break;
|
||||
}
|
||||
|
||||
case CLUTTER_r:
|
||||
{
|
||||
decrease_property_value (box, "spacing");
|
||||
break;
|
||||
}
|
||||
|
||||
case CLUTTER_s:
|
||||
{
|
||||
toggle_property_value (box, "use-transformed-box");
|
||||
break;
|
||||
}
|
||||
|
||||
case CLUTTER_t:
|
||||
{
|
||||
increase_property_value (box, "spacing");
|
||||
break;
|
||||
}
|
||||
|
||||
case CLUTTER_z:
|
||||
{
|
||||
if (clutter_timeline_is_playing (timeline))
|
||||
clutter_timeline_pause (timeline);
|
||||
else
|
||||
clutter_timeline_start (timeline);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
ClutterActor *instructions;
|
||||
gint i;
|
||||
GError *error = NULL;
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
clutter_actor_set_size (stage, 800, 600);
|
||||
|
||||
clutter_color_parse ("Red", &bg_color);
|
||||
|
||||
timeline = clutter_timeline_new_for_duration (2000);
|
||||
clutter_timeline_set_loop (timeline, TRUE);
|
||||
|
||||
behaviour = clutter_behaviour_scale_new (clutter_alpha_new_full (timeline,
|
||||
CLUTTER_ALPHA_SINE,
|
||||
NULL, NULL),
|
||||
1.0, 1.0, 2.0, 2.0);
|
||||
|
||||
box = my_thing_new (10, 10);
|
||||
|
||||
clutter_actor_set_position (box, 20, 20);
|
||||
clutter_actor_set_size (box, 400, -1);
|
||||
|
||||
icon = clutter_texture_new_from_file ("redhand.png", &error);
|
||||
if (error)
|
||||
g_error ("Unable to load 'redhand.png': %s", error->message);
|
||||
|
||||
for (i = 0; i < 33; i++)
|
||||
{
|
||||
ClutterActor *clone = create_item ();
|
||||
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (box), clone);
|
||||
}
|
||||
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), box);
|
||||
|
||||
instructions = clutter_label_new_with_text ("Sans 14",
|
||||
"<b>Instructions:</b>\n"
|
||||
"a - add a new item\n"
|
||||
"d - remove last item\n"
|
||||
"z - start/pause behaviour\n"
|
||||
"w - decrease padding\n"
|
||||
"e - increase padding\n"
|
||||
"r - decrease spacing\n"
|
||||
"t - increase spacing\n"
|
||||
"s - use transformed box\n"
|
||||
"q - quit");
|
||||
|
||||
clutter_label_set_use_markup (CLUTTER_LABEL (instructions), TRUE);
|
||||
clutter_actor_set_position (instructions, 450, 10);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), instructions);
|
||||
|
||||
g_signal_connect (stage, "key-release-event",
|
||||
G_CALLBACK (keypress_cb),
|
||||
NULL);
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
g_object_unref (timeline);
|
||||
g_object_unref (behaviour);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -31,9 +31,9 @@ main (int argc, char *argv[])
|
||||
clutter_label_get_color (CLUTTER_LABEL (label), &color_check);
|
||||
g_assert (color_check.alpha == label_color.alpha);
|
||||
|
||||
g_print ("label 50%%.get_abs_opacity() = %d\n",
|
||||
clutter_actor_get_abs_opacity (label));
|
||||
g_assert (clutter_actor_get_abs_opacity (label) == 128);
|
||||
g_print ("label 50%%.get_paint_opacity() = %d\n",
|
||||
clutter_actor_get_paint_opacity (label));
|
||||
g_assert (clutter_actor_get_paint_opacity (label) == 128);
|
||||
|
||||
clutter_actor_show (label);
|
||||
|
||||
@ -57,9 +57,9 @@ main (int argc, char *argv[])
|
||||
clutter_label_get_color (CLUTTER_LABEL (label), &color_check);
|
||||
g_assert (color_check.alpha == label_color.alpha);
|
||||
|
||||
g_print ("label 50%% + group 50%%.get_abs_opacity() = %d\n",
|
||||
clutter_actor_get_abs_opacity (label));
|
||||
g_assert (clutter_actor_get_abs_opacity (label) == 64);
|
||||
g_print ("label 50%% + group 50%%.get_paint_opacity() = %d\n",
|
||||
clutter_actor_get_paint_opacity (label));
|
||||
g_assert (clutter_actor_get_paint_opacity (label) == 64);
|
||||
|
||||
clutter_actor_show (label);
|
||||
|
||||
@ -81,9 +81,9 @@ main (int argc, char *argv[])
|
||||
clutter_rectangle_get_color (CLUTTER_RECTANGLE (rect), &color_check);
|
||||
g_assert (color_check.alpha == rect_color.alpha);
|
||||
|
||||
g_print ("rect 100%%.get_abs_opacity() = %d\n",
|
||||
clutter_actor_get_abs_opacity (rect));
|
||||
g_assert (clutter_actor_get_abs_opacity (rect) == 128);
|
||||
g_print ("rect 100%%.get_paint_opacity() = %d\n",
|
||||
clutter_actor_get_paint_opacity (rect));
|
||||
g_assert (clutter_actor_get_paint_opacity (rect) == 128);
|
||||
|
||||
clutter_actor_show (rect);
|
||||
|
||||
@ -101,9 +101,9 @@ main (int argc, char *argv[])
|
||||
clutter_rectangle_get_color (CLUTTER_RECTANGLE (rect), &color_check);
|
||||
g_assert (color_check.alpha == rect_color.alpha);
|
||||
|
||||
g_print ("rect 100%%.get_abs_opacity() = %d\n",
|
||||
clutter_actor_get_abs_opacity (rect));
|
||||
g_assert (clutter_actor_get_abs_opacity (rect) == 255);
|
||||
g_print ("rect 100%%.get_paint_opacity() = %d\n",
|
||||
clutter_actor_get_paint_opacity (rect));
|
||||
g_assert (clutter_actor_get_paint_opacity (rect) == 255);
|
||||
|
||||
clutter_actor_show (rect);
|
||||
|
||||
|
@ -12,7 +12,7 @@ init_handles ()
|
||||
ClutterVertex v1, v2;
|
||||
ClutterColor blue = { 0, 0, 0xff, 0xff };
|
||||
|
||||
clutter_actor_get_vertices (rect, v);
|
||||
clutter_actor_get_abs_allocation_vertices (rect, v);
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
p[i] = clutter_rectangle_new_with_color (&blue);
|
||||
@ -58,7 +58,7 @@ place_handles ()
|
||||
ClutterVertex v[4];
|
||||
ClutterVertex v1, v2;
|
||||
|
||||
clutter_actor_get_vertices (rect, v);
|
||||
clutter_actor_get_abs_allocation_vertices (rect, v);
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
clutter_actor_set_position (p[i],
|
||||
@ -136,8 +136,8 @@ on_event (ClutterStage *stage,
|
||||
|
||||
clutter_event_get_coords (event, &x, &y);
|
||||
|
||||
clutter_actor_query_coords (dragging, &box1);
|
||||
clutter_actor_query_coords (rect, &box2);
|
||||
clutter_actor_get_allocation_box (dragging, &box1);
|
||||
clutter_actor_get_allocation_box (rect, &box2);
|
||||
|
||||
xp = CLUTTER_INT_TO_FIXED (x-3) - box1.x1;
|
||||
yp = CLUTTER_INT_TO_FIXED (y-3) - box1.y1;
|
||||
@ -178,7 +178,10 @@ on_event (ClutterStage *stage,
|
||||
break;
|
||||
}
|
||||
|
||||
clutter_actor_request_coords (rect, &box2);
|
||||
/* FIXME this is just plain wrong, to allocate directly
|
||||
* like this
|
||||
*/
|
||||
clutter_actor_allocate (rect, &box2, TRUE);
|
||||
}
|
||||
|
||||
place_handles ();
|
||||
|
Loading…
Reference in New Issue
Block a user