[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 <cue raising dramatic music> 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.
This commit is contained in:
Emmanuele Bassi 2009-09-14 11:04:11 +01:00
parent a1853892ba
commit d096a3c791
2 changed files with 146 additions and 1 deletions

View File

@ -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 <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
/** /**
* SECTION:clutter-layout-manager * SECTION:clutter-layout-manager
* @short_description: Layout managers base class * @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 * #ClutterLayoutManager is available since Clutter 1.2
*/ */
@ -23,10 +57,19 @@
G_OBJECT_TYPE_NAME (_obj), \ G_OBJECT_TYPE_NAME (_obj), \
(method)); } G_STMT_END (method)); } G_STMT_END
enum
{
LAYOUT_CHANGED,
LAST_SIGNAL
};
G_DEFINE_ABSTRACT_TYPE (ClutterLayoutManager, G_DEFINE_ABSTRACT_TYPE (ClutterLayoutManager,
clutter_layout_manager, clutter_layout_manager,
G_TYPE_INITIALLY_UNOWNED); G_TYPE_INITIALLY_UNOWNED);
static guint manager_signals[LAST_SIGNAL] = { 0, };
static void static void
layout_manager_real_get_preferred_width (ClutterLayoutManager *manager, layout_manager_real_get_preferred_width (ClutterLayoutManager *manager,
ClutterContainer *container, 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_width = layout_manager_real_get_preferred_width;
klass->get_preferred_height = layout_manager_real_get_preferred_height; klass->get_preferred_height = layout_manager_real_get_preferred_height;
klass->allocate = layout_manager_real_allocate; 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 static void
@ -180,3 +262,22 @@ clutter_layout_manager_allocate (ClutterLayoutManager *manager,
klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager); klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager);
klass->allocate (manager, container, allocation, flags); 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);
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly." #error "Only <clutter/clutter.h> can be included directly."
#endif #endif
@ -30,11 +54,23 @@ typedef struct _ClutterLayoutManagerClass ClutterLayoutManagerClass;
*/ */
struct _ClutterLayoutManager struct _ClutterLayoutManager
{ {
/*< private >*/
GInitiallyUnowned parent_instance; GInitiallyUnowned parent_instance;
}; };
/** /**
* ClutterLayoutManagerClass: * 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 * The #ClutterLayoutManagerClass structure contains only private
* data and should be accessed using the provided API * data and should be accessed using the provided API
@ -43,8 +79,10 @@ struct _ClutterLayoutManager
*/ */
struct _ClutterLayoutManagerClass struct _ClutterLayoutManagerClass
{ {
/*< private >*/
GInitiallyUnownedClass parent_class; GInitiallyUnownedClass parent_class;
/*< public >*/
void (* get_preferred_width) (ClutterLayoutManager *manager, void (* get_preferred_width) (ClutterLayoutManager *manager,
ClutterContainer *container, ClutterContainer *container,
gfloat for_height, gfloat for_height,
@ -60,6 +98,10 @@ struct _ClutterLayoutManagerClass
const ClutterActorBox *allocation, const ClutterActorBox *allocation,
ClutterAllocationFlags flags); ClutterAllocationFlags flags);
void (* layout_changed) (ClutterLayoutManager *manager);
/*< private >*/
/* padding for future expansion */
void (* _clutter_padding_1) (void); void (* _clutter_padding_1) (void);
void (* _clutter_padding_2) (void); void (* _clutter_padding_2) (void);
void (* _clutter_padding_3) (void); void (* _clutter_padding_3) (void);
@ -87,6 +129,8 @@ void clutter_layout_manager_allocate (ClutterLayoutManager *manage
const ClutterActorBox *allocation, const ClutterActorBox *allocation,
ClutterAllocationFlags flags); ClutterAllocationFlags flags);
void clutter_layout_manager_layout_changed (ClutterLayoutManager *manager);
G_END_DECLS G_END_DECLS
#endif /* __CLUTTER_LAYOUT_MANAGER_H__ */ #endif /* __CLUTTER_LAYOUT_MANAGER_H__ */