mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 03:22:04 +00:00
Don't forget files when committing, stoopeed
This commit is contained in:
parent
e30df678ae
commit
42ebf073bd
379
clutter/clutter-container.c
Normal file
379
clutter/clutter-container.c
Normal file
@ -0,0 +1,379 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Authored By Matthew Allum <mallum@openedhand.com>
|
||||
*
|
||||
* Copyright (C) 2006 OpenedHand
|
||||
*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* ClutterContainer: Generic actor container interface.
|
||||
* Author: Emmanuele Bassi <ebassi@openedhand.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "clutter-container.h"
|
||||
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-main.h"
|
||||
#include "clutter-marshal.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-enum-types.h"
|
||||
|
||||
/**
|
||||
* SECTION:clutter-container
|
||||
* @short_description: An interface for implementing container actors
|
||||
*
|
||||
* #ClutterContainer is an interface for writing actors containing other
|
||||
* #ClutterActor<!-- -->s. It provides a standard API for adding, removing
|
||||
* and iterating on every contained actor.
|
||||
*
|
||||
* An actor implementing #ClutterContainer is #ClutterGroup.
|
||||
*
|
||||
* #ClutterContainer is available since Clutter 0.4
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
ACTOR_ADDED,
|
||||
ACTOR_REMOVED,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint container_signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
static void
|
||||
clutter_container_base_init (gpointer g_iface)
|
||||
{
|
||||
static gboolean initialised = FALSE;
|
||||
|
||||
if (!initialised)
|
||||
{
|
||||
GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
|
||||
|
||||
initialised = TRUE;
|
||||
|
||||
/**
|
||||
* ClutterContainer::actor-added:
|
||||
* @container: the actor which received the signal
|
||||
* @actor: the new child that has been added to @container
|
||||
*
|
||||
* The ::actor-added signal is emitted each time an actor
|
||||
* has been added to @container.
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
container_signals[ACTOR_ADDED] =
|
||||
g_signal_new ("actor-added",
|
||||
iface_type,
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (ClutterContainerIface, actor_added),
|
||||
NULL, NULL,
|
||||
clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_ACTOR);
|
||||
/**
|
||||
* ClutterContainer::actor-removed:
|
||||
* @container: the actor which received the signal
|
||||
* @actor: the child that has been removed from @container
|
||||
*
|
||||
* The ::actor-removed signal is emitted each time an actor
|
||||
* is removed from @container.
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
container_signals[ACTOR_REMOVED] =
|
||||
g_signal_new ("actor-removed",
|
||||
iface_type,
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (ClutterContainerIface, actor_removed),
|
||||
NULL, NULL,
|
||||
clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_ACTOR);
|
||||
}
|
||||
}
|
||||
|
||||
GType
|
||||
clutter_container_get_type (void)
|
||||
{
|
||||
static GType container_type = 0;
|
||||
|
||||
if (G_UNLIKELY (!container_type))
|
||||
{
|
||||
GTypeInfo container_info =
|
||||
{
|
||||
sizeof (ClutterContainerIface),
|
||||
clutter_container_base_init,
|
||||
NULL, /* iface_finalize */
|
||||
};
|
||||
|
||||
container_type = g_type_register_static (G_TYPE_INTERFACE,
|
||||
"ClutterContainer",
|
||||
&container_info, 0);
|
||||
|
||||
g_type_interface_add_prerequisite (container_type, CLUTTER_TYPE_ACTOR);
|
||||
}
|
||||
|
||||
return container_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_container_add:
|
||||
* @container: a #ClutterContainer
|
||||
* @first_actor: the first #ClutterActor to add
|
||||
* @Varargs: %NULL terminated list of actors to add
|
||||
*
|
||||
* Adds a list of #ClutterActor<!-- -->s to @container. Each time and
|
||||
* actor is added, the "actor-added" signal is emitted. Each actor should
|
||||
* be parented to @container, which takes a reference on the actor. You
|
||||
* cannot add a #ClutterActor to more than one #ClutterContainer.
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
void
|
||||
clutter_container_add (ClutterContainer *container,
|
||||
ClutterActor *first_actor,
|
||||
...)
|
||||
{
|
||||
va_list var_args;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (first_actor));
|
||||
|
||||
va_start (var_args, first_actor);
|
||||
clutter_container_add_valist (container, first_actor, var_args);
|
||||
va_end (var_args);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_container_add_actor:
|
||||
* @container: a #ClutterContainer
|
||||
* @actor: the first #ClutterActor to add
|
||||
*
|
||||
* Adds a #ClutterActor to @container. This function will emit the
|
||||
* "actor-added" signal is emitted. The actor should be parented to
|
||||
* @container. You cannot add a #ClutterActor to more than one
|
||||
* #ClutterContainer.
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
void
|
||||
clutter_container_add_actor (ClutterContainer *container,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
ClutterActor *parent;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||
|
||||
parent = clutter_actor_get_parent (actor);
|
||||
if (parent)
|
||||
{
|
||||
g_warning ("Attempting to add actor of type `%s' to a "
|
||||
"group of type `%s', but the actor has already "
|
||||
"a parent of type `%s'.",
|
||||
g_type_name (G_OBJECT_TYPE (actor)),
|
||||
g_type_name (G_OBJECT_TYPE (container)),
|
||||
g_type_name (G_OBJECT_TYPE (parent)));
|
||||
return;
|
||||
}
|
||||
|
||||
CLUTTER_CONTAINER_GET_IFACE (container)->add (container, actor);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_container_add:
|
||||
* @container: a #ClutterContainer
|
||||
* @first_actor: the first #ClutterActor to add
|
||||
* @var_args: list of actors to add, followed by %NULL
|
||||
*
|
||||
* Alternative va_list version of clutter_container_add().
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
void
|
||||
clutter_container_add_valist (ClutterContainer *container,
|
||||
ClutterActor *first_actor,
|
||||
va_list var_args)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (first_actor));
|
||||
|
||||
actor = first_actor;
|
||||
while (actor)
|
||||
{
|
||||
clutter_container_add_actor (container, actor);
|
||||
actor = va_arg (var_args, ClutterActor*);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_container_remove:
|
||||
* @container: a #ClutterContainer
|
||||
* @first_actor: first #ClutterActor to remove
|
||||
* @Varargs: a %NULL-terminated list of actors to remove
|
||||
*
|
||||
* Removes a %NULL terminated list of #ClutterActor<!-- -->s from
|
||||
* @container. Each actor should be unparented, so if you want to keep it
|
||||
* around you must hold a reference to it yourself, using g_object_ref().
|
||||
* Each time an actor is removed, the "actor-removed" signal is
|
||||
* emitted by @container.
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
void
|
||||
clutter_container_remove (ClutterContainer *container,
|
||||
ClutterActor *first_actor,
|
||||
...)
|
||||
{
|
||||
va_list var_args;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (first_actor));
|
||||
|
||||
va_start (var_args, first_actor);
|
||||
clutter_container_remove_valist (container, first_actor, var_args);
|
||||
va_end (var_args);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_container_remove_actor:
|
||||
* @container: a #ClutterContainer
|
||||
* @actor: a #ClutterActor
|
||||
*
|
||||
* Removes @actor from @container. The actor should be unparented, so
|
||||
* if you want to keep it around you must hold a reference to it
|
||||
* yourself, using g_object_ref(). When the actor has been removed,
|
||||
* the "actor-removed" signal is emitted by @container.
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
void
|
||||
clutter_container_remove_actor (ClutterContainer *container,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
ClutterActor *parent;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||
|
||||
parent = clutter_actor_get_parent (actor);
|
||||
if (parent != CLUTTER_ACTOR (container))
|
||||
{
|
||||
g_warning ("Attempting to remove actor of type `%s' from "
|
||||
"group of class `%s', but the group is not the "
|
||||
"actor's parent.",
|
||||
g_type_name (G_OBJECT_TYPE (actor)),
|
||||
g_type_name (G_OBJECT_TYPE (container)));
|
||||
return;
|
||||
}
|
||||
|
||||
CLUTTER_CONTAINER_GET_IFACE (container)->remove (container, actor);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_container_remove_valist:
|
||||
* @container: a #ClutterContainer
|
||||
* @first_actor: the first #ClutterActor to add
|
||||
* @var_args: list of actors to remove, followed by %NULL
|
||||
*
|
||||
* Alternative va_list version of clutter_container_remove().
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
void
|
||||
clutter_container_remove_valist (ClutterContainer *container,
|
||||
ClutterActor *first_actor,
|
||||
va_list var_args)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (first_actor));
|
||||
|
||||
actor = first_actor;
|
||||
while (actor)
|
||||
{
|
||||
clutter_container_remove_actor (container, actor);
|
||||
|
||||
actor = va_arg (var_args, ClutterActor*);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_children_cb (ClutterActor *child,
|
||||
gpointer data)
|
||||
{
|
||||
GList **children = data;
|
||||
|
||||
*children = g_list_prepend (*children, child);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_container_get_children:
|
||||
* @container: a #ClutterContainer
|
||||
*
|
||||
* Retrieves all the children of @container.
|
||||
*
|
||||
* Return value: a list of #ClutterActor<!-- -->s. Use g_list_free()
|
||||
* on the returned list when done.
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
GList *
|
||||
clutter_container_get_children (ClutterContainer *container)
|
||||
{
|
||||
GList *retval;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_CONTAINER (container), NULL);
|
||||
|
||||
retval = NULL;
|
||||
clutter_container_foreach (container, get_children_cb, &retval);
|
||||
|
||||
return g_list_reverse (retval);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_container_foreach:
|
||||
* @container: a #ClutterContainer
|
||||
* @callback: a function to be called for each child
|
||||
* @user_data: data to be passed to the function, or %NULL
|
||||
*
|
||||
* Calls @callback for each child of @container.
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
void
|
||||
clutter_container_foreach (ClutterContainer *container,
|
||||
ClutterCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
CLUTTER_CONTAINER_GET_IFACE (container)->foreach (container, callback, user_data);
|
||||
}
|
||||
|
98
clutter/clutter-container.h
Normal file
98
clutter/clutter-container.h
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Authored By Matthew Allum <mallum@openedhand.com>
|
||||
*
|
||||
* Copyright (C) 2006 OpenedHand
|
||||
*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* ClutterContainer: Generic actor container interface.
|
||||
* Author: Emmanuele Bassi <ebassi@openedhand.com>
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_CONTAINER_H__
|
||||
#define __CLUTTER_CONTAINER_H__
|
||||
|
||||
#include <clutter/clutter-actor.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_CONTAINER (clutter_container_get_type ())
|
||||
#define CLUTTER_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CONTAINER, ClutterContainer))
|
||||
#define CLUTTER_IS_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CONTAINER))
|
||||
#define CLUTTER_CONTAINER_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), CLUTTER_TYPE_CONTAINER, ClutterContainerIface))
|
||||
|
||||
typedef struct _ClutterContainer ClutterContainer; /* dummy */
|
||||
typedef struct _ClutterContainerIface ClutterContainerIface;
|
||||
|
||||
struct _ClutterContainerIface
|
||||
{
|
||||
GTypeInterface g_iface;
|
||||
|
||||
void (* add) (ClutterContainer *container,
|
||||
ClutterActor *actor);
|
||||
void (* remove) (ClutterContainer *container,
|
||||
ClutterActor *actor);
|
||||
void (* foreach) (ClutterContainer *container,
|
||||
ClutterCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
/* signals */
|
||||
void (* actor_added) (ClutterContainer *container,
|
||||
ClutterActor *actor);
|
||||
void (* actor_removed) (ClutterContainer *container,
|
||||
ClutterActor *actor);
|
||||
|
||||
/* padding, for future expansion */
|
||||
void (*_clutter_reserved1) (void);
|
||||
void (*_clutter_reserved2) (void);
|
||||
void (*_clutter_reserved3) (void);
|
||||
void (*_clutter_reserved4) (void);
|
||||
void (*_clutter_reserved5) (void);
|
||||
void (*_clutter_reserved6) (void);
|
||||
void (*_clutter_reserved7) (void);
|
||||
void (*_clutter_reserved8) (void);
|
||||
};
|
||||
|
||||
GType clutter_container_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void clutter_container_add (ClutterContainer *container,
|
||||
ClutterActor *first_actor,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
void clutter_container_add_actor (ClutterContainer *container,
|
||||
ClutterActor *actor);
|
||||
void clutter_container_add_valist (ClutterContainer *container,
|
||||
ClutterActor *first_actor,
|
||||
va_list varargs);
|
||||
void clutter_container_remove (ClutterContainer *container,
|
||||
ClutterActor *first_actor,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
void clutter_container_remove_actor (ClutterContainer *container,
|
||||
ClutterActor *actor);
|
||||
void clutter_container_remove_valist (ClutterContainer *container,
|
||||
ClutterActor *first_actor,
|
||||
va_list varargs);
|
||||
GList *clutter_container_get_children (ClutterContainer *container);
|
||||
void clutter_container_foreach (ClutterContainer *container,
|
||||
ClutterCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_CONTAINER_H__ */
|
378
clutter/clutter-layout.c
Normal file
378
clutter/clutter-layout.c
Normal file
@ -0,0 +1,378 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Authored By Matthew Allum <mallum@openedhand.com>
|
||||
*
|
||||
* Copyright (C) 2006 OpenedHand
|
||||
*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* ClutterLayout: interface to be implemented by actors providing
|
||||
* extended layouts.
|
||||
*
|
||||
* Author: Emmanuele Bassi <ebassi@openedhand.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter-layout.h"
|
||||
#include "clutter-main.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-units.h"
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-enum-types.h"
|
||||
|
||||
#define MAX_TUNE_REQUESTS 3
|
||||
|
||||
/**
|
||||
* SECTION:clutter-layout
|
||||
* @short_description: An interface for implementing layouts
|
||||
*
|
||||
* #ClutterLayout is an interface that #ClutterActor<!-- -->s might
|
||||
* implement to provide complex or extended layouts. The default
|
||||
* size allocation of a #ClutterActor inside a #ClutterGroup is to
|
||||
* make the group size allocation grow enough to contain the actor.
|
||||
* A #ClutterActor implementing the #ClutterLayout interface will
|
||||
* be queried for its size when it is added to a #ClutterGroup subclass
|
||||
* that honours the #ClutterLayout interface; the resulting size
|
||||
* allocation will depend on the #ClutterLayoutFlags that the actor
|
||||
* supports.
|
||||
*
|
||||
* There are various types of layout available for actors implementing
|
||||
* the #ClutterLayout interface: %CLUTTER_LAYOUT_WIDTH_FOR_HEIGHT will
|
||||
* ask the actor for its width given the height allocated by the
|
||||
* container; %CLUTTER_LAYOUT_HEIGHT_FOR_WIDTH will ask the actor for
|
||||
* its height given the width allocated by the container. These two
|
||||
* layout types are especially useful for labels and unidirectional
|
||||
* container types, like vertical and horizontal boxes.
|
||||
*
|
||||
* Another layout available is %CLUTTER_LAYOUT_NATURAL, which will
|
||||
* query the actor for its natural (default) width and height; the
|
||||
* container actor will then try to allocate as much as it can,
|
||||
* and might resort to scaling the actor to fit the allocation. This
|
||||
* layout type is suited for #ClutterTexture<!-- -->s and shapes.
|
||||
*
|
||||
* Finally, the %CLUTTER_LAYOUT_TUNABLE is an iterative layout. An actor
|
||||
* will be queried multiple times until it's satisfied with the size
|
||||
* given.
|
||||
*
|
||||
* A #ClutterGroup subclass that honours the #ClutterLayout interface
|
||||
* should check whether an actor is implementing this interface when
|
||||
* adding it, by using the %CLUTTER_IS_LAYOUT type check macro. If the
|
||||
* actor does implement the interface, the #ClutterGroup should get
|
||||
* the supported layouts using clutter_layout_get_layout_flags() and
|
||||
* verify which layout is compatible with the group's own layout; for
|
||||
* instance, vertical containers should check for actors implementing the
|
||||
* %CLUTTER_LAYOUT_WIDTH_FOR_HEIGHT layout management, while horizontal
|
||||
* containers should check for actors implementing the
|
||||
* %CLUTTER_LAYOUT_HEIGHT_FOR_WIDTH layout management. If the actor
|
||||
* satisfies the layout requirements, the container actor should query
|
||||
* the actor for a geometry request using the appropriate function and
|
||||
* allocate space for the newly added actor accordingly.
|
||||
*
|
||||
* #ClutterLayout is available since Clutter 0.4
|
||||
*/
|
||||
|
||||
static void
|
||||
clutter_layout_base_init (gpointer g_iface)
|
||||
{
|
||||
static gboolean initialised = FALSE;
|
||||
|
||||
if (G_UNLIKELY (!initialised))
|
||||
{
|
||||
initialised = TRUE;
|
||||
|
||||
/**
|
||||
* ClutterLayout:layout-flags:
|
||||
*
|
||||
* The layout types that the #ClutterLayout supports.
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
g_object_interface_install_property (g_iface,
|
||||
g_param_spec_flags ("layout-flags",
|
||||
"Layout Flags",
|
||||
"Supported layouts",
|
||||
CLUTTER_TYPE_LAYOUT_FLAGS,
|
||||
CLUTTER_LAYOUT_NONE,
|
||||
CLUTTER_PARAM_READABLE));
|
||||
}
|
||||
}
|
||||
|
||||
GType
|
||||
clutter_layout_get_type (void)
|
||||
{
|
||||
static GType layout_type = 0;
|
||||
|
||||
if (!layout_type)
|
||||
{
|
||||
GTypeInfo layout_info =
|
||||
{
|
||||
sizeof (ClutterLayoutIface),
|
||||
clutter_layout_base_init,
|
||||
NULL,
|
||||
};
|
||||
|
||||
layout_type = g_type_register_static (G_TYPE_INTERFACE, "ClutterLayout",
|
||||
&layout_info, 0);
|
||||
g_type_interface_add_prerequisite (layout_type, CLUTTER_TYPE_ACTOR);
|
||||
}
|
||||
|
||||
return layout_type;
|
||||
}
|
||||
|
||||
/*
|
||||
* Public API
|
||||
*/
|
||||
|
||||
/**
|
||||
* clutter_layout_get_layout_flags:
|
||||
* @layout: a #ClutterLayout
|
||||
*
|
||||
* Retrieves the supported layout types from the #ClutterLayout
|
||||
*
|
||||
* Return value: bitwise or of #ClutterLayoutFlags
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
ClutterLayoutFlags
|
||||
clutter_layout_get_layout_flags (ClutterLayout *layout)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_LAYOUT (layout), CLUTTER_LAYOUT_NONE);
|
||||
|
||||
if (CLUTTER_LAYOUT_GET_IFACE (layout)->get_layout_flags)
|
||||
return CLUTTER_LAYOUT_GET_IFACE (layout)->get_layout_flags (layout);
|
||||
|
||||
return CLUTTER_LAYOUT_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_layout_width_for_height:
|
||||
* @layout: a #ClutterLayout
|
||||
* @width: return location for the width
|
||||
* @height: height allocated by the parent
|
||||
*
|
||||
* Queries a #ClutterLayout actor for its width with a known height.
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
void
|
||||
clutter_layout_width_for_height (ClutterLayout *layout,
|
||||
gint *width,
|
||||
gint height)
|
||||
{
|
||||
ClutterLayoutFlags layout_type;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_LAYOUT (layout));
|
||||
|
||||
layout_type = clutter_layout_get_layout_flags (layout);
|
||||
if (layout_type & CLUTTER_LAYOUT_WIDTH_FOR_HEIGHT)
|
||||
{
|
||||
ClutterUnit u_width, u_height;
|
||||
|
||||
u_height = CLUTTER_UNITS_FROM_INT (height);
|
||||
CLUTTER_LAYOUT_GET_IFACE (layout)->width_for_height (layout,
|
||||
&u_width,
|
||||
u_height);
|
||||
|
||||
if (width)
|
||||
*width = CLUTTER_UNITS_TO_INT (u_width);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Actor queried for width with a given height, but "
|
||||
"actors of type `%s' do not support width-for-height "
|
||||
"layouts.",
|
||||
g_type_name (G_OBJECT_TYPE (layout)));
|
||||
|
||||
if (width)
|
||||
*width = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_layout_height_for_width:
|
||||
* @layout: a #ClutterLayout
|
||||
* @width: width allocated by the parent
|
||||
* @height: return location for the height
|
||||
*
|
||||
* Queries a #ClutterLayout actor for its height with a known width.
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
void
|
||||
clutter_layout_height_for_width (ClutterLayout *layout,
|
||||
gint width,
|
||||
gint *height)
|
||||
{
|
||||
ClutterLayoutFlags layout_type;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_LAYOUT (layout));
|
||||
|
||||
layout_type = clutter_layout_get_layout_flags (layout);
|
||||
if (layout_type & CLUTTER_LAYOUT_HEIGHT_FOR_WIDTH)
|
||||
{
|
||||
ClutterUnit u_width, u_height;
|
||||
|
||||
u_width = CLUTTER_UNITS_FROM_INT (width);
|
||||
CLUTTER_LAYOUT_GET_IFACE (layout)->height_for_width (layout,
|
||||
u_width,
|
||||
&u_height);
|
||||
|
||||
if (height)
|
||||
*height = CLUTTER_UNITS_TO_INT (u_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Actor queried for height with a given width, but "
|
||||
"actors of type `%s' do not support height-for-width "
|
||||
"layouts.",
|
||||
g_type_name (G_OBJECT_TYPE (layout)));
|
||||
|
||||
if (height)
|
||||
*height = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_layout_natural_request:
|
||||
* @layout: a #ClutterLayout
|
||||
* @width: return location for the natural width
|
||||
* @height: return location for the natural height
|
||||
*
|
||||
* Queries a #ClutterLayout actor for its natural (default) width
|
||||
* and height.
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
void
|
||||
clutter_layout_natural_request (ClutterLayout *layout,
|
||||
gint *width,
|
||||
gint *height)
|
||||
{
|
||||
ClutterLayoutFlags layout_type;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_LAYOUT (layout));
|
||||
|
||||
layout_type = clutter_layout_get_layout_flags (layout);
|
||||
if (layout_type & CLUTTER_LAYOUT_NATURAL)
|
||||
{
|
||||
ClutterUnit u_width, u_height;
|
||||
|
||||
CLUTTER_LAYOUT_GET_IFACE (layout)->natural_request (layout,
|
||||
&u_width,
|
||||
&u_height);
|
||||
|
||||
if (width)
|
||||
*width = CLUTTER_UNITS_TO_INT (u_width);
|
||||
|
||||
if (height)
|
||||
*height = CLUTTER_UNITS_TO_INT (u_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Actor queried for natural size, but actors of type `%s' "
|
||||
"do not support natural-size layouts.",
|
||||
g_type_name (G_OBJECT_TYPE (layout)));
|
||||
|
||||
if (width)
|
||||
*width = -1;
|
||||
if (height)
|
||||
*height = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_layout_tune_request:
|
||||
* @layout: a #ClutterLayout
|
||||
* @given_width: width allocated by the parent
|
||||
* @given_height: height allocated by the parent
|
||||
* @width: return location for the new width
|
||||
* @height: return location for the new height
|
||||
*
|
||||
* Iteratively queries a #ClutterLayout actor until it finds
|
||||
* its desired size, given a width and height tuple.
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
void
|
||||
clutter_layout_tune_request (ClutterLayout *layout,
|
||||
gint given_width,
|
||||
gint given_height,
|
||||
gint *width,
|
||||
gint *height)
|
||||
{
|
||||
ClutterLayoutFlags layout_type;
|
||||
gint tries;
|
||||
ClutterUnit try_width, try_height;
|
||||
ClutterUnit new_width, new_height;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_LAYOUT (layout));
|
||||
|
||||
layout_type = clutter_layout_get_layout_flags (layout);
|
||||
if ((layout_type & CLUTTER_LAYOUT_TUNABLE) == 0)
|
||||
{
|
||||
g_warning ("Actor queried for tunable size size but actors of "
|
||||
"type `%s' do not support tunable layouts.",
|
||||
g_type_name (G_OBJECT_TYPE (layout)));
|
||||
|
||||
if (width)
|
||||
*width = -1;
|
||||
|
||||
if (height)
|
||||
*height = -1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
tries = 0;
|
||||
try_width = CLUTTER_UNITS_FROM_INT (given_width);
|
||||
try_height = CLUTTER_UNITS_FROM_INT (given_height);
|
||||
new_width = new_height = 0;
|
||||
|
||||
do
|
||||
{
|
||||
gboolean res;
|
||||
|
||||
res = CLUTTER_LAYOUT_GET_IFACE (layout)->tune_request (layout,
|
||||
try_width,
|
||||
try_height,
|
||||
&new_width,
|
||||
&new_height);
|
||||
|
||||
if (res)
|
||||
break;
|
||||
|
||||
if (new_width)
|
||||
try_width = new_width;
|
||||
|
||||
if (new_height)
|
||||
try_height = new_height;
|
||||
|
||||
new_width = new_height = 0;
|
||||
|
||||
tries += 1;
|
||||
}
|
||||
while (tries <= MAX_TUNE_REQUESTS);
|
||||
|
||||
if (width)
|
||||
*width = CLUTTER_UNITS_TO_INT (new_width);
|
||||
|
||||
if (height)
|
||||
*height = CLUTTER_UNITS_TO_INT (new_height);
|
||||
}
|
134
clutter/clutter-layout.h
Normal file
134
clutter/clutter-layout.h
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Authored By Matthew Allum <mallum@openedhand.com>
|
||||
*
|
||||
* Copyright (C) 2006 OpenedHand
|
||||
*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* ClutterLayout: interface to be implemented by actors providing
|
||||
* extended layouts.
|
||||
*
|
||||
* Author: Emmanuele Bassi <ebassi@openedhand.com>
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_LAYOUT_H__
|
||||
#define __CLUTTER_LAYOUT_H__
|
||||
|
||||
#include <clutter/clutter-actor.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_LAYOUT (clutter_layout_get_type ())
|
||||
#define CLUTTER_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_LAYOUT, ClutterLayout))
|
||||
#define CLUTTER_IS_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_LAYOUT))
|
||||
#define CLUTTER_LAYOUT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), CLUTTER_TYPE_LAYOUT, ClutterLayoutIface))
|
||||
|
||||
/**
|
||||
* ClutterLayoutFlags
|
||||
*
|
||||
* Type of layouts supported by an actor.
|
||||
*
|
||||
* @CLUTTER_LAYOUT_NONE: No layout (default behaviour)
|
||||
* @CLUTTER_LAYOUT_WIDTH_FOR_HEIGHT: Width-for-height
|
||||
* @CLUTTER_LAYOUT_HEIGHT_FOR_WIDTH: Height-for-width
|
||||
* @CLUTTER_LAYOUT_NATURAL: Natural size request
|
||||
* @CLUTTER_LAYOUT_TUNABLE: Tunable size request
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
typedef enum {
|
||||
CLUTTER_LAYOUT_NONE = 0,
|
||||
CLUTTER_LAYOUT_WIDTH_FOR_HEIGHT = 1 << 0,
|
||||
CLUTTER_LAYOUT_HEIGHT_FOR_WIDTH = 1 << 1,
|
||||
CLUTTER_LAYOUT_NATURAL = 1 << 2,
|
||||
CLUTTER_LAYOUT_TUNABLE = 1 << 3
|
||||
} ClutterLayoutFlags;
|
||||
|
||||
typedef struct _ClutterLayout ClutterLayout; /* dummy */
|
||||
typedef struct _ClutterLayoutIface ClutterLayoutIface;
|
||||
|
||||
struct _ClutterLayoutIface
|
||||
{
|
||||
GTypeInterface g_iface;
|
||||
|
||||
/* Retrieve the layout mode used by the actor */
|
||||
ClutterLayoutFlags (* get_layout_flags) (ClutterLayout *layout);
|
||||
|
||||
/* Width-for-Height and Height-for-Width: one size is known
|
||||
* and the other is queried. useful for labels and unidirectional
|
||||
* containers, like vertical and horizontal boxes.
|
||||
*/
|
||||
void (* width_for_height) (ClutterLayout *layout,
|
||||
ClutterUnit *width,
|
||||
ClutterUnit height);
|
||||
void (* height_for_width) (ClutterLayout *layout,
|
||||
ClutterUnit width,
|
||||
ClutterUnit *height);
|
||||
|
||||
/* Natural size request: the actor is queried for its natural
|
||||
* size and the container can decide to either scale the actor
|
||||
* or to resize itself to make it fit. useful for textures
|
||||
* or shapes.
|
||||
*/
|
||||
void (* natural_request) (ClutterLayout *layout,
|
||||
ClutterUnit *width,
|
||||
ClutterUnit *height);
|
||||
|
||||
/* Iterative allocation: the actor is iteratively queried
|
||||
* for its size, until it finds it.
|
||||
*/
|
||||
gboolean (* tune_request) (ClutterLayout *layout,
|
||||
ClutterUnit given_width,
|
||||
ClutterUnit given_height,
|
||||
ClutterUnit *width,
|
||||
ClutterUnit *height);
|
||||
|
||||
/* padding, for future expansion */
|
||||
void (*_clutter_layout1) (void);
|
||||
void (*_clutter_layout2) (void);
|
||||
void (*_clutter_layout3) (void);
|
||||
void (*_clutter_layout4) (void);
|
||||
void (*_clutter_layout5) (void);
|
||||
void (*_clutter_layout6) (void);
|
||||
void (*_clutter_layout7) (void);
|
||||
void (*_clutter_layout8) (void);
|
||||
};
|
||||
|
||||
GType clutter_layout_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterLayoutFlags clutter_layout_get_layout_flags (ClutterLayout *layout);
|
||||
void clutter_layout_width_for_height (ClutterLayout *layout,
|
||||
gint *width,
|
||||
gint height);
|
||||
void clutter_layout_height_for_width (ClutterLayout *layout,
|
||||
gint width,
|
||||
gint *height);
|
||||
void clutter_layout_natural_request (ClutterLayout *layout,
|
||||
gint *width,
|
||||
gint *height);
|
||||
void clutter_layout_tune_request (ClutterLayout *layout,
|
||||
gint given_width,
|
||||
gint given_height,
|
||||
gint *width,
|
||||
gint *height);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_LAYOUT_H__ */
|
Loading…
Reference in New Issue
Block a user