From d096a3c791ab5b105d55a19ab316cd8b2fff878b Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Mon, 14 Sep 2009 11:04:11 +0100 Subject: [PATCH] [layout] Add LayoutManager::layout-changed signal If a sub-class of LayoutManager wishes to implement a parametrized layout policy it also needs a way to notify the container using the layout manager that the layout has changed. We cannot do it directly and automatically from the LayoutManager because a) it has no back link to the actor that it is using it and b) it can be attached to multiple actors. This is a job for signals! By adding ClutterLayoutManager::layout-changed (and its relative emitted function) we can notify actors using the layout manager that the layout parameters have been changed, and thus they should queue a relayout. --- clutter/clutter-layout-manager.c | 103 ++++++++++++++++++++++++++++++- clutter/clutter-layout-manager.h | 44 +++++++++++++ 2 files changed, 146 insertions(+), 1 deletion(-) diff --git a/clutter/clutter-layout-manager.c b/clutter/clutter-layout-manager.c index 912ccd2d3..f27b8cc81 100644 --- a/clutter/clutter-layout-manager.c +++ b/clutter/clutter-layout-manager.c @@ -1,8 +1,42 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Copyright (C) 2009 Intel Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Author: + * Emmanuele Bassi + */ + /** * SECTION:clutter-layout-manager * @short_description: Layout managers base class * - * #ClutterLayoutManager is FIXME + * #ClutterLayoutManager is a base abstract class for layout managers. A + * layout manager implements the layouting policy for a composite or a + * container actor: it controls the preferred size of the actor to which + * it has been paired, and it controls the allocation of its children. + * + * Any composite or container #ClutterActor subclass can delegate the + * layouting of its children to a #ClutterLayoutManager. Clutter provides + * a generic container using #ClutterLayoutManager called #ClutterBox. + * + * Clutter provides some simple #ClutterLayoutManager sub-classes, like + * #ClutterFixedLayout and #ClutterBinLayout. * * #ClutterLayoutManager is available since Clutter 1.2 */ @@ -23,10 +57,19 @@ G_OBJECT_TYPE_NAME (_obj), \ (method)); } G_STMT_END +enum +{ + LAYOUT_CHANGED, + + LAST_SIGNAL +}; + G_DEFINE_ABSTRACT_TYPE (ClutterLayoutManager, clutter_layout_manager, G_TYPE_INITIALLY_UNOWNED); +static guint manager_signals[LAST_SIGNAL] = { 0, }; + static void layout_manager_real_get_preferred_width (ClutterLayoutManager *manager, ClutterContainer *container, @@ -74,6 +117,45 @@ clutter_layout_manager_class_init (ClutterLayoutManagerClass *klass) klass->get_preferred_width = layout_manager_real_get_preferred_width; klass->get_preferred_height = layout_manager_real_get_preferred_height; klass->allocate = layout_manager_real_allocate; + + /** + * ClutterLayoutManager::layout-changed: + * @manager: the #ClutterLayoutManager that emitted the signal + * + * The ::layout-changed signal is emitted each time a layout manager + * has been changed. Every #ClutterActor using the @manager instance + * as a layout manager should connect a handler to the ::layout-changed + * signal and queue a relayout on themselves: + * + * |[ + * static void layout_changed (ClutterLayoutManager *manager, + * ClutterActor *self) + * { + * clutter_actor_queue_relayout (self); + * } + * ... + * self->manager = g_object_ref_sink (manager); + * g_signal_connect (self->manager, "layout-changed", + * G_CALLBACK (layout_changed), + * self); + * ]| + * + * Sub-classes of #ClutterLayoutManager that implement a layout that + * can be controlled or changed using parameters should emit the + * ::layout-changed signal whenever one of the parameters changes, + * by using clutter_layout_manager_layout_changed(). + * + * Since: 1.2 + */ + manager_signals[LAYOUT_CHANGED] = + g_signal_new (I_("layout-changed"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ClutterLayoutManagerClass, + layout_changed), + NULL, NULL, + clutter_marshal_VOID__VOID, + G_TYPE_NONE, 0); } static void @@ -180,3 +262,22 @@ clutter_layout_manager_allocate (ClutterLayoutManager *manager, klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager); klass->allocate (manager, container, allocation, flags); } + +/** + * clutter_layout_manager_layout_changed: + * @manager: a #ClutterLayoutManager + * + * Emits the #ClutterLayoutManager::layout-changed signal on @manager + * + * This function should only be called by implementations of the + * #ClutterLayoutManager class + * + * Since: 1.2 + */ +void +clutter_layout_manager_layout_changed (ClutterLayoutManager *manager) +{ + g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager)); + + g_signal_emit (manager, manager_signals[LAYOUT_CHANGED], 0); +} diff --git a/clutter/clutter-layout-manager.h b/clutter/clutter-layout-manager.h index e053c658e..b979430c0 100644 --- a/clutter/clutter-layout-manager.h +++ b/clutter/clutter-layout-manager.h @@ -1,3 +1,27 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Copyright (C) 2009 Intel Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Author: + * Emmanuele Bassi + */ + #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) #error "Only can be included directly." #endif @@ -30,11 +54,23 @@ typedef struct _ClutterLayoutManagerClass ClutterLayoutManagerClass; */ struct _ClutterLayoutManager { + /*< private >*/ GInitiallyUnowned parent_instance; }; /** * ClutterLayoutManagerClass: + * @get_preferred_width: virtual function; override to provide a preferred + * width for the layout manager. See also the get_preferred_width() + * virtual function in #ClutterActor + * @get_preferred_height: virtual function; override to provide a preferred + * height for the layout manager. See also the get_preferred_height() + * virtual function in #ClutterActor + * @allocate: virtual function; override to allocate the children of the + * layout manager. See also the allocate() virtual function in + * #ClutterActor + * @layout_changed: class handler for the #ClutterLayoutManager::layout-changed + * signal * * The #ClutterLayoutManagerClass structure contains only private * data and should be accessed using the provided API @@ -43,8 +79,10 @@ struct _ClutterLayoutManager */ struct _ClutterLayoutManagerClass { + /*< private >*/ GInitiallyUnownedClass parent_class; + /*< public >*/ void (* get_preferred_width) (ClutterLayoutManager *manager, ClutterContainer *container, gfloat for_height, @@ -60,6 +98,10 @@ struct _ClutterLayoutManagerClass const ClutterActorBox *allocation, ClutterAllocationFlags flags); + void (* layout_changed) (ClutterLayoutManager *manager); + + /*< private >*/ + /* padding for future expansion */ void (* _clutter_padding_1) (void); void (* _clutter_padding_2) (void); void (* _clutter_padding_3) (void); @@ -87,6 +129,8 @@ void clutter_layout_manager_allocate (ClutterLayoutManager *manage const ClutterActorBox *allocation, ClutterAllocationFlags flags); +void clutter_layout_manager_layout_changed (ClutterLayoutManager *manager); + G_END_DECLS #endif /* __CLUTTER_LAYOUT_MANAGER_H__ */