docs: drop docs

This commit is contained in:
Ray Strode 2016-01-12 11:33:24 -05:00 committed by Rui Matos
parent 5df9d89dec
commit fd17e83db8
157 changed files with 3 additions and 29663 deletions

View File

@ -1,12 +1,12 @@
NULL =
SUBDIRS = build clutter tests doc po
SUBDIRS = build clutter tests po
if BUILD_EXAMPLES
SUBDIRS += examples
endif
DIST_SUBDIRS = clutter tests examples doc po build
DIST_SUBDIRS = clutter tests examples po build
# XXX - this is a massive hack to make autoreconf honour the ACLOCAL_FLAGS
# that jhbuild sets while still retaining build/autotools as the authoritative
@ -17,7 +17,7 @@ CLEANFILES = $(pcfiles)
DISTCLEANFILES =
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc --enable-maintainer-flags --enable-docs
DISTCHECK_CONFIGURE_FLAGS = --enable-maintainer-flags
# proxy rules for tests
test-report full-report:

View File

@ -114,7 +114,6 @@ m4_define([atk_req_version], [2.5.3])
m4_define([cairo_req_version], [1.14.0])
m4_define([pango_req_version], [1.30])
m4_define([gi_req_version], [1.39.0])
m4_define([gtk_doc_req_version], [1.20])
m4_define([xcomposite_req_version], [0.4])
m4_define([gdk_req_version], [3.3.18])
m4_define([libinput_req_version], [0.19.0])
@ -127,7 +126,6 @@ AC_SUBST([ATK_REQ_VERSION], [atk_req_version])
AC_SUBST([CAIRO_REQ_VERSION], [cairo_req_version])
AC_SUBST([PANGO_REQ_VERSION], [pango_req_version])
AC_SUBST([GI_REQ_VERSION], [gi_req_version])
AC_SUBST([GTK_DOC_REQ_VERSION], [gtk_doc_req_version])
AC_SUBST([XCOMPOSITE_REQ_VERSION], [xcomposite_req_version])
AC_SUBST([GDK_REQ_VERSION], [gdk_req_version])
AC_SUBST([LIBINPUT_REQ_VERSION], [libinput_req_version])
@ -738,61 +736,6 @@ dnl === GObject-Introspection check ===========================================
GOBJECT_INTROSPECTION_CHECK([gi_req_version])
dnl === GTK Doc check =========================================================
GTK_DOC_CHECK([gtk_doc_req_version], [--flavour no-tmpl])
# we don't want to build the documentation from a Git clone unless we
# explicitly tell configure to do so; this allows avoiding to recurse into
# the documentation directory when building Clutter inside Poky for a
# target device that doesn't have gtk-doc installed. for reference
# see: http://bugzilla.openedhand.com/show_bug.cgi?id=1047
#
# we use autogen.sh as it exists only inside the Git clones, and it
# is not packaged into tarballs.
AM_CONDITIONAL([BUILD_GTK_DOC], [test "x$enable_gtk_doc" = "xyes" || test ! -f "autogen.sh"])
# prefixes for fixing gtk-doc references
CAIRO_PREFIX="`$PKG_CONFIG --variable=prefix cairo`"
GLIB_PREFIX="`$PKG_CONFIG --variable=prefix glib-2.0`"
PANGO_PREFIX="`$PKG_CONFIG --variable=prefix pango`"
COGL_PREFIX="`$PKG_CONFIG --variable=prefix cogl-1.0`"
ATK_PREFIX="`$PKG_CONFIG --variable=prefix atk`"
AC_SUBST(CAIRO_PREFIX)
AC_SUBST(GLIB_PREFIX)
AC_SUBST(PANGO_PREFIX)
AC_SUBST(COGL_PREFIX)
AC_SUBST(ATK_PREFIX)
dnl === Manual ================================================================
AC_ARG_ENABLE([docs],
[AS_HELP_STRING([--enable-docs=@<:@no/yes@:>@],
[Build optional documentation; requires xsltproc and jw.])],
[enable_docs=$enableval],
[enable_docs=no])
enable_pdfs=no
AS_IF([test "x$enable_docs" = "xyes"],
[
AC_PATH_PROG(JW, [jw], [no])
AS_IF([test "x$JW" = "xno"],
[
AC_MSG_WARN([jw not found; pdf generation has been disabled])
],
[enable_pdfs=yes])
AC_PATH_PROG(XSLTPROC, [xsltproc], [no])
AS_IF([test "x$XSLTPROC" = "xno"],
[
AC_MSG_ERROR([xsltproc not found])
])
]
)
AM_CONDITIONAL(ENABLE_DOCS, [test "x$enable_docs" = "xyes"])
AM_CONDITIONAL(ENABLE_PDFS, [test "x$enable_pdfs" = "xyes"])
dnl === I18N ==================================================================
AM_GNU_GETTEXT_VERSION([0.17])
@ -840,14 +783,6 @@ AC_CONFIG_FILES([
examples/Makefile
doc/Makefile
doc/reference/Makefile
doc/reference/clutter-docs.xml
doc/common/Makefile
doc/cookbook/Makefile
doc/cookbook/clutter-cookbook.xml
doc/cookbook/examples/Makefile
po/Makefile.in
])
@ -873,12 +808,6 @@ echo " Compiler flags: ${CFLAGS} ${MAINTAINER_CFLAGS}"
echo " Enable coverage tests: ${use_gcov}"
echo " Enable deprecated symbols: ${enable_deprecated}"
# Documentation
echo ""
echo " • Documentation:"
echo " Build API Reference: ${enable_gtk_doc}"
echo " Build Additional Documentation: ${enable_docs} (Generate PDF: ${enable_pdfs})"
# Miscellaneous
echo ""
echo " • Extra:"

View File

@ -1,17 +0,0 @@
# Do not modify this list; this file is maintained for historical
# reasons. The list of authors can be extracted from the Git commit
# log. See the clutter.doap file for the updated maintainers list.
Matthew Allum <mallum@o-hand.com> - Primary cat hurding authour.
Emmanuele Bassi <ebassi@o-hand.com> - python bindings, gobject/glib mastery.
Iain Holmes <iain@o-hand.com> - Original GTK Clutter widget.
Jorn Baayen <jorn@o-hand.com> - Original Gstreamer bits.
Tomas Frydrych <tf@o-hand.com> - Fixed point + behaviour + maths magic.
Neil Patel <njp@o-hand.com> - ClutterEntry, lots of API stress testing.
Neil Roberts <neil@o-hand.com> - PangoClutter Renderer, COGL and win32 backend.
Rober Bragg <bob@o-hand.com> - COGL, timeline mastery.
Ivan Leben <ivan@o-hand.com> - COGL.
Øyvind Kolås <pippin@o-hand.com> - Event handling, Clever magic stuff, Shaders, COGL.
Chris Lord <chris@o-hand.com> - Many bug fixes.
Havoc Pennington - New layout magic.
Tommi Komulainen - OSX Backend.

View File

@ -1,613 +0,0 @@
Clutter Coding Style
-------------------------------------------------------------------------------
This document is intended to be a short description of the preferred
coding style to be used for the Clutter source code.
Coding style is a matter of consistency, readability and maintainance;
coding style is also completely arbitrary and a matter of taste. This
document will use examples at the very least to provide authoritative
and consistent answers to common questions regarding the coding style,
and will also try to identify the allowed exceptions.
The examples will show the preferred coding style; the negative examples
will be clearly identified. Please, don't submit code to Clutter that
looks like any of these.
Part of the rationales for these coding style rules are available either
in the kernel CodingStyle document or in Cairo's CODING_STYLE one.
When in doubt, check the surrounding code and try to imitate it.
Clutter provides an Uncrustify configuration file that tries to match
this document. Since automated tools are not a substitute for human eye,
they should not be entirely relied upon - but they can give an initial
layout for contributors.
+ Line width
The maximum line width for source files is 80 characters, whenever possible.
Longer lines are usually an indication that you either need a function
or a pre-processor macro.
+ Indentation
Each new level is indented 2 or more spaces than the previous level:
if (condition)
single_statement ();
This can only be achieved using space characters. It may not be achieved
using tab characters alone, or using a combination of spaces and tabs.
Do not change the editor's configuration to change the meaning of a
tab character (see below); code using tabs to indent will not be accepted
into Clutter.
Even if two spaces for each indentation level allows deeper nesting than
8 spaces, Clutter favours self-documenting function names that can take
quite some space. For this reason you should avoid deeply nested code.
+ Tab characters
The tab character must always be expanded to spaces. If a literal
tab must be used inside the source, the tab must always be interpreted
according to its traditional meaning:
Advance to the next column which is a multiple of 8.
[ these two lines should be aligned ]
+ Braces
Curly braces should not be used for single statement blocks:
if (condition)
single_statement ();
else
another_single_statement (arg1);
In case of multiple statements, curly braces should be put on another
indentation level:
if (condition)
{
statement_1 ();
statement_2 ();
statement_3 ();
}
The "no block for single statements" rule has only three exceptions:
① if the single statement covers multiple lines, e.g. for functions with
many arguments, and it is followed by else or else if:
/* valid */
if (condition)
{
a_single_statement_with_many_arguments (some_lengthy_argument,
another_lengthy_argument,
and_another_one,
plus_one);
}
else
another_single_statement (arg1, arg2);
② if the condition is composed of many lines:
/* valid */
if (condition1 ||
(condition2 && condition3) ||
condition4 ||
(condition5 && (condition6 || condition7)))
{
a_single_statement ();
}
③ Nested if's, in which case the block should be placed on the
outermost if:
/* valid */
if (condition)
{
if (another_condition)
single_statement ();
else
another_single_statement ();
}
/* invalid */
if (condition)
if (another_condition)
single_statement ();
else if (yet_another_condition)
another_single_statement ();
In general, new blocks should be placed on a new indentation level,
like:
int retval = 0;
statement_1 ();
statement_2 ();
{
int var1 = 42;
gboolean res = FALSE;
res = statement_3 (var1);
retval = res ? -1 : 1;
}
While curly braces for function definitions should rest on a new line
they should not add an indentation level:
/* valid */
static void
my_function (int argument)
{
do_my_things ();
}
/* invalid */
static void
my_function (int argument) {
do_my_things ();
}
/* invalid */
static void
my_function (int argument)
{
do_my_things ();
}
Curly braces must not be placed on the same line as a condition:
/* invalid */
if (condition) {
statement_1 ();
statement_2 ();
}
+ Conditions
Do not check boolean values for equality:
/* invalid */
if (condition == TRUE)
do_foo ();
/* valid */
if (another_condition)
do_bar ();
Even if C handles NULL equality like a boolean, be explicit:
/* valid */
if (some_pointer == NULL)
do_blah ();
/* invalid */
if (some_other_pointer)
do_blurp ();
In case of conditions split over multiple lines, the logical operators should
always go at the end of the line:
/* invalid */
if (condition1
|| condition2
|| condition3)
{
do_foo ();
}
/* valid */
if (condition1 &&
condition2 &&
(condition3 || (condition4 && condition5)))
{
do_blah ();
}
+ Functions
Functions should be declared by placing the returned value on a separate
line from the function name:
void
my_function (void)
{
}
The arguments list must be broken into a new line for each argument,
with the argument names right aligned, taking into account pointers:
void
my_function (some_type_t type,
another_type_t *a_pointer,
final_type_t another_type)
{
}
The alignment also holds when invoking a function without breaking the
80 characters limit:
align_function_arguments (first_argument,
second_argument,
third_argument);
To respect the 80 characters limit do not break the function name from
the arguments:
/* invalid */
a_very_long_function_name_with_long_parameters
(argument_the_first, argument_the_second);
/* valid */
first_a = argument_the_first;
second_a = argument_the_second;
a_very_long_function_name_with_long_parameters (first_a, second_a);
+ Whitespace
Always put a space before a parenthesis but never after:
/* valid */
if (condition)
do_my_things ();
/* valid */
switch (condition)
{
}
/* invalid */
if(condition)
do_my_things();
/* invalid */
if ( condition )
do_my_things ( );
A switch() should open a block on a new indentation level, and each case
should start on the same indentation level as the curly braces, with the
case block on a new indentation level:
/* valid */
switch (condition)
{
case FOO:
do_foo ();
break;
case BAR:
do_bar ();
break;
}
/* invalid */
switch (condition) {
case FOO: do_foo (); break;
case BAR: do_bar (); break;
}
/* invalid */
switch (condition)
{
case FOO: do_foo ();
break;
case BAR: do_bar ();
break;
}
/* invalid */
switch (condition)
{
case FOO:
do_foo ();
break;
case BAR:
do_bar ();
break;
}
It is preferable, though not mandatory, to separate the various cases with
a newline:
switch (condition)
{
case FOO:
do_foo ();
break;
case BAR:
do_bar ();
break;
default:
do_default ();
}
The 'break' statement for the default: case is not mandatory.
If a case block needs to declare new variables, the same rules as the
inner blocks (see above) apply; the break statement should be placed
outside of the inner block:
switch (condition)
{
case FOO:
{
int foo;
foo = do_foo ();
}
break;
...
}
When declaring a structure type use newlines to separate logical sections
of the structure:
struct _ClutterActorPrivate
{
/* fixed position */
ClutterUnit fixed_x;
ClutterUnit fixed_y;
ClutterRequestMode request_mode;
/* requisition sizes */
ClutterUnit request_width_for_height;
ClutterUnit request_min_width;
ClutterUnit request_natural_width;
ClutterUnit request_height_for_width;
ClutterUnit request_min_height;
ClutterUnit request_natural_height;
ClutterActorBox allocation;
...
};
Do not eliminate whitespace and newlines just because something would
fit on 80 characters:
/* invalid */
if (condition) foo (); else bar ();
Do eliminate trailing whitespace on any line, preferably as a separate
patch or commit. Never use empty lines at the beginning or at the end of
a file.
Do enable the default git pre-commit hook that detect trailing
whitespace for you and help you to avoid corrupting Clutter's tree with
it. Do that as follows:
chmod a+x .git/hooks/pre-commit
You might also find the git-stripspace utility helpful which acts as a
filter to remove trailing whitespace as well as initial, final, and
duplicate blank lines.
+ Headers
Headers are special, for Clutter, in that they don't have to obey the
80 characters limit. The only major rule for headers is that the functions
definition should be vertically aligned in three columns:
return value function_name (type argument,
type argument,
type argument);
The maximum width of each column is given by the longest element in the
column:
void clutter_type_set_property (ClutterType *type,
const gchar *value,
GError **error);
const gchar *clutter_type_get_property (ClutterType *type);
It is also possible to align the columns to the next tab:
void clutter_type_set_prop (ClutterType *type,
gfloat value);
gfloat clutter_type_get_prop (ClutterType *type);
gint clutter_type_update_foobar (ClutterType *type);
Public headers should never be included directly:
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
Public headers should also have inclusion guards (for internal usage)
and C++ guards:
#ifndef __CLUTTER_HEADER_H__
#define __CLUTTER_HEADER_H__
#include <clutter/clutter-actor.h>
G_BEGIN_DECLS
...
G_END_DECLS
#endif /* __CLUTTER_HEADER_H__ */
+ Includes
Clutter source files should never include the global clutter.h header, but
instead include the individual headers that are needed. Every file must
include config.h first, then its own header, then other Clutter headers
that it needs, then system and third-party headers that it needs.
/* valid */
#include "config.h"
#include "clutter-foo.h"
#include "clutter-actor.h"
#include "clutter-container.h"
...
#include <string.h>
+ GObject
GObject classes definition and implementation require some additional
coding style notices.
Typedef declarations should be placed at the beginning of the file:
typedef struct _ClutterActor ClutterActor;
typedef struct _ClutterActorPrivate ClutterActorPrivate;
typedef struct _ClutterActorClass ClutterActorClass;
This includes enumeration types:
typedef enum {
CLUTTER_REQUEST_WIDTH_FOR_HEIGHT,
CLUTTER_REQUEST_HEIGHT_FOR_WIDTH
} ClutterRequestMode;
And callback types:
typedef void (* ClutterCallback) (ClutterActor *actor,
gpointer user_data);
Instance structures should only contain the parent type and a pointer to a
private data structure, and they should be annotated as "private":
struct _ClutterRectangle
{
/*< private >*/
ClutterActor parent_instance;
ClutterRectanglePrivate *priv;
};
All the properties should be stored inside the private data structure, which
is defined inside the source file - or, if needed, inside a private header
file; the private header filename must end with "-private.h" and must not be
installed.
The private data structure should only be accessed internally using the
pointer inside the instance structure, and never using the
G_TYPE_INSTANCE_GET_PRIVATE() macro or the g_type_instance_get_private()
function.
Always use the G_DEFINE_TYPE(), G_DEFINE_TYPE_WITH_CODE() macros, or
their abstract variants G_DEFINE_ABSTRACT_TYPE() and
G_DEFINE_ABSTRACT_TYPE_WITH_CODE().
Avoid forward declaration for functions: use the G_DEFINE_* macros right
after the private types, variables and macros declarations.
Interface types should always have the dummy typedef for cast purposes:
typedef struct _ClutterFoo ClutterFoo;
The interface structure should have "Iface" postfixed to the dummy typedef:
typedef struct _ClutterFooIface ClutterFooIface;
Interfaces must have the following macros:
- Macro: - Expands to:
• CLUTTER_TYPE_<iface_name> <iface_name>_get_type
• CLUTTER_<iface_name> G_TYPE_CHECK_INSTANCE_CAST
• CLUTTER_IS_<iface_name> G_TYPE_CHECK_INSTANCE_TYPE
• CLUTTER_<iface_name>_GET_IFACE G_TYPE_INSTANCE_GET_INTERFACE
+ Memory allocation
When dynamically allocating data on the heap either use g_new() or,
if allocating multiple small data structures, g_slice_new().
Public structure types should always be returned after being zero-ed,
either explicitly for each member, or by using g_new0() or g_slice_new0().
+ Macros
Try to avoid private macros unless strictly necessary. Remember to #undef
them at the end of a block or a series of functions needing them.
Inline functions are usually preferable to private macros.
Public macros should not be used unless they evaluate to a constant.
+ Public API
Avoid exporting variables as public API, since this is cumbersome on some
platforms. It is always preferable to add getters and setters instead.
+ Private API
Non-exported functions that are needed in more than one source file
should be named "_clutter_...", and declared in a private header file.
Underscore-prefixed functions are never exported.
Non-exported functions that are only needed in one source file
should be declared static.
+ Documentation
All public APIs must have gtk-doc comments. For functions, these should
be placed in the source file, directly above the function.
/* valid */
/**
* clutter_get_flow:
* @actor: a #ClutterActor
*
* Gets the flow of an actor.
*
* Note that flows may be laminar or turbulent...
*
* Return value: (transfer none): the flow of @actor
*/
ClutterFlow *
clutter_get_flow (ClutterActor *actor)
{
...
}
Doc comments for macros, function types, class structs, etc should be
placed next to the definitions, typically in headers.
Section introductions should be placed in the source file they describe,
after the license header:
/* valid */
/**
* SECTION:clutter-align-constraint
* @Title: ClutterAlignConstraint
* @Short_Description: A constraint aligning the position of an actor
*
* #ClutterAlignConstraint is a #ClutterConstraint that aligns the position
* of the #ClutterActor to which it is applied to the size of another
* #ClutterActor using an alignment factor
*
* [...]
*/
To properly document a new function, macro, function type or struct,
it needs to be listed in the clutter-sections.txt file.
To properly document a new class, it needs to be given its own section
in clutter-sections.txt, needs to be included in clutter-docs.xml, and the
get_type function needs to listed in clutter.types.
+ Old code
It is ok to update the style of a code block or function when you
are touching it anyway, but sweeping whitespace changes obscure the
git history and should be avoided.

View File

@ -1,95 +0,0 @@
GENERAL
=======
General notes and rules on clutter core hacking;
- Follow the CODING_STYLE document.
- *Really* follow the CODING_STYLE document.
- All non static public API funcs should be documented in the source files
via gtk-doc. Structures, enumerations and macros should be documented in
the header files.
- All non-trivial static and private API should be documented, especially
the eventual lifetime handling of the arguments/return values or locking
of mutexes.
- Properties should always be in floating point (never fixed point).
The preferred precision is double for angles, and single precision
for size and position -- especially if they have to be passed down
to Cogl.
- Properties should use pixels whenever is possible. Dimensional and
positional properties can also use ClutterParamSpecUnits to define
the units-based logical values with a unit type.
- The nick and blurb of properties in public classes should be marked for
translation by using the P_() macro defined in the clutter-private.h
header file.
- Public entry points must always check their arguments with
g_return_if_fail() or g_return_val_if_fail().
- Private entry points should use g_assert() or g_warn_if_fail() to
verify internal state; do not use g_return_if_fail() or
g_return_val_if_fail() as they might be compiled out.
- If you need to share some state variable across source files use
ClutterContext and a private accessor.
- Private, non-static functions must begin with an underscore and
be declared inside clutter-private.h.
- Don't add direct GL calls but add API to Cogl (both GL and GL|ES
versions if possible).
- Use the CLUTTER_NOTE() macro for debug statements in Clutter, and
the COGL_NOTE() macro for debug statements in Cogl. If necessary,
add a value inside ClutterDebugFlags or CoglDebugFlags to specify
the debug section.
- New features should also include an exhaustive test unit under
tests/conform and, eventually, a user-interactive test under
tests/interactive.
- When committing, use the standard git commit message format:
=== begin example commit ===
Short explanation of the commit
Longer explanation explaining exactly what's changed, whether any
external or private interfaces changed, what bugs were fixed (with bug
tracker reference if applicable) and so forth. Be concise but not too
brief. Don't be afraid of using UTF-8, or even ASCII art.
=== end example commit ===
- Always add a brief description of the commit to the _first_ line of
the commit and terminate by two newlines (it will work without the
second newline, but that is not nice for the interfaces).
short description - MUST be less than 72 characters
<newline> - MANDATORY empty line
long description - Each line MUST be less than 76 characters
- Do NOT put the commit message on the short description line. One line
commit messages should be avoided, unless they can be *fully* explained
in less than 72 characters (e.g. "Fix typo in
clutter_actor_create_pango_context() docs").
- The brief description might optionally have a "tag", i.e. a word or two
followed by a color, detailing what part of the repository the commit
affected, e.g.:
alpha: Add :mode property
text: Emit ::cursor-event only on changes
- The tag counts as part of overall character count, so try using
a short word. Optionally, you can also use the "[tag]" form.
- Build environment fixes should use the "build" tag.
- Think of the commit message as an email sent to the maintainers explaining
"what" you did and, more importantly, "why" you did it. The "how" is not
important, since "git show" will show the patch inlined with the commit
message.

View File

@ -1,207 +0,0 @@
IMPLEMENTING BACKENDS
===============================================================================
Clutter supports multiple backends for handling windowing systems and
GL/GLES API on different platforms.
The GL and GLES API are abstracted by the COGL library. The windowing
system is handled by the ClutterBackend implementations inside Clutter
itself.
Clutter, at the moment, supports only in-tree backends.
In order to write a new backend for a specific platform you should
create a new sub-directory under clutter/clutter containing:
<backend>/clutter-backend-<backend>.h
<backend>/clutter-backend-<backend>.c
-- The subclass of the ClutterBackend abstract class.
<backend>/clutter-stage-<backend>.h
<backend>/clutter-stage-<backend>.c
-- The implementation of the stage window
<backend>/clutter-device-manager-<backend>.h
<backend>/clutter-device-manager-<backend>.c
-- The implementation of the input device manager
<backend>/clutter-event-<backend>.c
-- Event-specific code (optional)
<backend>/clutter-<backend>.h
-- A header for the backend-specific API that should be installed
by Clutter inside the include directory along with the rest of
the public API headers (optional).
Implementing ClutterBackend
-------------------------------------------------------------------------------
Each backend must implement the
GType
_clutter_backend_impl_get_type (void);
function declared inside clutter/clutter-private.h. The implementation
of the function must return the same GType of the backend implementation,
for instance:
GType
_clutter_backend_impl_get_type (void)
{
return CLUTTER_TYPE_BACKEND_GLX;
}
The ClutterBackend implementation is a singleton instance, and the
backend must ensure that every time g_object_new() is called the same
pointer is returned (with its reference count increased). The GObject
API reference describes how to use the ::constructor virtual function
to implement a singleton, so you should refer to that.
The ClutterBackend implementation should hold a single drawing context
for its entire lifetime; stage implementations should be "made current"
when needed.
When implementing the ClutterBackend subclass these virtual functions
can be overridden:
ClutterBackend::add_options
-- Use this function to install new, backend-specific GOptionEntry
definitions to the Clutter GOptionGroup. This function is guaranteed
to be called just once.
ClutterBackend::pre_parse
-- Use this function to check for environment variables or setting
up default values before the command line arguments are parsed.
This function is guaranteed to be called just once.
ClutterBackend::post_parse
-- Use this function to prepare the backend with the values either
set inside the ::pre_parse virtual function or by the command
line options parsing code. This function is guaranteed to be
called just once.
ClutterBackend::init_events
-- Use this function to initialize the event handling. This function
is guaranteed to be called just once.
ClutterBackend::get_features
-- Use this function to retrieve the features detectable at runtime
from the GL or GLES implementation, plus the eventual backend-specific
features.
ClutterBackend::create_context
-- This function is used to create the drawing context to be used
by Clutter. Clutter will call this function during the initialization
phase. A GL (or GLES) context must always be available after the
initialization, so that Cogl and Clutter can query it for capabilities.
This function might be called multiple times so if a context was
successfully created in a previous call, this function should
short-circuit early and return TRUE
ClutterBackend::ensure_context
-- This function is used to ensure that the backend drawing context
is made current for passed ClutterStage, using the backend-specific
API. This function is called each time a new stage is going to
be painted. If the Stage is inside its destruction sequence this
function should either fall back the drawing context to a default
drawing surface or should unset the drawing surface from the
drawing context.
ClutterBackend::create_stage
-- This function is used to create the stage implementation. It will
receive as an argument the ClutterStage instance that is "wrapping"
the actual implementation being created. The backend must create
its stage implementation, initialise it and then return it; in case
of error, the backend must return NULL and set the passed GError.
ClutterBackend::get_device_manager
-- This function is used to return the ClutterDeviceManager instance
that is going to be returned by clutter_device_manager_get_default()
and that should be used internally by input event translation.
Implementing the stage
-------------------------------------------------------------------------------
ClutterStage acts as a wrapper object relaying all the drawing operations
to the actual implementation. The implementation of the stage can be any
GObject subclass, as long as it implements the ClutterStageWindow interface.
The ClutterStageWindow interface contains a set of virtual functions that
should be overridden by backends that support a windowing system, like
::set_title(), ::set_fullscreen(), ::set_cursor_visible(), etc.
The stage implementation actor must implement:
• ClutterStageWindow::get_wrapper()
• ClutterStageWindow::realize() and ::unrealize()
• ClutterStageWindow::show() and ::hide()
• ClutterStageWindow::resize()
• ClutterStageWindow::get_geometry()
• ClutterStageWindow::redraw()
The ::get_wrapper() implementation should return the pointer to the
ClutterStage actor using the ClutterStageWindow implementation.
In the ::realize virtual function the stage implementation should:
- create a new native window handle
- ensure that there is a GL (or GLES) context
- make sure that the native window handle is compatible with
the GL (or GLES) context
The return value should be TRUE if the stage implementation was successfully
realized, and FALSE otherwise.
Inside the ::unrealize function the stage implementation should destroy
the native window handle created in ::realize().
The ::resize() virtual function implementation should cause an update
of the COGL viewport.
The ::redraw() virtual function implementation should contain the platform
specific drawing logic, and call _clutter_stage_do_paint() on the ClutterStage
wrapper instance to cause the scene to be painted.
The stage implementation actor can optionally implement:
• ClutterStageWindow::get_pending_swaps()
The get_pending_swaps() implementation should return the number of swap
buffer requests pending completion. This is only relevent for backends
that also support CLUTTER_FEATURE_SWAP_EVENTS.
If the stage window is supposed to handle events, then it should also implement
the ClutterEventTranslator interface; this interface has a single virtual
function:
• ClutterEventTranslator::translate_event()
which gets passed a pointer to the native event data structure, and a pointer
to a newly-allocated, empty ClutterEvent. The EventTranslator implementation
should then decide between three options:
- translate the native event and return CLUTTER_TRANSLATE_QUEUE to
let Clutter queue it up in the events queue;
- return CLUTTER_TRANSLATE_CONTINUE to let other event translators handle
the event;
- return CLUTTER_TRANSLATE_REMOVE to ignore the event.
Implementing ClutterDeviceManager
-------------------------------------------------------------------------------
Backends with input devices should provide a ClutterDeviceManager
implementation to handle addition, removal and input device event translation
through the ClutterEventTranslator interface.
NOTES
===============================================================================
• If the platform is using X11 you should probably subclass ClutterBackendX11
and ClutterStageX11, which will provide you with a ready to use code
implementation for event handling and window management.

View File

@ -1,16 +0,0 @@
SUBDIRS =
if BUILD_GTK_DOC
SUBDIRS += reference
endif
if ENABLE_DOCS
SUBDIRS += common cookbook
endif
DIST_SUBDIRS = reference common cookbook
EXTRA_DIST = \
CODING_STYLE \
HACKING \
HACKING.backends

View File

@ -1,64 +0,0 @@
RELEASING
=========
When making a new release;
- Verify that you don't have uncommitted and unpublished
changes, i.e. both this:
$ git status
and this:
$ git diff --stat master origin/master
should be empty. Commit and push before the next step.
- Clean your work directory:
$ git clean -xdf
This ensures that you don't have stale files lying around.
- Run:
$ ./autogen.sh --enable-gtk-doc --enable-docs
$ make all
$ make check
And verify that the code builds from a clean Git snapshot.
- Update the release documentation:
- NEWS: new feature details, bugs fixed, acknowledgements
- README: dependencies, any behavioural changes relevant to
developers;
then commit the changes.
- Bump clutter_micro_version to the next even number; if this is a stable
release, bump up clutter_interface_version by one as well. Then commit
the changes.
- Run:
$ make release-publish
which will:
- do sanity checks on the build
- distcheck the release
- tag the repository with the version number
- upload the tarball to the remote server (needs SSH account)
- Bump clutter_micro_version to the next odd number; if this is a stable
release, bump up clutter_interface_version by one as well. Then commit
the changes.
- Push the branch and then the tag, e.g.:
$ git push origin master
$ git push origin 1.2.4
- Announce release to the waiting world on the blog and mailing lists. Use
the template printed by `make release-publish`.

View File

@ -1,278 +0,0 @@
ClutterActor Invariants
===============================================================================
ClutterActor behaviour has invariants that will be kept with the same API and
ABI guarantees as the whole Clutter library.
This document refers to the 0.8 release of Clutter.
Sections:
i. Flags
a. Public ClutterActor Flags
b. Private ClutterActor Flags
c. Private Pick Modes
ii. Invariants
iii. State changes
iv. Responsibilities of a ClutterActor
a. Adding to a container
b. Removing from a container
c. Initial state
i. Flags
-------------------------------------------------------------------------------
This section describes the various flags and enumerations used by
ClutterActor.
a. Public ClutterActor Flags
CLUTTER_ACTOR_REALIZED
Means: the actor has GPU resources associated to its paint
cycle. Note however that an actor is allowed to allocate Cogl
resources before being realized because Clutter only ever uses
one rendering context which is always current. An actor is
free to create resources at any time.
Set by clutter_actor_realize(), unset by
clutter_actor_unrealize(). Generally set implicitly when the
actor becomes MAPPED (see below).
May only be set if one of the actor's ancestors is a toplevel.
May only be set if all of the actor's ancestors are realized.
Once realized an actor remains realized until removed from the
toplevel. Hide, reparent will not unrealize; but unparent or
destroy will unrealize since they remove the actor from the
toplevel.
CLUTTER_ACTOR_MAPPED
Means: the actor will be painted if the stage is mapped.
On non-toplevels, will be set if all of the following are
true, and unset otherwise:
* the actor's VISIBLE flag is set
* all of the actor's non-toplevel ancestors have the MAPPED
flag set
* the actor has a toplevel ancestor
* the toplevel ancestor's VISIBLE flag is set
* the toplevel ancestor's REALIZED flag is set
On toplevels, MAPPED is set asynchronously when the window
system notifies Clutter that the toplevel has been made
visible on the screen.
The MAPPED flag requires that an actor is REALIZED. When
Clutter sets the MAPPED flag, it forces realization; this is
the "normal" way for realization to occur, though explicit
realization with clutter_actor_realize() is permitted.
Reparent may not change the MAPPED flag if the old and the
new parent are both MAPPED.
CLUTTER_ACTOR_VISIBLE
Means: the actor's "visible" property was set to true by
the application programmer.
Set by clutter_actor_show(), unset by clutter_actor_hide().
This is an application-controlled property, while MAPPED and
REALIZED are usually managed by Clutter (with the exception
that applications can "realize early" with
clutter_actor_realize()).
If VISIBLE is unset, the actor (and any children) must
be immediately unmapped, to maintain the invariants for
the MAPPED flag.
CLUTTER_ACTOR_REACTIVE
Set and unset by clutter_actor_set_reactive()
Means: the actor is now reactive to events.
Notes:
* If parents need to be reactive for child its up to the
parent implementation. In the case of ClutterGroup it
being marked unreactive does not mark all children unreactive.
* Clutter stage is always reactive.
b. Private ClutterActor flags
CLUTTER_ACTOR_IN_DESTRUCTION
Set internally by clutter_actor_destroy().
Used to avoid uneeded overhead when freeing GPU resources on unrealize
CLUTTER_ACTOR_IS_TOPLEVEL
Set internally by the initialization of ClutterStage
CLUTTER_ACTOR_IN_REPARENT [DEPRECATED]
Set internally by clutter_actor_reparent(). This flag
optimizes the reparent process by avoiding the need
to pass through an unrealized state when the actor is
removed from the old parent.
CLUTTER_ACTOR_IN_PAINT:
Set internally by clutter_actor_paint()
CLUTTER_ACTOR_IN_RELAYOUT
Set internally by clutter_actor_allocate()
c. Pick Modes
CLUTTER_PICK_NONE
No pick operation is performed during the paint
CLUTTER_PICK_REACTIVE
Only reactive actors will be picked
CLUTTER_PICK_ALL
All visible actors will be picked
ii. Invariants
-------------------------------------------------------------------------------
This section describes the various constraints and invariants on ClutterActor.
In the following
A => B means if A is true then B is true
A <=> B means A is true if and only if B is true
(equivalent to A => B && A <= B)
1) CLUTTER_ACTOR_IN_DESTRUCTION => !CLUTTER_ACTOR_IS_MAPPED (actor) &&
!CLUTTER_ACTOR_IS_REALIZED (actor)
clutter_actor_destroy() will cause an actor to be unparented,
which means the actor must be unmapped and unrealized as
well.
2) CLUTTER_ACTOR_IS_MAPPED (actor) => CLUTTER_ACTOR_IS_REALIZED (actor)
when an actor is mapped, it must first be realized.
This is the most common way an actor becomes realized.
3) if clutter_actor_add_child (parent, actor):
((parent_is_not_toplevel && CLUTTER_ACTOR_IS_MAPPED (parent)) ||
(parent_is_toplevel && CLUTTER_ACTOR_IS_VISIBLE(parent))) &&
CLUTTER_ACTOR_IS_VISIBLE (actor)
=> CLUTTER_ACTOR_IS_MAPPED (actor)
calling clutter_actor_add_child() on an actor and a mapped
parent will map the actor if it has been shown.
4) if clutter_actor_remove_child (parent, actor):
CLUTTER_ACTOR_IS_MAPPED (actor) <=> CLUTTER_ACTOR_IN_REPARENT
calling clutter_actor_remove_child() on an actor will unmap and
unrealize the actor since it no longer has a toplevel.
calling clutter_actor_reparent() on an actor will leave the
actor mapped and realized (if it was before) until it has a
new parent, at which point the invariants implied by the new
parent's state are applied. [DEPRECATED]
5) CLUTTER_ACTOR_IS_REALIZED(actor) => CLUTTER_ACTOR_IS_REALIZED(parent)
Actors may only be realized if their parent is realized.
However, they may be unrealized even though their parent
is realized.
This implies that an actor may not be realized unless
it has a parent, or is a toplevel.
Since only toplevels can realize without a parent, no actor
can be realized unless it either is a toplevel or has a
toplevel ancestor.
As long as they are unmapped, actors may be unrealized. This
will force all children of the actor to be unrealized, since
children may not be realized while parents are unrealized.
6) CLUTTER_ACTOR_IS_MAPPED(actor) <=>
( ( (CLUTTER_ACTOR_IS_VISIBLE(toplevel_parent) &&
CLUTTER_ACTOR_IS_REALIZED(toplevel_parent)) ||
CLUTTER_ACTOR_IS_MAPPED(non_toplevel_parent) ) ) &&
CLUTTER_ACTOR_IS_VISIBLE(actor)
Actors _must_ be mapped if and only if they are visible and
their parent is mapped, or they are visible and their
parent is a toplevel that's realized and visible.
This invariant enables us to track whether an actor will
be painted (whether it's MAPPED) without ever traversing
the actor graph.
iii. State changes
-------------------------------------------------------------------------------
clutter_actor_show:
1. sets VISIBLE
2. sets MAPPED if invariants are met; mapping in turn sets
REALIZED
clutter_actor_hide:
1. sets !VISIBLE
2. unsets MAPPED if actor was mapped previously
3. does not affect REALIZED
clutter_actor_destroy:
1. sets CLUTTER_ACTOR_IN_DESTRUCTION
2. unparents the actor, which in turn implies unmap and unrealize
clutter_actor_realize:
1. attempts to set REALIZED on all parents, failing if
invariants are not met, e.g. not in a toplevel yet
2. sets REALIZED on actor if parent was successfully realized
clutter_actor_unrealize:
1. sets !VISIBLE which forces !MAPPED
2. sets !REALIZED
3. !MAPPED and !REALIZED forces unmap and unrealize of all
children
clutter_actor_add_child:
1. sets actor->parent
2. if actor->show_on_set_parent is TRUE calls clutter_actor_show
3. sets MAPPED if all prerequisites are now met for map
4. if !CLUTTER_ACTOR_IN_REPARENT emits ::parent-set with
old_parent set to NULL
clutter_actor_remove_child:
1. unsets actor->parent
2. if !CLUTTER_ACTOR_IN_REPARENT, sets !MAPPED and !REALIZED
since the invariants for those flags are no longer met
3. if !CLUTTER_ACTOR_IN_REPARENT emits ::parent-set with
old_parent set to the previous parent
clutter_actor_reparent: [DEPRECATED]
1. sets CLUTTER_ACTOR_IN_REPARENT
2. emits ::parent-set with old_parent set to the previous parent
equivalent to:
clutter_actor_unparent
clutter_actor_set_parent
3. updates state of the actor to match invariants
(may change MAPPED or REALIZED in either direction,
depending on state of the new parent)
iv. Responsibilities of a ClutterActor
-------------------------------------------------------------------------------
a. Adding to a container
When adding an actor to a container, the container must:
1. call clutter_actor_add_child (container, actor)
b. Removing from a container
When removing an actor from a container, the container must:
1. call clutter_actor_remove_child (container, actor)
c. Initial state
When creating an actor, the initial state is:
1. !CLUTTER_ACTOR_REALIZED
2. !CLUTTER_ACTOR_MAPPED

View File

@ -1,10 +0,0 @@
NULL =
EXTRA_DIST = \
common.xsl \
cookbook.xsl \
devhelp.xsl \
html.xsl \
ref-html-style.xsl \
style.css \
$(NULL)

View File

@ -1,19 +0,0 @@
<?xml version='1.0'?>
<!DOCTYPE xsl:stylesheet [
]>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version='1.0'>
<xsl:template match="parameter">
<xsl:choose>
<xsl:when test="@role = 'keyword'">
<xsl:call-template name="inline.boldmonoseq"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="inline.italicmonoseq"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

View File

@ -1,102 +0,0 @@
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:include href="ref-html-style.xsl"/>
<!-- Make the ToC be of depth 2 -->
<xsl:param name="toc.max.depth" select="2"/>
<!-- Strip leading and trailing space from text children of programlisting -->
<xsl:template match="programlisting/text()">
<xsl:variable name="before" select="preceding-sibling::node()"/>
<xsl:variable name="after" select="following-sibling::node()"/>
<xsl:variable name="conts" select="."/>
<xsl:variable name="contsl">
<xsl:choose>
<xsl:when test="count($before) = 0">
<xsl:call-template name="remove-lf-left">
<xsl:with-param name="astr" select="$conts"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$conts"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="contslr">
<xsl:choose>
<xsl:when test="count($after) = 0">
<xsl:call-template name="remove-ws-right">
<xsl:with-param name="astr" select="$contsl"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$contsl"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="$contslr"/>
</xsl:template>
<!-- eats linefeeds from the left -->
<xsl:template name="remove-lf-left">
<xsl:param name="astr"/>
<xsl:choose>
<xsl:when test="starts-with($astr,'&#xA;') or
starts-with($astr,'&#xD;')">
<xsl:call-template name="remove-lf-left">
<xsl:with-param name="astr" select="substring($astr, 2)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$astr"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- eats whitespace from the right -->
<xsl:template name="remove-ws-right">
<xsl:param name="astr"/>
<xsl:variable name="last-char">
<xsl:value-of select="substring($astr, string-length($astr), 1)"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="($last-char = '&#xA;') or
($last-char = '&#xD;') or
($last-char = '&#x20;') or
($last-char = '&#x9;')">
<xsl:call-template name="remove-ws-right">
<xsl:with-param name="astr"
select="substring($astr, 1, string-length($astr) - 1)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$astr"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="inlinemediaobject" priority="100">
<p>
<video controls="controls">
<xsl:attribute name="src"><xsl:value-of select="videoobject/videodata/@fileref"/></xsl:attribute>
<!-- fallback link to video for non-HTML 5 browsers -->
<a>
<xsl:attribute name="href">
<xsl:value-of select="videoobject/videodata/@fileref"/>
</xsl:attribute>
<xsl:apply-templates select="alt"/>
</a>
</video>
</p>
</xsl:template>
</xsl:stylesheet>

View File

@ -1,154 +0,0 @@
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version='1.0'
xmlns="http://www.devhelp.net/book"
exclude-result-prefixes="#default">
<xsl:template name="generate.devhelp">
<xsl:call-template name="write.chunk">
<xsl:with-param name="filename">
<xsl:choose>
<xsl:when test="$gtkdoc.bookname">
<xsl:value-of select="$gtkdoc.bookname"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>book</xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:text>.devhelp</xsl:text>
</xsl:with-param>
<xsl:with-param name="method" select="'xml'"/>
<xsl:with-param name="indent" select="'yes'"/>
<xsl:with-param name="encoding" select="'utf-8'"/>
<xsl:with-param name="content">
<xsl:call-template name="devhelp"/>
</xsl:with-param>
</xsl:call-template>
</xsl:template>
<xsl:template name="devhelp">
<xsl:variable name="title">
<xsl:apply-templates select="." mode="generate.devhelp.toc.title.mode"/>
</xsl:variable>
<xsl:variable name="link">
<xsl:call-template name="href.target"/>
</xsl:variable>
<xsl:variable name="author">
<xsl:if test="articleinfo|bookinfo">
<xsl:apply-templates mode="generate.devhelp.authors"
select="articleinfo|bookinfo"/>
</xsl:if>
</xsl:variable>
<xsl:variable name="toc.nodes" select="part|reference|preface|chapter|
appendix|article|bibliography|
glossary|index|refentry|
bridgehead|sect1"/>
<book title="{$title}" link="{$link}" author="{$author}" name="{$gtkdoc.bookname}">
<xsl:if test="$toc.nodes">
<chapters>
<xsl:apply-templates select="$toc.nodes"
mode="generate.devhelp.toc.mode"/>
</chapters>
</xsl:if>
<functions>
<xsl:apply-templates select="//refsect1"
mode="generate.devhelp.constructor.index.mode"/>
<xsl:apply-templates select="//refsect2"
mode="generate.devhelp.index.mode"/>
</functions>
</book>
</xsl:template>
<xsl:template match="*" mode="generate.devhelp.toc.mode">
<xsl:variable name="title">
<xsl:apply-templates select="." mode="generate.devhelp.toc.title.mode"/>
</xsl:variable>
<xsl:variable name="target">
<xsl:variable name="anchor" select="title/anchor"/>
<xsl:choose>
<xsl:when test="$anchor">
<xsl:call-template name="href.target">
<xsl:with-param name="object" select="$anchor"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="href.target"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<sub name="{$title}" link="{$target}">
<xsl:apply-templates select="section|sect1|
refentry|refsect|
bridgehead|part|chapter"
mode="generate.devhelp.toc.mode"/>
</sub>
</xsl:template>
<xsl:template match="*" mode="generate.devhelp.index.mode">
<xsl:variable name="title" select="title"/>
<xsl:variable name="anchor" select="title/anchor"/>
<xsl:variable name="target">
<xsl:choose>
<xsl:when test="$anchor">
<xsl:call-template name="href.target">
<xsl:with-param name="object" select="$anchor"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="href.target"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<function name="{$title}" link="{$target}"/>
</xsl:template>
<xsl:template match="*" mode="generate.devhelp.constructor.index.mode">
<xsl:variable name="title" select="title"/>
<xsl:variable name="anchor" select="title/anchor"/>
<xsl:variable name="target">
<xsl:choose>
<xsl:when test="$anchor">
<xsl:call-template name="href.target">
<xsl:with-param name="object" select="$anchor"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="href.target"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:if test="$title='Constructor'">
<xsl:variable name ="constructor" select="programlisting//methodname"/>
<function name="{$constructor}" link="{$target}"/>
</xsl:if>
</xsl:template>
<!-- get title -->
<xsl:template match="article" mode="generate.devhelp.toc.title.mode">
<xsl:value-of select="articleinfo/title"/>
</xsl:template>
<xsl:template match="book" mode="generate.devhelp.toc.title.mode">
<xsl:value-of select="bookinfo/title"/>
</xsl:template>
<xsl:template match="refentry" mode="generate.devhelp.toc.title.mode">
<xsl:value-of select="refnamediv/refname"/>
</xsl:template>
<xsl:template match="*" mode="generate.devhelp.toc.title.mode">
<xsl:value-of select="title"/>
</xsl:template>
<!-- generate list of authors ... -->
<xsl:template match="articleinfo|bookinfo" mode="generate.devhelp.authors">
<xsl:for-each select="authorgroup/author">
<xsl:value-of select="firstname"/>
<xsl:text> </xsl:text>
<xsl:value-of select="surname"/>
<xsl:if test="not(last())">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

View File

@ -1,285 +0,0 @@
<?xml version='1.0'?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY RE "&#10;">
<!ENTITY nbsp "&#160;">
]>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version='1.0'>
<xsl:param name="html.stylesheet">style.css</xsl:param>
<xsl:param name="use.id.as.filename" select="1"/>
<xsl:param name="chunk.fast" select="1"/>
<xsl:param name="chunker.output.encoding" select="'utf-8'"/>
<xsl:param name="linenumbering.extension" select="1"/>
<xsl:param name="variablelist.as.table" select="1"/>
<xsl:template match="blockquote">
<div class="{local-name(.)}">
<xsl:if test="@lang or @xml:lang">
<xsl:call-template name="language.attribute"/>
</xsl:if>
<xsl:call-template name="anchor"/>
<xsl:choose>
<xsl:when test="attribution">
<table border="0" width="100%"
cellspacing="0" cellpadding="0" class="blockquote"
summary="Block quote">
<tr>
<td width="10%" valign="top">&#160;</td>
<td width="80%" valign="top">
<xsl:apply-templates select="child::*[local-name(.)!='attribution']"/>
</td>
<td width="10%" valign="top">&#160;</td>
</tr>
<tr>
<td colspan="2" align="right" valign="top">
<xsl:text>--</xsl:text>
<xsl:apply-templates select="attribution"/>
</td>
<td width="10%" valign="top">&#160;</td>
</tr>
</table>
</xsl:when>
<xsl:when test="@role = 'properties' or @role = 'prototypes'">
<table width="100%" border="0" bgcolor="#E0E0E0">
<tr>
<td valign="top">
<xsl:apply-templates select="child::*[local-name(.)!='attribution']"/>
</td>
</tr>
</table>
</xsl:when>
<xsl:otherwise>
<blockquote class="{local-name(.)}">
<xsl:apply-templates/>
</blockquote>
</xsl:otherwise>
</xsl:choose>
</div>
</xsl:template>
<!-- support for Python language for synopsises -->
<xsl:template match="classsynopsis
|fieldsynopsis
|methodsynopsis
|constructorsynopsis
|destructorsynopsis">
<xsl:param name="language">
<xsl:choose>
<xsl:when test="@language">
<xsl:value-of select="@language"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$default-classsynopsis-language"/>
</xsl:otherwise>
</xsl:choose>
</xsl:param>
<xsl:choose>
<xsl:when test="$language='python'">
<xsl:apply-templates select="." mode="python"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-imports/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="classsynopsis" mode="python">
<table bgcolor="#D0E0F0" width="100%">
<tr><td>
<pre class="{name(.)}">
<xsl:text>class </xsl:text>
<xsl:apply-templates select="ooclass[1]" mode="python"/>
<xsl:if test="ooclass[position() &gt; 1]">
<xsl:text>(</xsl:text>
<xsl:apply-templates select="ooclass[position() &gt; 1]" mode="python"/> <xsl:text>)</xsl:text>
</xsl:if>
<xsl:text>:&RE;</xsl:text>
<xsl:apply-templates select="constructorsynopsis
|destructorsynopsis
|fieldsynopsis
|methodsynopsis
|classsynopsisinfo" mode="python"/>
</pre></td></tr></table>
</xsl:template>
<xsl:template match="classsynopsisinfo" mode="python">
<xsl:apply-templates mode="python"/>
</xsl:template>
<xsl:template match="ooclass|oointerface|ooexception" mode="python">
<xsl:if test="position() &gt; 1">
<xsl:text>, </xsl:text>
</xsl:if>
<span class="{name(.)}">
<xsl:apply-templates mode="python"/>
</span>
</xsl:template>
<xsl:template match="modifier" mode="python">
<span class="{name(.)}">
<xsl:apply-templates mode="python"/>
<xsl:text>&nbsp;</xsl:text>
</span>
</xsl:template>
<xsl:template match="classname" mode="python">
<xsl:if test="name(preceding-sibling::*[1]) = 'classname'">
<xsl:text>, </xsl:text>
</xsl:if>
<span class="{name(.)}">
<xsl:apply-templates mode="python"/>
</span>
</xsl:template>
<xsl:template match="interfacename" mode="python">
<xsl:if test="name(preceding-sibling::*[1]) = 'interfacename'">
<xsl:text>, </xsl:text>
</xsl:if>
<span class="{name(.)}">
<xsl:apply-templates mode="python"/>
</span>
</xsl:template>
<xsl:template match="exceptionname" mode="python">
<xsl:if test="name(preceding-sibling::*[1]) = 'exceptionname'">
<xsl:text>, </xsl:text>
</xsl:if>
<span class="{name(.)}">
<xsl:apply-templates mode="python"/>
</span>
</xsl:template>
<xsl:template match="fieldsynopsis" mode="python">
<code class="{name(.)}">
<xsl:text>&nbsp;&nbsp;&nbsp;&nbsp;</xsl:text>
<xsl:apply-templates mode="python"/>
</code>
<xsl:call-template name="synop-break"/>
</xsl:template>
<xsl:template match="type" mode="python">
<span class="{name(.)}">
<xsl:apply-templates mode="python"/>
<xsl:text>&nbsp;</xsl:text>
</span>
</xsl:template>
<xsl:template match="varname" mode="python">
<span class="{name(.)}">
<xsl:apply-templates mode="python"/>
<xsl:text>&nbsp;</xsl:text>
</span>
</xsl:template>
<xsl:template match="initializer" mode="python">
<span class="{name(.)}">
<xsl:text>=</xsl:text>
<xsl:apply-templates mode="python"/>
</span>
</xsl:template>
<xsl:template match="void" mode="python">
<span class="{name(.)}">
<xsl:text>void&nbsp;</xsl:text>
</span>
</xsl:template>
<xsl:template match="methodname" mode="python">
<span class="{name(.)}">
<xsl:apply-templates mode="python"/>
</span>
</xsl:template>
<xsl:template match="methodparam" mode="python">
<xsl:if test="position() &gt; 1">
<xsl:text>, </xsl:text>
</xsl:if>
<span class="{name(.)}">
<xsl:apply-templates mode="python"/>
</span>
</xsl:template>
<xsl:template mode="python"
match="destructorsynopsis|methodsynopsis">
<code class="{name(.)}">
<xsl:text> def </xsl:text>
<xsl:apply-templates select="methodname" mode="python"/>
<xsl:text>(</xsl:text>
<xsl:apply-templates select="methodparam" mode="python"/>
<xsl:text>)</xsl:text>
</code>
<xsl:call-template name="synop-break"/>
</xsl:template>
<xsl:template mode="python"
match="constructorsynopsis">
<code class="{name(.)}">
<xsl:text> </xsl:text>
<xsl:apply-templates select="methodname" mode="python"/>
<xsl:text>(</xsl:text>
<xsl:apply-templates select="methodparam" mode="python"/>
<xsl:text>)</xsl:text>
</code>
<xsl:call-template name="synop-break"/>
</xsl:template>
<!-- this was the original parameter python mode styling
<xsl:template match="parameter" mode="python">
<span class="{name(.)}">
<xsl:apply-templates mode="python"/>
</span>
</xsl:template>
-->
<!-- hack -->
<xsl:template match="link" mode="python">
<xsl:apply-templates select="."/>
</xsl:template>
<!-- ========================================================= -->
<!-- template to output gtkdoclink elements for the unknown targets -->
<xsl:template match="link">
<xsl:choose>
<xsl:when test="id(@linkend)">
<xsl:apply-imports/>
</xsl:when>
<xsl:otherwise>
<PYGTKDOCLINK HREF="{@linkend}">
<xsl:apply-templates/>
</PYGTKDOCLINK>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="parameter" mode="python">
<span class="{name(.)}">
<xsl:choose>
<xsl:when test="@role = 'keyword'">
<xsl:call-template name="inline.boldmonoseq"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="inline.italicmonoseq"/>
</xsl:otherwise>
</xsl:choose>
</span>
</xsl:template>
<xsl:template match="variablelist">
<table border="0" width="100%" bgcolor="#FFECCE">
<col align="left" valign="top" width="0*">
</col>
<tbody>
<xsl:apply-templates select="varlistentry" mode="varlist-table"/>
</tbody>
</table>
</xsl:template>
</xsl:stylesheet>

View File

@ -1,54 +0,0 @@
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version='1.0'>
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl"/>
<xsl:include href="common.xsl"/>
<xsl:include href="html.xsl"/>
<xsl:include href="devhelp.xsl"/>
<!-- ========================================================= -->
<!-- template to create the index.sgml anchor index -->
<xsl:template name="generate.index">
<xsl:call-template name="write.text.chunk">
<xsl:with-param name="filename" select="'index.sgml'"/>
<xsl:with-param name="content">
<!-- check all anchor and refentry elements -->
<xsl:apply-templates select="//anchor|//refentry|//refsect1|//refsect2|//book"
mode="generate.index.mode"/>
</xsl:with-param>
<xsl:with-param name="encoding" select="'utf-8'"/>
</xsl:call-template>
</xsl:template>
<xsl:template match="*" mode="generate.index.mode">
<xsl:if test="not(@href)">
<xsl:if test="@id">
<xsl:text>&lt;ANCHOR id=&quot;</xsl:text>
<xsl:value-of select="@id"/>
<xsl:text>&quot; href=&quot;</xsl:text>
<xsl:if test="$gtkdoc.bookname">
<xsl:value-of select="$gtkdoc.bookname"/>
<xsl:text>/</xsl:text>
</xsl:if>
<xsl:call-template name="href.target"/>
<xsl:text>&quot;&gt;
</xsl:text>
</xsl:if>
</xsl:if>
</xsl:template>
<xsl:param name="gtkdoc.version" select="''"/>
<xsl:param name="gtkdoc.bookname" select="''"/>
<xsl:param name="refentry.generate.name" select="0"/>
<xsl:param name="refentry.generate.title" select="1"/>
<xsl:param name="chapter.autolabel" select="0"/>
<xsl:template match="book|article">
<xsl:apply-imports/>
<xsl:call-template name="generate.devhelp"/>
<xsl:call-template name="generate.index"/>
</xsl:template>
</xsl:stylesheet>

View File

@ -1,966 +0,0 @@
/*
Generic XHTML / DocBook XHTML CSS Stylesheet.
Browser wrangling and typographic design by
Oyvind Kolas / pippin@gimp.org
Customised for Poky by
Matthew Allum / mallum@o-hand.com
Thanks to:
Liam R. E. Quin
William Skaggs
Jakub Steiner
Structure
---------
The stylesheet is divided into the following sections:
Positioning
Margins, paddings, width, font-size, clearing.
Decorations
Borders, style
Colors
Colors
Graphics
Graphical backgrounds
Nasty IE tweaks
Workarounds needed to make it work in internet explorer,
currently makes the stylesheet non validating, but up until
this point it is validating.
Mozilla extensions
Transparency for footer
Rounded corners on boxes
*/
/*************** /
/ Positioning /
/ ***************/
body {
font-family: Verdana, Sans, sans-serif;
min-width: 640px;
width: 80%;
margin: 0em auto;
padding: 2em 5em 5em 5em;
color: #333;
}
h1,h2,h3,h4,h5,h6,h7 {
font-family: Arial, Sans;
color:#999999;
clear: both;
}
h1 {
font-size: 2em;
text-align: left;
padding: 0em 0em 0em 0em;
margin: 2em 0em 0em 0em;
}
h2.subtitle {
margin: 0.10em 0em 3.0em 0em;
padding: 0em 0em 0em 0em;
font-size: 1.8em;
padding-left: 20%;
font-weight: normal;
font-style: italic;
}
h2 {
margin: 2em 0em 0.66em 0em;
padding: 0.5em 0em 0em 0em;
font-size: 1.5em;
font-weight: normal;
}
h3.subtitle {
margin: 0em 0em 1em 0em;
padding: 0em 0em 0em 0em;
font-size: 142.14%;
text-align: right;
}
h3 {
margin: 1em 0em 0.5em 0em;
padding: 1em 0em 0em 0em;
font-size: 140%;
font-weight: normal;
}
h4 {
margin: 1em 0em 0.5em 0em;
padding: 1em 0em 0em 0em;
font-size: 120%;
font-weight: normal;
}
h5 {
margin: 1em 0em 0.5em 0em;
padding: 1em 0em 0em 0em;
font-size: 110.000%;
border-bottom: 1px solid black;
}
h6 {
margin: 1em 0em 0em 0em;
padding: 1em 0em 0em 0em;
font-size: 80%;
font-weight: normal;
}
.authorgroup {
background-color: transparent;
background-repeat: no-repeat;
padding-top: 256px;
/* background-image: url("images/clutter-logo.png"); */
background-position: right top;
float: right;
margin-top: -256px;
padding-right: 50px;
margin-left: 50px;
text-align: right;
width: 200px;
}
h3.author {
margin: 0em 0me 0em 0em;
padding: 0em 0em 0em 0em;
font-weight: normal;
font-size: 100%;
clear: both;
}
.author tt.email {
font-size: 66%;
}
.titlepage hr {
width: 0em;
clear: both;
}
.revhistory {
padding-top: 2em;
clear: both;
}
.toc,
.list-of-tables,
.list-of-examples,
.list-of-figures {
padding: 1.33em 0em 2.5em 0em;
}
.toc p,
.list-of-tables p,
.list-of-figures p,
.list-of-examples p {
padding: 0em 0em 0em 0em;
padding: 0em 0em 0.3em;
margin: 1.5em 0em 0em 0em;
}
.toc p b,
.list-of-tables p b,
.list-of-figures p b,
.list-of-examples p b{
font-size: 100.0%;
font-weight: bold;
}
.toc dl,
.list-of-tables dl,
.list-of-figures dl,
.list-of-examples dl {
margin: 0em 0em 0.5em 0em;
padding: 0em 0em 0em 0em;
}
.toc dt {
margin: 0em 0em 0em 0em;
padding: 0em 0em 0em 0em;
}
.toc dd {
margin: 0em 0em 0em 2.6em;
padding: 0em 0em 0em 0em;
}
div.glossary dl,
div.variablelist dl {
}
.glossary dl dt,
.variablelist dl dt,
.variablelist dl dt span.term {
font-weight: normal;
width: 20em;
text-align: right;
}
.variablelist dl dt {
margin-top: 0.5em;
}
.glossary dl dd,
.variablelist dl dd {
margin-top: -1em;
margin-left: 25.5em;
}
.glossary dd p,
.variablelist dd p {
margin-top: 0em;
margin-bottom: 1em;
}
div.calloutlist table td {
padding: 0em 0em 0em 0em;
margin: 0em 0em 0em 0em;
}
div.calloutlist table td p {
margin-top: 0em;
margin-bottom: 1em;
}
div p.copyright {
text-align: left;
}
div.legalnotice p.legalnotice-title {
margin-bottom: 0em;
font-size: 80%;
}
p {
line-height: 1.5em;
margin-top: 0em;
}
dl {
padding-top: 0em;
}
hr {
border: solid 1px;
}
.mediaobject,
.mediaobjectco {
text-align: center;
}
img {
border: none;
}
ul {
padding: 0em 0em 0em 1.5em;
}
ul li {
padding: 0em 0em 0em 0em;
}
ul li p {
text-align: left;
}
table {
width :100%;
}
th {
padding: 0.25em;
text-align: left;
font-weight: normal;
vertical-align: top;
}
td {
padding: 0.25em;
vertical-align: top;
}
p a[id] {
margin: 0px;
padding: 0px;
display: inline;
background-image: none;
}
a {
text-decoration: underline;
color: #444;
}
pre {
overflow: auto;
}
a:hover {
text-decoration: underline;
/*font-weight: bold;*/
}
div.informalfigure,
div.informalexample,
div.informaltable,
div.figure,
div.table,
div.example {
margin: 1em 0em;
padding: 1em;
page-break-inside: avoid;
background-color: #3ab1cc;
}
div.informalfigure p.title b,
div.informalexample p.title b,
div.informaltable p.title b,
div.figure p.title b,
div.example p.title b,
div.table p.title b{
padding-top: 0em;
margin-top: 0em;
font-size: 100%;
font-weight: normal;
}
.mediaobject .caption,
.mediaobject .caption p {
text-align: center;
font-size: 80%;
padding-top: 0.5em;
padding-bottom: 0.5em;
}
.epigraph {
padding-left: 55%;
margin-bottom: 1em;
color: #666;
font-size: 80%;
}
.epigraph p {
text-align: left;
}
.epigraph .quote {
font-style: italic;
}
.epigraph .attribution {
font-style: normal;
text-align: right;
}
span.application {
font-style: italic;
}
span.property, span.type {
font-family: monospace;
}
.programlisting {
font-family: monospace;
font-size: 80%;
white-space: pre;
margin: 1.33em 0em;
padding: 1.33em;
}
.tip,
.warning,
.caution,
.note {
margin-top: 1em;
margin-bottom: 1em;
}
/* force full width of table within div */
.tip table,
.warning table,
.caution table,
.note table {
border: none;
width: 100%;
}
.tip table th,
.warning table th,
.caution table th,
.note table th {
padding: 0.8em 0.0em 0.0em 0.0em;
margin : 0em 0em 0em 0em;
}
.tip p,
.warning p,
.caution p,
.note p {
margin-top: 0.5em;
margin-bottom: 0.5em;
padding-right: 1em;
text-align: left;
}
.acronym {
text-transform: uppercase;
}
b.keycap,
.keycap {
padding: 0.09em 0.3em;
margin: 0em;
}
.itemizedlist li {
clear: none;
}
.filename {
font-size: medium;
font-family: Courier, monospace;
}
div.navheader, div.heading{
position: absolute;
left: 0em;
top: 0em;
width: 100%;
background-color: #cdf;
width: 100%;
}
div.navfooter, div.footing{
position: fixed;
left: 0em;
bottom: 0em;
background-color: #eee;
width: 100%;
}
div.navheader td,
div.navfooter td {
font-size: 66%;
}
div.navheader table th {
/*font-family: Georgia, Times, serif;*/
/*font-size: x-large;*/
font-size: 80%;
}
div.navheader table {
border-left: 0em;
border-right: 0em;
border-top: 0em;
width: 100%;
}
div.navfooter table {
border-left: 0em;
border-right: 0em;
border-bottom: 0em;
width: 100%;
}
div.navheader table td a,
div.navfooter table td a {
color: #777;
text-decoration: none;
}
/* normal text in the footer */
div.navfooter table td {
color: black;
}
div.navheader table td a:visited,
div.navfooter table td a:visited {
color: #444;
}
/* links in header and footer */
div.navheader table td a:hover,
div.navfooter table td a:hover {
text-decoration: underline;
background-color: transparent;
color: #33a;
}
div.navheader hr,
div.navfooter hr {
display: none;
}
.qandaset tr.question td p {
margin: 0em 0em 1em 0em;
padding: 0em 0em 0em 0em;
}
.qandaset tr.answer td p {
margin: 0em 0em 1em 0em;
padding: 0em 0em 0em 0em;
}
.answer td {
padding-bottom: 1.5em;
}
.emphasis {
font-weight: bold;
}
pre.programlisting .emphasis {
font-weight: normal !important;
}
/************* /
/ decorations /
/ *************/
.titlepage {
}
.part .title {
}
.subtitle {
border: none;
}
/*
h1 {
border: none;
}
h2 {
border-top: solid 0.2em;
border-bottom: solid 0.06em;
}
h3 {
border-top: 0em;
border-bottom: solid 0.06em;
}
h4 {
border: 0em;
border-bottom: solid 0.06em;
}
h5 {
border: 0em;
}
*/
.programlisting {
border: solid 1px;
}
div.figure,
div.table,
div.informalfigure,
div.informaltable,
div.informalexample,
div.example {
border: 1px solid;
}
.tip,
.warning,
.caution,
.note {
border: 1px solid;
}
.tip table th,
.warning table th,
.caution table th,
.note table th {
border-bottom: 1px solid;
}
.question td {
border-top: 1px solid black;
}
.answer {
}
b.keycap,
.keycap {
border: 1px solid;
}
div.navheader, div.heading{
border-bottom: 1px solid;
}
div.navfooter, div.footing{
border-top: 1px solid;
}
/********* /
/ colors /
/ *********/
body {
color: #333;
background: white;
}
a {
background: transparent;
}
a:hover {
background-color: #dedede;
}
h1,
h2,
h3,
h4,
h5,
h6,
h7,
h8 {
background-color: transparent;
}
hr {
border-color: #aaa;
}
.tip, .warning, .caution, .note {
border-color: #aaa;
}
.tip table th,
.warning table th,
.caution table th,
.note table th {
border-bottom-color: #aaa;
}
.warning {
background-color: #fea;
}
.caution {
background-color: #fea;
}
.tip {
background-color: #eff;
}
.note {
background-color: #8bd12e;
}
.glossary dl dt,
.variablelist dl dt,
.variablelist dl dt span.term {
color: #044;
}
div.figure,
div.table,
div.example,
div.informalfigure,
div.informaltable,
div.informalexample {
border-color: #aaa;
}
pre.programlisting {
color: black;
background-color: #fff;
border-color: #aaa;
border-width: 2px;
}
.guimenu,
.guilabel,
.guimenuitem {
background-color: #eee;
}
b.keycap,
.keycap {
background-color: #eee;
border-color: #999;
}
div.navheader {
border-color: black;
}
div.navfooter {
border-color: black;
}
/*********** /
/ graphics /
/ ***********/
/*
body {
background-image: url("images/body_bg.jpg");
background-attachment: fixed;
}
.navheader,
.note,
.tip {
background-image: url("images/note_bg.jpg");
background-attachment: fixed;
}
.warning,
.caution {
background-image: url("images/warning_bg.jpg");
background-attachment: fixed;
}
.figure,
.informalfigure,
.example,
.informalexample,
.table,
.informaltable {
background-image: url("images/figure_bg.jpg");
background-attachment: fixed;
}
*/
h1,
h2,
h3,
h4,
h5,
h6,
h7{
}
div.preface .titlepage .title,
div.colophon .title,
div.chapter .titlepage .title {
background-image: url("images/title-bg.png");
background-position: bottom;
background-repeat: repeat-x;
}
div.section div.section .titlepage .title,
div.sect2 .titlepage .title {
background: none;
}
h1.title {
background-color: transparent;
background-image: url("images/clutter-logo.png");
background-repeat: no-repeat;
height: 128px;
text-indent: 400px;
overflow:hidden;
margin: 2em 1em 2em 0em;
text-align: right;
}
h2.subtitle {
background-color: transparent;
text-indent: -9000px;
overflow:hidden;
width: 0px;
display: none;
}
/*************************************** /
/ pippin.gimp.org specific alterations /
/ ***************************************/
/*
div.heading, div.navheader {
color: #777;
font-size: 80%;
padding: 0;
margin: 0;
text-align: left;
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 50px;
background: url('/gfx/heading_bg.png') transparent;
background-repeat: repeat-x;
background-attachment: fixed;
border: none;
}
div.heading a {
color: #444;
}
div.footing, div.navfooter {
border: none;
color: #ddd;
font-size: 80%;
text-align:right;
width: 100%;
padding-top: 10px;
position: absolute;
bottom: 0px;
left: 0px;
background: url('/gfx/footing_bg.png') transparent;
}
*/
/****************** /
/ nasty ie tweaks /
/ ******************/
/*
div.heading, div.navheader {
width:expression(document.body.clientWidth + "px");
}
div.footing, div.navfooter {
width:expression(document.body.clientWidth + "px");
margin-left:expression("-5em");
}
body {
padding:expression("4em 5em 0em 5em");
}
*/
/**************************************** /
/ mozilla vendor specific css extensions /
/ ****************************************/
/*
div.navfooter, div.footing{
-moz-opacity: 0.8em;
}
div.figure,
div.table,
div.informalfigure,
div.informaltable,
div.informalexample,
div.example,
.tip,
.warning,
.caution,
.note {
-moz-border-radius: 0.5em;
}
b.keycap,
.keycap {
-moz-border-radius: 0.3em;
}
*/
table tr td table tr td {
display: none;
}
hr {
display: none;
}
table {
border: 0em;
}
.photo {
float: right;
margin-left: 1.5em;
margin-bottom: 1.5em;
margin-top: 0em;
max-width: 17em;
border: 1px solid gray;
padding: 3px;
background: white;
}
.seperator {
padding-top: 2em;
clear: both;
}
#validators {
margin-top: 5em;
text-align: right;
color: #777;
}
@media print {
body {
font-size: 8pt;
}
.noprint {
display: none;
}
}
.tip,
.note {
background: #91ae35;
color: #fff;
padding: 20px;
margin: 20px;
}
.tip h3,
.note h3 {
padding: 0em;
margin: 0em;
font-size: 2em;
font-weight: bold;
color: #fff;
}
.tip a,
.note a {
color: #fff;
text-decoration: underline;
}

View File

@ -1,185 +0,0 @@
SUBDIRS = examples
NULL =
HTML_DIR = $(datadir)/gtk-doc/html
TARGET_DIR = $(HTML_DIR)/clutter-cookbook
XML_FILES = \
$(top_srcdir)/doc/cookbook/actors.xml \
$(top_srcdir)/doc/cookbook/animations.xml \
$(top_srcdir)/doc/cookbook/events.xml \
$(top_srcdir)/doc/cookbook/introduction.xml \
$(top_srcdir)/doc/cookbook/text.xml \
$(top_srcdir)/doc/cookbook/textures.xml \
$(top_srcdir)/doc/cookbook/layouts.xml \
$(top_srcdir)/doc/cookbook/script.xml \
$(top_srcdir)/doc/cookbook/effects.xml \
$(NULL)
XSLTOPTS = \
--stringparam html.stylesheet style.css \
--stringparam chapter.autolabel 1 \
--stringparam appendix.autolabel 1 \
--stringparam section.autolabel 1 \
--stringparam gtkdoc.bookname "clutter-cookbook" \
--stringparam gtkdoc.version @CLUTTER_API_VERSION@ \
--stringparam callout.graphics 0 \
--path $(top_srcdir)/doc/common \
--path $(top_srcdir)/doc/cookbook \
--xinclude
XSL_BASE_URI = http://docbook.sourceforge.net/release/xsl/current
XSL_XHTML_URI = $(XSL_BASE_URI)/xhtml/docbook.xsl
HTML_FILES = $(top_builddir)/doc/cookbook/html/*.html
CSS_FILES = $(top_builddir)/doc/cookbook/html/*.css
IMAGE_FILES = \
$(srcdir)/images/clutter-logo.png \
$(srcdir)/images/effects-basic.png \
$(srcdir)/images/effects-basic-background.png \
$(srcdir)/images/effects-built-in.png \
$(srcdir)/images/effects-custom-deform.png \
$(srcdir)/images/effects-custom-deform-back-material.png \
$(srcdir)/images/textures-reflection.png \
$(srcdir)/images/actors-opacity.png \
$(srcdir)/images/actors-opacity-container-affects-opacity.png \
$(srcdir)/images/text-shadow.png \
$(srcdir)/images/textures-sub-texture.png \
$(srcdir)/images/layouts-stacking-diff-actor-sizes.png \
$(srcdir)/images/events-pointer-motion-stacking.png \
$(srcdir)/images/layouts-bind-constraint-stage.png \
$(NULL)
VIDEO_FILES = \
$(srcdir)/videos/animations-fading-out.ogv \
$(srcdir)/videos/animations-fading-in-then-out.ogv \
$(srcdir)/videos/animations-path.ogv \
$(srcdir)/videos/animations-rotating-x-minus-45.ogv \
$(srcdir)/videos/animations-rotating-y-45.ogv \
$(srcdir)/videos/animations-rotating-z-90.ogv \
$(srcdir)/videos/animations-rotating-x-minus-180-with-y-minus-96.ogv \
$(srcdir)/videos/animations-rotating-x-minus-180-with-z-minus-96.ogv \
$(srcdir)/videos/animations-rotating-x-centered.ogv \
$(srcdir)/videos/animations-rotating-y-centered.ogv \
$(srcdir)/videos/animations-rotating-z-centered.ogv \
$(srcdir)/videos/animations-rotating-container-reverses-direction.ogv \
$(srcdir)/videos/effects-custom-deform.ogv \
$(srcdir)/videos/textures-split-go.ogv \
$(srcdir)/videos/events-mouse-scroll.ogv \
$(srcdir)/videos/textures-crossfade-two-textures.ogv \
$(srcdir)/videos/animations-complex.ogv \
$(srcdir)/videos/animations-reuse.ogv \
$(srcdir)/videos/animations-moving-anchors.ogv \
$(srcdir)/videos/animations-moving-depth.ogv \
$(srcdir)/videos/animations-looping.ogv \
$(NULL)
EXTRA_DIST = \
clutter-cookbook.xml.in \
recipe-template.xml \
$(IMAGE_FILES) \
$(XML_FILES) \
$(VIDEO_FILES)
CLEANFILES = \
pdf-build.stamp \
html-build.stamp \
clutter-cookbook.html
pdf-build.stamp: clutter-cookbook.xml $(XML_FILES)
SP_ENCODING=XML SP_CHARSET_FIXED=YES \
$(JW) -b pdf $(top_builddir)/doc/cookbook/clutter-cookbook.xml \
&& mv -f clutter-cookbook.pdf clutter-cookbook-@CLUTTER_API_VERSION@.pdf \
&& echo timestamp > $(@F)
html-build.stamp: clutter-cookbook.xml $(XML_FILES)
if [ ! -d html ] ; then mkdir html ; fi && \
if [ ! -d html/images ] ; then mkdir html/images ; fi && \
if [ ! -d html/videos ] ; then mkdir html/videos ; fi && \
if [ ! -d html/examples ] ; then mkdir html/examples ; fi && \
$(XSLTPROC) $(XSLTOPTS) -o clutter-cookbook.html $(XSL_XHTML_URI) $(top_builddir)/doc/cookbook/clutter-cookbook.xml && \
$(XSLTPROC) $(XSLTOPTS) -o html/ cookbook.xsl $(top_builddir)/doc/cookbook/clutter-cookbook.xml && \
cp $(top_srcdir)/doc/common/style.css html/ && \
if [[ "$(VIDEO_FILES)" != "" ]] ; then \
for file in `ls $(VIDEO_FILES)`; do \
cp $$file html/videos/ ; \
done \
fi && \
cp $(top_srcdir)/doc/cookbook/images/* html/images/ && \
cp $(top_srcdir)/doc/cookbook/examples/*.c html/examples/ && \
echo timestamp > $(@F)
if ENABLE_PDFS
#pdf_target = pdf-build.stamp
pdf_target =
else
pdf_target =
endif
if ENABLE_DOCS
all-local: html-build.stamp $(pdf_target)
else
all-local:
endif
clean-local:
@rm -rf html ; \
rm -f *.pdf ; \
rm -f *.stamp
dist-hook:
mkdir $(distdir)/html
cp -r ./html/* $(distdir)/html
uninstall-local:
@rm -rf $(DESTDIR)$(TARGET_DIR)
@rm -f $(DESTDIR)$(TARGET_DIR)/clutter-cookbook.devhelp
install-data-local:
installfiles=`echo $(top_builddir)/doc/cookbook/html/*`; \
if test "$$installfiles" = '$(top_builddir)/doc/cookbook/html/*'; \
then echo '-- Nothing to install' ; \
else \
$(mkinstalldirs) $(DESTDIR)$(TARGET_DIR) ; \
for file in `ls $(HTML_FILES) $(CSS_FILES)`; do \
if [ -f $$file ]; then \
basefile=`echo $$file | sed -e 's,^.*/,,'`; \
$(INSTALL_DATA) $$file $(DESTDIR)$(TARGET_DIR)/$$basefile; \
fi \
done; \
fi; \
if [ -d $(top_srcdir)/doc/cookbook/images ]; \
then \
$(mkinstalldirs) $(DESTDIR)$(TARGET_DIR)/images ; \
for file in `ls $(IMAGE_FILES)`; do \
if [ -f $$file ]; \
then \
basefile=`echo $$file | sed -e 's,^.*/,,'`; \
$(INSTALL_DATA) $$file $(DESTDIR)$(TARGET_DIR)/images/$$basefile; \
fi \
done; \
fi; \
if [ -d $(top_srcdir)/doc/cookbook/videos ]; \
then \
$(mkinstalldirs) $(DESTDIR)$(TARGET_DIR)/videos ; \
for file in `ls $(VIDEO_FILES)`; do \
if [ -f $$file ]; \
then \
basefile=`echo $$file | sed -e 's,^.*/,,'`; \
$(INSTALL_DATA) $$file $(DESTDIR)$(TARGET_DIR)/videos/$$basefile; \
fi \
done; \
fi; \
$(INSTALL_DATA) $(top_builddir)/doc/cookbook/html/clutter-cookbook.devhelp $(DESTDIR)$(TARGET_DIR)/clutter-cookbook.devhelp
.PHONY : doc
COOKBOOK_BASE_PATH = /home/clutter/web/docs.clutter-project.org/docs/clutter-cookbook
COOKBOOK_VERSION = $(CLUTTER_API_VERSION)
COOKBOOK_PATH = $(COOKBOOK_BASE_PATH)/$(COOKBOOK_VERSION)
publish: html-build.stamp
$(QUIET_CP)scp -r html/* clutter@clutter-project.org:$(COOKBOOK_PATH)
.PHONY : publish

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,266 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
<!ENTITY appurl "http://www.clutter-project.org">
<!ENTITY docurl "http://docs.clutter-project.org/docs/clutter-cookbook">
<!ENTITY license_url "http://creativecommons.org/licenses/by-nc-sa/2.0/uk/">
<!ENTITY ebassi_mail "ebassi@linux.intel.com">
<!ENTITY elliot_mail "elliot.smith@intel.com">
<!ENTITY apiversion "@CLUTTER_API_VERSION@">
]>
<book lang="en"
xmlns:xi="http://www.w3.org/2003/XInclude">
<bookinfo>
<authorgroup>
<author>
<firstname>Emmanuele</firstname>
<surname>Bassi</surname>
<address><email>&ebassi_mail;</email></address>
</author>
<author>
<firstname>Elliot</firstname>
<surname>Smith</surname>
<address><email>&elliot_mail;</email></address>
</author>
</authorgroup>
<copyright>
<year>2009, 2010, 2011</year>
<holder>Intel Corporation</holder>
</copyright>
<legalnotice>
<para>Permission is granted to copy, distribute and/or modify this
document under the terms of the <ulink url="&license_url;">Creative
Commons Attribution-Non-Commercial-Share Alike 2.0 UK: England &amp;
Wales</ulink> as published by Creative Commons.</para>
</legalnotice>
<title>The Clutter Cookbook</title>
<releaseinfo>for Clutter &apiversion;</releaseinfo>
</bookinfo>
<xi:include href="introduction.xml" />
<xi:include href="actors.xml" />
<xi:include href="events.xml" />
<xi:include href="textures.xml" />
<xi:include href="animations.xml" />
<xi:include href="text.xml" />
<xi:include href="layouts.xml" />
<xi:include href="script.xml" />
<xi:include href="effects.xml" />
<appendix id="contributing">
<title>Contributing to this document</title>
<para>This document is written in
<ulink url="http://docbook.org/">Docbook XML</ulink>. The source files
for this document are located in the subdirectory
<filename>doc/cookbook</filename> inside the Clutter source directory.</para>
<para>To maintain some degree of consistency, try to stick to the
following broad guidelines about how to write Docbook for this
cookbook:</para>
<itemizedlist>
<listitem>
<para>If adding a new recipe, use the
<filename>recipe-template.xml</filename> XML file as a basis.
You can find it in the <filename>&lt;clutter source&gt;/doc/cookbook/</filename>
directory.</para>
</listitem>
<listitem>
<para>Try to indent your XML sensibly using 2 spaces per level
(we're not too strict, but some indentation helps reading
the source).</para>
</listitem>
<listitem>
<para>Stick to a column width of around 80 characters.</para>
</listitem>
<listitem>
<para>Use the &lt;filename&gt; element for file
and directory names.</para>
</listitem>
<listitem>
<para>Use the &lt;property&gt; element for property names
(e.g. GObject properties).</para>
</listitem>
<listitem>
<para>Use the &lt;type&gt; element for GObject class
names.</para>
</listitem>
<listitem>
<para>Use the &lt;constant&gt; element for C defines.</para>
</listitem>
<listitem>
<para>Use the &lt;keycap&gt; element for keys, where
you are referring to what's actually printed on the key, e.g.
<keycap>Shift</keycap>. If you're referring to the key some
other way (e.g. "the Control key"), don't use
&lt;keycap&gt;.</para>
</listitem>
<listitem>
<para>Use the &lt;function&gt; element for functions;
the style adopted is to give the function name followed by
empty brackets, e.g. <function>clutter_actor_set_size()</function>.
</para>
</listitem>
<listitem>
<para>Use the &lt;note&gt; element for asides which might
otherwise interrupt the flow of the recipe.</para>
</listitem>
<listitem>
<para>To include a video in a recipe, do the following:</para>
<itemizedlist>
<listitem>
<para>Make the video as short as is practical, and only include
the relevant Clutter window(s).</para>
</listitem>
<listitem>
<para>Use Ogg Theora for the encoding.</para>
</listitem>
<listitem>
<para>Put the file into the
<filename>&lt;clutter source&gt;/doc/cookbook/videos</filename>
directory. The name should be in the format
<filename>&lt;section&gt;-&lt;recipe&gt;-&lt;identifier&gt;.ogv</filename>.
For example: <filename>animations-fading-fade-out.ogv</filename>.</para>
</listitem>
<listitem>
<para>Add the name of the file to the <varname></varname>
in the cookbook's <filename>Makefile.am</filename>, e.g.</para>
<informalexample>
<programlisting>
<![CDATA[
VIDEO_FILES = \
videos/animations-fading-fade-out.ogv \
$(NULL)
]]>
</programlisting>
</informalexample>
<para>This ensures it gets included in the distribution and
installation.</para>
</listitem>
<listitem>
<para>Use an &lt;inlinemediaobject&gt; to include it in the
Docbook recipe file. It should look something like this:</para>
<informalexample>
<programlisting>
<![CDATA[
<inlinemediaobject>
<videoobject>
<videodata fileref="videos/animations-fading-in-then-out.ogv"/>
</videoobject>
<alt>
<para>Video showing an actor fading in then out using
<type>ClutterState</type></para>
</alt>
</inlinemediaobject>
]]>
</programlisting>
</informalexample>
<para>The &lt;alt&gt; tag provides the text which
is presented as a link to the file for users whose browser
doesn't support HTML 5 embedded video.</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>To include a full code sample in a recipe (which can
be compiled into a runnable binary), do the following:</para>
<itemizedlist>
<listitem>
<para>Create a C code file in the
<filename>&lt;clutter source&gt;/doc/cookbook/examples</filename>
directory. It should be a standalone C application (with
a <function>main()</function> etc.). The filename should be
in the format
<filename>&lt;section&gt;-&lt;recipe&gt;.c</filename>; you
can add an optional identifier to the end if you have more
than one example for a recipe.</para>
<para>If you want to load image files into the application
(e.g. to demonstrate something with a texture), you can use
the <constant>TESTS_DATA_DIR</constant> variable in your C
code to reuse images in the Clutter <filename>tests</filename>
directory; this will be replaced with
<filename>&lt;clutter source&gt;/tests/data</filename>
during the build. For example:</para>
<informalexample>
<programlisting>
<![CDATA[
clutter_texture_set_from_file (CLUTTER_TEXTURE (texture),
TESTS_DATA_DIR "/redhand.png",
&error);
]]>
</programlisting>
</informalexample>
</listitem>
<listitem>
<para>Edit <filename>Makefile.am</filename>
in the <filename>cookbook/examples</filename> directory
so that the build recognises the new code; e.g. if
your C source file were called
<filename>fooing-barring.c</filename> you would do:</para>
<informalexample>
<programlisting>
<![CDATA[
noinst_PROGRAMS = \
textures-reflection \
text-shadow \
animations-rotating \
fooing-barring \
$(NULL)
fooing_barring_SOURCE = fooing-barring.c
]]>
</programlisting>
</informalexample>
<note>
<para>Note the second line is a new one to tell the
build where the source file is for your example.</para>
</note>
</listitem>
<listitem>
<para>Add a section at the end of your recipe which
XIncludes the sample code, e.g.:</para>
<informalexample>
<programlisting>
<![CDATA[
<section>
<title>Full example</title>
<example id="fooing-barring-example">
<title>Fooing with a bar</title>
<programlisting>
<xi:include href="examples/fooing-barring.c" parse="text">
<xi:fallback>a code sample should be here... but isn't</xi:fallback>
</xi:include>
</programlisting>
</example>
</section>
]]>
</programlisting>
</informalexample>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
</appendix>
</book>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,140 +0,0 @@
NULL =
EXTRA_DIST =
noinst_PROGRAMS =
examples_DATA =
examplesdir = $(datadir)/clutter-1.0/cookbook/examples
all_examples = \
actors-composite-main \
animations-complex \
animations-looping-animator \
animations-looping-implicit \
animations-looping-state \
animations-moving-animator \
animations-moving-implicit \
animations-moving-state \
animations-path \
animations-path-circle \
animations-path-easing \
animations-reuse \
animations-rotating \
animations-scaling \
animations-scaling-zoom \
effects-basic \
effects-built-in \
effects-custom-deform \
text-shadow \
textures-reflection \
textures-split-go \
textures-sub-texture \
layouts-bind-constraint-allocation \
layouts-bind-constraint-overlay \
layouts-bind-constraint-stage \
layouts-box \
layouts-box-menu \
layouts-box-property-effects \
layouts-stacking \
layouts-stacking-diff-sized-actors \
events-mouse-scroll \
events-pointer-motion \
events-pointer-motion-crossing \
events-pointer-motion-stacked \
events-pointer-motion-scribbler \
textures-crossfade \
textures-crossfade-cogl \
textures-crossfade-slideshow \
script-ui \
script-signals \
script-states \
events-buttons \
events-buttons-click \
events-buttons-lasso \
$(NULL)
LDADD = $(top_builddir)/clutter/libclutter-@CLUTTER_API_VERSION@.la $(LIBM)
AM_CFLAGS = $(CLUTTER_CFLAGS)
AM_CPPFLAGS = \
-I$(top_srcdir)/ \
-I$(top_builddir)/ \
-I$(top_srcdir)/clutter \
-I$(top_builddir)/clutter \
-DG_DISABLE_SINGLE_INCLUDES \
-DCOGL_DISABLE_DEPRECATION_WARNINGS \
-DCLUTTER_DISABLE_DEPRECATION_WARNINGS \
$(NULL)
AM_LDFLAGS = $(CLUTTER_LIBS) -export-dynamic
actors_composite_main_SOURCES = cb-button.c cb-button.h actors-composite-main.c
animations_complex_SOURCES = animations-complex.c
animations_looping_animator_SOURCES = animations-looping-animator.c
animations_looping_implicit_SOURCES = animations-looping-implicit.c
animations_looping_state_SOURCES = animations-looping-state.c
animations_moving_animator_SOURCES = animations-moving-animator.c
animations_moving_implicit_SOURCES = animations-moving-implicit.c
animations_moving_state_SOURCES = animations-moving-state.c
animations_path_SOURCES = animations-path.c
animations_path_circle_SOURCES = animations-path-circle.c
animations_path_easing_SOURCES = animations-path-easing.c
animations_reuse_SOURCES = animations-reuse.c
animations_rotating_SOURCES = animations-rotating.c
animations_scaling_SOURCES = animations-scaling.c
animations_scaling_zoom_SOURCES = animations-scaling-zoom.c
effects_basic_SOURCES = cb-border-effect.c \
cb-border-effect.h \
cb-background-effect.c \
cb-background-effect.h \
effects-basic.c
effects_built_in_SOURCES = effects-built-in.c
effects_custom_deform_SOURCES = cb-page-fold-effect.c cb-page-fold-effect.h effects-custom-deform.c
text_shadow_SOURCES = text-shadow.c
textures_reflection_SOURCES = textures-reflection.c
textures_split_go_SOURCES = textures-split-go.c
textures_sub_texture_SOURCES = textures-sub-texture.c
layouts_bind_constraint_allocation_SOURCES = layouts-bind-constraint-allocation.c
layouts_bind_constraint_overlay_SOURCES = layouts-bind-constraint-overlay.c
layouts_bind_constraint_stage_SOURCES = layouts-bind-constraint-stage.c
layouts_box_SOURCES = layouts-box.c
layouts_box_menu_SOURCES = layouts-box-menu.c
layouts_box_property_effects_SOURCES = layouts-box-property-effects.c
layouts_stacking_SOURCES = layouts-stacking.c
layouts_stacking_diff_sized_actors_SOURCES = layouts-stacking-diff-sized-actors.c
events_mouse_scroll_SOURCES = events-mouse-scroll.c
events_pointer_motion_SOURCES = events-pointer-motion.c
events_pointer_motion_crossing_SOURCES = events-pointer-motion-crossing.c
events_pointer_motion_stacked_SOURCES = events-pointer-motion-stacked.c
events_pointer_motion_scribbler_SOURCES = events-pointer-motion-scribbler.c
textures_crossfade_SOURCES = textures-crossfade.c
textures_crossfade_cogl_SOURCES = textures-crossfade-cogl.c
textures_crossfade_slideshow_SOURCES = textures-crossfade-slideshow.c
script_ui_SOURCES = script-ui.c
script_signals_SOURCES = script-signals.c
script_states_SOURCES = script-states.c
events_buttons_SOURCES = events-buttons.c
events_buttons_click_SOURCES = events-buttons-click.c
events_buttons_lasso_SOURCES = events-buttons-lasso.c
ui_data = \
$(srcdir)/animations-complex.json \
$(srcdir)/animations-complex-overlapping.json \
$(srcdir)/animations-reuse-animation.json \
$(srcdir)/animations-reuse-ui.json \
$(srcdir)/script-signals.json \
$(srcdir)/script-states.json \
$(srcdir)/script-ui.json \
$(NULL)
img_data = \
$(srcdir)/redhand.png \
$(srcdir)/smiley.png \
$(NULL)
EXTRA_DIST += $(ui_data) $(img_data)
examples_DATA += $(ui_data) $(img_data) $(srcdir)/*.c $(srcdir)/*.h
noinst_PROGRAMS += $(all_examples)

View File

@ -1,80 +0,0 @@
#include <stdlib.h>
#include "cb-button.h"
/* colors */
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
static const ClutterColor white_color = { 0xff, 0xff, 0xff, 0xff };
static const ClutterColor yellow_color = { 0x88, 0x88, 0x00, 0xff };
/* click handler */
static void
clicked (CbButton *button,
gpointer data)
{
const gchar *current_text;
g_debug ("Clicked");
current_text = cb_button_get_text (button);
if (g_strcmp0 (current_text, "hello") == 0)
cb_button_set_text (button, "world");
else
cb_button_set_text (button, "hello");
}
int
main (int argc,
char *argv[])
{
ClutterActor *stage;
ClutterActor *button;
ClutterConstraint *align_x_constraint;
ClutterConstraint *align_y_constraint;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, 400, 400);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
button = cb_button_new ();
cb_button_set_text (CB_BUTTON (button), "hello");
/* the following is equivalent to the two lines above:
*
* button = g_object_new (CB_TYPE_BUTTON,
* "text", "winkle",
* NULL);
*
* because we defined a set_property function, which can accept
* a PROP_TEXT parameter, GObject can create a button and set one
* or more properties with a single call to g_object_new()
*/
/* note that the size of the button is left to Clutter's size requisition */
cb_button_set_text_color (CB_BUTTON (button), &white_color);
cb_button_set_background_color (CB_BUTTON (button), &yellow_color);
g_signal_connect (button, "clicked", G_CALLBACK (clicked), NULL);
align_x_constraint = clutter_align_constraint_new (stage,
CLUTTER_ALIGN_X_AXIS,
0.5);
align_y_constraint = clutter_align_constraint_new (stage,
CLUTTER_ALIGN_Y_AXIS,
0.5);
clutter_actor_add_constraint (button, align_x_constraint);
clutter_actor_add_constraint (button, align_y_constraint);
clutter_actor_add_child (stage, button);
clutter_actor_show (stage);
clutter_main ();
return EXIT_SUCCESS;
}

View File

@ -1,80 +0,0 @@
[
{
"type" : "ClutterStage",
"id" : "stage",
"width" : 550,
"height" : 350,
"color" : "#333355ff",
"signals" : [
{ "name" : "destroy", "handler" : "clutter_main_quit" },
{ "name" : "key-press-event", "handler" : "foo_key_pressed_cb" }
],
"children" : [
{
"type" : "ClutterRectangle",
"id" : "rectangle",
"color" : "red",
"width" : 50,
"height" : 50,
"x" : 0,
"y" : 0,
"scale-gravity" : "center"
}
]
},
{
"type" : "ClutterAnimator",
"id" : "animator",
"duration" : 4000,
"properties" : [
{
"object" : "rectangle",
"name" : "x",
"ease-in" : true,
"keys" : [
[ 0.0, "linear", 0.0 ],
[ 0.1, "easeInCubic", 50.0 ],
[ 0.2, "easeInCubic", 200.0 ],
[ 0.4, "easeInCubic", 75.0 ],
[ 0.5, "easeOutCubic", 300.0 ],
[ 1.0, "easeInCubic", 400.0 ]
]
},
{
"object" : "rectangle",
"name" : "y",
"ease-in" : true,
"keys" : [
[ 0.0, "linear", 0.0 ],
[ 0.1, "easeInCubic", 50.0 ],
[ 0.2, "easeInCubic", 200.0 ],
[ 0.4, "easeInCubic", 75.0 ],
[ 0.5, "easeOutCubic", 150.0 ],
[ 1.0, "easeInCubic", 200.0 ]
]
},
{
"object" : "rectangle",
"name" : "scale-x",
"ease-in" : true,
"keys" : [
[ 0.0, "linear", 1.0 ],
[ 1.0, "linear", 4.0 ]
]
},
{
"object" : "rectangle",
"name" : "scale-y",
"ease-in" : true,
"keys" : [
[ 0.0, "linear", 1.0 ],
[ 1.0, "linear", 4.0 ]
]
}
]
}
]

View File

@ -1,70 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
#define UI_FILE "animations-complex.json"
/*
* start the animation when a key is pressed;
* see the signals recipe in the Script chapter for more details
*/
gboolean
foo_key_pressed_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
ClutterScript *script = CLUTTER_SCRIPT (user_data);
ClutterAnimator *animator;
clutter_script_get_objects (script,
"animator", &animator,
NULL);
if (clutter_timeline_is_playing (clutter_animator_get_timeline (animator)))
return FALSE;
clutter_animator_start (animator);
return TRUE;
}
int
main (int argc, char *argv[])
{
gchar *filename = UI_FILE;
ClutterScript *script;
ClutterActor *stage;
GError *error = NULL;
if (argc > 1)
filename = argv[1];
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
script = clutter_script_new ();
clutter_script_load_from_file (script, filename, &error);
if (error != NULL)
{
g_critical ("Error loading ClutterScript file %s\n%s", filename, error->message);
g_error_free (error);
exit (EXIT_FAILURE);
}
/* connect signal handlers as defined in the script */
clutter_script_connect_signals (script, script);
clutter_script_get_objects (script,
"stage", &stage,
NULL);
clutter_actor_show (stage);
clutter_main ();
g_object_unref (script);
return EXIT_SUCCESS;
}

View File

@ -1,80 +0,0 @@
[
{
"type" : "ClutterStage",
"id" : "stage",
"width" : 400,
"height" : 400,
"color" : "#333355ff",
"signals" : [
{ "name" : "destroy", "handler" : "clutter_main_quit" },
{ "name" : "key-press-event", "handler" : "foo_key_pressed_cb" }
],
"children" : [
{
"type" : "ClutterRectangle",
"id" : "rectangle",
"color" : "red",
"width" : 100,
"height" : 100,
"x" : 0,
"y" : 0,
"scale-gravity" : "center"
}
]
},
{
"type" : "ClutterAnimator",
"id" : "animator",
"duration" : 3000,
"properties" : [
{
"object" : "rectangle",
"name" : "x",
"ease-in" : true,
"keys" : [
[ 0.0, "linear", 0.0 ],
[ 0.1, "easeInCubic", 150.0 ],
[ 0.8, "linear", 150.0 ],
[ 1.0, "easeInCubic", 0.0 ]
]
},
{
"object" : "rectangle",
"name" : "y",
"ease-in" : true,
"keys" : [
[ 0.0, "linear", 0.0 ],
[ 0.1, "easeInCubic", 150.0 ],
[ 0.8, "linear", 150.0 ],
[ 1.0, "easeInCubic", 300.0 ]
]
},
{
"object" : "rectangle",
"name" : "scale-x",
"ease-in" : true,
"keys" : [
[ 0.1, "linear", 1.0 ],
[ 0.3, "easeOutBounce", 2.0 ],
[ 0.8, "linear", 2.0 ],
[ 1.0, "linear", 1.0 ]
]
},
{
"object" : "rectangle",
"name" : "scale-y",
"ease-in" : true,
"keys" : [
[ 0.1, "linear", 1.0 ],
[ 0.3, "easeOutBounce", 2.0 ],
[ 0.8, "linear", 2.0 ],
[ 1.0, "linear", 1.0 ]
]
}
]
}
]

View File

@ -1,67 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
static const ClutterColor red_color = { 0xff, 0x00, 0x00, 0xff };
static gboolean
key_pressed_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
ClutterTimeline *timeline = CLUTTER_TIMELINE (user_data);
if (!clutter_timeline_is_playing (timeline))
clutter_timeline_start (timeline);
return TRUE;
}
int
main (int argc,
char *argv[])
{
ClutterActor *stage;
ClutterActor *actor;
ClutterTimeline *timeline;
ClutterAnimator *animator;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, 300, 200);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
actor = clutter_rectangle_new_with_color (&red_color);
clutter_actor_set_size (actor, 100, 100);
clutter_actor_set_position (actor, 150, 50);
timeline = clutter_timeline_new (2000);
clutter_timeline_set_repeat_count (timeline, -1);
animator = clutter_animator_new ();
clutter_animator_set_timeline (animator, timeline);
clutter_animator_set (animator,
actor, "x", CLUTTER_LINEAR, 0.0, 150.0,
actor, "x", CLUTTER_LINEAR, 0.5, 50.0,
actor, "x", CLUTTER_LINEAR, 1.0, 150.0,
NULL);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor);
g_signal_connect (stage,
"key-press-event",
G_CALLBACK (key_pressed_cb),
timeline);
clutter_actor_show (stage);
clutter_main ();
g_object_unref (animator);
return EXIT_SUCCESS;
}

View File

@ -1,70 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
static const ClutterColor red_color = { 0xff, 0x00, 0x00, 0xff };
typedef struct
{
ClutterActor *actor;
ClutterTimeline *timeline;
} State;
static gboolean
key_pressed_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
State *state = (State *) user_data;
/* only start animating if actor isn't animating already */
if (clutter_actor_get_animation (state->actor) == NULL)
clutter_actor_animate_with_timeline (state->actor,
CLUTTER_LINEAR,
state->timeline,
"x", 50.0,
NULL);
return TRUE;
}
int
main (int argc,
char *argv[])
{
State *state = g_new0 (State, 1);
ClutterActor *stage;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, 300, 200);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
state->actor = clutter_rectangle_new_with_color (&red_color);
clutter_actor_set_size (state->actor, 100, 100);
clutter_actor_set_position (state->actor, 150, 50);
state->timeline = clutter_timeline_new (1000);
clutter_timeline_set_repeat_count (state->timeline, -1);
clutter_timeline_set_auto_reverse (state->timeline, TRUE);
g_signal_connect (stage,
"key-press-event",
G_CALLBACK (key_pressed_cb),
state);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), state->actor);
clutter_actor_show (stage);
clutter_main ();
g_object_unref (state->timeline);
g_free (state);
return EXIT_SUCCESS;
}

View File

@ -1,84 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
static const ClutterColor red_color = { 0xff, 0x00, 0x00, 0xff };
static void
next_state (ClutterState *transitions,
gpointer user_data)
{
const gchar *state = clutter_state_get_state (transitions);
if (g_strcmp0 (state, "right") == 0)
clutter_state_set_state (transitions, "left");
else
clutter_state_set_state (transitions, "right");
}
static gboolean
key_pressed_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
ClutterState *transitions = CLUTTER_STATE (user_data);
if (!clutter_timeline_is_playing (clutter_state_get_timeline (transitions)))
next_state (transitions, NULL);
return TRUE;
}
int
main (int argc,
char *argv[])
{
ClutterActor *stage;
ClutterActor *actor;
ClutterState *transitions;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, 300, 200);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
actor = clutter_rectangle_new_with_color (&red_color);
clutter_actor_set_position (actor, 150, 50);
clutter_actor_set_size (actor, 100, 100);
transitions = clutter_state_new ();
clutter_state_set_duration (transitions, NULL, NULL, 1000);
clutter_state_set (transitions, NULL, "right",
actor, "x", CLUTTER_LINEAR, 150.0,
NULL);
clutter_state_set (transitions, NULL, "left",
actor, "x", CLUTTER_LINEAR, 50.0,
NULL);
clutter_state_warp_to_state (transitions, "right");
g_signal_connect (stage,
"key-press-event",
G_CALLBACK (key_pressed_cb),
transitions);
g_signal_connect (transitions,
"completed",
G_CALLBACK (next_state),
NULL);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor);
clutter_actor_show (stage);
clutter_main ();
g_object_unref (transitions);
return EXIT_SUCCESS;
}

View File

@ -1,127 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
typedef struct
{
ClutterActor *stage;
ClutterActor *group;
ClutterAnimator *animator;
} State;
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
static const ClutterColor red_color = { 0xff, 0x00, 0x00, 0xff };
static const ClutterColor green_color = { 0x00, 0xff, 0x00, 0xff };
static const ClutterColor blue_color = { 0x00, 0x00, 0xff, 0xff };
/* add keys to the animator such that the actor is moved
* to a random x position
*/
static void
add_keys_for_actor (ClutterActor *actor,
ClutterAnimator *animator)
{
gfloat x, end_x;
x = clutter_actor_get_x (actor);
end_x = 50.0;
if (x == 50.0)
end_x = 225.0 + (100.0 * rand () / (RAND_MAX + 1.0));
clutter_animator_set (animator,
actor, "x", CLUTTER_LINEAR, 0.0, x,
actor, "x", CLUTTER_EASE_OUT_CUBIC, 1.0, end_x,
NULL);
}
static gboolean
move_actors (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
State *state = user_data;
ClutterActor *child;
/* do nothing if the animator is already running */
if (clutter_timeline_is_playing (clutter_animator_get_timeline (state->animator)))
return TRUE;
/* remove all keys from the animator */
clutter_animator_remove_key (state->animator, NULL, NULL, -1);
/* add keys for all actors in the group */
for (child = clutter_actor_get_first_child (state->group);
child != NULL;
child = clutter_actor_get_next_sibling (child))
{
add_keys_for_actor (child, state->animator);
}
/* start the animation */
clutter_animator_start (state->animator);
return TRUE;
}
int
main (int argc,
char *argv[])
{
ClutterActor *red;
ClutterActor *green;
ClutterActor *blue;
State *state = g_new0 (State, 1);
/* seed random number generator */
srand ((unsigned int) time (NULL));
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
state->animator = clutter_animator_new ();
clutter_animator_set_duration (state->animator, 500);
state->stage = clutter_stage_new ();
clutter_actor_set_size (state->stage, 400, 350);
clutter_stage_set_color (CLUTTER_STAGE (state->stage), &stage_color);
g_signal_connect (state->stage,
"destroy",
G_CALLBACK (clutter_main_quit),
NULL);
state->group = clutter_actor_new ();
clutter_actor_add_child (state->stage, state->group);
red = clutter_actor_new ();
clutter_actor_set_background_color (red, &red_color);
clutter_actor_set_size (red, 50, 50);
clutter_actor_set_position (red, 50, 50);
clutter_actor_add_child (state->group, red);
green = clutter_actor_new ();
clutter_actor_set_background_color (green, &green_color);
clutter_actor_set_size (green, 50, 50);
clutter_actor_set_position (green, 50, 150);
clutter_actor_add_child (state->group, green);
blue = clutter_actor_new ();
clutter_actor_set_background_color (blue, &blue_color);
clutter_actor_set_size (blue, 50, 50);
clutter_actor_set_position (blue, 50, 250);
clutter_actor_add_child (state->group, blue);
g_signal_connect (state->stage,
"key-press-event",
G_CALLBACK (move_actors),
state);
clutter_actor_show (state->stage);
clutter_main ();
g_object_unref (state->animator);
g_free (state);
return EXIT_SUCCESS;
}

View File

@ -1,96 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
typedef struct
{
gchar *axis;
gfloat target;
} AnimationSpec;
static gboolean
button_pressed_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
AnimationSpec *animation_spec = user_data;
ClutterTransition *transition;
if (clutter_actor_get_transition (actor, animation_spec->axis) != NULL)
return TRUE;
clutter_actor_save_easing_state (actor);
clutter_actor_set_easing_duration (actor, 500);
g_object_set (actor, animation_spec->axis, animation_spec->target, NULL);
transition = clutter_actor_get_transition (actor, animation_spec->axis);
clutter_timeline_set_auto_reverse (CLUTTER_TIMELINE (transition), TRUE);
clutter_timeline_set_repeat_count (CLUTTER_TIMELINE (transition), 1);
clutter_actor_restore_easing_state (actor);
return TRUE;
}
int
main (int argc,
char *argv[])
{
ClutterActor *stage;
ClutterActor *rectangle1;
ClutterActor *rectangle2;
ClutterActor *rectangle3;
AnimationSpec x_move = { "x", 50.0 };
AnimationSpec y_move = { "y", 400.0 };
AnimationSpec z_move = { "depth", -1000.0 };
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, 500, 500);
clutter_stage_set_color (CLUTTER_STAGE (stage), CLUTTER_COLOR_Aluminium2);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
rectangle1 = clutter_actor_new ();
clutter_actor_set_background_color (rectangle1, CLUTTER_COLOR_ScarletRed);
clutter_actor_set_reactive (rectangle1, TRUE);
clutter_actor_set_size (rectangle1, 50, 50);
clutter_actor_set_position (rectangle1, 400, 400);
clutter_actor_add_child (stage, rectangle1);
rectangle2 = clutter_actor_new ();
clutter_actor_set_background_color (rectangle2, CLUTTER_COLOR_Chameleon);
clutter_actor_set_reactive (rectangle2, TRUE);
clutter_actor_set_size (rectangle2, 50, 50);
clutter_actor_set_position (rectangle2, 50, 50);
clutter_actor_add_child (stage, rectangle2);
rectangle3 = clutter_actor_new ();
clutter_actor_set_background_color (rectangle3, CLUTTER_COLOR_SkyBlue);
clutter_actor_set_reactive (rectangle3, TRUE);
clutter_actor_set_size (rectangle3, 50, 50);
clutter_actor_set_position (rectangle3, 225, 225);
clutter_actor_add_child (stage, rectangle3);
g_signal_connect (rectangle1,
"button-press-event",
G_CALLBACK (button_pressed_cb),
&x_move);
g_signal_connect (rectangle2,
"button-press-event",
G_CALLBACK (button_pressed_cb),
&y_move);
g_signal_connect (rectangle3,
"button-press-event",
G_CALLBACK (button_pressed_cb),
&z_move);
clutter_actor_show (stage);
clutter_main ();
return EXIT_SUCCESS;
}

View File

@ -1,99 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
static const ClutterColor red_color = { 0xff, 0x00, 0x00, 0xff };
static const ClutterColor green_color = { 0x00, 0xff, 0x00, 0xff };
static gboolean
button_pressed_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
ClutterState *transitions = CLUTTER_STATE (user_data);
/* set the state to the one with a name matching the actor's name */
clutter_state_set_state (transitions, clutter_actor_get_name (actor));
return TRUE;
}
int
main (int argc,
char *argv[])
{
ClutterActor *stage;
ClutterActor *red;
ClutterActor *green;
ClutterState *transitions;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, 650, 500);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
/* actor names choose the next ClutterState to transition to */
red = clutter_rectangle_new_with_color (&red_color);
clutter_actor_set_reactive (red, TRUE);
clutter_actor_set_name (red, "red");
clutter_actor_set_size (red, 100, 100);
clutter_actor_set_position (red, 50, 50);
green = clutter_rectangle_new_with_color (&green_color);
clutter_actor_set_reactive (green, TRUE);
clutter_actor_set_name (green, "green");
clutter_actor_set_size (green, 100, 100);
clutter_actor_set_position (green, 50, 350);
transitions = clutter_state_new ();
clutter_state_set_duration (transitions, NULL, NULL, 250);
/* state names match actor names */
clutter_state_set (transitions, NULL, "red",
red, "x", CLUTTER_EASE_OUT_CUBIC, 200.0,
red, "y", CLUTTER_EASE_OUT_CUBIC, 50.0,
red, "scale-x", CLUTTER_EASE_OUT_CUBIC, 4.0,
red, "scale-y", CLUTTER_EASE_OUT_CUBIC, 4.0,
green, "x", CLUTTER_EASE_OUT_CUBIC, 50.0,
green, "y", CLUTTER_EASE_OUT_CUBIC, 350.0,
green, "scale-x", CLUTTER_EASE_OUT_CUBIC, 1.0,
green, "scale-y", CLUTTER_EASE_OUT_CUBIC, 1.0,
NULL);
clutter_state_set (transitions, NULL, "green",
green, "x", CLUTTER_EASE_OUT_CUBIC, 200.0,
green, "y", CLUTTER_EASE_OUT_CUBIC, 50.0,
green, "scale-x", CLUTTER_EASE_OUT_CUBIC, 4.0,
green, "scale-y", CLUTTER_EASE_OUT_CUBIC, 4.0,
red, "x", CLUTTER_EASE_OUT_CUBIC, 50.0,
red, "y", CLUTTER_EASE_OUT_CUBIC, 50.0,
red, "scale-x", CLUTTER_EASE_OUT_CUBIC, 1.0,
red, "scale-y", CLUTTER_EASE_OUT_CUBIC, 1.0,
NULL);
g_signal_connect (red,
"button-press-event",
G_CALLBACK (button_pressed_cb),
transitions);
g_signal_connect (green,
"button-press-event",
G_CALLBACK (button_pressed_cb),
transitions);
clutter_container_add (CLUTTER_CONTAINER (stage),
red,
green,
NULL);
clutter_actor_show (stage);
clutter_main ();
g_object_unref (transitions);
return EXIT_SUCCESS;
}

View File

@ -1,129 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
#define STAGE_SIDE 400.0
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
static const ClutterColor red_color = { 0xff, 0x00, 0x00, 0xff };
/* Build a "circular" path out of 4 Bezier curves
*
* code modified from
* http://git.clutter-project.org/dax/tree/dax/dax-traverser-clutter.c#n328
*
* see http://www.whizkidtech.redprince.net/bezier/circle/
* for further explanation
*/
static ClutterPath *
build_circular_path (gfloat cx,
gfloat cy,
gfloat r)
{
ClutterPath *path;
static gfloat kappa = 4 * (G_SQRT2 - 1) / 3;
path = clutter_path_new ();
clutter_path_add_move_to (path, cx + r, cy);
clutter_path_add_curve_to (path,
cx + r, cy + r * kappa,
cx + r * kappa, cy + r,
cx, cy + r);
clutter_path_add_curve_to (path,
cx - r * kappa, cy + r,
cx - r, cy + r * kappa,
cx - r, cy);
clutter_path_add_curve_to (path,
cx - r, cy - r * kappa,
cx - r * kappa, cy - r,
cx, cy - r);
clutter_path_add_curve_to (path,
cx + r * kappa, cy - r,
cx + r, cy - r * kappa,
cx + r, cy);
clutter_path_add_close (path);
return path;
}
static gboolean
key_pressed_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
ClutterTimeline *timeline = CLUTTER_TIMELINE (user_data);
if (!clutter_timeline_is_playing (timeline))
clutter_timeline_start (timeline);
return TRUE;
}
int
main (int argc,
char *argv[])
{
ClutterPath *path;
ClutterConstraint *constraint;
ClutterAnimator *animator;
ClutterTimeline *timeline;
ClutterActor *stage;
ClutterActor *rectangle;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, STAGE_SIDE, STAGE_SIDE);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
rectangle = clutter_rectangle_new_with_color (&red_color);
clutter_actor_set_size (rectangle, STAGE_SIDE / 8, STAGE_SIDE / 8);
clutter_actor_set_position (rectangle,
STAGE_SIDE / 2,
STAGE_SIDE / 2);
clutter_container_add_actor (CLUTTER_CONTAINER (stage),
rectangle);
/* set up a path and make a constraint with it */
path = build_circular_path (STAGE_SIDE / 2,
STAGE_SIDE / 2,
STAGE_SIDE / 4);
constraint = clutter_path_constraint_new (path, 0.0);
/* apply the constraint to the rectangle; note that there
* is no need to name the constraint, as we will be animating
* the constraint's offset property directly using ClutterAnimator
*/
clutter_actor_add_constraint (rectangle, constraint);
/* animation to animate the path offset */
animator = clutter_animator_new ();
clutter_animator_set_duration (animator, 5000);
/* use ClutterAnimator to animate the constraint directly */
clutter_animator_set (animator,
constraint, "offset", CLUTTER_LINEAR, 0.0, 0.0,
constraint, "offset", CLUTTER_LINEAR, 1.0, 1.0,
NULL);
timeline = clutter_animator_get_timeline (animator);
clutter_timeline_set_repeat_count (timeline, -1);
clutter_timeline_set_auto_reverse (timeline, TRUE);
g_signal_connect (stage,
"key-press-event",
G_CALLBACK (key_pressed_cb),
timeline);
clutter_actor_show (stage);
clutter_main ();
/* clean up */
g_object_unref (animator);
return EXIT_SUCCESS;
}

View File

@ -1,105 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
typedef struct {
ClutterActor *red;
ClutterActor *green;
ClutterTimeline *timeline;
} State;
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
static const ClutterColor red_color = { 0xff, 0x00, 0x00, 0xff };
static const ClutterColor green_color = { 0x00, 0xff, 0x00, 0xff };
static void
reverse_timeline (ClutterTimeline *timeline)
{
ClutterTimelineDirection dir = clutter_timeline_get_direction (timeline);
if (dir == CLUTTER_TIMELINE_FORWARD)
dir = CLUTTER_TIMELINE_BACKWARD;
else
dir = CLUTTER_TIMELINE_FORWARD;
clutter_timeline_set_direction (timeline, dir);
}
/* a key press either starts the timeline or reverses it */
static gboolean
key_pressed_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
State *state = (State *) user_data;
if (clutter_timeline_is_playing (state->timeline))
reverse_timeline (state->timeline);
else
clutter_timeline_start (state->timeline);
return TRUE;
}
int
main (int argc,
char *argv[])
{
State *state = g_new0 (State, 1);
ClutterActor *stage;
ClutterAnimator *animator;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, 400, 400);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
state->red = clutter_rectangle_new_with_color (&red_color);
clutter_actor_set_size (state->red, 100, 100);
clutter_actor_set_position (state->red, 300, 300);
state->green = clutter_rectangle_new_with_color (&green_color);
clutter_actor_set_size (state->green, 100, 100);
clutter_actor_set_position (state->green, 0, 0);
animator = clutter_animator_new ();
clutter_animator_set_duration (animator, 1000);
clutter_animator_set (animator,
state->red, "x", CLUTTER_LINEAR, 0.0, 300.0,
state->red, "y", CLUTTER_LINEAR, 0.0, 300.0,
state->red, "x", CLUTTER_LINEAR, 1.0, 0.0,
state->red, "y", CLUTTER_EASE_IN_QUINT, 1.0, 0.0,
NULL);
clutter_animator_set (animator,
state->green, "x", CLUTTER_LINEAR, 0.0, 0.0,
state->green, "y", CLUTTER_LINEAR, 0.0, 0.0,
state->green, "x", CLUTTER_LINEAR, 1.0, 300.0,
state->green, "y", CLUTTER_EASE_IN_QUINT, 1.0, 300.0,
NULL);
state->timeline = clutter_animator_get_timeline (animator);
clutter_timeline_set_auto_reverse (state->timeline, TRUE);
g_signal_connect (stage,
"key-press-event",
G_CALLBACK (key_pressed_cb),
state);
clutter_container_add (CLUTTER_CONTAINER (stage), state->red, state->green, NULL);
clutter_actor_show (stage);
clutter_main ();
g_object_unref (animator);
g_free (state);
return EXIT_SUCCESS;
}

View File

@ -1,62 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
int
main (int argc,
char *argv[])
{
ClutterActor *stage;
ClutterPath *path;
ClutterConstraint *constraint;
ClutterActor *rectangle;
ClutterTimeline *timeline;
const ClutterColor *stage_color = clutter_color_new (51, 51, 85, 255);
const ClutterColor *red_color = clutter_color_new (255, 0, 0, 255);
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, 360, 300);
clutter_stage_set_color (CLUTTER_STAGE (stage), stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
/* create the path */
path = clutter_path_new ();
clutter_path_add_move_to (path, 30, 60);
/* add a curve round to the top-right of the stage */
clutter_path_add_rel_curve_to (path,
120, 180,
180, 120,
240, 0);
/* create a constraint based on the path */
constraint = clutter_path_constraint_new (path, 0.0);
/* put a rectangle at the start of the path */
rectangle = clutter_rectangle_new_with_color (red_color);
clutter_actor_set_size (rectangle, 60, 60);
/* add the constraint to the rectangle */
clutter_actor_add_constraint_with_name (rectangle, "path", constraint);
/* add the rectangle to the stage */
clutter_container_add_actor (CLUTTER_CONTAINER (stage), rectangle);
/* set up the timeline */
timeline = clutter_timeline_new (1000);
clutter_timeline_set_repeat_count (timeline, -1);
clutter_timeline_set_auto_reverse (timeline, TRUE);
clutter_actor_animate_with_timeline (rectangle, CLUTTER_LINEAR, timeline,
"@constraints.path.offset", 1.0,
NULL);
clutter_actor_show (stage);
clutter_main ();
return EXIT_SUCCESS;
}

View File

@ -1,42 +0,0 @@
[
{
"type" : "ClutterGroup",
"id" : "rig"
},
{
"type" : "ClutterAnimator",
"id" : "animator",
"duration" : 2000,
"properties" : [
{
"object" : "rig",
"name" : "x",
"ease-in" : true,
"keys" : [
[ 0.0, "linear", 0.0 ],
[ 1.0, "easeOutCubic", 150.0 ]
]
},
{
"object" : "rig",
"name" : "scale-x",
"ease-in" : true,
"keys" : [
[ 0.5, "linear", 1.0 ],
[ 1.0, "easeOutBack", 2.0 ]
]
},
{
"object" : "rig",
"name" : "scale-y",
"ease-in" : true,
"keys" : [
[ 0.5, "linear", 1.0 ],
[ 1.0, "easeOutBack", 2.0 ]
]
}
]
}
]

View File

@ -1,80 +0,0 @@
[
{
"type" : "ClutterStage",
"id" : "stage",
"width" : 300,
"height" : 200,
"color" : "#333355ff",
"signals" : [
{ "name" : "destroy", "handler" : "clutter_main_quit" }
],
"children" : [
{
"type" : "ClutterRectangle",
"id" : "rect1",
"color" : "white",
"width" : 50,
"height" : 50,
"y" : 50,
"reactive" : true,
"signals" : [
{ "name" : "button-press-event", "handler" : "foo_button_pressed_cb" }
]
},
{
"type" : "ClutterRectangle",
"id" : "rect2",
"color" : "blue",
"width" : 50,
"height" : 50,
"y" : 50,
"reactive" : true,
"signals" : [
{ "name" : "button-press-event", "handler" : "foo_button_pressed_cb" }
]
},
{
"type" : "ClutterRectangle",
"id" : "rect3",
"color" : "green",
"width" : 50,
"height" : 50,
"y" : 50,
"reactive" : true,
"signals" : [
{ "name" : "button-press-event", "handler" : "foo_button_pressed_cb" }
]
},
{
"type" : "ClutterRectangle",
"id" : "rect4",
"color" : "red",
"width" : 50,
"height" : 50,
"y" : 50,
"reactive" : true,
"signals" : [
{ "name" : "button-press-event", "handler" : "foo_button_pressed_cb" }
]
},
{
"type" : "ClutterRectangle",
"id" : "rect5",
"color" : "grey",
"width" : 50,
"height" : 50,
"y" : 50,
"reactive" : true,
"signals" : [
{ "name" : "button-press-event", "handler" : "foo_button_pressed_cb" }
]
}
]
}
]

View File

@ -1,100 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
#define UI_FILE "animations-reuse-ui.json"
#define ANIMATION_FILE "animations-reuse-animation.json"
static gboolean
load_script_from_file (ClutterScript *script,
gchar *filename)
{
GError *error = NULL;
clutter_script_load_from_file (script, filename, &error);
if (error != NULL)
{
g_critical ("Error loading ClutterScript file %s\n%s", filename, error->message);
g_error_free (error);
exit (EXIT_FAILURE);
}
return TRUE;
}
gboolean
foo_button_pressed_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
ClutterScript *ui = CLUTTER_SCRIPT (user_data);
ClutterStage *stage = CLUTTER_STAGE (clutter_script_get_object (ui, "stage"));
ClutterScript *script;
ClutterActor *rig;
ClutterAnimator *animator;
/* load the rig and its animator from a JSON file */
script = clutter_script_new ();
/* use a function defined statically in this source file to load the JSON */
load_script_from_file (script, ANIMATION_FILE);
clutter_script_get_objects (script,
"rig", &rig,
"animator", &animator,
NULL);
/* remove the button press handler from the rectangle */
g_signal_handlers_disconnect_by_func (actor,
G_CALLBACK (foo_button_pressed_cb),
NULL);
/* add a callback to clean up the script when the rig is destroyed */
g_object_set_data_full (G_OBJECT (rig), "script", script, g_object_unref);
/* add the rig to the stage */
clutter_container_add_actor (CLUTTER_CONTAINER (stage), rig);
/* place the rig at the same coordinates on the stage as the rectangle */
clutter_actor_set_position (rig,
clutter_actor_get_x (actor),
clutter_actor_get_y (actor));
/* put the rectangle into the top-left corner of the rig */
clutter_actor_reparent (actor, rig);
clutter_actor_set_position (actor, 0, 0);
/* animate the rig */
clutter_animator_start (animator);
return TRUE;
}
int
main (int argc, char *argv[])
{
ClutterScript *script;
ClutterActor *stage;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
script = clutter_script_new ();
load_script_from_file (script, UI_FILE);
clutter_script_connect_signals (script, script);
clutter_script_get_objects (script,
"stage", &stage,
NULL);
clutter_actor_show (stage);
clutter_main ();
g_object_unref (script);
return EXIT_SUCCESS;
}

View File

@ -1,137 +0,0 @@
#include <clutter/clutter.h>
#define ROTATION_ANGLE 75.0
#define DURATION 2000
static void
_set_next_state (ClutterState *transitions,
gpointer user_data)
{
const gchar *current = clutter_state_get_state (transitions);
gchar *next_state = "start";
if (g_strcmp0 (current, "start") == 0)
next_state = "x-cw";
else if (g_strcmp0 (current, "x-cw") == 0)
next_state = "x-ccw";
else if (g_strcmp0 (current, "x-ccw") == 0)
next_state = "x-after";
else if (g_strcmp0 (current, "x-after") == 0)
next_state = "y-cw";
else if (g_strcmp0 (current, "y-cw") == 0)
next_state = "y-ccw";
else if (g_strcmp0 (current, "y-ccw") == 0)
next_state = "y-after";
else if (g_strcmp0 (current, "y-after") == 0)
next_state = "z-cw";
else if (g_strcmp0 (current, "z-cw") == 0)
next_state = "z-ccw";
clutter_state_set_state (transitions, next_state);
}
int
main (int argc, char *argv[])
{
ClutterActor *stage;
ClutterActor *texture;
ClutterState *transitions;
GError *error = NULL;
gfloat texture_width, texture_height;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
texture = clutter_texture_new ();
clutter_actor_add_constraint (texture,
clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5));
clutter_actor_add_constraint (texture,
clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.5));
clutter_texture_set_sync_size (CLUTTER_TEXTURE (texture), TRUE);
clutter_texture_set_from_file (CLUTTER_TEXTURE (texture),
"redhand.png",
&error);
if (error != NULL)
{
g_error ("Problem loading image into texture - %s", error->message);
g_error_free (error);
return 1;
}
clutter_actor_get_size (texture, &texture_width, &texture_height);
clutter_actor_set_size (stage, texture_width * 2, texture_height * 2);
/* set all centres of rotation to the centre of the texture */
clutter_actor_set_rotation (texture,
CLUTTER_X_AXIS,
0.0,
texture_width * 0.5,
texture_height * 0.5,
0.0);
clutter_actor_set_rotation (texture,
CLUTTER_Y_AXIS,
0.0,
texture_width * 0.5,
texture_height * 0.5,
0.0);
clutter_actor_set_z_rotation_from_gravity (texture, 0.0, CLUTTER_GRAVITY_CENTER);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), texture);
/* set up the animations */
transitions = clutter_state_new ();
clutter_state_set (transitions, NULL, "start",
texture, "rotation-angle-x", CLUTTER_LINEAR, 0.0,
texture, "rotation-angle-y", CLUTTER_LINEAR, 0.0,
texture, "rotation-angle-z", CLUTTER_LINEAR, 0.0,
NULL);
clutter_state_set (transitions, NULL, "x-cw",
texture, "rotation-angle-x", CLUTTER_LINEAR, ROTATION_ANGLE,
NULL);
clutter_state_set (transitions, NULL, "x-ccw",
texture, "rotation-angle-x", CLUTTER_LINEAR, -ROTATION_ANGLE,
NULL);
clutter_state_set (transitions, NULL, "x-after",
texture, "rotation-angle-x", CLUTTER_LINEAR, 0.0,
NULL);
clutter_state_set (transitions, NULL, "y-cw",
texture, "rotation-angle-y", CLUTTER_LINEAR, ROTATION_ANGLE,
NULL);
clutter_state_set (transitions, NULL, "y-ccw",
texture, "rotation-angle-y", CLUTTER_LINEAR, -ROTATION_ANGLE,
NULL);
clutter_state_set (transitions, NULL, "y-after",
texture, "rotation-angle-y", CLUTTER_LINEAR, 0.0,
NULL);
clutter_state_set (transitions, NULL, "z-cw",
texture, "rotation-angle-z", CLUTTER_LINEAR, ROTATION_ANGLE,
NULL);
clutter_state_set (transitions, NULL, "z-ccw",
texture, "rotation-angle-z", CLUTTER_LINEAR, -ROTATION_ANGLE,
NULL);
clutter_state_set_duration (transitions, NULL, NULL, DURATION);
clutter_state_set_duration (transitions, "start", NULL, DURATION * 0.5);
clutter_state_set_duration (transitions, NULL, "start", DURATION * 0.5);
clutter_state_set_duration (transitions, NULL, "x-after", DURATION * 0.5);
clutter_state_set_duration (transitions, NULL, "y-after", DURATION * 0.5);
clutter_state_warp_to_state (transitions, "start");
g_signal_connect (transitions,
"completed",
G_CALLBACK (_set_next_state),
NULL);
clutter_state_set_state (transitions, "x-cw");
clutter_actor_show (stage);
clutter_main ();
return 0;
}

View File

@ -1,156 +0,0 @@
/*
* Load an image into a texture, which can then be zoomed in/out
* (double click on button 1, double click on button 3 respectively);
* also resets the texture to the stage center when a key is pressed
* (better would be to prevent drags taking the actor off-stage,
* but the implementation is much more complicated)
*/
#include <stdlib.h>
#include <clutter/clutter.h>
#define STAGE_SIDE 400.0
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
/* on key press, center the actor on the stage;
* useful if you drag it off-stage accidentally
*/
static gboolean
key_press_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
gfloat width, height;
clutter_actor_get_size (actor, &width, &height);
clutter_actor_set_anchor_point (actor, width / 2, height / 2);
clutter_actor_set_position (actor,
STAGE_SIDE / 2,
STAGE_SIDE / 2);
return TRUE;
}
/* on double click, zoom in on the clicked point;
* also keeps scale in the range 0.1 to 20
*/
static gboolean
clicked_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
gdouble scale;
gfloat click_x, click_y;
gfloat click_target_x, click_target_y;
guint32 button;
/* don't do anything unless there was a double click */
if (clutter_event_get_click_count (event) < 2)
return TRUE;
/* work out new scale */
button = clutter_event_get_button (event);
clutter_actor_get_scale (actor, &scale, NULL);
if (button == CLUTTER_BUTTON_PRIMARY)
scale *= 1.2;
else if (button == CLUTTER_BUTTON_SECONDARY)
scale /= 1.2;
/* don't do anything if scale is outside bounds */
if (scale < 0.1 || scale > 20.0)
return TRUE;
/* get the location of the click on the scaled actor */
clutter_event_get_coords (event, &click_x, &click_y);
clutter_actor_transform_stage_point (actor,
click_x, click_y,
&click_target_x, &click_target_y);
/* anchor the actor on the clicked point on its surface */
clutter_actor_set_anchor_point (actor, click_target_x, click_target_y);
/* set the actor's position to the click coords: it won't move,
* because the anchor point is already there; but
* the scale will now be centered on these coords (as the
* scale center defaults to the anchor point); so the anchor point
* on the actor won't move from under the pointer
*/
clutter_actor_set_position (actor, click_x, click_y);
clutter_actor_animate (actor, CLUTTER_LINEAR, 500,
"scale-x", scale,
"scale-y", scale,
NULL);
return TRUE;
}
int
main (int argc,
char *argv[])
{
ClutterActor *stage;
ClutterActor *texture;
gchar *image_path;
GError *error = NULL;
if (argc < 2)
{
g_print ("Usage: %s <path to image file>\n", argv[0]);
exit (EXIT_FAILURE);
}
image_path = argv[1];
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, STAGE_SIDE, STAGE_SIDE);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
texture = clutter_texture_new ();
clutter_actor_set_reactive (texture, TRUE);
clutter_actor_set_width (texture, STAGE_SIDE);
clutter_texture_set_keep_aspect_ratio (CLUTTER_TEXTURE (texture), TRUE);
clutter_actor_add_action (texture, clutter_drag_action_new ());
g_object_set (G_OBJECT (texture),
"scale-gravity", CLUTTER_GRAVITY_NORTH_WEST,
NULL);
clutter_texture_set_from_file (CLUTTER_TEXTURE (texture), image_path, &error);
if (error != NULL)
{
g_warning ("Error loading %s\n%s", image_path, error->message);
g_error_free (error);
exit (EXIT_FAILURE);
}
clutter_actor_set_y (texture, (STAGE_SIDE - clutter_actor_get_height (texture)) * 0.5);
g_signal_connect (texture,
"button-release-event",
G_CALLBACK (clicked_cb),
NULL);
g_signal_connect_swapped (stage,
"key-press-event",
G_CALLBACK (key_press_cb),
texture);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), texture);
clutter_actor_show (stage);
clutter_main ();
return EXIT_SUCCESS;
}

View File

@ -1,184 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
typedef struct
{
ClutterState *transitions;
ClutterActor *actor;
ClutterActor *props_display;
guint scale_gravity;
gboolean transitions_running;
} State;
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
static const ClutterColor red_color = { 0xff, 0x00, 0x00, 0xff };
static const ClutterColor yellow_color = { 0xff, 0xff, 0x00, 0xff };
static void
show_scale_properties_cb (ClutterActor *actor,
gpointer user_data)
{
State *state = (State *) user_data;
gfloat transformed_x, transformed_y;
gfloat transformed_width, transformed_height;
gfloat scale_center_x, scale_center_y;
gchar *message;
clutter_actor_get_transformed_position (state->actor,
&transformed_x,
&transformed_y);
clutter_actor_get_transformed_size (state->actor,
&transformed_width,
&transformed_height);
g_object_get (G_OBJECT (actor),
"scale-center-x", &scale_center_x,
"scale-center-y", &scale_center_y,
NULL);
/* draw cross on the scale center */
cogl_set_source_color4ub (255, 255, 0, 255);
cogl_path_move_to (scale_center_x, scale_center_y);
cogl_path_rel_line_to (10, 10);
cogl_path_rel_line_to (-20, -20);
cogl_path_move_to (scale_center_x, scale_center_y);
cogl_path_rel_line_to (10, -10);
cogl_path_rel_line_to (-20, 20);
cogl_path_stroke ();
/* show actor properties */
message = g_strdup_printf ("Scale center: %.0f, %.0f\n"
"Transformed position: %.2f, %.2f\n"
"Transformed size: %.2f, %.2f",
scale_center_x, scale_center_y,
transformed_x, transformed_y,
transformed_width, transformed_height);
clutter_text_set_text (CLUTTER_TEXT (state->props_display), message);
g_free (message);
}
static void
next_transition_cb (ClutterState *transitions,
gpointer user_data)
{
State *state = (State *) user_data;
if (clutter_actor_is_scaled (state->actor))
clutter_state_set_state (state->transitions, "not-scaled");
else if (state->scale_gravity > 9)
{
/* gravity is at center, so reset ready for next key press */
state->scale_gravity = CLUTTER_GRAVITY_NORTH;
state->transitions_running = FALSE;
}
else
{
g_object_set (G_OBJECT (state->actor),
"scale-gravity", state->scale_gravity,
NULL);
state->scale_gravity++;
clutter_state_set_state (state->transitions, "scaled-down");
}
}
static gboolean
key_pressed_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
State *state = (State *) user_data;
if (!state->transitions_running)
{
state->transitions_running = TRUE;
next_transition_cb (NULL, state);
}
return TRUE;
}
int
main (int argc,
char *argv[])
{
State *state = g_new0 (State, 1);
ClutterActor *stage;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, 350, 350);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
state->scale_gravity = CLUTTER_GRAVITY_NORTH;
state->transitions_running = FALSE;
state->props_display = clutter_text_new ();
clutter_actor_set_size (state->props_display, 340, 80);
clutter_actor_set_position (state->props_display, 5, 280);
clutter_text_set_color (CLUTTER_TEXT (state->props_display), &yellow_color);
state->actor = clutter_rectangle_new_with_color (&red_color);
clutter_actor_set_size (state->actor, 200, 200);
clutter_actor_set_position (state->actor, 75, 50);
g_object_set (G_OBJECT (state->actor),
"scale-gravity", state->scale_gravity,
NULL);
state->transitions = clutter_state_new ();
clutter_state_set_duration (state->transitions, NULL, NULL, 400);
clutter_state_set (state->transitions, NULL, "not-scaled",
state->actor, "scale-x", CLUTTER_LINEAR, 1.0,
state->actor, "scale-y", CLUTTER_LINEAR, 1.0,
NULL);
clutter_state_set (state->transitions, NULL, "scaled-down",
state->actor, "scale-x", CLUTTER_LINEAR, 0.25,
state->actor, "scale-y", CLUTTER_LINEAR, 0.25,
NULL);
clutter_state_warp_to_state (state->transitions, "not-scaled");
g_signal_connect (stage,
"key-press-event",
G_CALLBACK (key_pressed_cb),
state);
g_signal_connect (state->transitions,
"completed",
G_CALLBACK (next_transition_cb),
state);
g_signal_connect_after (state->actor,
"paint",
G_CALLBACK (show_scale_properties_cb),
state);
clutter_container_add (CLUTTER_CONTAINER (stage),
state->actor,
state->props_display,
NULL);
clutter_actor_show (stage);
clutter_main ();
g_object_unref (state->transitions);
g_free (state);
return EXIT_SUCCESS;
}

View File

@ -1,104 +0,0 @@
#include "cb-background-effect.h"
G_DEFINE_TYPE (CbBackgroundEffect, cb_background_effect, CLUTTER_TYPE_EFFECT);
#define CB_BACKGROUND_EFFECT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
CB_TYPE_BACKGROUND_EFFECT, \
CbBackgroundEffectPrivate))
struct _CbBackgroundEffectPrivate
{
CoglMaterial *background;
CoglColor *color;
};
/* ClutterEffect implementation */
/* note that if pre_paint() returns FALSE
* any post_paint() defined for the effect will not be called
*/
static gboolean
cb_background_effect_pre_paint (ClutterEffect *self)
{
ClutterActor *actor;
gfloat width;
gfloat height;
CbBackgroundEffectPrivate *priv;
priv = CB_BACKGROUND_EFFECT (self)->priv;
/* get the associated actor's dimensions */
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (self));
clutter_actor_get_size (actor, &width, &height);
/* draw a grey Cogl rectangle in the background */
cogl_set_source (priv->background);
cogl_rectangle (0, 0, width, height);
return TRUE;
}
/* GObject implementation */
static void
cb_background_effect_dispose (GObject *gobject)
{
CbBackgroundEffectPrivate *priv = CB_BACKGROUND_EFFECT (gobject)->priv;
if (priv->background != COGL_INVALID_HANDLE)
{
cogl_handle_unref (priv->background);
priv->background = COGL_INVALID_HANDLE;
}
if (priv->color != NULL)
{
cogl_color_free (priv->color);
priv->color = NULL;
}
G_OBJECT_CLASS (cb_background_effect_parent_class)->dispose (gobject);
}
static void
cb_background_effect_class_init (CbBackgroundEffectClass *klass)
{
ClutterEffectClass *effect_class = CLUTTER_EFFECT_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
effect_class->pre_paint = cb_background_effect_pre_paint;
gobject_class->dispose = cb_background_effect_dispose;
g_type_class_add_private (klass, sizeof (CbBackgroundEffectPrivate));
}
static void
cb_background_effect_init (CbBackgroundEffect *self)
{
CbBackgroundEffectPrivate *priv;
priv = self->priv = CB_BACKGROUND_EFFECT_GET_PRIVATE (self);
priv->background = cogl_material_new ();
/* grey color for filling the background material */
priv->color = cogl_color_new ();
cogl_color_init_from_4ub (priv->color, 122, 122, 122, 255);
cogl_material_set_color (priv->background, priv->color);
}
/* public API */
/**
* cb_background_effect_new:
*
* Creates a new #ClutterEffect which adds a grey background
* when applied to a rectangular actor.
*/
ClutterEffect *
cb_background_effect_new ()
{
return g_object_new (CB_TYPE_BACKGROUND_EFFECT,
NULL);
}

View File

@ -1,42 +0,0 @@
#ifndef __CB_BACKGROUND_EFFECT_H__
#define __CB_BACKGROUND_EFFECT_H__
#include <clutter/clutter.h>
GType cb_background_effect_get_type (void);
#define CB_TYPE_BACKGROUND_EFFECT (cb_background_effect_get_type ())
#define CB_BACKGROUND_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
CB_TYPE_BACKGROUND_EFFECT, \
CbBackgroundEffect))
#define CB_IS_BACKGROUND_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
CB_TYPE_BACKGROUND_EFFECT))
#define CB_BACKGROUND_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
CB_TYPE_BACKGROUND_EFFECT, \
CbBackgroundEffectClass))
#define CB_IS_BACKGROUND_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
CB_TYPE_BACKGROUND_EFFECT))
#define CB_BACKGROUND_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
CB_TYPE_BACKGROUND_EFFECT, \
CbBackgroundEffectClass))
typedef struct _CbBackgroundEffectPrivate CbBackgroundEffectPrivate;
typedef struct _CbBackgroundEffect CbBackgroundEffect;
typedef struct _CbBackgroundEffectClass CbBackgroundEffectClass;
/* object */
struct _CbBackgroundEffect
{
ClutterEffect parent_instance;
CbBackgroundEffectPrivate *priv;
};
/* class */
struct _CbBackgroundEffectClass
{
ClutterEffectClass parent_class;
};
ClutterEffect *cb_background_effect_new ();
#endif /* __CB_BACKGROUND_EFFECT_H__ */

View File

@ -1,311 +0,0 @@
#include "cb-border-effect.h"
G_DEFINE_TYPE (CbBorderEffect, cb_border_effect, CLUTTER_TYPE_EFFECT);
#define CB_BORDER_EFFECT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
CB_TYPE_BORDER_EFFECT, \
CbBorderEffectPrivate))
static const ClutterColor grey = { 0xaa, 0xaa, 0xaa, 0xff };
struct _CbBorderEffectPrivate
{
CoglMaterial *border;
ClutterColor color;
gfloat width;
};
enum {
PROP_0,
PROP_COLOR,
PROP_WIDTH,
PROP_LAST
};
static GParamSpec *obj_props[PROP_LAST];
/* ClutterEffect implementation */
static void
cb_border_effect_post_paint (ClutterEffect *self)
{
ClutterActor *actor;
gfloat width;
gfloat height;
CbBorderEffectPrivate *priv;
priv = CB_BORDER_EFFECT (self)->priv;
/* get the associated actor's dimensions */
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (self));
clutter_actor_get_size (actor, &width, &height);
/* draw Cogl rectangles on top */
cogl_set_source (priv->border);
cogl_path_new ();
/* left rectangle */
cogl_path_rectangle (0, 0, priv->width, height);
/* top rectangle */
cogl_path_rectangle (priv->width, 0, width, priv->width);
/* right rectangle */
cogl_path_rectangle (width - priv->width, priv->width, width, height);
/* bottom rectangle */
cogl_path_rectangle (priv->width,
height - priv->width,
width - priv->width,
height);
cogl_path_fill ();
}
/* GObject implementation */
static void
cb_border_effect_dispose (GObject *gobject)
{
CbBorderEffectPrivate *priv = CB_BORDER_EFFECT (gobject)->priv;
if (priv->border != COGL_INVALID_HANDLE)
{
cogl_handle_unref (priv->border);
priv->border = COGL_INVALID_HANDLE;
}
G_OBJECT_CLASS (cb_border_effect_parent_class)->dispose (gobject);
}
static void
cb_border_effect_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
CbBorderEffect *effect = CB_BORDER_EFFECT (gobject);
switch (prop_id)
{
case PROP_COLOR:
cb_border_effect_set_color (effect, clutter_value_get_color (value));
break;
case PROP_WIDTH:
cb_border_effect_set_width (effect, g_value_get_float (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
cb_border_effect_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
CbBorderEffectPrivate *priv = CB_BORDER_EFFECT (gobject)->priv;
switch (prop_id)
{
case PROP_COLOR:
g_value_set_object (value, &(priv->color));
break;
case PROP_WIDTH:
g_value_set_float (value, priv->width);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
/* GObject class and instance init */
static void
cb_border_effect_class_init (CbBorderEffectClass *klass)
{
ClutterEffectClass *effect_class = CLUTTER_EFFECT_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
effect_class->post_paint = cb_border_effect_post_paint;
gobject_class->set_property = cb_border_effect_set_property;
gobject_class->get_property = cb_border_effect_get_property;
gobject_class->dispose = cb_border_effect_dispose;
g_type_class_add_private (klass, sizeof (CbBorderEffectPrivate));
/**
* CbBorderEffect:width:
*
* The width of the border
*/
pspec = g_param_spec_float ("width",
"Width",
"The width of the border (in pixels)",
1.0, 100.0,
10.0,
G_PARAM_READWRITE);
obj_props[PROP_WIDTH] = pspec;
g_object_class_install_property (gobject_class, PROP_WIDTH, pspec);
/**
* CbBorderEffect:color:
*
* The color of the border
*/
pspec = clutter_param_spec_color ("color",
"Color",
"The border color",
&grey,
G_PARAM_READWRITE);
obj_props[PROP_COLOR] = pspec;
g_object_class_install_property (gobject_class, PROP_COLOR, pspec);
}
static void
cb_border_effect_init (CbBorderEffect *self)
{
CbBorderEffectPrivate *priv;
priv = self->priv = CB_BORDER_EFFECT_GET_PRIVATE (self);
priv->border = cogl_material_new ();
priv->color = grey;
}
/* called each time a property is set on the effect */
static void
cb_border_effect_update (CbBorderEffect *self)
{
ClutterActor *actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (self));
if (actor != NULL)
clutter_actor_queue_redraw (actor);
}
/* public API */
/**
* cb_border_effect_new:
* @width: width of the border applied by the effect
* @color: a #ClutterColor
*
* Creates a new #ClutterEffect with the given @width
* and of the given @color.
*/
ClutterEffect *
cb_border_effect_new (gfloat width,
const ClutterColor *color)
{
return g_object_new (CB_TYPE_BORDER_EFFECT,
"width", width,
"color", color,
NULL);
}
/**
* cb_border_effect_set_color:
* @self: a #CbBorderEffect
* @color: a #ClutterColor
*
* Sets the color of the border provided by the effect @self.
*/
void
cb_border_effect_set_color (CbBorderEffect *self,
const ClutterColor *color)
{
CbBorderEffectPrivate *priv;
g_return_if_fail (CB_IS_BORDER_EFFECT (self));
g_return_if_fail (color != NULL);
priv = CB_BORDER_EFFECT_GET_PRIVATE (self);
priv->color.red = color->red;
priv->color.green = color->green;
priv->color.blue = color->blue;
priv->color.alpha = color->alpha;
cogl_material_set_color4ub (priv->border,
color->red,
color->green,
color->blue,
color->alpha);
cb_border_effect_update (self);
}
/**
* cb_border_effect_get_color:
* @self: a #CbBorderEffect
* @color: return location for a #ClutterColor
*
* Retrieves the color of the border applied by the effect @self.
*/
void
cb_border_effect_get_color (CbBorderEffect *self,
ClutterColor *color)
{
CbBorderEffectPrivate *priv;
g_return_if_fail (CB_IS_BORDER_EFFECT (self));
priv = CB_BORDER_EFFECT_GET_PRIVATE (self);
color->red = priv->color.red;
color->green = priv->color.green;
color->blue = priv->color.blue;
color->alpha = priv->color.alpha;
}
/**
* cb_border_effect_set_width:
* @self: a #CbBorderEffect
* @width: the width of the border
*
* Sets the width (in pixels) of the border applied by the effect @self.
*/
void
cb_border_effect_set_width (CbBorderEffect *self,
gfloat width)
{
CbBorderEffectPrivate *priv;
g_return_if_fail (CB_IS_BORDER_EFFECT (self));
priv = CB_BORDER_EFFECT_GET_PRIVATE (self);
priv->width = width;
cb_border_effect_update (self);
}
/**
* cb_border_effect_get_width:
* @self: a #CbBorderEffect
*
* Gets the width (in pixels) of the border applied by the effect @self.
*
* Return value: the border's width, or 0.0 if @self is not
* a #CbBorderEffect
*/
gfloat
cb_border_effect_get_width (CbBorderEffect *self)
{
CbBorderEffectPrivate *priv;
g_return_val_if_fail (CB_IS_BORDER_EFFECT (self), 0.0);
priv = CB_BORDER_EFFECT_GET_PRIVATE (self);
return priv->width;
}

View File

@ -1,54 +0,0 @@
#ifndef __CB_BORDER_EFFECT_H__
#define __CB_BORDER_EFFECT_H__
#include <clutter/clutter.h>
GType cb_border_effect_get_type (void);
#define CB_TYPE_BORDER_EFFECT (cb_border_effect_get_type ())
#define CB_BORDER_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
CB_TYPE_BORDER_EFFECT, \
CbBorderEffect))
#define CB_IS_BORDER_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
CB_TYPE_BORDER_EFFECT))
#define CB_BORDER_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
CB_TYPE_BORDER_EFFECT, \
CbBorderEffectClass))
#define CB_IS_BORDER_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
CB_TYPE_BORDER_EFFECT))
#define CB_BORDER_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
CB_TYPE_BORDER_EFFECT, \
CbBorderEffectClass))
typedef struct _CbBorderEffectPrivate CbBorderEffectPrivate;
typedef struct _CbBorderEffect CbBorderEffect;
typedef struct _CbBorderEffectClass CbBorderEffectClass;
/* object */
struct _CbBorderEffect
{
ClutterEffect parent_instance;
CbBorderEffectPrivate *priv;
};
/* class */
struct _CbBorderEffectClass
{
ClutterEffectClass parent_class;
};
ClutterEffect *cb_border_effect_new (gfloat width,
const ClutterColor *color);
void cb_border_effect_set_color (CbBorderEffect *self,
const ClutterColor *color);
void cb_border_effect_get_color (CbBorderEffect *self,
ClutterColor *color);
void cb_border_effect_set_width (CbBorderEffect *self,
gfloat width);
gfloat cb_border_effect_get_width (CbBorderEffect *self);
#endif /* __CB_BORDER_EFFECT_H__ */

View File

@ -1,450 +0,0 @@
#include "cb-button.h"
/**
* SECTION:cb-button
* @short_description: Button widget
*
* A button widget with support for a text label and background color.
*/
/* convenience macro for GType implementations; see:
* http://library.gnome.org/devel/gobject/2.27/gobject-Type-Information.html#G-DEFINE-TYPE:CAPS
*/
G_DEFINE_TYPE (CbButton, cb_button, CLUTTER_TYPE_ACTOR);
/* macro for accessing the object's private structure */
#define CB_BUTTON_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), CB_TYPE_BUTTON, CbButtonPrivate))
/* private structure - should only be accessed through the public API;
* this is used to store member variables whose properties
* need to be accessible from the implementation; for example, if we
* intend to create wrapper functions which modify properties on the
* actors composing an object, we should keep a reference to the actors
* here
*
* this is also the place where other state variables go:
* for example, you might record the current state of the button
* (toggled on or off) or a background image
*/
struct _CbButtonPrivate
{
ClutterActor *child;
ClutterActor *label;
ClutterAction *click_action;
gchar *text;
};
/* enumerates property identifiers for this class;
* note that property identifiers should be non-zero integers,
* so we add an unused PROP_0 to occupy the 0 position in the enum
*/
enum {
PROP_0,
PROP_TEXT
};
/* enumerates signal identifiers for this class;
* LAST_SIGNAL is not used as a signal identifier, but is instead
* used to delineate the size of the cache array for signals (see below)
*/
enum {
CLICKED,
LAST_SIGNAL
};
/* cache array for signals */
static guint cb_button_signals[LAST_SIGNAL] = { 0, };
/* from http://mail.gnome.org/archives/gtk-devel-list/2004-July/msg00158.html:
*
* "The finalize method finishes releasing the remaining
* resources just before the object itself will be freed from memory, and
* therefore it will only be called once. The two step process helps break
* cyclic references. Both dispose and finalize must chain up to their
* parent objects by calling their parent's respective methods *after* they
* have disposed or finalized their own members."
*/
static void
cb_button_finalize (GObject *gobject)
{
CbButtonPrivate *priv = CB_BUTTON (gobject)->priv;
g_free (priv->text);
/* call the parent class' finalize() method */
G_OBJECT_CLASS (cb_button_parent_class)->finalize (gobject);
}
/* enables objects to be uniformly treated as GObjects;
* also exposes properties so they become scriptable, e.g.
* through ClutterScript
*/
static void
cb_button_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
CbButton *button = CB_BUTTON (gobject);
switch (prop_id)
{
case PROP_TEXT:
cb_button_set_text (button, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
/* enables objects to be uniformly treated as GObjects */
static void
cb_button_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
CbButtonPrivate *priv = CB_BUTTON (gobject)->priv;
switch (prop_id)
{
case PROP_TEXT:
g_value_set_string (value, priv->text);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
/* ClutterActor implementation
*
* we only implement destroy(), get_preferred_height(), get_preferred_width(),
* allocate(), and paint(), as this is the minimum we can get away with
*/
/* composite actors should implement destroy(), and inside their
* implementation destroy any actors they are composed from;
* in this case, we just destroy the child ClutterBox
*/
static void
cb_button_destroy (ClutterActor *self)
{
CbButtonPrivate *priv = CB_BUTTON (self)->priv;
/* we just destroy the child, and let the child
* deal with destroying _its_ children; note that we have a guard
* here in case the child has already been destroyed
*/
if (priv->child)
{
clutter_actor_destroy (priv->child);
priv->child = NULL;
}
/* chain up to destroy() on the parent ClutterActorClass;
* note that we check the parent class has a destroy() implementation
* before calling it
*/
if (CLUTTER_ACTOR_CLASS (cb_button_parent_class)->destroy)
CLUTTER_ACTOR_CLASS (cb_button_parent_class)->destroy (self);
}
/* get_preferred_height and get_preferred_width defer to the
* internal ClutterBox, adding 20px padding on each axis;
* min_*_p is the minimum height or width the actor should occupy
* to be useful; natural_*_p is the height or width the actor
* would occupy if not constrained
*
* note that if we required explicit sizing for CbButtons
* (i.e. a developer must set their height and width),
* we wouldn't need to implement these functions
*/
static void
cb_button_get_preferred_height (ClutterActor *self,
gfloat for_width,
gfloat *min_height_p,
gfloat *natural_height_p)
{
CbButtonPrivate *priv = CB_BUTTON (self)->priv;
clutter_actor_get_preferred_height (priv->child,
for_width,
min_height_p,
natural_height_p);
*min_height_p += 20.0;
*natural_height_p += 20.0;
}
static void
cb_button_get_preferred_width (ClutterActor *self,
gfloat for_height,
gfloat *min_width_p,
gfloat *natural_width_p)
{
CbButtonPrivate *priv = CB_BUTTON (self)->priv;
clutter_actor_get_preferred_width (priv->child,
for_height,
min_width_p,
natural_width_p);
*min_width_p += 20.0;
*natural_width_p += 20.0;
}
/* use the actor's allocation for the ClutterBox */
static void
cb_button_allocate (ClutterActor *actor,
const ClutterActorBox *box,
ClutterAllocationFlags flags)
{
CbButtonPrivate *priv = CB_BUTTON (actor)->priv;
ClutterActorBox child_box = { 0, };
/* set the allocation for the whole button */
CLUTTER_ACTOR_CLASS (cb_button_parent_class)->allocate (actor, box, flags);
/* make the child (the ClutterBox) fill the parent;
* note that this allocation box is relative to the
* coordinates of the whole button actor, so we can't just
* use the box passed into this function; instead, it
* is adjusted to span the whole of the actor, from its
* top-left corner (0,0) to its bottom-right corner
* (width,height)
*/
child_box.x1 = 0.0;
child_box.y1 = 0.0;
child_box.x2 = clutter_actor_box_get_width (box);
child_box.y2 = clutter_actor_box_get_height (box);
clutter_actor_allocate (priv->child, &child_box, flags);
}
/* paint function implementation: just calls paint() on the ClutterBox */
static void
cb_button_paint (ClutterActor *actor)
{
CbButtonPrivate *priv = CB_BUTTON (actor)->priv;
clutter_actor_paint (priv->child);
}
/* proxy ClickAction signals so they become signals from the actor */
static void
cb_button_clicked (ClutterClickAction *action,
ClutterActor *actor,
gpointer user_data)
{
/* emit signal via the cache array */
g_signal_emit (actor, cb_button_signals[CLICKED], 0);
}
/* GObject class and instance initialization functions; note that
* these have been placed after the Clutter implementation, as
* they refer to the static function implementations above
*/
/* class init: attach functions to superclasses, define properties
* and signals
*/
static void
cb_button_class_init (CbButtonClass *klass)
{
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
gobject_class->finalize = cb_button_finalize;
gobject_class->set_property = cb_button_set_property;
gobject_class->get_property = cb_button_get_property;
actor_class->destroy = cb_button_destroy;
actor_class->get_preferred_height = cb_button_get_preferred_height;
actor_class->get_preferred_width = cb_button_get_preferred_width;
actor_class->allocate = cb_button_allocate;
actor_class->paint = cb_button_paint;
g_type_class_add_private (klass, sizeof (CbButtonPrivate));
/**
* CbButton:text:
*
* The text shown on the #CbButton
*/
pspec = g_param_spec_string ("text",
"Text",
"Text of the button",
NULL,
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_TEXT, pspec);
/**
* CbButton::clicked:
* @button: the #CbButton that emitted the signal
*
* The ::clicked signal is emitted when the internal #ClutterClickAction
* associated with a #CbButton emits its own ::clicked signal
*/
cb_button_signals[CLICKED] =
g_signal_new ("clicked",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (CbButtonClass, clicked),
NULL,
NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
}
/* object init: create a private structure and pack
* composed ClutterActors into it
*/
static void
cb_button_init (CbButton *self)
{
CbButtonPrivate *priv;
ClutterLayoutManager *layout;
priv = self->priv = CB_BUTTON_GET_PRIVATE (self);
clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE);
/* the only child of this actor is a ClutterBox with a
* ClutterBinLayout: painting and allocation of the actor basically
* involves painting and allocating this child box
*/
layout = clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER,
CLUTTER_BIN_ALIGNMENT_CENTER);
priv->child = clutter_actor_new ();
clutter_actor_set_layout_manager (priv->child, layout);
/* set the parent of the ClutterBox to this instance */
clutter_actor_add_child (CLUTTER_ACTOR (self), priv->child);
/* add text label to the button; see the ClutterText API docs
* for more information about available properties
*/
priv->label = g_object_new (CLUTTER_TYPE_TEXT,
"line-alignment", PANGO_ALIGN_CENTER,
"ellipsize", PANGO_ELLIPSIZE_END,
NULL);
clutter_actor_add_child (priv->child, priv->label);
/* add a ClutterClickAction on this actor, so we can proxy its
* "clicked" signal into a signal from this actor
*/
priv->click_action = clutter_click_action_new ();
clutter_actor_add_action (CLUTTER_ACTOR (self), priv->click_action);
g_signal_connect (priv->click_action,
"clicked",
G_CALLBACK (cb_button_clicked),
NULL);
}
/* public API */
/* examples of public API functions which wrap functions
* on internal actors
*/
/**
* cb_button_set_text:
* @self: a #CbButton
* @text: the text to display on the button
*
* Set the text on the button
*/
void
cb_button_set_text (CbButton *self,
const gchar *text)
{
CbButtonPrivate *priv;
/* public API should check its arguments;
* see also g_return_val_if_fail for functions which
* return a value
*/
g_return_if_fail (CB_IS_BUTTON (self));
priv = self->priv;
g_free (priv->text);
if (text)
priv->text = g_strdup (text);
else
priv->text = g_strdup ("");
/* call a function on the ClutterText inside the layout */
clutter_text_set_text (CLUTTER_TEXT (priv->label), priv->text);
}
/**
* cb_button_set_background_color:
* @self: a #CbButton
* @color: the #ClutterColor to use for the button's background
*
* Set the color of the button's background
*/
void
cb_button_set_background_color (CbButton *self,
const ClutterColor *color)
{
g_return_if_fail (CB_IS_BUTTON (self));
clutter_actor_set_background_color (self->priv->child, color);
}
/**
* cb_button_set_text_color:
* @self: a #CbButton
* @color: the #ClutterColor to use as the color for the button text
*
* Set the color of the text on the button
*/
void
cb_button_set_text_color (CbButton *self,
const ClutterColor *color)
{
g_return_if_fail (CB_IS_BUTTON (self));
clutter_text_set_color (CLUTTER_TEXT (self->priv->label), color);
}
/**
* cb_button_get_text:
* @self: a #CbButton
*
* Get the text displayed on the button
*
* Returns: the button's text. This must not be freed by the application.
*/
const gchar *
cb_button_get_text (CbButton *self)
{
g_return_val_if_fail (CB_IS_BUTTON (self), NULL);
return self->priv->text;
}
/**
* cb_button_new:
*
* Creates a new #CbButton instance
*
* Returns: a new #CbButton
*/
ClutterActor *
cb_button_new (void)
{
return g_object_new (CB_TYPE_BUTTON, NULL);
}

View File

@ -1,84 +0,0 @@
/* inclusion guard */
#ifndef __CB_BUTTON_H__
#define __CB_BUTTON_H__
/* include any dependencies */
#include <clutter/clutter.h>
/* GObject implementation */
/* declare this function signature to remove compilation errors with -Wall;
* the cb_button_get_type() function is actually added via the
* G_DEFINE_TYPE macro in the .c file
*/
GType cb_button_get_type (void);
/* GObject type macros */
/* returns the class type identifier (GType) for CbButton */
#define CB_TYPE_BUTTON (cb_button_get_type ())
/* cast obj to a CbButton object structure*/
#define CB_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CB_TYPE_BUTTON, CbButton))
/* check whether obj is a CbButton */
#define CB_IS_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CB_TYPE_BUTTON))
/* cast klass to CbButtonClass class structure */
#define CB_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CB_TYPE_BUTTON, CbButtonClass))
/* check whether klass is a member of the CbButtonClass */
#define CB_IS_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CB_TYPE_BUTTON))
/* get the CbButtonClass structure for a CbButton obj */
#define CB_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CB_TYPE_BUTTON, CbButtonClass))
/*
* Private instance fields; see
* http://www.gotw.ca/gotw/024.htm for the rationale
*/
typedef struct _CbButtonPrivate CbButtonPrivate;
typedef struct _CbButton CbButton;
typedef struct _CbButtonClass CbButtonClass;
/* object structure */
struct _CbButton
{
/*<private>*/
ClutterActor parent_instance;
/* structure containing private members */
/*<private>*/
CbButtonPrivate *priv;
};
/* class structure */
struct _CbButtonClass
{
/* signals */
void (* clicked)(CbButton *button);
/*<private>*/
ClutterActorClass parent_class;
};
/* public API */
/* constructor - note this returns a ClutterActor instance */
ClutterActor *cb_button_new (void);
/* getter */
const gchar *cb_button_get_text (CbButton *self);
/* setters - these are wrappers round functions
* which change properties of the internal actors
*/
void cb_button_set_text (CbButton *self,
const gchar *text);
void cb_button_set_background_color (CbButton *self,
const ClutterColor *color);
void cb_button_set_text_color (CbButton *self,
const ClutterColor *color);
#endif /* __CB_BUTTON_H__ */

View File

@ -1,250 +0,0 @@
#include <math.h>
#include "cb-page-fold-effect.h"
G_DEFINE_TYPE (CbPageFoldEffect, cb_page_fold_effect, CLUTTER_TYPE_DEFORM_EFFECT);
#define CB_PAGE_FOLD_EFFECT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
CB_TYPE_PAGE_FOLD_EFFECT, \
CbPageFoldEffectPrivate))
struct _CbPageFoldEffectPrivate
{
gdouble angle;
gdouble period;
};
enum {
PROP_0,
PROP_PERIOD,
PROP_ANGLE,
PROP_LAST
};
static GParamSpec *obj_props[PROP_LAST];
/* ClutterDeformEffect implementation */
static void
cb_page_fold_effect_deform_vertex (ClutterDeformEffect *effect,
gfloat width,
gfloat height,
CoglTextureVertex *vertex)
{
CbPageFoldEffectPrivate *priv = CB_PAGE_FOLD_EFFECT (effect)->priv;
gfloat radians = (priv->angle * priv->period) / (180.0f / G_PI);
/* rotate from the center of the actor on the y axis */
gfloat adjusted_x = vertex->x - (width / 2);
/* only rotate vertices to the right of the middle of the actor */
if (adjusted_x >= 0.0)
{
vertex->x = (vertex->z * sin (radians))
+ (adjusted_x * cos (radians))
+ width / 2;
/* NB add 1 to z to prevent "z fighting"; otherwise, when fully-folded
* the image has "stripes" where vertices from the folded part
* of the actor interfere with vertices from the unfolded part
*/
vertex->z = (vertex->z * cos (radians))
+ (adjusted_x * sin (radians))
+ 1;
}
/* adjust depth of all vertices so they fit inside the actor while folding;
* this has the effect of making the image smaller within the texture,
* but does produce a cleaner fold animation
*/
vertex->z -= width / 2;
}
/* GObject implementation */
static void
cb_page_fold_effect_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
CbPageFoldEffect *effect = CB_PAGE_FOLD_EFFECT (gobject);
switch (prop_id)
{
case PROP_PERIOD:
cb_page_fold_effect_set_period (effect, g_value_get_double (value));
break;
case PROP_ANGLE:
cb_page_fold_effect_set_angle (effect, g_value_get_double (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
cb_page_fold_effect_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
CbPageFoldEffectPrivate *priv = CB_PAGE_FOLD_EFFECT (gobject)->priv;
switch (prop_id)
{
case PROP_PERIOD:
g_value_set_double (value, priv->period);
break;
case PROP_ANGLE:
g_value_set_double (value, priv->angle);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
/* GObject class and instance init */
static void
cb_page_fold_effect_class_init (CbPageFoldEffectClass *klass)
{
GParamSpec *pspec;
ClutterDeformEffectClass *effect_class = CLUTTER_DEFORM_EFFECT_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
effect_class->deform_vertex = cb_page_fold_effect_deform_vertex;
gobject_class->set_property = cb_page_fold_effect_set_property;
gobject_class->get_property = cb_page_fold_effect_get_property;
g_type_class_add_private (klass, sizeof (CbPageFoldEffectPrivate));
/**
* CbPageFoldEffect:period:
*
* The period of the page fold, between 0.0 (no fold) and
* 1.0 (fully folded)
*/
pspec = g_param_spec_double ("period",
"Period",
"The period of the page fold",
0.0, 1.0,
0.0,
G_PARAM_READWRITE);
obj_props[PROP_PERIOD] = pspec;
g_object_class_install_property (gobject_class, PROP_PERIOD, pspec);
/**
* CbPageFoldEffect:angle:
*
* The angle of the page fold, in degrees, between 0.0 and 180.0
*/
pspec = g_param_spec_double ("angle",
"Angle",
"The angle of the page fold, in degrees",
0.0, 180.0,
0.0,
G_PARAM_READWRITE);
obj_props[PROP_ANGLE] = pspec;
g_object_class_install_property (gobject_class, PROP_ANGLE, pspec);
}
static void
cb_page_fold_effect_init (CbPageFoldEffect *self)
{
CbPageFoldEffectPrivate *priv;
priv = self->priv = CB_PAGE_FOLD_EFFECT_GET_PRIVATE (self);
priv->period = 0.0;
priv->angle = 0.0;
}
/* public API */
ClutterEffect *
cb_page_fold_effect_new (gdouble angle,
gdouble period)
{
return g_object_new (CB_TYPE_PAGE_FOLD_EFFECT,
"angle", angle,
"period", period,
NULL);
}
/**
* cb_page_fold_effect_set_period:
* @effect: a #CbPageFoldEffect
* @period: the period of the page fold, between 0.0 and 1.0
*
* Sets the period of the page fold, between 0.0 (no fold)
* and 1.0 (fully folded)
*/
void
cb_page_fold_effect_set_period (CbPageFoldEffect *effect,
gdouble period)
{
g_return_if_fail (CB_IS_PAGE_FOLD_EFFECT (effect));
g_return_if_fail (period >= 0.0 && period <= 1.0);
effect->priv->period = period;
clutter_deform_effect_invalidate (CLUTTER_DEFORM_EFFECT (effect));
}
/**
* cb_page_fold_effect_get_period:
* @effect: a #CbPageFoldEffect
*
* Retrieves the value set using cb_page_fold_effect_get_period()
*
* Return value: the period of the page fold
*/
gdouble
cb_page_fold_effect_get_period (CbPageFoldEffect *effect)
{
g_return_val_if_fail (CB_IS_PAGE_FOLD_EFFECT (effect), 0.0);
return effect->priv->period;
}
/**
* cb_page_fold_effect_set_angle:
* @effect: #CbPageFoldEffect
* @angle: the angle of the page fold, in degrees
*
* Sets the angle of the page fold, in degrees; must be a value between
* 0.0 and 180.0
*/
void
cb_page_fold_effect_set_angle (CbPageFoldEffect *effect,
gdouble angle)
{
g_return_if_fail (CB_IS_PAGE_FOLD_EFFECT (effect));
g_return_if_fail (angle >= 0.0 && angle <= 180.0);
effect->priv->angle = angle;
clutter_deform_effect_invalidate (CLUTTER_DEFORM_EFFECT (effect));
}
/**
* cb_page_fold_effect_get_angle:
* @effect: a #CbPageFoldEffect:
*
* Retrieves the angle of the page fold, in degrees
*
* Return value: the angle of the page fold
*/
gdouble
cb_page_fold_effect_get_angle (CbPageFoldEffect *effect)
{
g_return_val_if_fail (CB_IS_PAGE_FOLD_EFFECT (effect), 0.0);
return effect->priv->angle;
}

View File

@ -1,49 +0,0 @@
#ifndef __CB_PAGE_FOLD_EFFECT_H__
#define __CB_PAGE_FOLD_EFFECT_H__
#include <clutter/clutter.h>
GType cb_page_fold_effect_get_type (void);
#define CB_TYPE_PAGE_FOLD_EFFECT (cb_page_fold_effect_get_type ())
#define CB_PAGE_FOLD_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
CB_TYPE_PAGE_FOLD_EFFECT, \
CbPageFoldEffect))
#define CB_IS_PAGE_FOLD_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
CB_TYPE_PAGE_FOLD_EFFECT))
#define CB_PAGE_FOLD_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
CB_TYPE_PAGE_FOLD_EFFECT, \
CbPageFoldEffectClass))
#define CB_IS_PAGE_FOLD_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
CB_TYPE_PAGE_FOLD_EFFECT))
#define CB_PAGE_FOLD_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
CB_TYPE_PAGE_FOLD_EFFECT, \
CbPageFoldEffectClass))
typedef struct _CbPageFoldEffectPrivate CbPageFoldEffectPrivate;
typedef struct _CbPageFoldEffect CbPageFoldEffect;
typedef struct _CbPageFoldEffectClass CbPageFoldEffectClass;
/* object */
struct _CbPageFoldEffect
{
ClutterDeformEffect parent_instance;
CbPageFoldEffectPrivate *priv;
};
/* class */
struct _CbPageFoldEffectClass
{
ClutterDeformEffectClass parent_class;
};
ClutterEffect *cb_page_fold_effect_new (gdouble angle,
gdouble period);
void cb_page_fold_effect_set_angle (CbPageFoldEffect *effect,
gdouble angle);
void cb_page_fold_effect_set_period (CbPageFoldEffect *effect,
gdouble period);
gdouble cb_page_fold_effect_get_period (CbPageFoldEffect *effect);
gdouble cb_page_fold_effect_get_angle (CbPageFoldEffect *effect);
#endif /* __CB_PAGE_FOLD_EFFECT_H__ */

View File

@ -1,118 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
#include "cb-border-effect.h"
#include "cb-background-effect.h"
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
static ClutterColor red_color = { 0xff, 0x00, 0x00, 0xff };
static gboolean
toggle_highlight (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
ClutterActorMeta *meta = CLUTTER_ACTOR_META (user_data);
gboolean effect_enabled = clutter_actor_meta_get_enabled (meta);
clutter_actor_meta_set_enabled (meta, !effect_enabled);
return CLUTTER_EVENT_STOP;
}
int
main (int argc,
char *argv[])
{
ClutterActor *stage;
ClutterActor *box;
ClutterLayoutManager *layout_manager;
ClutterActor *texture;
ClutterEffect *background_effect;
ClutterEffect *border_effect;
ClutterConstraint *width_constraint;
gchar *filename;
guint i;
GError *error = NULL;
if (argc < 2)
{
g_print ("Usage: %s <image files>\n", argv[0]);
return EXIT_FAILURE;
}
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return EXIT_FAILURE;
stage = clutter_stage_new ();
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
clutter_actor_set_size (stage, 600, 400);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
layout_manager = clutter_flow_layout_new (CLUTTER_FLOW_HORIZONTAL);
clutter_flow_layout_set_column_spacing (CLUTTER_FLOW_LAYOUT (layout_manager),
10);
clutter_flow_layout_set_row_spacing (CLUTTER_FLOW_LAYOUT (layout_manager),
10);
box = clutter_actor_new ();
clutter_actor_set_layout_manager (box, layout_manager);
width_constraint = clutter_bind_constraint_new (stage,
CLUTTER_BIND_WIDTH,
0.0);
clutter_actor_add_constraint (box, width_constraint);
/* loop through the files specified on the command line, adding
* each one into the box
*/
for (i = 1; i < argc; i++)
{
filename = argv[i];
texture = clutter_texture_new ();
clutter_texture_set_keep_aspect_ratio (CLUTTER_TEXTURE (texture), TRUE);
clutter_actor_set_width (texture, 150);
clutter_actor_set_reactive (texture, TRUE);
clutter_texture_set_from_file (CLUTTER_TEXTURE (texture),
filename,
&error);
if (error != NULL)
g_warning ("Error loading file %s:\n%s",
filename,
error->message);
/* create a grey background effect */
background_effect = cb_background_effect_new ();
/* apply the effect to the actor */
clutter_actor_add_effect (texture, background_effect);
/* create a 5 pixel red border effect */
border_effect = cb_border_effect_new (5.0, &red_color);
/* apply the effect to the actor, but disabled */
clutter_actor_add_effect (texture, border_effect);
clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (border_effect),
FALSE);
/* on mouse click, toggle the "enabled" property of the border effect */
g_signal_connect (texture,
"button-press-event",
G_CALLBACK (toggle_highlight),
border_effect);
clutter_container_add_actor (CLUTTER_CONTAINER (box), texture);
}
clutter_container_add_actor (CLUTTER_CONTAINER (stage), box);
clutter_actor_show (stage);
clutter_main ();
return EXIT_SUCCESS;
}

View File

@ -1,59 +0,0 @@
#include <clutter/clutter.h>
int
main (int argc,
char *argv[])
{
ClutterActor *stage;
ClutterActor *texture;
ClutterConstraint *constraint_x;
ClutterConstraint *constraint_y;
ClutterColor *pink;
ClutterEffect *effect;
gchar *filename;
if (argc < 2)
{
g_print ("Usage: %s <path to image file>\n", argv[0]);
return 1;
}
filename = argv[1];
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, 400, 400);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
texture = clutter_texture_new ();
clutter_texture_set_keep_aspect_ratio (CLUTTER_TEXTURE (texture), TRUE);
clutter_actor_set_width (texture, 300);
/* NB ignoring missing file errors here for brevity */
clutter_texture_set_from_file (CLUTTER_TEXTURE (texture),
filename,
NULL);
/* align the texture on the x and y axes */
constraint_x = clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5);
constraint_y = clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.5);
clutter_actor_add_constraint (texture, constraint_x);
clutter_actor_add_constraint (texture, constraint_y);
/* create a colorize effect with pink tint */
pink = clutter_color_new (230, 187, 210, 255);
effect = clutter_colorize_effect_new (pink);
/* apply the effect to the texture */
clutter_actor_add_effect (texture, effect);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), texture);
clutter_actor_show (stage);
clutter_main ();
return 0;
}

View File

@ -1,120 +0,0 @@
/* Example of using a custom CbPageFoldEffect to do
* an animated fold of a texture containing an image
*
* Pass the full path to the image on the command line;
* click on the texture to trigger the folding animation
*/
#include <stdlib.h>
#include <clutter/clutter.h>
#include "cb-page-fold-effect.h"
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
static gboolean
button_pressed_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
ClutterState *transitions = CLUTTER_STATE (user_data);
if (g_strcmp0 (clutter_state_get_state (transitions), "folded") == 0)
clutter_state_set_state (transitions, "unfolded");
else
clutter_state_set_state (transitions, "folded");
return TRUE;
}
int
main (int argc,
char *argv[])
{
ClutterActor *stage;
ClutterActor *texture;
ClutterEffect *effect;
ClutterState *transitions;
GError *error = NULL;
gchar *filename;
if (argc < 2)
{
g_print ("Usage: %s <path to image file>\n", argv[0]);
return EXIT_FAILURE;
}
filename = argv[1];
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, 400, 300);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
texture = clutter_texture_new ();
clutter_texture_set_keep_aspect_ratio (CLUTTER_TEXTURE (texture), TRUE);
clutter_actor_set_width (texture, 400);
clutter_actor_set_reactive (texture, TRUE);
clutter_texture_set_from_file (CLUTTER_TEXTURE (texture),
filename,
&error);
if (error != NULL)
{
g_critical ("Error loading texture from file %s; error was:\n%s",
filename,
error->message);
return EXIT_FAILURE;
}
/* create the page fold effect instance with destination fold angle
* of 180 degrees and starting period of 0 (no folding)
*/
effect = cb_page_fold_effect_new (180.0, 0.0);
/* add the effect to the texture actor */
clutter_actor_add_effect (texture, effect);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), texture);
/* animation for the period property of the effect,
* to animate its value between 0.0 and 1.0 and back
*/
transitions = clutter_state_new ();
clutter_state_set_duration (transitions, NULL, NULL, 500);
clutter_state_set_duration (transitions,
"partially-folded",
"folded",
375);
clutter_state_set (transitions, NULL, "folded",
effect, "period", CLUTTER_LINEAR, 1.0,
NULL);
clutter_state_set (transitions, NULL, "partially-folded",
effect, "period", CLUTTER_LINEAR, 0.25,
NULL);
clutter_state_set (transitions, NULL, "unfolded",
effect, "period", CLUTTER_LINEAR, 0.0,
NULL);
clutter_state_warp_to_state (transitions, "partially-folded");
g_signal_connect (texture,
"button-press-event",
G_CALLBACK (button_pressed_cb),
transitions);
clutter_actor_show (stage);
clutter_main ();
g_object_unref (transitions);
return EXIT_SUCCESS;
}

View File

@ -1,71 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
void
clicked_cb (ClutterClickAction *action,
ClutterActor *actor,
gpointer user_data)
{
g_print ("Pointer button %d clicked on actor %s\n",
clutter_click_action_get_button (action),
clutter_actor_get_name (actor));
}
int
main (int argc,
char *argv[])
{
ClutterActor *stage;
ClutterAction *action1;
ClutterAction *action2;
ClutterActor *actor1;
ClutterActor *actor2;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, 400, 400);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
actor1 = clutter_actor_new ();
clutter_actor_set_name (actor1, "Red Button");
clutter_actor_set_background_color (actor1, CLUTTER_COLOR_Red);
clutter_actor_set_size (actor1, 100, 100);
clutter_actor_set_reactive (actor1, TRUE);
clutter_actor_set_position (actor1, 50, 150);
clutter_actor_add_child (stage, actor1);
actor2 = clutter_actor_new ();
clutter_actor_set_name (actor2, "Blue Button");
clutter_actor_set_background_color (actor2, CLUTTER_COLOR_Blue);
clutter_actor_set_size (actor2, 100, 100);
clutter_actor_set_position (actor2, 250, 150);
clutter_actor_set_reactive (actor2, TRUE);
clutter_actor_add_child (stage, actor2);
action1 = clutter_click_action_new ();
clutter_actor_add_action (actor1, action1);
action2 = clutter_click_action_new ();
clutter_actor_add_action (actor2, action2);
g_signal_connect (action1,
"clicked",
G_CALLBACK (clicked_cb),
NULL);
g_signal_connect (action2,
"clicked",
G_CALLBACK (clicked_cb),
NULL);
clutter_actor_show (stage);
clutter_main ();
return EXIT_SUCCESS;
}

View File

@ -1,155 +0,0 @@
/* Simple rectangle drawing using button and pointer events;
* click, drag and release a mouse button to draw a rectangle
*/
#include <stdlib.h>
#include <clutter/clutter.h>
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
static const ClutterColor lasso_color = { 0xaa, 0xaa, 0xaa, 0x33 };
typedef struct
{
ClutterActor *actor;
gfloat x;
gfloat y;
} Lasso;
static guint
random_color_component ()
{
return (guint) (155 + (100.0 * rand () / (RAND_MAX + 1.0)));
}
static gboolean
button_pressed_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
Lasso *lasso = (Lasso *) user_data;
/* start drawing the lasso actor */
lasso->actor = clutter_rectangle_new_with_color (&lasso_color);
/* store lasso's start coordinates */
clutter_event_get_coords (event, &(lasso->x), &(lasso->y));
clutter_container_add_actor (CLUTTER_CONTAINER (actor), lasso->actor);
return TRUE;
}
static gboolean
button_released_cb (ClutterActor *stage,
ClutterEvent *event,
gpointer user_data)
{
Lasso *lasso = (Lasso *) user_data;
ClutterActor *rectangle;
ClutterColor *random_color;
gfloat x;
gfloat y;
gfloat width;
gfloat height;
if (lasso->actor == NULL)
return TRUE;
/* create a new rectangle */
random_color = clutter_color_new (random_color_component (),
random_color_component (),
random_color_component (),
random_color_component ());
rectangle = clutter_rectangle_new_with_color (random_color);
/* set the rectangle to the same size and shape as the lasso */
clutter_actor_get_position (lasso->actor, &x, &y);
clutter_actor_get_size (lasso->actor, &width, &height);
clutter_actor_set_position (rectangle, x, y);
clutter_actor_set_size (rectangle, width, height);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), rectangle);
/* clear up the lasso actor */
clutter_actor_destroy (lasso->actor);
lasso->actor = NULL;
clutter_actor_queue_redraw (stage);
return TRUE;
}
static gboolean
pointer_motion_cb (ClutterActor *stage,
ClutterEvent *event,
gpointer user_data)
{
gfloat pointer_x;
gfloat pointer_y;
gfloat new_x;
gfloat new_y;
gfloat width;
gfloat height;
Lasso *lasso = (Lasso *) user_data;
if (lasso->actor == NULL)
return TRUE;
/* redraw the lasso actor */
clutter_event_get_coords (event, &pointer_x, &pointer_y);
new_x = MIN (pointer_x, lasso->x);
new_y = MIN (pointer_y, lasso->y);
width = MAX (pointer_x, lasso->x) - new_x;
height = MAX (pointer_y, lasso->y) - new_y;
clutter_actor_set_position (lasso->actor, new_x, new_y);
clutter_actor_set_size (lasso->actor, width, height);
return TRUE;
}
int
main (int argc,
char *argv[])
{
Lasso *lasso = g_new0 (Lasso, 1);
ClutterActor *stage;
/* seed random number generator */
srand ((unsigned int) time (NULL));
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, 320, 240);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
g_signal_connect (stage,
"button-press-event",
G_CALLBACK (button_pressed_cb),
lasso);
g_signal_connect (stage,
"button-release-event",
G_CALLBACK (button_released_cb),
lasso);
g_signal_connect (stage,
"motion-event",
G_CALLBACK (pointer_motion_cb),
lasso);
clutter_actor_show (stage);
clutter_main ();
g_free (lasso);
return EXIT_SUCCESS;
}

View File

@ -1,108 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
static const ClutterColor red_color = { 0xff, 0x00, 0x00, 0xff };
static const ClutterColor green_color = { 0x00, 0xff, 0x00, 0xff };
static gboolean
button_event_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
gfloat x, y;
gchar *event_type;
guint button_pressed;
ClutterModifierType state;
gchar *ctrl_pressed;
guint32 click_count;
/* where the pointer was when the button event occurred */
clutter_event_get_coords (event, &x, &y);
/* check whether it was a press or release event */
event_type = "released";
if (clutter_event_type (event) == CLUTTER_BUTTON_PRESS)
event_type = "pressed";
/* which button triggered the event */
button_pressed = clutter_event_get_button (event);
/* keys down when the button was pressed */
state = clutter_event_get_state (event);
ctrl_pressed = "ctrl not pressed";
if (state & CLUTTER_CONTROL_MASK)
ctrl_pressed = "ctrl pressed";
/* click count */
click_count = clutter_event_get_click_count (event);
g_debug ("button %d %s at %.0f,%.0f; %s; click count %d",
button_pressed,
event_type,
x,
y,
ctrl_pressed,
click_count);
return TRUE;
}
int
main (int argc,
char *argv[])
{
ClutterActor *stage;
ClutterActor *red;
ClutterActor *green;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, 400, 400);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
red = clutter_rectangle_new_with_color (&red_color);
clutter_actor_set_size (red, 100, 100);
clutter_actor_set_position (red, 50, 150);
clutter_actor_set_reactive (red, TRUE);
green = clutter_rectangle_new_with_color (&green_color);
clutter_actor_set_size (green, 100, 100);
clutter_actor_set_position (green, 250, 150);
clutter_actor_set_reactive (green, TRUE);
g_signal_connect (red,
"button-press-event",
G_CALLBACK (button_event_cb),
NULL);
g_signal_connect (red,
"button-release-event",
G_CALLBACK (button_event_cb),
NULL);
g_signal_connect (green,
"button-press-event",
G_CALLBACK (button_event_cb),
NULL);
g_signal_connect (green,
"button-release-event",
G_CALLBACK (button_event_cb),
NULL);
clutter_container_add (CLUTTER_CONTAINER (stage),
red,
green,
NULL);
clutter_actor_show (stage);
clutter_main ();
return EXIT_SUCCESS;
}

View File

@ -1,129 +0,0 @@
#include <clutter/clutter.h>
#define STAGE_HEIGHT 300
#define STAGE_WIDTH STAGE_HEIGHT
#define SCROLL_AMOUNT STAGE_HEIGHT * 0.125
static gboolean
_scroll_event_cb (ClutterActor *viewport,
ClutterEvent *event,
gpointer user_data)
{
ClutterActor *scrollable = CLUTTER_ACTOR (user_data);
gfloat viewport_height = clutter_actor_get_height (viewport);
gfloat scrollable_height = clutter_actor_get_height (scrollable);
gfloat y;
ClutterScrollDirection direction;
/* no need to scroll if the scrollable is shorter than the viewport */
if (scrollable_height < viewport_height)
return TRUE;
y = clutter_actor_get_y (scrollable);
direction = clutter_event_get_scroll_direction (event);
switch (direction)
{
case CLUTTER_SCROLL_UP:
y -= SCROLL_AMOUNT;
break;
case CLUTTER_SCROLL_DOWN:
y += SCROLL_AMOUNT;
break;
/* we're only interested in up and down */
case CLUTTER_SCROLL_LEFT:
case CLUTTER_SCROLL_RIGHT:
break;
}
/*
* the CLAMP macro returns a value for the first argument
* that falls within the range specified by the second and
* third arguments
*
* we allow the scrollable's y position to be decremented to the point
* where its base is aligned with the base of the viewport
*/
y = CLAMP (y,
viewport_height - scrollable_height,
0.0);
/* animate the change to the scrollable's y coordinate */
clutter_actor_animate (scrollable,
CLUTTER_EASE_OUT_CUBIC,
300,
"y", y,
NULL);
return TRUE;
}
int
main (int argc, char *argv[])
{
ClutterActor *stage;
ClutterActor *viewport;
ClutterActor *texture;
const gchar *image_file_path = "redhand.png";
if (argc > 1)
{
image_file_path = argv[1];
}
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
/* the scrollable actor */
texture = clutter_texture_new ();
clutter_texture_set_keep_aspect_ratio (CLUTTER_TEXTURE (texture),
TRUE);
/* set the texture's height so it's as tall as the stage */
clutter_actor_set_request_mode (texture, CLUTTER_REQUEST_WIDTH_FOR_HEIGHT);
clutter_actor_set_height (texture, STAGE_HEIGHT);
clutter_texture_set_from_file (CLUTTER_TEXTURE (texture),
image_file_path,
NULL);
/* the viewport which the box is scrolled within */
viewport = clutter_actor_new ();
/* viewport is shorter than the stage */
clutter_actor_set_size (viewport, STAGE_WIDTH, STAGE_HEIGHT * 0.5);
/* align the viewport to the center of the stage's y axis */
clutter_actor_add_constraint (viewport, clutter_align_constraint_new (stage, CLUTTER_BIND_Y, 0.5));
/* viewport needs to respond to scroll events */
clutter_actor_set_reactive (viewport, TRUE);
/* clip all actors inside the viewport to that group's allocation */
clutter_actor_set_clip_to_allocation (viewport, TRUE);
/* put the texture inside the viewport */
clutter_actor_add_child (viewport, texture);
/* add the viewport to the stage */
clutter_actor_add_child (stage, viewport);
g_signal_connect (viewport,
"scroll-event",
G_CALLBACK (_scroll_event_cb),
texture);
clutter_actor_show (stage);
clutter_main ();
return 0;
}

View File

@ -1,115 +0,0 @@
#include <clutter/clutter.h>
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
static const ClutterColor yellow = { 0xaa, 0x99, 0x00, 0xff };
static const ClutterColor white = { 0xff, 0xff, 0xff, 0xff };
static gboolean
_pointer_enter_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
ClutterState *transitions = CLUTTER_STATE (user_data);
clutter_state_set_state (transitions, "fade-in");
return TRUE;
}
static gboolean
_pointer_leave_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
ClutterState *transitions = CLUTTER_STATE (user_data);
clutter_state_set_state (transitions, "fade-out");
return TRUE;
}
int
main (int argc, char *argv[])
{
ClutterActor *stage;
ClutterLayoutManager *layout;
ClutterActor *box;
ClutterActor *rect;
ClutterActor *text;
ClutterState *transitions;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_stage_set_title (CLUTTER_STAGE (stage), "btn");
clutter_actor_set_background_color (stage, &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
layout = clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_FILL,
CLUTTER_BIN_ALIGNMENT_FILL);
box = clutter_actor_new ();
clutter_actor_set_layout_manager (box, layout);
clutter_actor_set_position (box, 25, 25);
clutter_actor_set_reactive (box, TRUE);
clutter_actor_set_size (box, 100, 30);
/* background for the button */
rect = clutter_rectangle_new_with_color (&yellow);
clutter_actor_add_child (box, rect);
/* text for the button */
text = clutter_text_new_full ("Sans 10pt", "Hover me", &white);
/*
* NB don't set the height, so the actor assumes the height of the text;
* then when added to the bin layout, it gets centred on it;
* also if you don't set the width, the layout goes gets really wide;
* the 10pt text fits inside the 30px height of the rectangle
*/
clutter_actor_set_width (text, 100);
clutter_bin_layout_add (CLUTTER_BIN_LAYOUT (layout),
text,
CLUTTER_BIN_ALIGNMENT_CENTER,
CLUTTER_BIN_ALIGNMENT_CENTER);
/* animations */
transitions = clutter_state_new ();
clutter_state_set (transitions, NULL, "fade-out",
box, "opacity", CLUTTER_LINEAR, 180,
NULL);
/*
* NB you can't use an easing mode where alpha > 1.0 if you're
* animating to a value of 255, as the value you're animating
* to will possibly go > 255
*/
clutter_state_set (transitions, NULL, "fade-in",
box, "opacity", CLUTTER_LINEAR, 255,
NULL);
clutter_state_set_duration (transitions, NULL, NULL, 50);
clutter_state_warp_to_state (transitions, "fade-out");
g_signal_connect (box,
"enter-event",
G_CALLBACK (_pointer_enter_cb),
transitions);
g_signal_connect (box,
"leave-event",
G_CALLBACK (_pointer_leave_cb),
transitions);
/* bind the stage size to the box size + 50px in each axis */
clutter_actor_add_constraint (stage, clutter_bind_constraint_new (box, CLUTTER_BIND_HEIGHT, 50.0));
clutter_actor_add_constraint (stage, clutter_bind_constraint_new (box, CLUTTER_BIND_WIDTH, 50.0));
clutter_actor_add_child (stage, box);
clutter_actor_show (stage);
clutter_main ();
g_object_unref (transitions);
return 0;
}

View File

@ -1,163 +0,0 @@
/*
* Simple scribble application: move mouse over the dark yellow
* rectangle to draw brighter yellow lines
*/
#include <clutter/clutter.h>
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
static const ClutterColor actor_color = { 0xaa, 0x99, 0x00, 0xff };
typedef struct {
ClutterPath *path;
CoglPath *cogl_path;
} Context;
static void
_convert_clutter_path_node_to_cogl_path (const ClutterPathNode *node,
gpointer data)
{
ClutterKnot knot;
g_return_if_fail (node != NULL);
switch (node->type)
{
case CLUTTER_PATH_MOVE_TO:
knot = node->points[0];
cogl_path_move_to (knot.x, knot.y);
g_debug ("move to %d, %d", knot.x, knot.y);
break;
case CLUTTER_PATH_LINE_TO:
knot = node->points[0];
cogl_path_line_to (knot.x, knot.y);
g_debug ("line to %d, %d", knot.x, knot.y);
break;
default:
break;
}
}
static void
_canvas_paint_cb (ClutterActor *actor,
gpointer user_data)
{
Context *context = (Context *)user_data;
cogl_set_source_color4ub (255, 255, 0, 255);
cogl_set_path (context->cogl_path);
clutter_path_foreach (context->path, _convert_clutter_path_node_to_cogl_path, NULL);
cogl_path_stroke_preserve ();
clutter_path_clear (context->path);
context->cogl_path = cogl_get_path ();
g_signal_stop_emission_by_name (actor, "paint");
}
static gboolean
_pointer_motion_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
ClutterMotionEvent *motion_event = (ClutterMotionEvent *)event;
Context *context = (Context *)user_data;
gfloat x, y;
clutter_actor_transform_stage_point (actor, motion_event->x, motion_event->y, &x, &y);
g_debug ("motion; x %f, y %f", x, y);
clutter_path_add_line_to (context->path, x, y);
clutter_actor_queue_redraw (actor);
return TRUE;
}
static gboolean
_pointer_enter_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
ClutterCrossingEvent *cross_event = (ClutterCrossingEvent *)event;
Context *context = (Context *)user_data;
gfloat x, y;
clutter_actor_transform_stage_point (actor, cross_event->x, cross_event->y, &x, &y);
g_debug ("enter; x %f, y %f", x, y);
clutter_path_add_move_to (context->path, x, y);
clutter_actor_queue_redraw (actor);
return TRUE;
}
int
main (int argc, char *argv[])
{
Context *context = g_new0 (Context, 1);
ClutterActor *stage;
ClutterActor *rect;
ClutterActor *canvas;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
context->path = clutter_path_new ();
cogl_path_new ();
context->cogl_path = cogl_get_path ();
stage = clutter_stage_new ();
clutter_actor_set_size (stage, 400, 400);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
rect = clutter_rectangle_new_with_color (&actor_color);
clutter_actor_set_size (rect, 300, 300);
clutter_actor_add_constraint (rect, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5));
clutter_actor_add_constraint (rect, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.5));
clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
canvas = clutter_texture_new ();
clutter_actor_set_size (canvas, 300, 300);
clutter_actor_add_constraint (canvas, clutter_align_constraint_new (rect, CLUTTER_ALIGN_X_AXIS, 0.0));
clutter_actor_add_constraint (canvas, clutter_align_constraint_new (rect, CLUTTER_ALIGN_Y_AXIS, 0.0));
clutter_actor_set_reactive (canvas, TRUE);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), canvas);
clutter_actor_raise_top (canvas);
g_signal_connect (canvas,
"motion-event",
G_CALLBACK (_pointer_motion_cb),
context);
g_signal_connect (canvas,
"enter-event",
G_CALLBACK (_pointer_enter_cb),
context);
g_signal_connect (canvas,
"paint",
G_CALLBACK (_canvas_paint_cb),
context);
clutter_actor_show (stage);
clutter_main ();
g_object_unref (context->path);
g_free (context);
return 0;
}

View File

@ -1,93 +0,0 @@
/*
* Testing what happens with a stack of actors and pointer events
* red and green are reactive; blue is not
*
* when the pointer is over green (even if green is obscured by blue)
* signals are emitted by green (not by blue);
*
* but when the pointer is over the overlap between red and green,
* signals are emitted by green
*
* gcc -g -O0 -o stacked-actors-and-events stacked-actors-and-events.c `pkg-config --libs --cflags clutter-1.0 glib-2.0` -lm
*/
#include <clutter/clutter.h>
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
static const ClutterColor red = { 0xff, 0x00, 0x00, 0xff };
static const ClutterColor green = { 0x00, 0xff, 0x00, 0xff };
static const ClutterColor blue = { 0x00, 0x00, 0xff, 0xff };
static gboolean
_pointer_motion_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
gfloat stage_x, stage_y;
gfloat actor_x, actor_y;
/* get the coordinates where the pointer crossed into the actor */
clutter_event_get_coords (event, &stage_x, &stage_y);
/*
* as the coordinates are relative to the stage, rather than
* the actor which emitted the signal, it can be useful to
* transform them to actor-relative coordinates
*/
clutter_actor_transform_stage_point (actor,
stage_x, stage_y,
&actor_x, &actor_y);
g_debug ("pointer on actor %s @ x %.0f, y %.0f",
clutter_actor_get_name (actor),
actor_x, actor_y);
return TRUE;
}
int
main (int argc, char *argv[])
{
ClutterActor *stage;
ClutterActor *r1, *r2, *r3;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, 300, 300);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
r1 = clutter_rectangle_new_with_color (&red);
clutter_actor_set_size (r1, 150, 150);
clutter_actor_add_constraint (r1, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.25));
clutter_actor_add_constraint (r1, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.25));
clutter_actor_set_reactive (r1, TRUE);
clutter_actor_set_name (r1, "red");
r2 = clutter_rectangle_new_with_color (&green);
clutter_actor_set_size (r2, 150, 150);
clutter_actor_add_constraint (r2, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5));
clutter_actor_add_constraint (r2, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.5));
clutter_actor_set_reactive (r2, TRUE);
clutter_actor_set_depth (r2, -100);
clutter_actor_set_name (r2, "green");
r3 = clutter_rectangle_new_with_color (&blue);
clutter_actor_set_size (r3, 150, 150);
clutter_actor_add_constraint (r3, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.75));
clutter_actor_add_constraint (r3, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.75));
clutter_actor_set_opacity (r3, 125);
clutter_actor_set_name (r3, "blue");
clutter_container_add (CLUTTER_CONTAINER (stage), r1, r2, r3, NULL);
g_signal_connect (r1, "motion-event", G_CALLBACK (_pointer_motion_cb), NULL);
g_signal_connect (r2, "motion-event", G_CALLBACK (_pointer_motion_cb), NULL);
clutter_actor_show (stage);
clutter_main ();
return 0;
}

View File

@ -1,57 +0,0 @@
#include <clutter/clutter.h>
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
static const ClutterColor rectangle_color = { 0xaa, 0x99, 0x00, 0xff };
static gboolean
_pointer_motion_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
gfloat stage_x, stage_y;
gfloat actor_x, actor_y;
clutter_event_get_coords (event, &stage_x, &stage_y);
clutter_actor_transform_stage_point (actor,
stage_x, stage_y,
&actor_x, &actor_y);
g_debug ("pointer @ stage x %.0f, y %.0f; actor x %.0f, y %.0f",
stage_x, stage_y,
actor_x, actor_y);
return TRUE;
}
int
main (int argc, char *argv[])
{
ClutterActor *stage;
ClutterActor *rectangle;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, 400, 400);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
rectangle = clutter_rectangle_new_with_color (&rectangle_color);
clutter_actor_set_size (rectangle, 300, 300);
clutter_actor_set_position (rectangle, 50, 50);
clutter_actor_set_reactive (rectangle, TRUE);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), rectangle);
g_signal_connect (rectangle,
"motion-event",
G_CALLBACK (_pointer_motion_cb),
NULL);
clutter_actor_show (stage);
clutter_main ();
return 0;
}

View File

@ -1,73 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
#define OVERLAY_FACTOR 1.1
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
void
allocation_changed_cb (ClutterActor *actor,
const ClutterActorBox *allocation,
ClutterAllocationFlags flags,
gpointer user_data)
{
ClutterActor *overlay = CLUTTER_ACTOR (user_data);
gfloat width, height, x, y;
clutter_actor_box_get_size (allocation, &width, &height);
clutter_actor_box_get_origin (allocation, &x, &y);
clutter_actor_set_size (overlay,
width * OVERLAY_FACTOR,
height * OVERLAY_FACTOR);
clutter_actor_set_position (overlay,
x - ((OVERLAY_FACTOR - 1) * width * 0.5),
y - ((OVERLAY_FACTOR - 1) * width * 0.5));
}
int
main (int argc, char *argv[])
{
ClutterActor *stage;
ClutterActor *actor;
ClutterActor *overlay;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, 400, 400);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
actor = clutter_actor_new ();
clutter_actor_set_background_color (actor, CLUTTER_COLOR_Red);
clutter_actor_set_size (actor, 100, 100);
clutter_actor_set_position (actor, 150, 150);
clutter_actor_add_child (stage, actor);
overlay = clutter_actor_new ();
clutter_actor_set_background_color (overlay, CLUTTER_COLOR_Blue);
clutter_actor_set_opacity (overlay, 128);
g_signal_connect (actor,
"allocation-changed",
G_CALLBACK (allocation_changed_cb),
overlay);
clutter_actor_add_child (stage, overlay);
clutter_actor_animate (actor, CLUTTER_LINEAR, 2000,
"width", 300.0,
"height", 300.0,
"x", 50.0,
"y", 50.0,
NULL);
clutter_actor_show (stage);
clutter_main ();
return EXIT_SUCCESS;
}

View File

@ -1,136 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
#define STAGE_SIDE 400
#define RECTANGLE_SIDE STAGE_SIDE * 0.5
#define TEXTURE_SIZE_MAX STAGE_SIDE * 0.9
#define TEXTURE_SIZE_MIN STAGE_SIDE * 0.1
#define TEXTURE_SIZE_STEP 0.2
#define OVERLAY_OPACITY_OFF 0
#define OVERLAY_OPACITY_ON 100
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
static const ClutterColor overlay_color = { 0xaa, 0x99, 0x00, 0xff };
/* change the texture size with +/- */
static gboolean
key_press_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
ClutterActor *texture;
gfloat texture_width, texture_height;
guint key_pressed;
texture = CLUTTER_ACTOR (user_data);
clutter_actor_get_size (texture, &texture_width, &texture_height);
key_pressed = clutter_event_get_key_symbol (event);
if (key_pressed == CLUTTER_KEY_plus)
{
texture_width *= 1.0 + TEXTURE_SIZE_STEP;
texture_height *= 1.0 + TEXTURE_SIZE_STEP;
}
else if (key_pressed == CLUTTER_KEY_minus)
{
texture_width *= 1.0 - TEXTURE_SIZE_STEP;
texture_height *= 1.0 - TEXTURE_SIZE_STEP;
}
if (texture_width <= TEXTURE_SIZE_MAX && texture_width >= TEXTURE_SIZE_MIN)
clutter_actor_animate (texture, CLUTTER_EASE_OUT_CUBIC, 500,
"width", texture_width,
"height", texture_height,
NULL);
return TRUE;
}
/* turn overlay opacity on/off */
static void
click_cb (ClutterClickAction *action,
ClutterActor *actor,
gpointer user_data)
{
ClutterActor *overlay = CLUTTER_ACTOR (user_data);
guint8 opacity = clutter_actor_get_opacity (overlay);
if (opacity < OVERLAY_OPACITY_ON)
opacity = OVERLAY_OPACITY_ON;
else
opacity = OVERLAY_OPACITY_OFF;
clutter_actor_set_opacity (overlay, opacity);
}
int
main (int argc, char *argv[])
{
ClutterActor *stage;
ClutterActor *texture;
ClutterActor *overlay;
ClutterAction *click;
GError *error = NULL;
const gchar *filename = "redhand.png";
if (argc > 1)
filename = argv[1];
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, STAGE_SIDE, STAGE_SIDE);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
texture = clutter_texture_new ();
clutter_texture_set_keep_aspect_ratio (CLUTTER_TEXTURE (texture), TRUE);
clutter_actor_set_reactive (texture, TRUE);
clutter_actor_set_size (texture, RECTANGLE_SIDE, RECTANGLE_SIDE);
clutter_actor_add_constraint (texture, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5));
clutter_actor_add_constraint (texture, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.5));
clutter_texture_set_from_file (CLUTTER_TEXTURE (texture),
filename,
&error);
if (error != NULL)
{
g_warning ("Error loading %s\n%s", filename, error->message);
g_error_free (error);
exit (EXIT_FAILURE);
}
/* overlay is 10px wider and taller than the texture, and centered on it;
* initially, it is transparent; but it is made semi-opaque when the
* texture is clicked
*/
overlay = clutter_rectangle_new_with_color (&overlay_color);
clutter_actor_set_opacity (overlay, OVERLAY_OPACITY_OFF);
clutter_actor_add_constraint (overlay, clutter_bind_constraint_new (texture, CLUTTER_BIND_WIDTH, 10));
clutter_actor_add_constraint (overlay, clutter_bind_constraint_new (texture, CLUTTER_BIND_HEIGHT, 10));
clutter_actor_add_constraint (overlay, clutter_align_constraint_new (texture, CLUTTER_ALIGN_X_AXIS, 0.5));
clutter_actor_add_constraint (overlay, clutter_align_constraint_new (texture, CLUTTER_ALIGN_Y_AXIS, 0.5));
click = clutter_click_action_new ();
clutter_actor_add_action (texture, click);
clutter_container_add (CLUTTER_CONTAINER (stage), texture, overlay, NULL);
clutter_actor_raise_top (overlay);
g_signal_connect (click, "clicked", G_CALLBACK (click_cb), overlay);
g_signal_connect (stage,
"key-press-event",
G_CALLBACK (key_press_cb),
texture);
clutter_actor_show (stage);
clutter_main ();
return EXIT_SUCCESS;
}

View File

@ -1,56 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
static const ClutterColor rectangle_color = { 0xaa, 0x99, 0x00, 0xff };
int
main (int argc, char *argv[])
{
/* the stage is the "source" for constraints on the texture */
ClutterActor *stage;
/* the "target" actor which will be bound by the constraints */
ClutterActor *texture;
ClutterConstraint *width_binding;
ClutterConstraint *height_binding;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, 400, 400);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
/* make the stage resizable */
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
texture = clutter_texture_new ();
clutter_actor_set_opacity (texture, 50);
clutter_texture_set_repeat (CLUTTER_TEXTURE (texture), TRUE, TRUE);
clutter_texture_set_from_file (CLUTTER_TEXTURE (texture), "smiley.png", NULL);
/* the texture's width will be 100px less than the stage's */
width_binding = clutter_bind_constraint_new (stage, CLUTTER_BIND_WIDTH, -100);
/* the texture's height will be 100px less than the stage's */
height_binding = clutter_bind_constraint_new (stage, CLUTTER_BIND_HEIGHT, -100);
/* add the constraints to the texture */
clutter_actor_add_constraint (texture, width_binding);
clutter_actor_add_constraint (texture, height_binding);
/* add some alignment constraints */
clutter_actor_add_constraint (texture, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5));
clutter_actor_add_constraint (texture, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.5));
clutter_container_add_actor (CLUTTER_CONTAINER (stage), texture);
clutter_actor_show (stage);
clutter_main ();
return EXIT_SUCCESS;
}

View File

@ -1,152 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
#define FONT "Sans 20px"
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
static const ClutterColor yellow_color = { 0xaa, 0xaa, 0x00, 0xff };
static const ClutterColor black_color = { 0x00, 0x00, 0x00, 0xff };
static void
menu_run_option (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
g_debug ("%s pressed", (gchar *) user_data);
}
static void
menu_add_option (ClutterBox *menu,
gchar *text,
gchar *shortcut)
{
ClutterActor *entry;
entry = clutter_box_new (clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER,
CLUTTER_BIN_ALIGNMENT_CENTER));
clutter_box_set_color (CLUTTER_BOX (entry), &black_color);
clutter_actor_set_width (entry, 250);
clutter_actor_set_reactive (entry, TRUE);
clutter_box_pack (CLUTTER_BOX (entry),
clutter_text_new_full (FONT, text, &yellow_color),
"x-align", CLUTTER_BIN_ALIGNMENT_START,
NULL);
clutter_box_pack (CLUTTER_BOX (entry),
clutter_text_new_full (FONT, shortcut, &yellow_color),
"x-align", CLUTTER_BIN_ALIGNMENT_END,
NULL);
clutter_container_add_actor (CLUTTER_CONTAINER (menu), entry);
g_signal_connect (entry,
"button-press-event",
G_CALLBACK (menu_run_option),
text);
}
static void
menu_toggle (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
ClutterAnimation *animation;
ClutterActor *menu = CLUTTER_ACTOR (user_data);
if (clutter_actor_get_animation (menu))
return;
if (clutter_actor_get_opacity (menu) > 0)
{
animation = clutter_actor_animate (menu, CLUTTER_EASE_OUT_CUBIC, 200,
"opacity", 0,
NULL);
/* hide the menu once it is fully transparent */
g_signal_connect_swapped (animation,
"completed",
G_CALLBACK (clutter_actor_hide),
menu);
}
else
{
clutter_actor_show (menu);
clutter_actor_animate (menu, CLUTTER_EASE_OUT_CUBIC, 200,
"opacity", 255,
NULL);
}
}
int
main (int argc,
char *argv[])
{
ClutterActor *stage;
ClutterActor *button;
ClutterLayoutManager *menu_layout;
ClutterActor *menu;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, 400, 400);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
/* button */
button = clutter_box_new (clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER,
CLUTTER_BIN_ALIGNMENT_CENTER));
clutter_actor_set_width (button, 100);
clutter_actor_set_position (button, 50, 50);
clutter_actor_set_reactive (button, TRUE);
clutter_box_set_color (CLUTTER_BOX (button), &black_color);
clutter_box_pack (CLUTTER_BOX (button),
clutter_text_new_full (FONT, "Edit", &yellow_color),
"x-align", CLUTTER_BIN_ALIGNMENT_FILL,
"y-align", CLUTTER_BIN_ALIGNMENT_FILL,
NULL);
/* menu */
menu_layout = clutter_box_layout_new ();
clutter_box_layout_set_homogeneous (CLUTTER_BOX_LAYOUT (menu_layout), TRUE);
clutter_box_layout_set_vertical (CLUTTER_BOX_LAYOUT (menu_layout), TRUE);
clutter_box_layout_set_spacing (CLUTTER_BOX_LAYOUT (menu_layout), 2);
menu = clutter_box_new (menu_layout);
clutter_box_set_color (CLUTTER_BOX (menu), &yellow_color);
menu_add_option (CLUTTER_BOX (menu), "Undo", "Ctrl-z");
menu_add_option (CLUTTER_BOX (menu), "Redo", "Ctrl-Shift-z");
menu_add_option (CLUTTER_BOX (menu), "Cut", "Ctrl-x");
menu_add_option (CLUTTER_BOX (menu), "Copy", "Ctrl-c");
menu_add_option (CLUTTER_BOX (menu), "Paste", "Ctrl-v");
/* align left-hand side of menu with left-hand side of button */
clutter_actor_add_constraint (menu, clutter_align_constraint_new (button,
CLUTTER_ALIGN_X_AXIS,
0.0));
/* align top of menu with the bottom of the button */
clutter_actor_add_constraint (menu, clutter_bind_constraint_new (button,
CLUTTER_BIND_Y,
clutter_actor_get_height (button)));
/* hide the menu until we're ready to animate it in */
clutter_actor_set_opacity (menu, 0);
clutter_actor_hide (menu);
/* clicking on the button toggles the menu */
g_signal_connect (button, "button-press-event", G_CALLBACK (menu_toggle), menu);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), menu);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), button);
clutter_actor_show (stage);
clutter_main ();
return EXIT_SUCCESS;
}

View File

@ -1,466 +0,0 @@
/*
* Experiment with permutations of layout properties for a ClutterBoxLayout
*
* See the text (in brackets) at the bottom of the application
* window for available key presses
*/
#include <stdlib.h>
#include <clutter/clutter.h>
#define STAGE_SIDE 510
#define BOX_SIDE STAGE_SIDE * 0.75
#define RED_SIDE STAGE_SIDE / 4
#define GREEN_SIDE STAGE_SIDE / 8
#define BLUE_SIDE STAGE_SIDE / 16
typedef struct
{
ClutterLayoutManager *box_layout;
ClutterActor *box;
ClutterActor *status_display;
gboolean x_fill;
gboolean y_fill;
gboolean expand;
ClutterBoxAlignment x_align;
ClutterBoxAlignment y_align;
} State;
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
static const ClutterColor box_color = { 0x66, 0x66, 0x00, 0xff };
static const ClutterColor red_color = { 0xff, 0x00, 0x00, 0xff };
static const ClutterColor green_color = { 0x00, 0xff, 0x00, 0xff };
static const ClutterColor blue_color = { 0x00, 0x00, 0xff, 0xff };
static const ClutterColor white_color = { 0xff, 0xff, 0xff, 0xff };
static GValue
gboolean_to_gvalue (gboolean value)
{
GValue gval = {0};
g_value_init (&gval, G_TYPE_BOOLEAN);
g_value_set_boolean (&gval, value);
return gval;
}
static GValue
alignment_to_gvalue (ClutterBoxAlignment value)
{
GValue gval = {0};
g_value_init (&gval, G_TYPE_INT);
g_value_set_int (&gval, value);
return gval;
}
static gchar*
alignment_as_string (ClutterBoxAlignment value)
{
gchar *align_string = "start ";
switch (value)
{
case CLUTTER_BOX_ALIGNMENT_CENTER:
align_string = "center";
break;
case CLUTTER_BOX_ALIGNMENT_END:
align_string = "end ";
break;
case CLUTTER_BOX_ALIGNMENT_START:
align_string = "start ";
break;
}
return align_string;
}
static ClutterBoxAlignment
get_next_alignment (ClutterBoxAlignment alignment)
{
alignment++;
if (alignment > CLUTTER_BOX_ALIGNMENT_CENTER)
alignment = CLUTTER_BOX_ALIGNMENT_START;
return alignment;
}
static void
show_status (State *state)
{
ClutterText *text = CLUTTER_TEXT (state->status_display);
ClutterBoxLayout *box_layout = CLUTTER_BOX_LAYOUT (state->box_layout);
gboolean homogeneous = clutter_box_layout_get_homogeneous (box_layout);
gboolean vertical = clutter_box_layout_get_vertical (box_layout);
gchar *message = g_strdup_printf ("x_fill (x): %s\t\t\t"
"y_fill (y): %s\n"
"expand (e): %s\t\t"
"homogeneous (h): %s\n"
"spacing (+/-): %dpx\t\t"
"vertical (v): %s\n"
"x_align (right): %s\t"
"y_align (up): %s",
(state->x_fill ? "true" : "false"),
(state->y_fill ? "true" : "false"),
(state->expand ? "true" : "false"),
(homogeneous ? "true" : "false"),
clutter_box_layout_get_spacing (box_layout),
(vertical ? "true" : "false"),
alignment_as_string (state->x_align),
alignment_as_string (state->y_align));
clutter_text_set_text (text, message);
g_free (message);
}
static void
set_property_on_layout_children (State *state,
const gchar *property,
GValue value)
{
ClutterActor *actor;
ClutterContainer *container = CLUTTER_CONTAINER (state->box);
ClutterLayoutManager *manager = CLUTTER_LAYOUT_MANAGER (state->box_layout);
GList *actors = clutter_container_get_children (container);
for (; actors; actors = actors->next)
{
actor = CLUTTER_ACTOR (actors->data);
clutter_layout_manager_child_set_property (manager,
container,
actor,
property,
&value);
}
g_list_free (actors);
}
static void
toggle_x_fill (GObject *instance,
const gchar *action_name,
guint key_val,
ClutterModifierType modifiers,
gpointer user_data)
{
State *state = (State *) user_data;
state->x_fill = !state->x_fill;
set_property_on_layout_children (state,
"x-fill",
gboolean_to_gvalue (state->x_fill));
}
static void
toggle_y_fill (GObject *instance,
const gchar *action_name,
guint key_val,
ClutterModifierType modifiers,
gpointer user_data)
{
State *state = (State *) user_data;
state->y_fill = !state->y_fill;
set_property_on_layout_children (state,
"y-fill",
gboolean_to_gvalue (state->y_fill));
}
static void
toggle_expand (GObject *instance,
const gchar *action_name,
guint key_val,
ClutterModifierType modifiers,
gpointer user_data)
{
State *state = (State *) user_data;
state->expand = !state->expand;
set_property_on_layout_children (state,
"expand",
gboolean_to_gvalue (state->expand));
}
static void
rotate_x_alignment (GObject *instance,
const gchar *action_name,
guint key_val,
ClutterModifierType modifiers,
gpointer user_data)
{
State *state = (State *) user_data;
state->x_align = get_next_alignment (state->x_align);
set_property_on_layout_children (state,
"x-align",
alignment_to_gvalue (state->x_align));
}
static void
rotate_y_alignment (GObject *instance,
const gchar *action_name,
guint key_val,
ClutterModifierType modifiers,
gpointer user_data)
{
State *state = (State *) user_data;
state->y_align = get_next_alignment (state->y_align);
set_property_on_layout_children (state,
"y-align",
alignment_to_gvalue (state->y_align));
}
static void
toggle_vertical (GObject *instance,
const gchar *action_name,
guint key_val,
ClutterModifierType modifiers,
gpointer user_data)
{
State *state = (State *) user_data;
ClutterBoxLayout *box_layout = CLUTTER_BOX_LAYOUT (state->box_layout);
gboolean vertical = clutter_box_layout_get_vertical (box_layout);
clutter_box_layout_set_vertical (box_layout, !vertical);
}
static void
toggle_homogeneous (GObject *instance,
const gchar *action_name,
guint key_val,
ClutterModifierType modifiers,
gpointer user_data)
{
State *state = (State *) user_data;
ClutterBoxLayout *box_layout = CLUTTER_BOX_LAYOUT (state->box_layout);
gboolean homogeneous = clutter_box_layout_get_homogeneous (box_layout);
clutter_box_layout_set_homogeneous (box_layout, !homogeneous);
}
static void
increase_spacing (GObject *instance,
const gchar *action_name,
guint key_val,
ClutterModifierType modifiers,
gpointer user_data)
{
State *state = (State *) user_data;
ClutterBoxLayout *box_layout = CLUTTER_BOX_LAYOUT (state->box_layout);
guint spacing = clutter_box_layout_get_spacing (box_layout) + 5;
clutter_box_layout_set_spacing (box_layout, spacing);
}
static void
decrease_spacing (GObject *instance,
const gchar *action_name,
guint key_val,
ClutterModifierType modifiers,
gpointer user_data)
{
State *state = (State *) user_data;
ClutterBoxLayout *box_layout = CLUTTER_BOX_LAYOUT (state->box_layout);
guint spacing = clutter_box_layout_get_spacing (box_layout);
if (spacing >= 5)
clutter_box_layout_set_spacing (box_layout, spacing - 5);
}
static gboolean
key_pressed_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
State *state = (State *) user_data;
ClutterBindingPool *pool;
gboolean return_value;
pool = clutter_binding_pool_find (G_OBJECT_TYPE_NAME (actor));
return_value = clutter_binding_pool_activate (pool,
clutter_event_get_key_symbol (event),
clutter_event_get_state (event),
G_OBJECT (actor));
show_status (state);
return return_value;
}
int
main (int argc,
char *argv[])
{
ClutterActor *stage;
GObjectClass *stage_class;
ClutterBindingPool *binding_pool;
ClutterActor *red;
ClutterActor *green;
ClutterActor *blue;
State *state = g_new0 (State, 1);
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
state->x_fill = FALSE;
state->y_fill = FALSE;
state->expand = FALSE;
state->x_align = CLUTTER_BOX_ALIGNMENT_START;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, STAGE_SIDE, STAGE_SIDE);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
/* for key bindings */
stage_class = G_OBJECT_GET_CLASS (stage);
binding_pool = clutter_binding_pool_get_for_class (stage_class);
clutter_binding_pool_install_action (binding_pool,
"toggle-expand",
CLUTTER_KEY_e,
0,
G_CALLBACK (toggle_expand),
state,
NULL);
clutter_binding_pool_install_action (binding_pool,
"toggle-x-fill",
CLUTTER_KEY_x,
0,
G_CALLBACK (toggle_x_fill),
state,
NULL);
clutter_binding_pool_install_action (binding_pool,
"toggle-y-fill",
CLUTTER_KEY_y,
0,
G_CALLBACK (toggle_y_fill),
state,
NULL);
clutter_binding_pool_install_action (binding_pool,
"toggle-vertical",
CLUTTER_KEY_v,
0,
G_CALLBACK (toggle_vertical),
state,
NULL);
clutter_binding_pool_install_action (binding_pool,
"toggle-homogeneous",
CLUTTER_KEY_h,
0,
G_CALLBACK (toggle_homogeneous),
state,
NULL);
clutter_binding_pool_install_action (binding_pool,
"rotate-x-alignment",
CLUTTER_KEY_Right,
0,
G_CALLBACK (rotate_x_alignment),
state,
NULL);
clutter_binding_pool_install_action (binding_pool,
"rotate-y-alignment",
CLUTTER_KEY_Up,
0,
G_CALLBACK (rotate_y_alignment),
state,
NULL);
clutter_binding_pool_install_action (binding_pool,
"increase-spacing",
CLUTTER_KEY_plus,
CLUTTER_SHIFT_MASK,
G_CALLBACK (increase_spacing),
state,
NULL);
clutter_binding_pool_install_action (binding_pool,
"decrease-spacing",
CLUTTER_KEY_minus,
0,
G_CALLBACK (decrease_spacing),
state,
NULL);
/* rectangles inside the layout */
red = clutter_rectangle_new_with_color (&red_color);
clutter_actor_set_size (red, RED_SIDE, RED_SIDE);
green = clutter_rectangle_new_with_color (&green_color);
clutter_actor_set_size (green, GREEN_SIDE, GREEN_SIDE);
blue = clutter_rectangle_new_with_color (&blue_color);
clutter_actor_set_size (blue, BLUE_SIDE, BLUE_SIDE);
/* the layout */
state->box_layout = clutter_box_layout_new ();
clutter_box_layout_set_use_animations (CLUTTER_BOX_LAYOUT (state->box_layout),
TRUE);
state->box = clutter_box_new (state->box_layout);
clutter_box_set_color (CLUTTER_BOX (state->box), &box_color);
clutter_actor_set_size (state->box, BOX_SIDE, BOX_SIDE);
clutter_actor_add_constraint (state->box,
clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5));
clutter_actor_add_constraint (state->box,
clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.1));
/* text to show status */
state->status_display = clutter_text_new ();
clutter_text_set_color (CLUTTER_TEXT (state->status_display), &white_color);
clutter_actor_set_size (state->status_display,
STAGE_SIDE,
STAGE_SIDE * 0.2);
clutter_actor_set_position (state->status_display,
(STAGE_SIDE - BOX_SIDE) / 2,
STAGE_SIDE * 0.8);
/* set text for initial state */
show_status (state);
/* connect key presses to a callback on the binding pool */
g_signal_connect (stage,
"key-press-event",
G_CALLBACK (key_pressed_cb),
state);
/* pack UI */
clutter_container_add (CLUTTER_CONTAINER (state->box), red, green, blue, NULL);
clutter_container_add (CLUTTER_CONTAINER (stage),
state->box,
state->status_display,
NULL);
/* show stage */
clutter_actor_show (stage);
clutter_main ();
/* clean up */
g_object_unref (binding_pool);
g_free (state);
return EXIT_SUCCESS;
}

View File

@ -1,97 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
static const ClutterColor box_color = { 0xff, 0xff, 0xff, 0xff };
static const ClutterColor yellow_color = { 0xaa, 0xaa, 0x00, 0xff };
static const ClutterColor red_color = { 0xff, 0x00, 0x00, 0xff };
static const ClutterColor blue_color = { 0x00, 0x00, 0xff, 0xff };
int
main (int argc,
char *argv[])
{
ClutterActor *stage;
ClutterLayoutManager *box_layout;
ClutterActor *box;
ClutterActor *yellow;
ClutterActor *red;
ClutterActor *blue;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, 400, 400);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
/* create a ClutterBoxLayout */
box_layout = clutter_box_layout_new ();
/* configure it to lay out actors vertically */
clutter_box_layout_set_vertical (CLUTTER_BOX_LAYOUT (box_layout), TRUE);
/* put 5px of spacing between actors */
clutter_box_layout_set_spacing (CLUTTER_BOX_LAYOUT (box_layout), 5);
/* actors are packed into this actor; we set its width, but
* allow its height to be determined by the children it contains
*/
box = clutter_actor_new ();
clutter_actor_set_layout_manager (box, box_layout);
clutter_actor_set_background_color (box, CLUTTER_COLOR_White);
clutter_actor_set_position (box, 100, 50);
clutter_actor_set_width (box, 200);
/* pack an actor into the layout and set all layout properties on it
* at the same time
*/
yellow = clutter_actor_new ();
clutter_actor_set_background_color (yellow, CLUTTER_COLOR_Yellow);
clutter_actor_set_size (yellow, 100, 100);
clutter_box_layout_pack (CLUTTER_BOX_LAYOUT (box_layout),
yellow,
FALSE, /* expand */
TRUE, /* x-fill */
FALSE, /* y-fill */
CLUTTER_BOX_ALIGNMENT_START, /* x-align */
CLUTTER_BOX_ALIGNMENT_START); /* y-align */
/* add an actor to the box as a container and set layout properties
* afterwards; the latter is useful if you want to change properties on
* actors already inside a layout, but note that you have to
* pass the function both the layout AND the container
*/
red = clutter_actor_new ();
clutter_actor_set_background_color (red, CLUTTER_COLOR_Red);
clutter_actor_set_size (red, 100, 100);
clutter_actor_add_child (box, red);
clutter_layout_manager_child_set (box_layout,
CLUTTER_CONTAINER (box),
red,
"x-fill", TRUE,
NULL);
blue = clutter_actor_new ();
clutter_actor_set_background_color (blue, CLUTTER_COLOR_Blue);
clutter_actor_set_size (blue, 100, 100);
clutter_actor_add_child (box, blue);
clutter_layout_manager_child_set (box_layout,
CLUTTER_CONTAINER (box),
blue,
"x-fill", TRUE,
NULL);
/* put the box on the stage */
clutter_actor_add_child (stage, box);
clutter_actor_show (stage);
clutter_main ();
return EXIT_SUCCESS;
}

View File

@ -1,82 +0,0 @@
#include <clutter/clutter.h>
static const ClutterColor dark_grey = { 0x66, 0x66, 0x66, 0xff };
static const ClutterColor light_grey = { 0xcc, 0xcc, 0xcc, 0xff };
int
main (int argc, char *argv[])
{
ClutterActor *stage;
ClutterLayoutManager *layout;
ClutterActor *box;
ClutterActor *rect1, *rect2;
guint align_x, align_y, diff_x, diff_y;
ClutterColor *color;
ClutterActor *rect;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, 400, 400);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
layout = clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_START,
CLUTTER_BIN_ALIGNMENT_START);
box = clutter_box_new (layout);
rect1 = clutter_rectangle_new_with_color (&dark_grey);
clutter_actor_set_size (rect1, 400, 200);
rect2 = clutter_rectangle_new_with_color (&light_grey);
clutter_actor_set_size (rect2, 200, 400);
clutter_container_add (CLUTTER_CONTAINER (box),
rect1,
rect2,
NULL);
/*
* 2 = CLUTTER_BIN_ALIGNMENT_START
* 3 = CLUTTER_BIN_ALIGNMENT_END
* 4 = CLUTTER_BIN_ALIGNMENT_CENTER
*/
for (align_x = 2; align_x < 5; align_x++)
{
for (align_y = 2; align_y < 5; align_y++)
{
diff_x = align_x - 1;
if (align_x == 3)
diff_x = 3;
else if (align_x == 4)
diff_x = 2;
diff_y = align_y - 1;
if (align_y == 3)
diff_y = 3;
else if (align_y == 4)
diff_y = 2;
color = clutter_color_new (255 - diff_x * 50,
100 + diff_y * 50,
0,
255);
rect = clutter_rectangle_new_with_color (color);
clutter_actor_set_size (rect, 100, 100);
clutter_bin_layout_set_alignment (CLUTTER_BIN_LAYOUT (layout),
rect,
align_x,
align_y);
clutter_container_add_actor (CLUTTER_CONTAINER (box), rect);
}
}
clutter_container_add_actor (CLUTTER_CONTAINER (stage), box);
clutter_actor_show (stage);
clutter_main ();
return 0;
}

View File

@ -1,82 +0,0 @@
/*
* Display multiple rotated copies of an image on top of each other
*
* Invoke with the path to a file to load a custom image
*/
#include <clutter/clutter.h>
#define STAGE_SIDE 512
static const ClutterColor box_color = { 0x33, 0x33, 0x55, 0xff };
int
main (int argc, char *argv[])
{
ClutterLayoutManager *layout;
ClutterActor *box;
ClutterActor *stage;
ClutterActor *texture;
CoglHandle *cogl_texture;
GError *error = NULL;
gfloat width;
const gchar *filename = "redhand.png";
if (argc > 1)
filename = argv[1];
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, STAGE_SIDE, STAGE_SIDE);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
layout = clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER,
CLUTTER_BIN_ALIGNMENT_CENTER);
box = clutter_actor_new ();
clutter_actor_set_layout_manager (box, layout);
clutter_actor_set_background_color (box, &box_color);
texture = clutter_texture_new_from_file (filename, &error);
if (error != NULL)
g_error ("Error loading file %s; message was:\n%s",
filename,
error->message);
/*
* get a reference to the underlying Cogl texture
* for copying onto each Clutter texture placed into the layout
*/
cogl_texture = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (texture));
/*
* add gradually turning and shrinking textures,
* smallest one last; each actor ends up on top
* of the one added just before it
*/
for (width = STAGE_SIDE * 0.75; width >= STAGE_SIDE * 0.0625; width -= STAGE_SIDE * 0.0625)
{
ClutterActor *texture_copy = clutter_texture_new ();
clutter_texture_set_cogl_texture (CLUTTER_TEXTURE (texture_copy),
cogl_texture);
clutter_texture_set_keep_aspect_ratio (CLUTTER_TEXTURE (texture_copy),
TRUE);
clutter_actor_set_z_rotation_from_gravity (texture_copy,
(gfloat)(width * 0.5) - (STAGE_SIDE * 0.03125),
CLUTTER_GRAVITY_CENTER);
clutter_actor_set_width (texture_copy, width);
clutter_actor_add_child (box, texture_copy);
}
clutter_actor_add_constraint (box, clutter_align_constraint_new (stage, CLUTTER_ALIGN_BOTH, 0.5));
clutter_actor_add_child (stage, box);
clutter_actor_show (stage);
clutter_main ();
return 0;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -1,98 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
/* callbacks cannot be declared static as they
* are looked up dynamically by ClutterScript
*/
gboolean
foo_pointer_motion_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
gfloat x, y;
clutter_event_get_coords (event, &x, &y);
g_print ("Pointer movement at %.0f,%.0f\n", x, y);
return TRUE;
}
void
foo_button_clicked_cb (ClutterClickAction *action,
ClutterActor *actor,
gpointer user_data)
{
gfloat z_angle;
/* get the UI definition passed to the handler */
ClutterScript *ui = CLUTTER_SCRIPT (user_data);
/* get the rectangle defined in the JSON */
ClutterActor *rectangle;
clutter_script_get_objects (ui,
"rectangle", &rectangle,
NULL);
/* do nothing if the actor is already animating */
if (clutter_actor_get_animation (rectangle) != NULL)
return;
/* get the current rotation and increment it */
z_angle = clutter_actor_get_rotation (rectangle,
CLUTTER_Z_AXIS,
NULL, NULL, NULL);
if (clutter_click_action_get_button (action) == 1)
z_angle += 90.0;
else
z_angle -= 90.0;
/* animate to new rotation angle */
clutter_actor_animate (rectangle,
CLUTTER_EASE_OUT_CUBIC,
1000,
"rotation-angle-z", z_angle,
NULL);
}
int
main (int argc, char *argv[])
{
ClutterActor *stage;
ClutterScript *ui;
gchar *filename = "script-signals.json";
GError *error = NULL;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
ui = clutter_script_new ();
clutter_script_load_from_file (ui, filename, &error);
if (error != NULL)
{
g_critical ("Error loading ClutterScript file %s\n%s", filename, error->message);
g_error_free (error);
exit (EXIT_FAILURE);
}
clutter_script_get_objects (ui,
"stage", &stage,
NULL);
/* make the objects in the script available to all signals
* by passing the script as the second argument
* to clutter_script_connect_signals()
*/
clutter_script_connect_signals (ui, ui);
clutter_actor_show (stage);
clutter_main ();
g_object_unref (ui);
return EXIT_SUCCESS;
}

View File

@ -1,40 +0,0 @@
[
{
"id" : "stage",
"type" : "ClutterStage",
"width" : 300,
"height" : 300,
"color" : "#335",
"signals" : [
{ "name" : "destroy", "handler" : "clutter_main_quit" }
],
"children" : [ "rectangle" ]
},
{
"id" : "rectangle",
"type" : "ClutterRectangle",
"width" : 200,
"height" : 200,
"x" : 50,
"y" : 50,
"color" : "#a90",
"rotation-center-z-gravity" : "center",
"reactive" : true,
"signals" : [
{ "name" : "motion-event", "handler" : "foo_pointer_motion_cb" }
],
"actions" : [
{
"type" : "ClutterClickAction",
"signals" : [
{ "name" : "clicked", "handler" : "foo_button_clicked_cb" }
]
}
]
}
]

View File

@ -1,44 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
int
main (int argc, char *argv[])
{
ClutterActor *stage;
ClutterScript *ui;
gchar *filename = "script-states.json";
GError *error = NULL;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
ui = clutter_script_new ();
clutter_script_load_from_file (ui, filename, &error);
if (error != NULL)
{
g_critical ("Error loading ClutterScript file %s\n%s", filename, error->message);
g_error_free (error);
exit (EXIT_FAILURE);
}
clutter_script_get_objects (ui,
"stage", &stage,
NULL);
/* make the objects in the script available to all signals
* by passing the script as the second argument
* to clutter_script_connect_signals()
*/
clutter_script_connect_signals (ui, ui);
clutter_actor_show (stage);
clutter_main ();
g_object_unref (ui);
return EXIT_SUCCESS;
}

View File

@ -1,92 +0,0 @@
[
{
"id" : "stage",
"type" : "ClutterStage",
"width" : 300,
"height" : 300,
"color" : "#335",
"signals" : [
{ "name" : "destroy", "handler" : "clutter_main_quit" }
],
"children" : [ "rectangle" ]
},
{
"id" : "rectangle-states",
"type" : "ClutterState",
"duration" : 1000,
"transitions" : [
{
"source" : null,
"target" : "base",
"keys" : [
[ "rectangle", "scale-x", "ease-in-cubic", 0.7 ],
[ "rectangle", "scale-y", "ease-in-cubic", 0.7 ],
[ "rectangle", "rotation-angle-z", "ease-out-cubic", 0.0 ]
]
},
{
"source" : null,
"target" : "hover",
"keys" : [
[ "rectangle", "scale-x", "ease-in-cubic", 1.2 ],
[ "rectangle", "scale-y", "ease-in-cubic", 1.2 ]
]
},
{
"source" : null,
"target" : "clicked",
"keys" : [
[ "rectangle", "rotation-angle-z", "ease-out-bounce", 90.0 ]
]
}
]
},
{
"id" : "rectangle",
"type" : "ClutterRectangle",
"width" : 200,
"height" : 200,
"x" : 50,
"y" : 50,
"color" : "#a90",
"rotation-center-z-gravity" : "center",
"scale-gravity" : "center",
"scale-x" : 0.7,
"scale-y" : 0.7,
"reactive" : true,
"signals" : [
{
"name" : "enter-event",
"states" : "rectangle-states",
"target-state" : "hover"
},
{
"name" : "leave-event",
"states" : "rectangle-states",
"target-state" : "base"
}
],
"actions" : [
{
"type" : "ClutterClickAction",
"signals" : [
{
"name" : "clicked",
"states" : "rectangle-states",
"target-state" : "clicked"
}
]
}
]
}
]

View File

@ -1,38 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
int
main (int argc, char *argv[])
{
ClutterActor *stage;
ClutterScript *ui;
gchar *filename = "script-ui.json";
GError *error = NULL;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
ui = clutter_script_new ();
/* load a JSON file into the script */
clutter_script_load_from_file (ui, filename, &error);
if (error != NULL)
{
g_critical ("Error loading ClutterScript file %s\n%s", filename, error->message);
g_error_free (error);
exit (EXIT_FAILURE);
}
/* retrieve objects from the script */
clutter_script_get_objects (ui,
"stage", &stage,
NULL);
clutter_actor_show (stage);
clutter_main ();
return EXIT_SUCCESS;
}

View File

@ -1,34 +0,0 @@
[
{
"id" : "stage",
"type" : "ClutterStage",
"width" : 400,
"height" : 400,
"color" : "#333355ff",
"children" : [ "box" ]
},
{
"id" : "box",
"type" : "ClutterBox",
"width" : 400,
"height" : 400,
"layout-manager" : {
"type" : "ClutterBinLayout",
"x-align" : "center",
"y-align" : "center"
},
"children" : [
{
"id" : "rectangle",
"type" : "ClutterRectangle",
"width" : 200,
"height" : 200,
"color" : "red"
}
]
}
]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -1,64 +0,0 @@
#include <stdlib.h>
#include <cogl/cogl.h>
#include <cogl-pango/cogl-pango.h>
#include <clutter/clutter.h>
#define SHADOW_X_OFFSET 3
#define SHADOW_Y_OFFSET 3
static void
_text_paint_cb (ClutterActor *actor)
{
PangoLayout *layout;
guint8 real_opacity;
CoglColor color;
ClutterText *text = CLUTTER_TEXT (actor);
ClutterColor text_color = { 0, };
/* Get the PangoLayout that the Text actor is going to paint */
layout = clutter_text_get_layout (text);
/* Get the color of the text, to extract the alpha component */
clutter_text_get_color (text, &text_color);
/* Composite the opacity so that the shadow is correctly blended */
real_opacity = clutter_actor_get_paint_opacity (actor)
* text_color.alpha
/ 255;
/* Create a #ccc color and premultiply it */
cogl_color_init_from_4ub (&color, 0xcc, 0xcc, 0xcc, real_opacity);
cogl_color_premultiply (&color);
/* Finally, render the Text layout at a given offset using the color */
cogl_pango_render_layout (layout, SHADOW_X_OFFSET, SHADOW_Y_OFFSET, &color, 0);
}
int
main (int argc, char *argv[])
{
ClutterActor *stage;
ClutterActor *text;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_stage_set_title (CLUTTER_STAGE (stage), "Text shadow");
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
text = clutter_text_new ();
clutter_text_set_text (CLUTTER_TEXT (text), "Hello, World!");
clutter_text_set_font_name (CLUTTER_TEXT (text), "Sans 64px");
clutter_actor_add_constraint (text, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5));
clutter_actor_add_constraint (text, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.5));
g_signal_connect (text, "paint", G_CALLBACK (_text_paint_cb), NULL);
clutter_container_add (CLUTTER_CONTAINER (stage), text, NULL);
clutter_actor_show (stage);
clutter_main ();
return EXIT_SUCCESS;
}

View File

@ -1,175 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
static gchar *source = NULL;
static gchar *target = NULL;
static guint duration = 1000;
static GOptionEntry entries[] = {
{
"source", 's',
0,
G_OPTION_ARG_FILENAME, &source,
"The source image of the cross-fade", "FILE"
},
{
"target", 't',
0,
G_OPTION_ARG_FILENAME, &target,
"The target image of the cross-fade", "FILE"
},
{
"duration", 'd',
0,
G_OPTION_ARG_INT, &duration,
"The duration of the cross-fade, in milliseconds", "MSECS"
},
{ NULL }
};
static void
_update_progress_cb (ClutterTimeline *timeline,
guint elapsed_msecs,
ClutterTexture *texture)
{
CoglHandle copy;
gdouble progress;
CoglColor constant;
CoglHandle material = clutter_texture_get_cogl_material (texture);
if (material == COGL_INVALID_HANDLE)
return;
/* You should assume that a material can only be modified once, after
* its creation; if you need to modify it later you should use a copy
* instead. Cogl makes copying materials reasonably cheap
*/
copy = cogl_material_copy (material);
progress = clutter_timeline_get_progress (timeline);
/* Create the constant color to be used when combining the two
* material layers; we use a black color with an alpha component
* depending on the current progress of the timeline
*/
cogl_color_init_from_4ub (&constant, 0x00, 0x00, 0x00, 0xff * progress);
/* This sets the value of the constant color we use when combining
* the two layers
*/
cogl_material_set_layer_combine_constant (copy, 1, &constant);
/* The Texture now owns the material */
clutter_texture_set_cogl_material (texture, copy);
cogl_handle_unref (copy);
clutter_actor_queue_redraw (CLUTTER_ACTOR (texture));
}
static CoglHandle
load_cogl_texture (const char *type,
const char *file)
{
GError *error = NULL;
CoglHandle retval = cogl_texture_new_from_file (file,
COGL_TEXTURE_NO_SLICING,
COGL_PIXEL_FORMAT_ANY,
&error);
if (error != NULL)
{
g_print ("Unable to load %s image: %s\n", type, error->message);
g_error_free (error);
exit (EXIT_FAILURE);
}
return retval;
}
static int
print_usage_and_exit (const char *exec_name,
int exit_code)
{
g_print ("Usage: %s -s <source> -t <target> [-d <duration>]\n", exec_name);
return exit_code;
}
int
main (int argc, char *argv[])
{
CoglHandle texture_1;
CoglHandle texture_2;
CoglHandle material;
ClutterActor *stage;
ClutterActor *texture;
ClutterTimeline *timeline;
if (clutter_init_with_args (&argc, &argv,
" - Crossfade", entries,
NULL,
NULL) != CLUTTER_INIT_SUCCESS)
return 1;
if (source == NULL || target == NULL)
return print_usage_and_exit (argv[0], EXIT_FAILURE);
/* Load the source and target images using Cogl, because we need
* to combine them into the same ClutterTexture.
*/
texture_1 = load_cogl_texture ("source", source);
texture_2 = load_cogl_texture ("target", target);
/* Create a new Cogl material holding the two textures inside two
* separate layers.
*/
material = cogl_material_new ();
cogl_material_set_layer (material, 1, texture_1);
cogl_material_set_layer (material, 0, texture_2);
/* Set the layer combination description for the second layer; the
* default for Cogl is to simply multiply the layer with the
* precendent one. In this case we interpolate the color for each
* pixel between the pixel value of the previous layer and the
* current one, using the alpha component of a constant color as
* the interpolation factor.
*/
cogl_material_set_layer_combine (material, 1,
"RGBA = INTERPOLATE (PREVIOUS, "
"TEXTURE, "
"CONSTANT[A])",
NULL);
/* The material now owns the two textures */
cogl_handle_unref (texture_1);
cogl_handle_unref (texture_2);
/* Create a Texture and place it in the middle of the stage; then
* assign the material we created earlier to the Texture for painting
* it
*/
stage = clutter_stage_new ();
clutter_stage_set_title (CLUTTER_STAGE (stage), "cross-fade");
clutter_actor_set_size (stage, 400, 300);
clutter_actor_show (stage);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
texture = clutter_texture_new ();
clutter_container_add_actor (CLUTTER_CONTAINER (stage), texture);
clutter_texture_set_cogl_material (CLUTTER_TEXTURE (texture), material);
clutter_actor_add_constraint (texture, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5));
clutter_actor_add_constraint (texture, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.5));
cogl_handle_unref (material);
/* The timeline will drive the cross-fading */
timeline = clutter_timeline_new (duration);
g_signal_connect (timeline, "new-frame", G_CALLBACK (_update_progress_cb), texture);
clutter_timeline_start (timeline);
clutter_main ();
g_object_unref (timeline);
return EXIT_SUCCESS;
}

View File

@ -1,186 +0,0 @@
/*
* Simple slideshow application, cycling images between
* two ClutterTextures
*
* Run by passing one or more image paths or directory globs
* which will pick up image files
*
* When running, press any key to go to the next image
*/
#include <stdlib.h>
#include <clutter/clutter.h>
static guint stage_side = 600;
static guint animation_duration_ms = 1500;
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
typedef struct {
ClutterActor *top;
ClutterActor *bottom;
ClutterState *transitions;
GSList *image_paths;
guint next_image_index;
} State;
static gboolean
load_next_image (State *app)
{
gpointer next;
gchar *image_path;
CoglHandle *cogl_texture;
GError *error = NULL;
/* don't do anything if already animating */
ClutterTimeline *timeline = clutter_state_get_timeline (app->transitions);
if (clutter_timeline_is_playing (timeline) == 1)
{
g_debug ("Animation is running already");
return FALSE;
}
if (!app->next_image_index)
app->next_image_index = 0;
next = g_slist_nth_data (app->image_paths, app->next_image_index);
if (next == NULL)
return FALSE;
image_path = (gchar *)next;
g_debug ("Loading %s", image_path);
cogl_texture = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (app->top));
if (cogl_texture != NULL)
{
/* copy the current texture into the background */
clutter_texture_set_cogl_texture (CLUTTER_TEXTURE (app->bottom), cogl_texture);
/* make the bottom opaque and top transparent */
clutter_state_warp_to_state (app->transitions, "show-bottom");
}
/* load the next image into the top */
clutter_texture_set_from_file (CLUTTER_TEXTURE (app->top),
image_path,
&error);
if (error != NULL)
{
g_warning ("Error loading %s\n%s", image_path, error->message);
g_error_free (error);
return FALSE;
}
/* fade in the top texture and fade out the bottom texture */
clutter_state_set_state (app->transitions, "show-top");
app->next_image_index++;
return TRUE;
}
static gboolean
_key_pressed_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
State *app = (State *)user_data;
load_next_image (app);
return TRUE;
}
int
main (int argc, char *argv[])
{
State *app = g_new0 (State, 1);
guint i;
GError *error = NULL;
/* UI */
ClutterActor *stage;
ClutterLayoutManager *layout;
ClutterActor *box;
if (argc < 2)
{
g_print ("Usage: %s <image paths to load>\n", argv[0]);
exit (EXIT_FAILURE);
}
app->image_paths = NULL;
/*
* NB if your shell globs arguments to this program so argv
* includes non-image files, they will fail to load and throw errors
*/
for (i = 1; i < argc; i++)
app->image_paths = g_slist_append (app->image_paths, argv[i]);
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
clutter_stage_set_title (CLUTTER_STAGE (stage), "cross-fade");
clutter_actor_set_size (stage, stage_side, stage_side);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
layout = clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER,
CLUTTER_BIN_ALIGNMENT_CENTER);
box = clutter_box_new (layout);
clutter_actor_set_size (box, stage_side, stage_side);
app->bottom = clutter_texture_new ();
clutter_texture_set_keep_aspect_ratio (CLUTTER_TEXTURE (app->bottom), TRUE);
app->top = clutter_texture_new ();
clutter_texture_set_keep_aspect_ratio (CLUTTER_TEXTURE (app->top), TRUE);
clutter_container_add_actor (CLUTTER_CONTAINER (box), app->bottom);
clutter_container_add_actor (CLUTTER_CONTAINER (box), app->top);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), box);
/* animations */
app->transitions = clutter_state_new ();
clutter_state_set (app->transitions, NULL, "show-top",
app->top, "opacity", CLUTTER_EASE_IN_CUBIC, 255,
app->bottom, "opacity", CLUTTER_EASE_IN_CUBIC, 0,
NULL);
clutter_state_set (app->transitions, NULL, "show-bottom",
app->top, "opacity", CLUTTER_LINEAR, 0,
app->bottom, "opacity", CLUTTER_LINEAR, 255,
NULL);
clutter_state_set_duration (app->transitions,
NULL,
NULL,
animation_duration_ms);
/* display the next (first) image */
load_next_image (app);
/* key press displays the next image */
g_signal_connect (stage,
"key-press-event",
G_CALLBACK (_key_pressed_cb),
app);
clutter_actor_show (stage);
clutter_main ();
g_slist_free (app->image_paths);
g_object_unref (app->transitions);
g_free (app);
if (error != NULL)
g_error_free (error);
return EXIT_SUCCESS;
}

View File

@ -1,144 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
static gchar *source = NULL;
static gchar *target = NULL;
static guint duration = 1000;
static GOptionEntry entries[] = {
{
"source", 's',
0,
G_OPTION_ARG_FILENAME, &source,
"The source image of the cross-fade", "FILE"
},
{
"target", 't',
0,
G_OPTION_ARG_FILENAME, &target,
"The target image of the cross-fade", "FILE"
},
{
"duration", 'd',
0,
G_OPTION_ARG_INT, &duration,
"The duration of the cross-fade, in milliseconds", "MSECS"
},
{ NULL }
};
static gboolean
start_animation (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
ClutterState *transitions = CLUTTER_STATE (user_data);
clutter_state_set_state (transitions, "show-top");
return TRUE;
}
static gboolean
load_image (ClutterTexture *texture,
gchar *image_path)
{
GError *error = NULL;
gboolean success = clutter_texture_set_from_file (CLUTTER_TEXTURE (texture),
image_path,
&error);
if (error != NULL)
{
g_warning ("Error loading %s\n%s", image_path, error->message);
g_error_free (error);
exit (EXIT_FAILURE);
}
return success;
}
int
main (int argc, char *argv[])
{
GError *error = NULL;
/* UI */
ClutterActor *stage;
ClutterLayoutManager *layout;
ClutterActor *box;
ClutterActor *top, *bottom;
ClutterState *transitions;
if (clutter_init_with_args (&argc, &argv,
" - cross-fade", entries,
NULL,
NULL) != CLUTTER_INIT_SUCCESS)
return 1;
if (source == NULL || target == NULL)
{
g_print ("Usage: %s -s <source> -t <target> [-d <duration>]\n", argv[0]);
exit (EXIT_FAILURE);
}
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_stage_set_title (CLUTTER_STAGE (stage), "cross-fade");
clutter_actor_set_size (stage, 400, 300);
clutter_actor_show (stage);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
layout = clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER,
CLUTTER_BIN_ALIGNMENT_CENTER);
box = clutter_box_new (layout);
clutter_actor_set_size (box, 400, 300);
bottom = clutter_texture_new ();
top = clutter_texture_new ();
clutter_container_add_actor (CLUTTER_CONTAINER (box), bottom);
clutter_container_add_actor (CLUTTER_CONTAINER (box), top);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), box);
/* load the first image into the bottom */
load_image (CLUTTER_TEXTURE (bottom), source);
/* load the second image into the top */
load_image (CLUTTER_TEXTURE (top), target);
/* animations */
transitions = clutter_state_new ();
clutter_state_set (transitions, NULL, "show-bottom",
top, "opacity", CLUTTER_LINEAR, 0,
bottom, "opacity", CLUTTER_LINEAR, 255,
NULL);
clutter_state_set (transitions, NULL, "show-top",
top, "opacity", CLUTTER_EASE_IN_CUBIC, 255,
bottom, "opacity", CLUTTER_EASE_IN_CUBIC, 0,
NULL);
clutter_state_set_duration (transitions, NULL, NULL, duration);
/* make the bottom opaque and top transparent */
clutter_state_warp_to_state (transitions, "show-bottom");
/* on key press, fade in the top texture and fade out the bottom texture */
g_signal_connect (stage,
"key-press-event",
G_CALLBACK (start_animation),
transitions);
clutter_actor_show (stage);
clutter_main ();
g_object_unref (transitions);
if (error != NULL)
g_error_free (error);
return EXIT_SUCCESS;
}

View File

@ -1,111 +0,0 @@
#include <stdlib.h>
#include <clutter/clutter.h>
/* pixels between the source and its reflection */
#define V_PADDING 4
static void
_clone_paint_cb (ClutterActor *actor)
{
ClutterActor *source;
ClutterActorBox box;
CoglHandle material;
gfloat width, height;
guint8 opacity;
CoglColor color_1, color_2;
CoglTextureVertex vertices[4];
/* if we don't have a source actor, don't paint */
source = clutter_clone_get_source (CLUTTER_CLONE (actor));
if (source == NULL)
goto out;
/* if the source texture does not have any content, don't paint */
material = clutter_texture_get_cogl_material (CLUTTER_TEXTURE (source));
if (material == NULL)
goto out;
/* get the size of the reflection */
clutter_actor_get_allocation_box (actor, &box);
clutter_actor_box_get_size (&box, &width, &height);
/* get the composite opacity of the actor */
opacity = clutter_actor_get_paint_opacity (actor);
/* figure out the two colors for the reflection: the first is
* full color and the second is the same, but at 0 opacity
*/
cogl_color_init_from_4f (&color_1, 1.0, 1.0, 1.0, opacity / 255.);
cogl_color_premultiply (&color_1);
cogl_color_init_from_4f (&color_2, 1.0, 1.0, 1.0, 0.0);
cogl_color_premultiply (&color_2);
/* now describe the four vertices of the quad; since it has
* to be a reflection, we need to invert it as well
*/
vertices[0].x = 0; vertices[0].y = 0; vertices[0].z = 0;
vertices[0].tx = 0.0; vertices[0].ty = 1.0;
vertices[0].color = color_1;
vertices[1].x = width; vertices[1].y = 0; vertices[1].z = 0;
vertices[1].tx = 1.0; vertices[1].ty = 1.0;
vertices[1].color = color_1;
vertices[2].x = width; vertices[2].y = height; vertices[2].z = 0;
vertices[2].tx = 1.0; vertices[2].ty = 0.0;
vertices[2].color = color_2;
vertices[3].x = 0; vertices[3].y = height; vertices[3].z = 0;
vertices[3].tx = 0.0; vertices[3].ty = 0.0;
vertices[3].color = color_2;
/* paint the same texture but with a different geometry */
cogl_set_source (material);
cogl_polygon (vertices, 4, TRUE);
out:
/* prevent the default clone handler from running */
g_signal_stop_emission_by_name (actor, "paint");
}
int
main (int argc, char *argv[])
{
ClutterActor *stage;
ClutterActor *texture;
GError *error = NULL;
ClutterActor *clone;
gfloat y_offset;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_stage_set_title (CLUTTER_STAGE (stage), "Reflection");
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
texture = clutter_texture_new ();
clutter_texture_set_from_file (CLUTTER_TEXTURE (texture),
"redhand.png",
&error);
clutter_actor_add_constraint (texture, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5));
clutter_actor_add_constraint (texture, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.2));
y_offset = clutter_actor_get_height (texture) + V_PADDING;
clone = clutter_clone_new (texture);
clutter_actor_add_constraint (clone, clutter_bind_constraint_new (texture, CLUTTER_BIND_X, 0.0));
clutter_actor_add_constraint (clone, clutter_bind_constraint_new (texture, CLUTTER_BIND_Y, y_offset));
g_signal_connect (clone,
"paint",
G_CALLBACK (_clone_paint_cb),
NULL);
clutter_container_add (CLUTTER_CONTAINER (stage), texture, clone, NULL);
clutter_actor_show (stage);
clutter_main ();
return EXIT_SUCCESS;
}

View File

@ -1,186 +0,0 @@
#include <clutter/clutter.h>
/* Context will be used to carry interesting variables between functions */
typedef struct
{
ClutterActor *sub_nw, *sub_ne, *sub_sw, *sub_se;
gfloat image_width, image_height;
} Context;
/* Here, we animate the texture to go way by giving the new coordinates
* outside of the stage. We rotate the sub-textures around their anchor
* point (set in setup_sub() as well, it looks cool. */
static gboolean
go_away (gpointer data)
{
Context *context = data;
clutter_actor_animate (context->sub_nw, CLUTTER_EASE_OUT_CUBIC, 1500,
"x", -context->image_width,
"y", -context->image_height,
"rotation-angle-z", 2000.,
NULL);
clutter_actor_animate (context->sub_ne, CLUTTER_EASE_OUT_CUBIC, 1500,
"x", +context->image_width,
"y", -context->image_height,
"rotation-angle-z", 2000.,
NULL);
clutter_actor_animate (context->sub_sw, CLUTTER_EASE_OUT_CUBIC, 1500,
"x", -context->image_width,
"y", +context->image_height,
"rotation-angle-z", 2000.,
NULL);
clutter_actor_animate (context->sub_se, CLUTTER_EASE_OUT_CUBIC, 1500,
"x", -context->image_width,
"y", +context->image_height,
"rotation-angle-z", 2000.,
NULL);
return G_SOURCE_REMOVE; /* remove the timeout source */
}
/* We split the four sub-textures faking to be the big texture, moving them
* away by 10 pixels in each direction */
static gboolean
split (gpointer data)
{
Context *context = data;
gfloat x, y;
clutter_actor_get_position (context->sub_nw, &x, &y);
clutter_actor_animate (context->sub_nw, CLUTTER_EASE_OUT_CUBIC, 300,
"x", x - 10,
"y", y - 10,
NULL);
clutter_actor_get_position (context->sub_ne, &x, &y);
clutter_actor_animate (context->sub_ne, CLUTTER_EASE_OUT_CUBIC, 300,
"x", x + 10,
"y", y - 10,
NULL);
clutter_actor_get_position (context->sub_sw, &x, &y);
clutter_actor_animate (context->sub_sw, CLUTTER_EASE_OUT_CUBIC, 300,
"x", x - 10,
"y", y + 10,
NULL);
clutter_actor_get_position (context->sub_se, &x, &y);
clutter_actor_animate (context->sub_se, CLUTTER_EASE_OUT_CUBIC, 300,
"x", x + 10,
"y", y + 10,
NULL);
/* In 500ms the textures will flee! */
clutter_threads_add_timeout (500, go_away, context);
return G_SOURCE_REMOVE; /* remove the timeout source */
}
static ClutterActor *
setup_sub (CoglHandle texture,
gint image_width,
gint image_height,
gint t_x,
gint t_y,
gint t_width,
gint t_height)
{
CoglHandle sub_texture;
ClutterActor *sub_image;
/* Create a new sub-texture from textures */
sub_texture = cogl_texture_new_from_sub_texture (texture,
t_x, t_y,
t_width, t_height);
/* Create the corresponding ClutterTexture */
sub_image = g_object_new (CLUTTER_TYPE_TEXTURE,
"cogl-texture", sub_texture,
NULL);
/* Set the anchor point in the middle of each sub_image so the position and
* rotation of the textures are relative to that point */
clutter_actor_set_anchor_point (sub_image, image_width / 4, image_height / 4);
return sub_image;
}
#define IMAGE "smiley.png"
int
main (int argc,
char **argv)
{
gfloat image_width, image_height, stage_width, stage_height;
ClutterActor *stage, *image;
GError *error = NULL;
CoglHandle texture;
Context context;
if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_get_size (stage, &stage_width, &stage_height);
clutter_stage_set_title (CLUTTER_STAGE (stage), "Animate sub-textures");
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
/* Load smiley.png, creating a new ClutterTexture, get its size and the
* Cogl texture handle */
image = clutter_texture_new_from_file (IMAGE, &error);
if (error != NULL)
{
g_warning ("Could not load " IMAGE ": %s", error->message);
g_clear_error (&error);
return 1;
}
clutter_actor_get_size (image, &image_width, &image_height);
texture = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (image));
/* Create four sub-textures from image, actually splitting the image in
* four */
context.sub_nw = setup_sub (texture, image_width, image_height,
0, 0, image_width / 2 , image_height / 2);
context.sub_ne = setup_sub (texture, image_width, image_height,
image_width / 2 , 0,
image_width / 2, image_height / 2);
context.sub_sw = setup_sub (texture, image_width, image_height,
0.f, image_height / 2,
image_width / 2, image_height / 2);
context.sub_se = setup_sub (texture, image_width, image_height,
image_width / 2, image_height / 2,
image_width / 2, image_height / 2);
/* We don't need the image anymore as we won't display it and as
* cogl_texture_new_from_sub_texture() keeps a reference to the underlying
* texture ressource */
g_object_unref (image);
/* Position the sub-texures in the middle of the screen, recreating the
* original texture */
clutter_actor_set_position (context.sub_nw,
stage_width / 2 - image_width / 4,
stage_height / 2 - image_height / 4);
clutter_actor_set_position (context.sub_ne,
stage_width / 2 + image_width / 4,
stage_height / 2 - image_height / 4);
clutter_actor_set_position (context.sub_sw,
stage_width / 2 - image_width / 4,
stage_height / 2 + image_height / 4);
clutter_actor_set_position (context.sub_se,
stage_width / 2 + image_width / 4,
stage_height / 2 + image_height / 4);
/* Add the four sub-textures to the stage */
clutter_container_add (CLUTTER_CONTAINER (stage), context.sub_nw,
context.sub_ne, context.sub_sw, context.sub_se, NULL);
clutter_actor_show_all (stage);
context.image_width = image_width;
context.image_height = image_height;
/* In two seconds, we'll split the texture! */
clutter_threads_add_timeout (2000, split, &context);
clutter_main ();
return 0;
}

View File

@ -1,62 +0,0 @@
#include <clutter/clutter.h>
int
main (int argc, char **argv)
{
ClutterActor *stage, *image, *sub_image;
CoglHandle texture, sub_texture;
gfloat image_width, image_height;
/* Initialize Clutter */
if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS)
return 1;
/* Get the default stage */
stage = clutter_stage_new ();
clutter_stage_set_title (CLUTTER_STAGE (stage), "Sub-texture");
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
/* Create a new ClutterTexture that shows smiley.png */
image = clutter_texture_new_from_file ("smiley.png", NULL);
clutter_actor_get_size (image, &image_width, &image_height);
clutter_actor_set_size (stage,
image_width * 3 / 2 + 30,
image_height + 20);
/* Grab the CoglHandle of the underlying Cogl texture */
texture = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (image));
/* Create a new Cogl texture from the handle above. That new texture is a
* rectangular region from image, more precisely the northwest corner
* of the image */
sub_texture = cogl_texture_new_from_sub_texture (texture,
0, 0,
image_width / 2,
image_height / 2);
/* Finally, use the newly created Cogl texture to feed a new ClutterTexture
* and thus create a new actor that displays sub_texture */
sub_image = clutter_texture_new ();
clutter_texture_set_cogl_texture (CLUTTER_TEXTURE (sub_image), sub_texture);
/*
* You could have used the more straightforward g_object_new() function that
* can create an object and set some properties on it at the same time:
* sub_image = g_object_new (CLUTTER_TYPE_TEXTURE,
* "cogl-texture", sub_texture,
* NULL);
*/
/* Put the original image at (10,10) and the new sub image next to it */
clutter_actor_set_position (image, 10, 10);
clutter_actor_set_position (sub_image, 20 + image_width, 10);
/* Add both ClutterTexture to the stage */
clutter_container_add (CLUTTER_CONTAINER (stage), image, sub_image, NULL);
clutter_actor_show_all (stage);
clutter_main ();
return 0;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -1,147 +0,0 @@
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
<!ENTITY appurl "http://www.clutter-project.org">
<!ENTITY docurl "http://docs.clutter-project.org/docs/clutter-cookbook">
]>
<chapter id="introduction">
<title>Preface</title>
<epigraph>
<attribution>The Perl Cookbook</attribution>
<para>Let me show you that easy way, so others may easily follow.</para>
</epigraph>
<para>There is a wonderful simile in the preface of the <emphasis>Perl
Cookbook</emphasis>: approaching a programming problem is oftentimes
similar to balancing Columbus's egg. The initial difficulties of dealing
with, and more importantly solving, problems in the software engineering
field sometimes can only be overcome if somebody shows you how to use a
new tool. This is true for programming languages but also for programming
libraries.</para>
<para>This book has been written to try and give you a reference on
how to solve common issues that you might have to face when using
the Clutter toolkit.</para>
<para>This book is not meant to be a replacement for the Clutter API
reference, even though there will be descriptions of how Clutter works
and how its API looks like. We will require knowledge of the Clutter API,
but we will also point out where to find more information on the API that
examples have used.</para>
<para>Indeed, this book should be used as a companion to the API reference,
expanding its examples and showing how to achieve a specific result.</para>
<para>This is not a book for learning Clutter. This is also not a book
for learning C, or GObject or even GUI development.</para>
<para>Above all, this is a book for learning <emphasis>more</emphasis>
about Clutter, and about how to use it in the most efficient and easiest
way. It is meant to help you move past the basic usage of Clutter.</para>
<para>This book is divided into chapters. Each chapter is dedicated to
a specific class, like ClutterTexture, or a specific area, like animations.
Each chapter starts with a short introduction, followed by different
<emphasis>recipes</emphasis>. Each recipe starts with a problem, or a short
statement describing what we want to achieve; a solution, containing the
source code; and a discussion section, where the code is explained, where
alternative approaches might be useful, and where caveats and references to
the Clutter API for further studying can be found.</para>
<para>This book, in the cookbook spirit, can be accessed mostly at
random.</para>
<section>
<title>About Clutter</title>
<para>Clutter is an free and open source software library for creating
portable, dynamic, compelling and fast graphical user interfaces.</para>
<para>Clutter uses OpenGL (and, optionally, OpenGL ES on mobile and
embedded platforms) for rendering the user interface elements, but
at the same time it exposes an application program interface that hides
the underlying complexity of the OpenGL state machine from the
developer.</para>
<para>The program interface of Clutter is intended to be easy to use,
efficient, flexible and as self-documenting as possible.</para>
</section>
<section>
<title>About this document</title>
<para>This document is available in various formats like HTML, and
PDF.</para>
<para>The latest version is always available at
<ulink url="&docurl;">&docurl;</ulink>.</para>
<para>To contribute to this document, see the
<link linkend="contributing">Contributing</link> appendix.</para>
<section>
<title>Compiling the examples</title>
<para>This document comes with full examples, usually stored
on disk in <filename><emphasis>datadir</emphasis>/clutter-1.0/cookbook/examples</filename>
directory.</para>
<para>Each example can be compiled using:</para>
<informalexample>
<programlisting>
cc \
`pkg-config --cflags clutter-1.0` \
-o <emphasis>example</emphasis> <emphasis>example</emphasis>.c \
`pkg-config --libs clutter-1.0`
</programlisting>
</informalexample>
<para>substituting the <emphasis>example</emphasis> with in the
line above with the name of the example.</para>
</section>
</section>
<section>
<title>Acknowledgments</title>
<para>This book has been written taking the inspiration from the Perl
Cookbook, authored by Tom Christiansen and Nathan Torkington.</para>
<para>This book would not have been possible without the existence of
the Clutter library itself, and without the help and contributions of
all the people that have been working on it every day.</para>
<section>
<title>Acknowledgments from Emmanuele</title>
<para>To Matthew, for starting the flame. To Robert and Neil, for
keeping it ablaze.</para>
<para>To Marta, for her love and patience.</para>
</section>
<section>
<title>Acknowledgements from Elliot</title>
</section>
</section>
<section>
<title>Where to get Clutter</title>
<para>You can obtain the Clutter source code ready for compilation
from <ulink url="&appurl;">&appurl;</ulink>.</para>
<para>Clutter is also available on all major GNU/Linux distributions,
in various package formats.</para>
<para>On OSX, Clutter is available with both Fink and MacPorts.</para>
<para>Binaries for Microsoft Windows are also available.</para>
</section>
</chapter>

Some files were not shown because too many files have changed in this diff Show More