docs: drop docs
@ -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:
|
||||
|
71
configure.ac
@ -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:"
|
||||
|
@ -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.
|
613
doc/CODING_STYLE
@ -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.
|
95
doc/HACKING
@ -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.
|
@ -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.
|
@ -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
|
@ -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`.
|
@ -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
|
@ -1,10 +0,0 @@
|
||||
NULL =
|
||||
|
||||
EXTRA_DIST = \
|
||||
common.xsl \
|
||||
cookbook.xsl \
|
||||
devhelp.xsl \
|
||||
html.xsl \
|
||||
ref-html-style.xsl \
|
||||
style.css \
|
||||
$(NULL)
|
@ -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>
|
@ -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,'
') or
|
||||
starts-with($astr,'
')">
|
||||
<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 = '
') or
|
||||
($last-char = '
') or
|
||||
($last-char = ' ') or
|
||||
($last-char = '	')">
|
||||
<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>
|
@ -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>
|
@ -1,285 +0,0 @@
|
||||
<?xml version='1.0'?>
|
||||
<!DOCTYPE xsl:stylesheet [
|
||||
<!ENTITY RE " ">
|
||||
<!ENTITY nbsp " ">
|
||||
]>
|
||||
|
||||
<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"> </td>
|
||||
<td width="80%" valign="top">
|
||||
<xsl:apply-templates select="child::*[local-name(.)!='attribution']"/>
|
||||
</td>
|
||||
<td width="10%" valign="top"> </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"> </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() > 1]">
|
||||
<xsl:text>(</xsl:text>
|
||||
<xsl:apply-templates select="ooclass[position() > 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() > 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> </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> </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> </xsl:text>
|
||||
</span>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="varname" mode="python">
|
||||
<span class="{name(.)}">
|
||||
<xsl:apply-templates mode="python"/>
|
||||
<xsl:text> </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 </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() > 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>
|
@ -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><ANCHOR id="</xsl:text>
|
||||
<xsl:value-of select="@id"/>
|
||||
<xsl:text>" href="</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>">
|
||||
</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>
|
@ -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;
|
||||
}
|
@ -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
|
@ -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 &
|
||||
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><clutter source>/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 <filename> element for file
|
||||
and directory names.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Use the <property> element for property names
|
||||
(e.g. GObject properties).</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Use the <type> element for GObject class
|
||||
names.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Use the <constant> element for C defines.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Use the <keycap> 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
|
||||
<keycap>.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Use the <function> 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 <note> 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><clutter source>/doc/cookbook/videos</filename>
|
||||
directory. The name should be in the format
|
||||
<filename><section>-<recipe>-<identifier>.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 <inlinemediaobject> 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 <alt> 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><clutter source>/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><section>-<recipe>.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><clutter source>/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>
|
@ -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)
|
@ -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;
|
||||
}
|
@ -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 ]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
@ -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;
|
||||
}
|
@ -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 ]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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 ]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
@ -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" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
@ -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__ */
|
@ -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;
|
||||
}
|
@ -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__ */
|
@ -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);
|
||||
}
|
@ -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__ */
|
@ -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;
|
||||
}
|
@ -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__ */
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
Before Width: | Height: | Size: 8.1 KiB |
@ -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;
|
||||
}
|
@ -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" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
@ -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;
|
||||
}
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
@ -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;
|
||||
}
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
]
|
Before Width: | Height: | Size: 2.8 KiB |
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
Before Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 90 KiB |
Before Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 90 KiB |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 4.6 KiB |
@ -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>
|