Experimentally add build infrastructure and a few Tidy widgets
For experimenting with using tidy, import TidyButton and TidyGrid (+ dependencies) into our source tree and set up build machinery to build them and build a typelib for them. The sources are build right into libgnome-shell.so, so the Shell.gir and Tidy.gir actually point to the same shared library. src/Makefile-tidy.am: Build libtidy-1.0.la src/Makefile.am: Include built tidy into gnome-shell.la and build Tidy-1.0.typelib src/tidy/*: Add some source files from Tidy svn path=/trunk/; revision=42
This commit is contained in:
parent
536bc24f61
commit
f8db7689af
109
src/Makefile-tidy.am
Normal file
109
src/Makefile-tidy.am
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
NULL =
|
||||||
|
|
||||||
|
GLIB_GENMARSHAL = `pkg-config --variable=glib_genmarshal glib-2.0`
|
||||||
|
GLIB_MKENUMS = `pkg-config --variable=glib_mkenums glib-2.0`
|
||||||
|
|
||||||
|
tidy_cflags = \
|
||||||
|
-I$(top_srcdir)/src \
|
||||||
|
-DPREFIX=\""$(prefix)"\" \
|
||||||
|
-DLIBDIR=\""$(libdir)"\" \
|
||||||
|
-DG_DISABLE_DEPRECATED \
|
||||||
|
-DG_LOG_DOMAIN=\"Tidy\" \
|
||||||
|
$(MUTTER_PLUGIN_CFLAGS) \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
tidy_built_sources = \
|
||||||
|
tidy-enum-types.h \
|
||||||
|
tidy-enum-types.c \
|
||||||
|
tidy-marshal.h \
|
||||||
|
tidy-marshal.c
|
||||||
|
|
||||||
|
BUILT_SOURCES += $(tidy_built_sources)
|
||||||
|
|
||||||
|
STAMP_FILES = stamp-tidy-marshal.h stamp-tidy-enum-types.h
|
||||||
|
|
||||||
|
# please, keep this sorted alphabetically
|
||||||
|
tidy_source_h = \
|
||||||
|
tidy/tidy-actor.h \
|
||||||
|
tidy/tidy-button.h \
|
||||||
|
tidy/tidy-frame.h \
|
||||||
|
tidy/tidy-grid.h \
|
||||||
|
tidy/tidy-stylable.h \
|
||||||
|
tidy/tidy-style.h \
|
||||||
|
tidy/tidy-types.h \
|
||||||
|
tidy/tidy-util.h \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
tidy_source_h_private = \
|
||||||
|
tidy/tidy-debug.h \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
# please, keep this sorted alphabetically
|
||||||
|
tidy_source_c = \
|
||||||
|
tidy/tidy-actor.c \
|
||||||
|
tidy/tidy-button.c \
|
||||||
|
tidy/tidy-frame.c \
|
||||||
|
tidy/tidy-grid.c \
|
||||||
|
tidy/tidy-stylable.c \
|
||||||
|
tidy/tidy-style.c \
|
||||||
|
tidy/tidy-util.c \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
tidy-marshal.h: stamp-tidy-marshal.h
|
||||||
|
@true
|
||||||
|
stamp-tidy-marshal.h: Makefile tidy/tidy-marshal.list
|
||||||
|
$(GLIB_GENMARSHAL) \
|
||||||
|
--prefix=_tidy_marshal \
|
||||||
|
--header \
|
||||||
|
$(srcdir)/tidy/tidy-marshal.list > xgen-tmh && \
|
||||||
|
(cmp -s xgen-tmh tidy-marshal.h || cp -f xgen-tmh tidy-marshal.h) && \
|
||||||
|
rm -f xgen-tmh && \
|
||||||
|
echo timestamp > $(@F)
|
||||||
|
|
||||||
|
tidy-marshal.c: Makefile tidy/tidy-marshal.list
|
||||||
|
(echo "#include \"tidy-marshal.h\"" ; \
|
||||||
|
$(GLIB_GENMARSHAL) \
|
||||||
|
--prefix=_tidy_marshal \
|
||||||
|
--body \
|
||||||
|
$(srcdir)/tidy/tidy-marshal.list ) > xgen-tmc && \
|
||||||
|
cp -f xgen-tmc tidy-marshal.c && \
|
||||||
|
rm -f xgen-tmc
|
||||||
|
|
||||||
|
tidy-enum-types.h: stamp-tidy-enum-types.h Makefile
|
||||||
|
@true
|
||||||
|
stamp-tidy-enum-types.h: $(tidy_source_h) tidy/tidy-enum-types.h.in
|
||||||
|
( cd $(srcdir) && \
|
||||||
|
$(GLIB_MKENUMS) \
|
||||||
|
--template $(srcdir)/tidy/tidy-enum-types.h.in \
|
||||||
|
$(tidy_source_h) ) >> xgen-teth && \
|
||||||
|
(cmp xgen-teth tidy-enum-types.h || cp xgen-teth tidy-enum-types.h) && \
|
||||||
|
rm -f xgen-teth && \
|
||||||
|
echo timestamp > $(@F)
|
||||||
|
|
||||||
|
tidy-enum-types.c: stamp-tidy-enum-types.h tidy/tidy-enum-types.c.in
|
||||||
|
( cd $(srcdir) && \
|
||||||
|
$(GLIB_MKENUMS) \
|
||||||
|
--template $(srcdir)/tidy/tidy-enum-types.c.in \
|
||||||
|
$(tidy_source_h) ) >> xgen-tetc && \
|
||||||
|
cp xgen-tetc tidy-enum-types.c && \
|
||||||
|
rm -f xgen-tetc
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = libtidy-1.0.la
|
||||||
|
|
||||||
|
libtidy_1_0_la_LIBADD = $(TIDY_LIBS)
|
||||||
|
libtidy_1_0_la_SOURCES = \
|
||||||
|
$(tidy_source_c) \
|
||||||
|
$(tidy_source_h) \
|
||||||
|
$(tidy_source_h_priv) \
|
||||||
|
$(tidy_built_sources) \
|
||||||
|
$(NULL)
|
||||||
|
libtidy_1_0_la_CPPFLAGS = $(tidy_cflags)
|
||||||
|
libtidy_1_0_la_LDFLAGS = $(LDADD)
|
||||||
|
|
||||||
|
CLEANFILES += $(STAMP_FILES) $(BUILT_SOURCES)
|
||||||
|
|
||||||
|
EXTRA_DIST = \
|
||||||
|
tidy/tidy-enum-types.h.in \
|
||||||
|
tidy/tidy-enum-types.c.in \
|
||||||
|
tidy/tidy-private.h \
|
||||||
|
tidy/tidy-marshal.list
|
@ -1,4 +1,9 @@
|
|||||||
INCLUDES = \
|
BUILT_SOURCES =
|
||||||
|
CLEANFILES =
|
||||||
|
|
||||||
|
include Makefile-tidy.am
|
||||||
|
|
||||||
|
gnome_shell_cflags = \
|
||||||
$(MUTTER_PLUGIN_CFLAGS) \
|
$(MUTTER_PLUGIN_CFLAGS) \
|
||||||
-DGETTEXT_PACKAGE=gnome-shell \
|
-DGETTEXT_PACKAGE=gnome-shell \
|
||||||
-DJSDIR=\"$(pkgdatadir)/js\"
|
-DJSDIR=\"$(pkgdatadir)/js\"
|
||||||
@ -14,7 +19,8 @@ libgnome_shell_la_SOURCES = \
|
|||||||
shell-global.h
|
shell-global.h
|
||||||
|
|
||||||
libgnome_shell_la_LDFLAGS = -avoid-version -module
|
libgnome_shell_la_LDFLAGS = -avoid-version -module
|
||||||
libgnome_shell_la_LIBADD = $(MUTTER_PLUGIN_LIBS)
|
libgnome_shell_la_LIBADD = $(MUTTER_PLUGIN_LIBS) libtidy-1.0.la
|
||||||
|
libgnome_shell_la_CPPFLAGS = $(gnome_shell_cflags)
|
||||||
|
|
||||||
# We can't have any undefined symbols when g-ir-scanner dlopens the library
|
# We can't have any undefined symbols when g-ir-scanner dlopens the library
|
||||||
# to introspect it, so we link everything a _second_ time, including a
|
# to introspect it, so we link everything a _second_ time, including a
|
||||||
@ -27,14 +33,15 @@ libgnome_shell_introspect_la_SOURCES = \
|
|||||||
# The dummy -rpath here is needed to convince libtool to build a
|
# The dummy -rpath here is needed to convince libtool to build a
|
||||||
# noinst_LTLIBRARY shared
|
# noinst_LTLIBRARY shared
|
||||||
libgnome_shell_introspect_la_LDFLAGS = -avoid-version -module -rpath $(libdir)
|
libgnome_shell_introspect_la_LDFLAGS = -avoid-version -module -rpath $(libdir)
|
||||||
libgnome_shell_introspect_la_LIBADD = $(MUTTER_PLUGIN_LIBS)
|
libgnome_shell_introspect_la_LIBADD = $(MUTTER_PLUGIN_LIBS) libtidy-1.0.la
|
||||||
|
libgnome_shell_introspect_la_CPPFLAGS = $(gnome_shell_cflags)
|
||||||
|
|
||||||
typelibdir = $(pkglibdir)/girepository
|
typelibdir = $(pkglibdir)/girepository
|
||||||
typelib_DATA = Shell-0.1.typelib
|
typelib_DATA = Shell-0.1.typelib Tidy-1.0.typelib
|
||||||
|
|
||||||
# After we run g-ir-scanner, we need to change the library name written in
|
# After we run g-ir-scanner, we need to change the library name written in
|
||||||
# the .gir file from the "fake" second copy of the library to the real name
|
# the .gir file from the "fake" second copy of the library to the real name
|
||||||
Shell-0.1.gir: libgnome-shell-introspect.la $(libgnome_shell_la_SOURCES)
|
Shell-0.1.gir: libgnome-shell-introspect.la $(libgnome_shell_la_SOURCES) Makefile
|
||||||
g-ir-scanner \
|
g-ir-scanner \
|
||||||
--namespace=Shell \
|
--namespace=Shell \
|
||||||
--nsversion=0.1 \
|
--nsversion=0.1 \
|
||||||
@ -42,8 +49,8 @@ Shell-0.1.gir: libgnome-shell-introspect.la $(libgnome_shell_la_SOURCES)
|
|||||||
--include=Clutter-0.8 \
|
--include=Clutter-0.8 \
|
||||||
--include=Meta-2.25 \
|
--include=Meta-2.25 \
|
||||||
--library=gnome-shell-introspect \
|
--library=gnome-shell-introspect \
|
||||||
$(libgnome_shell_la_SOURCES) \
|
- $(libgnome_shell_la_SOURCES) \
|
||||||
$(INCLUDES) \
|
$(libgnome_shell_la_CPPFLAGS) \
|
||||||
-o $@.tmp
|
-o $@.tmp
|
||||||
sed 's/gnome-shell-introspect/gnome-shell/' < $@.tmp > $@ && rm $@.tmp
|
sed 's/gnome-shell-introspect/gnome-shell/' < $@.tmp > $@ && rm $@.tmp
|
||||||
|
|
||||||
@ -51,3 +58,23 @@ Shell-0.1.gir: libgnome-shell-introspect.la $(libgnome_shell_la_SOURCES)
|
|||||||
# (not the fake library, since we've already done the rewriting)
|
# (not the fake library, since we've already done the rewriting)
|
||||||
Shell-0.1.typelib: libgnome-shell.la Shell-0.1.gir
|
Shell-0.1.typelib: libgnome-shell.la Shell-0.1.gir
|
||||||
LD_LIBRARY_PATH=$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}. g-ir-compiler Shell-0.1.gir -o $@
|
LD_LIBRARY_PATH=$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}. g-ir-compiler Shell-0.1.gir -o $@
|
||||||
|
|
||||||
|
# After we run g-ir-scanner, we need to change the library name written in
|
||||||
|
# the .gir file from the "fake" second copy of the library to the real name
|
||||||
|
Tidy-1.0.gir: libgnome-shell-introspect.la $(libgnome_shell_la_SOURCES) Makefile
|
||||||
|
g-ir-scanner \
|
||||||
|
--namespace=Tidy \
|
||||||
|
--nsversion=1.0 \
|
||||||
|
--include=GObject-2.0 \
|
||||||
|
--include=Clutter-0.8 \
|
||||||
|
--library=gnome-shell-introspect \
|
||||||
|
$(tidy_source_h) \
|
||||||
|
$(tidy_source_c) \
|
||||||
|
$(tidy_cflags) \
|
||||||
|
-o $@.tmp
|
||||||
|
sed 's/gnome-shell-introspect/gnome-shell/' < $@.tmp > $@ && rm $@.tmp
|
||||||
|
|
||||||
|
# The dependency on libgnome-shell.la here is because g-ir-compiler opens it
|
||||||
|
# (not the fake library, since we've already done the rewriting)
|
||||||
|
Tidy-1.0.typelib: libgnome-shell.la Tidy-1.0.gir
|
||||||
|
LD_LIBRARY_PATH=$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}. g-ir-compiler Tidy-1.0.gir -o $@
|
||||||
|
529
src/tidy/tidy-actor.c
Normal file
529
src/tidy/tidy-actor.c
Normal file
@ -0,0 +1,529 @@
|
|||||||
|
/* tidy-actor.c: Base class for Tidy actors
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 OpenedHand
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:tidy-actor
|
||||||
|
* @short_description: Base class for stylable actors
|
||||||
|
*
|
||||||
|
* #TidyActor is a simple abstract class on top of #ClutterActor. It
|
||||||
|
* provides basic themeing properties, support for padding and alignment.
|
||||||
|
*
|
||||||
|
* Actors in the Tidy library should subclass #TidyActor if they plan
|
||||||
|
* to obey to a certain #TidyStyle or if they implement #ClutterContainer
|
||||||
|
* and want to offer basic layout capabilities.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "tidy-actor.h"
|
||||||
|
|
||||||
|
#include "tidy-debug.h"
|
||||||
|
#include "tidy-marshal.h"
|
||||||
|
#include "tidy-private.h"
|
||||||
|
#include "tidy-stylable.h"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
|
||||||
|
PROP_STYLE,
|
||||||
|
PROP_PADDING,
|
||||||
|
PROP_X_ALIGN,
|
||||||
|
PROP_Y_ALIGN
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
static void tidy_stylable_iface_init (TidyStylableIface *iface);
|
||||||
|
|
||||||
|
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (TidyActor, tidy_actor, CLUTTER_TYPE_ACTOR,
|
||||||
|
G_IMPLEMENT_INTERFACE (TIDY_TYPE_STYLABLE,
|
||||||
|
tidy_stylable_iface_init));
|
||||||
|
|
||||||
|
#define TIDY_ACTOR_GET_PRIVATE(obj) \
|
||||||
|
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), TIDY_TYPE_ACTOR, TidyActorPrivate))
|
||||||
|
|
||||||
|
struct _TidyActorPrivate
|
||||||
|
{
|
||||||
|
TidyStyle *style;
|
||||||
|
|
||||||
|
TidyPadding padding;
|
||||||
|
|
||||||
|
ClutterFixed x_align;
|
||||||
|
ClutterFixed y_align;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_actor_set_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
TidyActor *actor = TIDY_ACTOR (gobject);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_PADDING:
|
||||||
|
tidy_actor_set_padding (actor, g_value_get_boxed (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_X_ALIGN:
|
||||||
|
actor->priv->x_align =
|
||||||
|
CLUTTER_FIXED_TO_FLOAT (g_value_get_double (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_Y_ALIGN:
|
||||||
|
actor->priv->y_align =
|
||||||
|
CLUTTER_FIXED_TO_FLOAT (g_value_get_double (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_STYLE:
|
||||||
|
tidy_stylable_set_style (TIDY_STYLABLE (actor),
|
||||||
|
g_value_get_object (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_actor_get_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
TidyActor *actor = TIDY_ACTOR (gobject);
|
||||||
|
TidyActorPrivate *priv = actor->priv;
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_PADDING:
|
||||||
|
{
|
||||||
|
TidyPadding padding = { 0, };
|
||||||
|
|
||||||
|
tidy_actor_get_padding (actor, &padding);
|
||||||
|
g_value_set_boxed (value, &padding);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_X_ALIGN:
|
||||||
|
g_value_set_double (value, CLUTTER_FIXED_TO_FLOAT (priv->x_align));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_Y_ALIGN:
|
||||||
|
g_value_set_double (value, CLUTTER_FIXED_TO_FLOAT (priv->y_align));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_STYLE:
|
||||||
|
g_value_set_object (value, priv->style);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_actor_dispose (GObject *gobject)
|
||||||
|
{
|
||||||
|
TidyActor *actor = TIDY_ACTOR (gobject);
|
||||||
|
|
||||||
|
if (actor->priv->style)
|
||||||
|
{
|
||||||
|
g_object_unref (actor->priv->style);
|
||||||
|
actor->priv->style = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (tidy_actor_parent_class)->dispose (gobject);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_actor_class_init (TidyActorClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
g_type_class_add_private (klass, sizeof (TidyActorPrivate));
|
||||||
|
|
||||||
|
gobject_class->set_property = tidy_actor_set_property;
|
||||||
|
gobject_class->get_property = tidy_actor_get_property;
|
||||||
|
gobject_class->dispose = tidy_actor_dispose;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TidyActor:padding:
|
||||||
|
*
|
||||||
|
* Padding around an actor, expressed in #ClutterUnit<!-- -->s. Padding
|
||||||
|
* is the internal space between an actors bounding box and its internal
|
||||||
|
* children.
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_PADDING,
|
||||||
|
g_param_spec_boxed ("padding",
|
||||||
|
"Padding",
|
||||||
|
"Units of padding around an actor",
|
||||||
|
TIDY_TYPE_PADDING,
|
||||||
|
TIDY_PARAM_READWRITE));
|
||||||
|
/**
|
||||||
|
* TidyActor:x-align:
|
||||||
|
*
|
||||||
|
* Alignment of internal children along the X axis, relative to the
|
||||||
|
* actor's bounding box origin, and in relative units (1.0 is the
|
||||||
|
* current width of the actor).
|
||||||
|
*
|
||||||
|
* A value of 0.0 will left-align the children; 0.5 will align them at
|
||||||
|
* the middle of the actor's width; 1.0 will right align the children.
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_X_ALIGN,
|
||||||
|
g_param_spec_double ("x-align",
|
||||||
|
"X Alignment",
|
||||||
|
"Alignment (between 0.0 and 1.0) on the X axis",
|
||||||
|
0.0, 1.0, 0.5,
|
||||||
|
TIDY_PARAM_READWRITE));
|
||||||
|
/**
|
||||||
|
* TidyActor:y-align:
|
||||||
|
*
|
||||||
|
* Alignment of internal children along the Y axis, relative to the
|
||||||
|
* actor's bounding box origin, and in relative units (1.0 is the
|
||||||
|
* current height of the actor).
|
||||||
|
*
|
||||||
|
* A value of 0.0 will top-align the children; 0.5 will align them at
|
||||||
|
* the middle of the actor's height; 1.0 will bottom align the children.
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_Y_ALIGN,
|
||||||
|
g_param_spec_double ("y-align",
|
||||||
|
"Y Alignement",
|
||||||
|
"Alignment (between 0.0 and 1.0) on the Y axis",
|
||||||
|
0.0, 1.0, 0.5,
|
||||||
|
TIDY_PARAM_READWRITE));
|
||||||
|
g_object_class_override_property (gobject_class, PROP_STYLE, "style");
|
||||||
|
}
|
||||||
|
|
||||||
|
static TidyStyle *
|
||||||
|
tidy_actor_get_style (TidyStylable *stylable)
|
||||||
|
{
|
||||||
|
TidyActorPrivate *priv = TIDY_ACTOR (stylable)->priv;
|
||||||
|
|
||||||
|
if (!priv->style)
|
||||||
|
priv->style = g_object_ref (tidy_style_get_default ());
|
||||||
|
|
||||||
|
return priv->style;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_actor_set_style (TidyStylable *stylable,
|
||||||
|
TidyStyle *style)
|
||||||
|
{
|
||||||
|
TidyActorPrivate *priv = TIDY_ACTOR (stylable)->priv;
|
||||||
|
|
||||||
|
if (priv->style)
|
||||||
|
g_object_unref (priv->style);
|
||||||
|
|
||||||
|
priv->style = g_object_ref_sink (style);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_stylable_iface_init (TidyStylableIface *iface)
|
||||||
|
{
|
||||||
|
static gboolean is_initialized = FALSE;
|
||||||
|
|
||||||
|
if (!is_initialized)
|
||||||
|
{
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
pspec = g_param_spec_string ("font-name",
|
||||||
|
"Font Name",
|
||||||
|
"The font to use for displaying text",
|
||||||
|
"Sans 12px",
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
tidy_stylable_iface_install_property (iface, TIDY_TYPE_ACTOR, pspec);
|
||||||
|
|
||||||
|
pspec = g_param_spec_boxed ("bg-color",
|
||||||
|
"Background Color",
|
||||||
|
"The background color of an actor",
|
||||||
|
CLUTTER_TYPE_COLOR,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
tidy_stylable_iface_install_property (iface, TIDY_TYPE_ACTOR, pspec);
|
||||||
|
|
||||||
|
pspec = g_param_spec_boxed ("active-color",
|
||||||
|
"Active Color",
|
||||||
|
"The color of an active actor",
|
||||||
|
CLUTTER_TYPE_COLOR,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
tidy_stylable_iface_install_property (iface, TIDY_TYPE_ACTOR, pspec);
|
||||||
|
|
||||||
|
pspec = g_param_spec_boxed ("text-color",
|
||||||
|
"Text Color",
|
||||||
|
"The color of the text of an actor",
|
||||||
|
CLUTTER_TYPE_COLOR,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
tidy_stylable_iface_install_property (iface, TIDY_TYPE_ACTOR, pspec);
|
||||||
|
|
||||||
|
iface->get_style = tidy_actor_get_style;
|
||||||
|
iface->set_style = tidy_actor_set_style;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_actor_init (TidyActor *actor)
|
||||||
|
{
|
||||||
|
TidyActorPrivate *priv;
|
||||||
|
|
||||||
|
actor->priv = priv = TIDY_ACTOR_GET_PRIVATE (actor);
|
||||||
|
|
||||||
|
/* no padding */
|
||||||
|
priv->padding.top = priv->padding.bottom = 0;
|
||||||
|
priv->padding.right = priv->padding.left = 0;
|
||||||
|
|
||||||
|
/* middle align */
|
||||||
|
priv->x_align = priv->y_align = CLUTTER_FLOAT_TO_FIXED (0.5);
|
||||||
|
|
||||||
|
clutter_actor_set_reactive (CLUTTER_ACTOR (actor), TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tidy_actor_set_padding:
|
||||||
|
* @actor: a #TidyActor
|
||||||
|
* @padding: padding for internal children
|
||||||
|
*
|
||||||
|
* Sets @padding around @actor.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tidy_actor_set_padding (TidyActor *actor,
|
||||||
|
const TidyPadding *padding)
|
||||||
|
{
|
||||||
|
g_return_if_fail (TIDY_IS_ACTOR (actor));
|
||||||
|
g_return_if_fail (padding != NULL);
|
||||||
|
|
||||||
|
actor->priv->padding = *padding;
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (actor), "padding");
|
||||||
|
|
||||||
|
if (CLUTTER_ACTOR_IS_VISIBLE (actor))
|
||||||
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (actor));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tidy_actor_get_padding:
|
||||||
|
* @actor: a #TidyActor
|
||||||
|
* @padding: return location for the padding
|
||||||
|
*
|
||||||
|
* Retrieves the padding aound @actor.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tidy_actor_get_padding (TidyActor *actor,
|
||||||
|
TidyPadding *padding)
|
||||||
|
{
|
||||||
|
g_return_if_fail (TIDY_IS_ACTOR (actor));
|
||||||
|
g_return_if_fail (padding != NULL);
|
||||||
|
|
||||||
|
*padding = actor->priv->padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tidy_actor_set_alignment:
|
||||||
|
* @actor: a #TidyActor
|
||||||
|
* @x_align: relative alignment on the X axis
|
||||||
|
* @y_align: relative alignment on the Y axis
|
||||||
|
*
|
||||||
|
* Sets the alignment, relative to the @actor's width and height, of
|
||||||
|
* the internal children.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tidy_actor_set_alignment (TidyActor *actor,
|
||||||
|
gdouble x_align,
|
||||||
|
gdouble y_align)
|
||||||
|
{
|
||||||
|
TidyActorPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (TIDY_IS_ACTOR (actor));
|
||||||
|
|
||||||
|
g_object_ref (actor);
|
||||||
|
g_object_freeze_notify (G_OBJECT (actor));
|
||||||
|
|
||||||
|
priv = actor->priv;
|
||||||
|
|
||||||
|
x_align = CLAMP (x_align, 0.0, 1.0);
|
||||||
|
y_align = CLAMP (y_align, 0.0, 1.0);
|
||||||
|
|
||||||
|
priv->x_align = CLUTTER_FLOAT_TO_FIXED (x_align);
|
||||||
|
g_object_notify (G_OBJECT (actor), "x-align");
|
||||||
|
|
||||||
|
priv->y_align = CLUTTER_FLOAT_TO_FIXED (y_align);
|
||||||
|
g_object_notify (G_OBJECT (actor), "y-align");
|
||||||
|
|
||||||
|
if (CLUTTER_ACTOR_IS_VISIBLE (actor))
|
||||||
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (actor));
|
||||||
|
|
||||||
|
g_object_thaw_notify (G_OBJECT (actor));
|
||||||
|
g_object_unref (actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tidy_actor_get_alignment:
|
||||||
|
* @actor: a #TidyActor
|
||||||
|
* @x_align: return location for the relative alignment on the X axis,
|
||||||
|
* or %NULL
|
||||||
|
* @y_align: return location for the relative alignment on the Y axis,
|
||||||
|
* or %NULL
|
||||||
|
*
|
||||||
|
* Retrieves the alignment, relative to the @actor's width and height, of
|
||||||
|
* the internal children.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tidy_actor_get_alignment (TidyActor *actor,
|
||||||
|
gdouble *x_align,
|
||||||
|
gdouble *y_align)
|
||||||
|
{
|
||||||
|
TidyActorPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (TIDY_IS_ACTOR (actor));
|
||||||
|
|
||||||
|
priv = actor->priv;
|
||||||
|
|
||||||
|
if (x_align)
|
||||||
|
*x_align = CLUTTER_FIXED_TO_FLOAT (priv->x_align);
|
||||||
|
|
||||||
|
if (y_align)
|
||||||
|
*y_align = CLUTTER_FIXED_TO_FLOAT (priv->y_align);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tidy_actor_set_alignmentx:
|
||||||
|
* @actor: a #TidyActor
|
||||||
|
* @x_align: relative alignment on the X axis
|
||||||
|
* @y_align: relative alignment on the Y axis
|
||||||
|
*
|
||||||
|
* Fixed point version of tidy_actor_set_alignment().
|
||||||
|
*
|
||||||
|
* Sets the alignment, relative to the @actor's width and height, of
|
||||||
|
* the internal children.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tidy_actor_set_alignmentx (TidyActor *actor,
|
||||||
|
ClutterFixed x_align,
|
||||||
|
ClutterFixed y_align)
|
||||||
|
{
|
||||||
|
TidyActorPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (TIDY_IS_ACTOR (actor));
|
||||||
|
|
||||||
|
g_object_ref (actor);
|
||||||
|
g_object_freeze_notify (G_OBJECT (actor));
|
||||||
|
|
||||||
|
priv = actor->priv;
|
||||||
|
|
||||||
|
x_align = CLAMP (x_align, 0, CFX_ONE);
|
||||||
|
y_align = CLAMP (y_align, 0, CFX_ONE);
|
||||||
|
|
||||||
|
if (priv->x_align != x_align)
|
||||||
|
{
|
||||||
|
priv->x_align = x_align;
|
||||||
|
g_object_notify (G_OBJECT (actor), "x-align");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->y_align != y_align)
|
||||||
|
{
|
||||||
|
priv->y_align = y_align;
|
||||||
|
g_object_notify (G_OBJECT (actor), "y-align");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CLUTTER_ACTOR_IS_VISIBLE (actor))
|
||||||
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (actor));
|
||||||
|
|
||||||
|
g_object_thaw_notify (G_OBJECT (actor));
|
||||||
|
g_object_unref (actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tidy_actor_get_alignmentx:
|
||||||
|
* @actor: a #TidyActor
|
||||||
|
* @x_align: return location for the relative alignment on the X axis,
|
||||||
|
* or %NULL
|
||||||
|
* @y_align: return location for the relative alignment on the Y axis,
|
||||||
|
* or %NULL
|
||||||
|
*
|
||||||
|
* Fixed point version of tidy_actor_get_alignment().
|
||||||
|
*
|
||||||
|
* Retrieves the alignment, relative to the @actor's width and height, of
|
||||||
|
* the internal children.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tidy_actor_get_alignmentx (TidyActor *actor,
|
||||||
|
ClutterFixed *x_align,
|
||||||
|
ClutterFixed *y_align)
|
||||||
|
{
|
||||||
|
TidyActorPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (TIDY_IS_ACTOR (actor));
|
||||||
|
|
||||||
|
priv = actor->priv;
|
||||||
|
|
||||||
|
if (x_align)
|
||||||
|
*x_align = priv->x_align;
|
||||||
|
|
||||||
|
if (y_align)
|
||||||
|
*y_align = priv->y_align;
|
||||||
|
}
|
||||||
|
|
||||||
|
static TidyPadding *
|
||||||
|
tidy_padding_copy (const TidyPadding *padding)
|
||||||
|
{
|
||||||
|
TidyPadding *copy;
|
||||||
|
|
||||||
|
g_return_val_if_fail (padding != NULL, NULL);
|
||||||
|
|
||||||
|
copy = g_slice_new (TidyPadding);
|
||||||
|
*copy = *padding;
|
||||||
|
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_padding_free (TidyPadding *padding)
|
||||||
|
{
|
||||||
|
if (G_LIKELY (padding))
|
||||||
|
g_slice_free (TidyPadding, padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
GType
|
||||||
|
tidy_padding_get_type (void)
|
||||||
|
{
|
||||||
|
static GType our_type = 0;
|
||||||
|
|
||||||
|
if (G_UNLIKELY (our_type == 0))
|
||||||
|
our_type =
|
||||||
|
g_boxed_type_register_static (I_("TidyPadding"),
|
||||||
|
(GBoxedCopyFunc) tidy_padding_copy,
|
||||||
|
(GBoxedFreeFunc) tidy_padding_free);
|
||||||
|
|
||||||
|
return our_type;
|
||||||
|
}
|
88
src/tidy/tidy-actor.h
Normal file
88
src/tidy/tidy-actor.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/* tidy-actor.h: Base class for Tidy actors
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 OpenedHand
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __TIDY_ACTOR_H__
|
||||||
|
#define __TIDY_ACTOR_H__
|
||||||
|
|
||||||
|
#include <clutter/clutter-actor.h>
|
||||||
|
#include <tidy/tidy-types.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define TIDY_TYPE_ACTOR (tidy_actor_get_type ())
|
||||||
|
#define TIDY_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TIDY_TYPE_ACTOR, TidyActor))
|
||||||
|
#define TIDY_IS_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TIDY_TYPE_ACTOR))
|
||||||
|
#define TIDY_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TIDY_TYPE_ACTOR, TidyActorClass))
|
||||||
|
#define TIDY_IS_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TIDY_TYPE_ACTOR))
|
||||||
|
#define TIDY_ACTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TIDY_TYPE_ACTOR, TidyActorClass))
|
||||||
|
|
||||||
|
typedef struct _TidyActor TidyActor;
|
||||||
|
typedef struct _TidyActorPrivate TidyActorPrivate;
|
||||||
|
typedef struct _TidyActorClass TidyActorClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TidyActor:
|
||||||
|
*
|
||||||
|
* Base class for stylable actors. The contents of the #TidyActor
|
||||||
|
* structure are private and should only be accessed through the
|
||||||
|
* public API.
|
||||||
|
*/
|
||||||
|
struct _TidyActor
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
ClutterActor parent_instance;
|
||||||
|
|
||||||
|
TidyActorPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TidyActorClass:
|
||||||
|
*
|
||||||
|
* Base class for stylable actors.
|
||||||
|
*/
|
||||||
|
struct _TidyActorClass
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
ClutterActorClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType tidy_actor_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
void tidy_actor_set_padding (TidyActor *actor,
|
||||||
|
const TidyPadding *padding);
|
||||||
|
void tidy_actor_get_padding (TidyActor *actor,
|
||||||
|
TidyPadding *padding);
|
||||||
|
|
||||||
|
void tidy_actor_set_alignment (TidyActor *actor,
|
||||||
|
gdouble x_align,
|
||||||
|
gdouble y_align);
|
||||||
|
void tidy_actor_get_alignment (TidyActor *actor,
|
||||||
|
gdouble *x_align,
|
||||||
|
gdouble *y_align);
|
||||||
|
void tidy_actor_set_alignmentx (TidyActor *actor,
|
||||||
|
ClutterFixed x_align,
|
||||||
|
ClutterFixed y_align);
|
||||||
|
void tidy_actor_get_alignmentx (TidyActor *actor,
|
||||||
|
ClutterFixed *x_align,
|
||||||
|
ClutterFixed *y_align);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __TIDY_ACTOR_H__ */
|
374
src/tidy/tidy-button.c
Normal file
374
src/tidy/tidy-button.c
Normal file
@ -0,0 +1,374 @@
|
|||||||
|
/* tidy-button.c: Plain button actor
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 OpenedHand
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Written by: Emmanuele Bassi <ebassi@openedhand.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
|
#include "tidy-button.h"
|
||||||
|
|
||||||
|
#include "tidy-debug.h"
|
||||||
|
#include "tidy-marshal.h"
|
||||||
|
#include "tidy-stylable.h"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
|
||||||
|
PROP_LABEL
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CLICKED,
|
||||||
|
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TIDY_BUTTON_GET_PRIVATE(obj) \
|
||||||
|
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), TIDY_TYPE_BUTTON, TidyButtonPrivate))
|
||||||
|
|
||||||
|
struct _TidyButtonPrivate
|
||||||
|
{
|
||||||
|
gchar *text;
|
||||||
|
|
||||||
|
ClutterTimeline *timeline;
|
||||||
|
ClutterEffectTemplate *press_tmpl;
|
||||||
|
|
||||||
|
guint8 old_opacity;
|
||||||
|
|
||||||
|
guint is_pressed : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint button_signals[LAST_SIGNAL] = { 0, };
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (TidyButton, tidy_button, TIDY_TYPE_FRAME);
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_button_real_pressed (TidyButton *button)
|
||||||
|
{
|
||||||
|
TidyButtonPrivate *priv = button->priv;
|
||||||
|
ClutterActor *actor = CLUTTER_ACTOR (button);
|
||||||
|
|
||||||
|
if (G_UNLIKELY (!priv->press_tmpl))
|
||||||
|
{
|
||||||
|
priv->timeline = clutter_timeline_new_for_duration (250);
|
||||||
|
priv->press_tmpl = clutter_effect_template_new (priv->timeline,
|
||||||
|
clutter_sine_inc_func);
|
||||||
|
clutter_effect_template_set_timeline_clone (priv->press_tmpl, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clutter_timeline_is_playing (priv->timeline))
|
||||||
|
{
|
||||||
|
clutter_timeline_stop (priv->timeline);
|
||||||
|
clutter_actor_set_opacity (actor, priv->old_opacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->old_opacity = clutter_actor_get_opacity (actor);
|
||||||
|
|
||||||
|
clutter_effect_fade (priv->press_tmpl, actor,
|
||||||
|
0x44,
|
||||||
|
NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_button_real_released (TidyButton *button)
|
||||||
|
{
|
||||||
|
TidyButtonPrivate *priv = button->priv;
|
||||||
|
ClutterActor *actor = CLUTTER_ACTOR (button);
|
||||||
|
|
||||||
|
if (G_UNLIKELY (!priv->press_tmpl))
|
||||||
|
{
|
||||||
|
priv->timeline = clutter_timeline_new_for_duration (250);
|
||||||
|
priv->press_tmpl = clutter_effect_template_new (priv->timeline,
|
||||||
|
clutter_sine_inc_func);
|
||||||
|
clutter_effect_template_set_timeline_clone (priv->press_tmpl, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clutter_timeline_is_playing (priv->timeline))
|
||||||
|
clutter_timeline_stop (priv->timeline);
|
||||||
|
|
||||||
|
clutter_effect_fade (priv->press_tmpl, actor,
|
||||||
|
priv->old_opacity,
|
||||||
|
NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_button_construct_child (TidyButton *button)
|
||||||
|
{
|
||||||
|
TidyButtonPrivate *priv = button->priv;
|
||||||
|
gchar *font_name;
|
||||||
|
ClutterColor *text_color;
|
||||||
|
ClutterActor *label;
|
||||||
|
|
||||||
|
if (!priv->text)
|
||||||
|
return;
|
||||||
|
|
||||||
|
tidy_stylable_get (TIDY_STYLABLE (button),
|
||||||
|
"font-name", &font_name,
|
||||||
|
"text-color", &text_color,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
label = g_object_new (CLUTTER_TYPE_LABEL,
|
||||||
|
"font-name", font_name,
|
||||||
|
"text", priv->text,
|
||||||
|
"color", text_color,
|
||||||
|
"alignment", PANGO_ALIGN_CENTER,
|
||||||
|
"ellipsize", PANGO_ELLIPSIZE_MIDDLE,
|
||||||
|
"use-markup", TRUE,
|
||||||
|
"wrap", FALSE,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
clutter_actor_show (label);
|
||||||
|
clutter_container_add_actor (CLUTTER_CONTAINER (button), label);
|
||||||
|
|
||||||
|
clutter_color_free (text_color);
|
||||||
|
g_free (font_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
tidy_button_button_press (ClutterActor *actor,
|
||||||
|
ClutterButtonEvent *event)
|
||||||
|
{
|
||||||
|
if (event->button == 1 &&
|
||||||
|
event->click_count == 1)
|
||||||
|
{
|
||||||
|
TidyButton *button = TIDY_BUTTON (actor);
|
||||||
|
TidyButtonClass *klass = TIDY_BUTTON_GET_CLASS (button);
|
||||||
|
|
||||||
|
button->priv->is_pressed = TRUE;
|
||||||
|
|
||||||
|
clutter_grab_pointer (actor);
|
||||||
|
|
||||||
|
if (klass->pressed)
|
||||||
|
klass->pressed (button);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
tidy_button_button_release (ClutterActor *actor,
|
||||||
|
ClutterButtonEvent *event)
|
||||||
|
{
|
||||||
|
if (event->button == 1)
|
||||||
|
{
|
||||||
|
TidyButton *button = TIDY_BUTTON (actor);
|
||||||
|
TidyButtonClass *klass = TIDY_BUTTON_GET_CLASS (button);
|
||||||
|
|
||||||
|
if (!button->priv->is_pressed)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
clutter_ungrab_pointer ();
|
||||||
|
|
||||||
|
button->priv->is_pressed = FALSE;
|
||||||
|
|
||||||
|
if (klass->released)
|
||||||
|
klass->released (button);
|
||||||
|
|
||||||
|
g_signal_emit (button, button_signals[CLICKED], 0);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
tidy_button_leave (ClutterActor *actor,
|
||||||
|
ClutterCrossingEvent *event)
|
||||||
|
{
|
||||||
|
TidyButton *button = TIDY_BUTTON (actor);
|
||||||
|
|
||||||
|
if (button->priv->is_pressed)
|
||||||
|
{
|
||||||
|
TidyButtonClass *klass = TIDY_BUTTON_GET_CLASS (button);
|
||||||
|
|
||||||
|
clutter_ungrab_pointer ();
|
||||||
|
|
||||||
|
button->priv->is_pressed = FALSE;
|
||||||
|
|
||||||
|
if (klass->released)
|
||||||
|
klass->released (button);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_button_set_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
TidyButton *button = TIDY_BUTTON (gobject);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_LABEL:
|
||||||
|
tidy_button_set_label (button, g_value_get_string (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_button_get_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
TidyButtonPrivate *priv = TIDY_BUTTON (gobject)->priv;
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_LABEL:
|
||||||
|
g_value_set_string (value, priv->text);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_button_finalize (GObject *gobject)
|
||||||
|
{
|
||||||
|
TidyButtonPrivate *priv = TIDY_BUTTON (gobject)->priv;
|
||||||
|
|
||||||
|
g_free (priv->text);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (tidy_button_parent_class)->finalize (gobject);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_button_dispose (GObject *gobject)
|
||||||
|
{
|
||||||
|
TidyButtonPrivate *priv = TIDY_BUTTON (gobject)->priv;
|
||||||
|
|
||||||
|
if (priv->press_tmpl)
|
||||||
|
{
|
||||||
|
g_object_unref (priv->press_tmpl);
|
||||||
|
g_object_unref (priv->timeline);
|
||||||
|
|
||||||
|
priv->press_tmpl = NULL;
|
||||||
|
priv->timeline = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (tidy_button_parent_class)->dispose (gobject);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_button_class_init (TidyButtonClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||||
|
|
||||||
|
g_type_class_add_private (klass, sizeof (TidyButtonPrivate));
|
||||||
|
|
||||||
|
klass->pressed = tidy_button_real_pressed;
|
||||||
|
klass->released = tidy_button_real_released;
|
||||||
|
|
||||||
|
gobject_class->set_property = tidy_button_set_property;
|
||||||
|
gobject_class->get_property = tidy_button_get_property;
|
||||||
|
gobject_class->dispose = tidy_button_dispose;
|
||||||
|
gobject_class->finalize = tidy_button_finalize;
|
||||||
|
|
||||||
|
actor_class->button_press_event = tidy_button_button_press;
|
||||||
|
actor_class->button_release_event = tidy_button_button_release;
|
||||||
|
actor_class->leave_event = tidy_button_leave;
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_LABEL,
|
||||||
|
g_param_spec_string ("label",
|
||||||
|
"Label",
|
||||||
|
"Label of the button",
|
||||||
|
NULL,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
|
||||||
|
button_signals[CLICKED] =
|
||||||
|
g_signal_new ("clicked",
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (TidyButtonClass, clicked),
|
||||||
|
NULL, NULL,
|
||||||
|
_tidy_marshal_VOID__VOID,
|
||||||
|
G_TYPE_NONE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_button_init (TidyButton *button)
|
||||||
|
{
|
||||||
|
button->priv = TIDY_BUTTON_GET_PRIVATE (button);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClutterActor *
|
||||||
|
tidy_button_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (TIDY_TYPE_BUTTON, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClutterActor *
|
||||||
|
tidy_button_new_with_label (const gchar *text)
|
||||||
|
{
|
||||||
|
return g_object_new (TIDY_TYPE_BUTTON, "label", text, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
G_CONST_RETURN gchar *
|
||||||
|
tidy_button_get_label (TidyButton *button)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (TIDY_IS_BUTTON (button), NULL);
|
||||||
|
|
||||||
|
return button->priv->text;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tidy_button_set_label (TidyButton *button,
|
||||||
|
const gchar *text)
|
||||||
|
{
|
||||||
|
TidyButtonPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (TIDY_IS_BUTTON (button));
|
||||||
|
|
||||||
|
priv = button->priv;
|
||||||
|
|
||||||
|
g_free (priv->text);
|
||||||
|
priv->text = g_strdup (text);
|
||||||
|
|
||||||
|
tidy_button_construct_child (button);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (button), "label");
|
||||||
|
}
|
70
src/tidy/tidy-button.h
Normal file
70
src/tidy/tidy-button.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/* tidy-button.h: Plain button actor
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 OpenedHand
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Written by: Emmanuele Bassi <ebassi@openedhand.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __TIDY_BUTTON_H__
|
||||||
|
#define __TIDY_BUTTON_H__
|
||||||
|
|
||||||
|
#include <tidy/tidy-frame.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define TIDY_TYPE_BUTTON (tidy_button_get_type ())
|
||||||
|
#define TIDY_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TIDY_TYPE_BUTTON, TidyButton))
|
||||||
|
#define TIDY_IS_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TIDY_TYPE_BUTTON))
|
||||||
|
#define TIDY_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TIDY_TYPE_BUTTON, TidyButtonClass))
|
||||||
|
#define TIDY_IS_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TIDY_TYPE_BUTTON))
|
||||||
|
#define TIDY_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TIDY_TYPE_BUTTON, TidyButtonClass))
|
||||||
|
|
||||||
|
typedef struct _TidyButton TidyButton;
|
||||||
|
typedef struct _TidyButtonPrivate TidyButtonPrivate;
|
||||||
|
typedef struct _TidyButtonClass TidyButtonClass;
|
||||||
|
|
||||||
|
struct _TidyButton
|
||||||
|
{
|
||||||
|
TidyFrame parent_instance;
|
||||||
|
|
||||||
|
TidyButtonPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _TidyButtonClass
|
||||||
|
{
|
||||||
|
TidyFrameClass parent_class;
|
||||||
|
|
||||||
|
/* vfuncs, not signals */
|
||||||
|
void (* pressed) (TidyButton *button);
|
||||||
|
void (* released) (TidyButton *button);
|
||||||
|
|
||||||
|
/* signals */
|
||||||
|
void (* clicked) (TidyButton *button);
|
||||||
|
};
|
||||||
|
|
||||||
|
GType tidy_button_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
ClutterActor * tidy_button_new (void);
|
||||||
|
ClutterActor * tidy_button_new_with_label (const gchar *text);
|
||||||
|
G_CONST_RETURN gchar *tidy_button_get_label (TidyButton *button);
|
||||||
|
void tidy_button_set_label (TidyButton *button,
|
||||||
|
const gchar *text);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __TIDY_BUTTON_H__ */
|
4
src/tidy/tidy-debug.h
Normal file
4
src/tidy/tidy-debug.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#ifndef __TIDY_DEBUG_H__
|
||||||
|
#define __TIDY_DEBUG_H__
|
||||||
|
|
||||||
|
#endif /* __TIDY_DEBUG_H__ */
|
30
src/tidy/tidy-enum-types.c.in
Normal file
30
src/tidy/tidy-enum-types.c.in
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*** BEGIN file-header ***/
|
||||||
|
#include "tidy-enum-types.h"
|
||||||
|
/*** END file-header ***/
|
||||||
|
|
||||||
|
/*** BEGIN file-production ***/
|
||||||
|
/* enumerations from "@filename@" */
|
||||||
|
#include "@filename@"
|
||||||
|
/*** END file-production ***/
|
||||||
|
|
||||||
|
/*** BEGIN value-header ***/
|
||||||
|
GType
|
||||||
|
@enum_name@_get_type(void) {
|
||||||
|
static GType enum_type_id = 0;
|
||||||
|
if (G_UNLIKELY (!enum_type_id))
|
||||||
|
{
|
||||||
|
static const G@Type@Value values[] = {
|
||||||
|
/*** END value-header ***/
|
||||||
|
|
||||||
|
/*** BEGIN value-production ***/
|
||||||
|
{ @VALUENAME@, "@VALUENAME@", "@valuenick@" },
|
||||||
|
/*** END value-production ***/
|
||||||
|
|
||||||
|
/*** BEGIN value-tail ***/
|
||||||
|
{ 0, NULL, NULL }
|
||||||
|
};
|
||||||
|
enum_type_id = g_@type@_register_static("@EnumName@", values);
|
||||||
|
}
|
||||||
|
return enum_type_id;
|
||||||
|
}
|
||||||
|
/*** END value-tail ***/
|
25
src/tidy/tidy-enum-types.h.in
Normal file
25
src/tidy/tidy-enum-types.h.in
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*** BEGIN file-header ***/
|
||||||
|
#ifndef __TIDY_ENUM_TYPES_H__
|
||||||
|
#define __TIDY_ENUM_TYPES_H__
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
/*** END file-header ***/
|
||||||
|
|
||||||
|
/*** BEGIN file-production ***/
|
||||||
|
/* enumerations from "@filename@" */
|
||||||
|
/*** END file-production ***/
|
||||||
|
|
||||||
|
/*** BEGIN file-tail ***/
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* !__TIDY_ENUM_TYPES_H__ */
|
||||||
|
/*** END file-tail ***/
|
||||||
|
|
||||||
|
/*** BEGIN value-header ***/
|
||||||
|
GType @enum_name@_get_type (void) G_GNUC_CONST;
|
||||||
|
#define TIDY_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
|
||||||
|
|
||||||
|
/*** END value-header ***/
|
515
src/tidy/tidy-frame.c
Normal file
515
src/tidy/tidy-frame.c
Normal file
@ -0,0 +1,515 @@
|
|||||||
|
/* tidy-frame.c: Simple container with a background
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 OpenedHand
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Written by: Emmanuele Bassi <ebassi@openedhand.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#include <cogl/cogl.h>
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
|
#include "tidy-frame.h"
|
||||||
|
#include "tidy-private.h"
|
||||||
|
#include "tidy-stylable.h"
|
||||||
|
|
||||||
|
#define TIDY_FRAME_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TIDY_TYPE_FRAME, TidyFramePrivate))
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
|
||||||
|
PROP_CHILD,
|
||||||
|
PROP_TEXTURE
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _TidyFramePrivate
|
||||||
|
{
|
||||||
|
ClutterActor *child;
|
||||||
|
ClutterActor *texture;
|
||||||
|
};
|
||||||
|
|
||||||
|
static ClutterColor default_bg_color = { 0xcc, 0xcc, 0xcc, 0xff };
|
||||||
|
|
||||||
|
static void clutter_container_iface_init (ClutterContainerIface *iface);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_CODE (TidyFrame, tidy_frame, TIDY_TYPE_ACTOR,
|
||||||
|
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER,
|
||||||
|
clutter_container_iface_init));
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_frame_get_preferred_width (ClutterActor *actor,
|
||||||
|
ClutterUnit for_height,
|
||||||
|
ClutterUnit *min_width_p,
|
||||||
|
ClutterUnit *natural_width_p)
|
||||||
|
{
|
||||||
|
TidyFramePrivate *priv = TIDY_FRAME (actor)->priv;
|
||||||
|
TidyPadding padding = { 0, };
|
||||||
|
ClutterUnit min_width, natural_width;
|
||||||
|
|
||||||
|
tidy_actor_get_padding (TIDY_ACTOR (actor), &padding);
|
||||||
|
|
||||||
|
min_width = 0;
|
||||||
|
natural_width = padding.left + padding.right;
|
||||||
|
|
||||||
|
if (priv->child)
|
||||||
|
{
|
||||||
|
ClutterUnit child_min, child_natural;
|
||||||
|
|
||||||
|
clutter_actor_get_preferred_width (priv->child, for_height,
|
||||||
|
&child_min,
|
||||||
|
&child_natural);
|
||||||
|
|
||||||
|
min_width += child_min;
|
||||||
|
natural_width += child_natural;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (min_width_p)
|
||||||
|
*min_width_p = min_width;
|
||||||
|
|
||||||
|
if (natural_width_p)
|
||||||
|
*natural_width_p = natural_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_frame_get_preferred_height (ClutterActor *actor,
|
||||||
|
ClutterUnit for_width,
|
||||||
|
ClutterUnit *min_height_p,
|
||||||
|
ClutterUnit *natural_height_p)
|
||||||
|
{
|
||||||
|
TidyFramePrivate *priv = TIDY_FRAME (actor)->priv;
|
||||||
|
TidyPadding padding = { 0, };
|
||||||
|
ClutterUnit min_height, natural_height;
|
||||||
|
|
||||||
|
tidy_actor_get_padding (TIDY_ACTOR (actor), &padding);
|
||||||
|
|
||||||
|
min_height = 0;
|
||||||
|
natural_height = padding.top + padding.bottom;
|
||||||
|
|
||||||
|
if (priv->child)
|
||||||
|
{
|
||||||
|
ClutterUnit child_min, child_natural;
|
||||||
|
|
||||||
|
clutter_actor_get_preferred_height (priv->child, for_width,
|
||||||
|
&child_min,
|
||||||
|
&child_natural);
|
||||||
|
|
||||||
|
min_height += child_min;
|
||||||
|
natural_height += child_natural;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (min_height_p)
|
||||||
|
*min_height_p = min_height;
|
||||||
|
|
||||||
|
if (natural_height_p)
|
||||||
|
*natural_height_p = natural_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_frame_allocate (ClutterActor *actor,
|
||||||
|
const ClutterActorBox *box,
|
||||||
|
gboolean origin_changed)
|
||||||
|
{
|
||||||
|
TidyFramePrivate *priv = TIDY_FRAME (actor)->priv;
|
||||||
|
ClutterActorClass *klass;
|
||||||
|
|
||||||
|
klass = CLUTTER_ACTOR_CLASS (tidy_frame_parent_class);
|
||||||
|
klass->allocate (actor, box, origin_changed);
|
||||||
|
|
||||||
|
if (priv->texture)
|
||||||
|
{
|
||||||
|
ClutterActorBox texture_box = { 0, };
|
||||||
|
|
||||||
|
texture_box.x1 = 0;
|
||||||
|
texture_box.y1 = 0;
|
||||||
|
texture_box.x2 = box->x2 - box->x1;
|
||||||
|
texture_box.y2 = box->y2 - box->y1;
|
||||||
|
|
||||||
|
clutter_actor_allocate (priv->texture, &texture_box, origin_changed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->child)
|
||||||
|
{
|
||||||
|
TidyPadding padding = { 0, };
|
||||||
|
ClutterFixed x_align, y_align;
|
||||||
|
ClutterUnit available_width, available_height;
|
||||||
|
ClutterUnit child_width, child_height;
|
||||||
|
ClutterActorBox child_box = { 0, };
|
||||||
|
|
||||||
|
tidy_actor_get_padding (TIDY_ACTOR (actor), &padding);
|
||||||
|
tidy_actor_get_alignmentx (TIDY_ACTOR (actor), &x_align, &y_align);
|
||||||
|
|
||||||
|
available_width = box->x2 - box->x1
|
||||||
|
- padding.left
|
||||||
|
- padding.right;
|
||||||
|
available_height = box->y2 - box->y1
|
||||||
|
- padding.top
|
||||||
|
- padding.bottom;
|
||||||
|
|
||||||
|
if (available_width < 0)
|
||||||
|
available_width = 0;
|
||||||
|
|
||||||
|
if (available_height < 0)
|
||||||
|
available_height = 0;
|
||||||
|
|
||||||
|
clutter_actor_get_preferred_size (priv->child,
|
||||||
|
NULL, NULL,
|
||||||
|
&child_width,
|
||||||
|
&child_height);
|
||||||
|
|
||||||
|
if (child_width > available_width)
|
||||||
|
child_width = available_width;
|
||||||
|
|
||||||
|
if (child_height > available_height)
|
||||||
|
child_height = available_height;
|
||||||
|
|
||||||
|
child_box.x1 = CLUTTER_FIXED_MUL ((available_width - child_width),
|
||||||
|
x_align)
|
||||||
|
+ padding.left;
|
||||||
|
child_box.y1 = CLUTTER_FIXED_MUL ((available_height - child_height),
|
||||||
|
y_align)
|
||||||
|
+ padding.top;
|
||||||
|
|
||||||
|
child_box.x2 = child_box.x1 + child_width;
|
||||||
|
child_box.y2 = child_box.y1 + child_height;
|
||||||
|
|
||||||
|
clutter_actor_allocate (priv->child, &child_box, origin_changed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_frame_paint (ClutterActor *actor)
|
||||||
|
{
|
||||||
|
TidyFrame *frame = TIDY_FRAME (actor);
|
||||||
|
TidyFramePrivate *priv = frame->priv;
|
||||||
|
|
||||||
|
cogl_push_matrix ();
|
||||||
|
|
||||||
|
if (priv->texture)
|
||||||
|
clutter_actor_paint (priv->texture);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ClutterActorBox allocation = { 0, };
|
||||||
|
ClutterColor *bg_color;
|
||||||
|
guint w, h;
|
||||||
|
|
||||||
|
tidy_stylable_get (TIDY_STYLABLE (frame), "bg-color", &bg_color, NULL);
|
||||||
|
if (!bg_color)
|
||||||
|
bg_color = &default_bg_color;
|
||||||
|
|
||||||
|
bg_color->alpha = clutter_actor_get_paint_opacity (actor)
|
||||||
|
* bg_color->alpha
|
||||||
|
/ 255;
|
||||||
|
|
||||||
|
clutter_actor_get_allocation_box (actor, &allocation);
|
||||||
|
|
||||||
|
w = CLUTTER_UNITS_TO_DEVICE (allocation.x2 - allocation.x1);
|
||||||
|
h = CLUTTER_UNITS_TO_DEVICE (allocation.y2 - allocation.y1);
|
||||||
|
|
||||||
|
cogl_color (bg_color);
|
||||||
|
cogl_rectangle (0, 0, w, h);
|
||||||
|
|
||||||
|
if (bg_color != &default_bg_color)
|
||||||
|
clutter_color_free (bg_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->child && CLUTTER_ACTOR_IS_VISIBLE (priv->child))
|
||||||
|
clutter_actor_paint (priv->child);
|
||||||
|
|
||||||
|
cogl_pop_matrix ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_frame_pick (ClutterActor *actor,
|
||||||
|
const ClutterColor *pick_color)
|
||||||
|
{
|
||||||
|
TidyFramePrivate *priv = TIDY_FRAME (actor)->priv;
|
||||||
|
|
||||||
|
/* chain up, so we get a box with our coordinates */
|
||||||
|
CLUTTER_ACTOR_CLASS (tidy_frame_parent_class)->pick (actor, pick_color);
|
||||||
|
|
||||||
|
if (priv->child && CLUTTER_ACTOR_IS_VISIBLE (priv->child))
|
||||||
|
clutter_actor_paint (priv->child);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_frame_dispose (GObject *gobject)
|
||||||
|
{
|
||||||
|
TidyFramePrivate *priv = TIDY_FRAME (gobject)->priv;
|
||||||
|
|
||||||
|
if (priv->child)
|
||||||
|
{
|
||||||
|
clutter_actor_unparent (priv->child);
|
||||||
|
priv->child = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->texture)
|
||||||
|
{
|
||||||
|
clutter_actor_unparent (priv->texture);
|
||||||
|
priv->texture = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (tidy_frame_parent_class)->dispose (gobject);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_frame_set_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_CHILD:
|
||||||
|
clutter_container_add_actor (CLUTTER_CONTAINER (gobject),
|
||||||
|
g_value_get_object (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_TEXTURE:
|
||||||
|
tidy_frame_set_texture (TIDY_FRAME (gobject),
|
||||||
|
g_value_get_object (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_frame_get_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
TidyFramePrivate *priv = TIDY_FRAME (gobject)->priv;
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_CHILD:
|
||||||
|
g_value_set_object (value, priv->child);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_TEXTURE:
|
||||||
|
g_value_set_object (value, priv->texture);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_frame_class_init (TidyFrameClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||||
|
|
||||||
|
g_type_class_add_private (klass, sizeof (TidyFramePrivate));
|
||||||
|
|
||||||
|
gobject_class->set_property = tidy_frame_set_property;
|
||||||
|
gobject_class->get_property = tidy_frame_get_property;
|
||||||
|
gobject_class->dispose = tidy_frame_dispose;
|
||||||
|
|
||||||
|
actor_class->pick = tidy_frame_pick;
|
||||||
|
actor_class->paint = tidy_frame_paint;
|
||||||
|
actor_class->allocate = tidy_frame_allocate;
|
||||||
|
actor_class->get_preferred_width = tidy_frame_get_preferred_width;
|
||||||
|
actor_class->get_preferred_height = tidy_frame_get_preferred_height;
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_CHILD,
|
||||||
|
g_param_spec_object ("child",
|
||||||
|
"Child",
|
||||||
|
"The child of the frame",
|
||||||
|
CLUTTER_TYPE_ACTOR,
|
||||||
|
TIDY_PARAM_READWRITE));
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_TEXTURE,
|
||||||
|
g_param_spec_object ("texture",
|
||||||
|
"Texture",
|
||||||
|
"The background texture of the frame",
|
||||||
|
CLUTTER_TYPE_ACTOR,
|
||||||
|
TIDY_PARAM_READWRITE));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_frame_init (TidyFrame *frame)
|
||||||
|
{
|
||||||
|
frame->priv = TIDY_FRAME_GET_PRIVATE (frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_frame_add_actor (ClutterContainer *container,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
TidyFramePrivate *priv = TIDY_FRAME (container)->priv;
|
||||||
|
|
||||||
|
if (priv->child)
|
||||||
|
clutter_actor_unparent (priv->child);
|
||||||
|
|
||||||
|
clutter_actor_set_parent (actor, CLUTTER_ACTOR (container));
|
||||||
|
priv->child = actor;
|
||||||
|
|
||||||
|
clutter_actor_queue_relayout (CLUTTER_ACTOR (container));
|
||||||
|
|
||||||
|
g_signal_emit_by_name (container, "actor-added", actor);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (container), "child");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_frame_remove_actor (ClutterContainer *container,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
TidyFramePrivate *priv = TIDY_FRAME (container)->priv;
|
||||||
|
|
||||||
|
if (priv->child == actor)
|
||||||
|
{
|
||||||
|
g_object_ref (priv->child);
|
||||||
|
|
||||||
|
clutter_actor_unparent (priv->child);
|
||||||
|
priv->child = NULL;
|
||||||
|
|
||||||
|
clutter_actor_queue_relayout (CLUTTER_ACTOR (container));
|
||||||
|
|
||||||
|
g_signal_emit_by_name (container, "actor-removed", priv->child);
|
||||||
|
|
||||||
|
g_object_unref (priv->child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_frame_foreach (ClutterContainer *container,
|
||||||
|
ClutterCallback callback,
|
||||||
|
gpointer callback_data)
|
||||||
|
{
|
||||||
|
TidyFramePrivate *priv = TIDY_FRAME (container)->priv;
|
||||||
|
|
||||||
|
if (priv->texture)
|
||||||
|
callback (priv->texture, callback_data);
|
||||||
|
|
||||||
|
if (priv->child)
|
||||||
|
callback (priv->child, callback_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_frame_lower (ClutterContainer *container,
|
||||||
|
ClutterActor *actor,
|
||||||
|
ClutterActor *sibling)
|
||||||
|
{
|
||||||
|
/* single child */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_frame_raise (ClutterContainer *container,
|
||||||
|
ClutterActor *actor,
|
||||||
|
ClutterActor *sibling)
|
||||||
|
{
|
||||||
|
/* single child */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_frame_sort_depth_order (ClutterContainer *container)
|
||||||
|
{
|
||||||
|
/* single child */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_container_iface_init (ClutterContainerIface *iface)
|
||||||
|
{
|
||||||
|
iface->add = tidy_frame_add_actor;
|
||||||
|
iface->remove = tidy_frame_remove_actor;
|
||||||
|
iface->foreach = tidy_frame_foreach;
|
||||||
|
iface->lower = tidy_frame_lower;
|
||||||
|
iface->raise = tidy_frame_raise;
|
||||||
|
iface->sort_depth_order = tidy_frame_sort_depth_order;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClutterActor *
|
||||||
|
tidy_frame_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (TIDY_TYPE_FRAME, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClutterActor *
|
||||||
|
tidy_frame_get_child (TidyFrame *frame)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (TIDY_IS_FRAME (frame), NULL);
|
||||||
|
|
||||||
|
return frame->priv->child;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tidy_frame_set_texture (TidyFrame *frame,
|
||||||
|
ClutterActor *texture)
|
||||||
|
{
|
||||||
|
TidyFramePrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (TIDY_IS_FRAME (frame));
|
||||||
|
g_return_if_fail (CLUTTER_IS_ACTOR (texture));
|
||||||
|
|
||||||
|
priv = frame->priv;
|
||||||
|
|
||||||
|
if (priv->texture == texture)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (priv->texture)
|
||||||
|
{
|
||||||
|
clutter_actor_unparent (priv->texture);
|
||||||
|
priv->texture = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texture)
|
||||||
|
{
|
||||||
|
ClutterActor *parent = clutter_actor_get_parent (texture);
|
||||||
|
|
||||||
|
if (G_UNLIKELY (parent != NULL))
|
||||||
|
{
|
||||||
|
g_warning ("Unable to set the background texture of type `%s' for "
|
||||||
|
"the frame of type `%s': the texture actor is already "
|
||||||
|
"a child of a container of type `%s'",
|
||||||
|
g_type_name (G_OBJECT_TYPE (texture)),
|
||||||
|
g_type_name (G_OBJECT_TYPE (frame)),
|
||||||
|
g_type_name (G_OBJECT_TYPE (parent)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->texture = texture;
|
||||||
|
clutter_actor_set_parent (texture, CLUTTER_ACTOR (frame));
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_actor_queue_relayout (CLUTTER_ACTOR (frame));
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (frame), "texture");
|
||||||
|
}
|
||||||
|
|
||||||
|
ClutterActor *
|
||||||
|
tidy_frame_get_texture (TidyFrame *frame)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (TIDY_IS_FRAME (frame), NULL);
|
||||||
|
|
||||||
|
return frame->priv->texture;
|
||||||
|
}
|
||||||
|
|
64
src/tidy/tidy-frame.h
Normal file
64
src/tidy/tidy-frame.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/* tidy-frame.h: Simple container with a background
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 OpenedHand
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Written by: Emmanuele Bassi <ebassi@openedhand.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __TIDY_FRAME_H__
|
||||||
|
#define __TIDY_FRAME_H__
|
||||||
|
|
||||||
|
#include <clutter/clutter-actor.h>
|
||||||
|
#include <tidy/tidy-actor.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define TIDY_TYPE_FRAME (tidy_frame_get_type ())
|
||||||
|
#define TIDY_FRAME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TIDY_TYPE_FRAME, TidyFrame))
|
||||||
|
#define TIDY_IS_FRAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TIDY_TYPE_FRAME))
|
||||||
|
#define TIDY_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TIDY_TYPE_FRAME, TidyFrameClass))
|
||||||
|
#define TIDY_IS_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TIDY_TYPE_FRAME))
|
||||||
|
#define TIDY_FRAME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TIDY_TYPE_FRAME, TidyFrameClass))
|
||||||
|
|
||||||
|
typedef struct _TidyFrame TidyFrame;
|
||||||
|
typedef struct _TidyFramePrivate TidyFramePrivate;
|
||||||
|
typedef struct _TidyFrameClass TidyFrameClass;
|
||||||
|
|
||||||
|
struct _TidyFrame
|
||||||
|
{
|
||||||
|
TidyActor parent_instance;
|
||||||
|
|
||||||
|
TidyFramePrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _TidyFrameClass
|
||||||
|
{
|
||||||
|
TidyActorClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType tidy_frame_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
ClutterActor *tidy_frame_new (void);
|
||||||
|
ClutterActor *tidy_frame_get_child (TidyFrame *frame);
|
||||||
|
void tidy_frame_set_texture (TidyFrame *frame,
|
||||||
|
ClutterActor *actor);
|
||||||
|
ClutterActor *tidy_frame_get_texture (TidyFrame *frame);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __TIDY_FRAME_H__ */
|
1005
src/tidy/tidy-grid.c
Normal file
1005
src/tidy/tidy-grid.c
Normal file
File diff suppressed because it is too large
Load Diff
99
src/tidy/tidy-grid.h
Normal file
99
src/tidy/tidy-grid.h
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* Clutter.
|
||||||
|
*
|
||||||
|
* An OpenGL based 'interactive canvas' library.
|
||||||
|
*
|
||||||
|
* Authored By Matthew Allum <mallum@openedhand.com>
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 OpenedHand
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __TIDY_GRID_H__
|
||||||
|
#define __TIDY_GRID_H__
|
||||||
|
|
||||||
|
#include <clutter/clutter-actor.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define TIDY_TYPE_GRID (tidy_grid_get_type())
|
||||||
|
#define TIDY_GRID(obj) \
|
||||||
|
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
||||||
|
TIDY_TYPE_GRID, \
|
||||||
|
TidyGrid))
|
||||||
|
#define TIDY_GRID_CLASS(klass) \
|
||||||
|
(G_TYPE_CHECK_CLASS_CAST ((klass), \
|
||||||
|
TIDY_TYPE_GRID, \
|
||||||
|
TidyGridClass))
|
||||||
|
#define TIDY_IS_GRID(obj) \
|
||||||
|
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
||||||
|
TIDY_TYPE_GRID))
|
||||||
|
#define TIDY_IS_GRID_CLASS(klass) \
|
||||||
|
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
||||||
|
TIDY_TYPE_GRID))
|
||||||
|
#define TIDY_GRID_GET_CLASS(obj) \
|
||||||
|
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
||||||
|
TIDY_TYPE_GRID, \
|
||||||
|
TidyGridClass))
|
||||||
|
|
||||||
|
typedef struct _TidyGrid TidyGrid;
|
||||||
|
typedef struct _TidyGridClass TidyGridClass;
|
||||||
|
typedef struct _TidyGridPrivate TidyGridPrivate;
|
||||||
|
|
||||||
|
struct _TidyGridClass
|
||||||
|
{
|
||||||
|
ClutterActorClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _TidyGrid
|
||||||
|
{
|
||||||
|
ClutterActor parent;
|
||||||
|
|
||||||
|
TidyGridPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType tidy_grid_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
ClutterActor *tidy_grid_new (void);
|
||||||
|
void tidy_grid_set_end_align (TidyGrid *self,
|
||||||
|
gboolean value);
|
||||||
|
gboolean tidy_grid_get_end_align (TidyGrid *self);
|
||||||
|
void tidy_grid_set_homogenous_rows (TidyGrid *self,
|
||||||
|
gboolean value);
|
||||||
|
gboolean tidy_grid_get_homogenous_rows (TidyGrid *self);
|
||||||
|
void tidy_grid_set_homogenous_columns (TidyGrid *self,
|
||||||
|
gboolean value);
|
||||||
|
gboolean tidy_grid_get_homogenous_columns (TidyGrid *self);
|
||||||
|
void tidy_grid_set_column_major (TidyGrid *self,
|
||||||
|
gboolean value);
|
||||||
|
gboolean tidy_grid_get_column_major (TidyGrid *self);
|
||||||
|
void tidy_grid_set_row_gap (TidyGrid *self,
|
||||||
|
ClutterUnit value);
|
||||||
|
ClutterUnit tidy_grid_get_row_gap (TidyGrid *self);
|
||||||
|
void tidy_grid_set_column_gap (TidyGrid *self,
|
||||||
|
ClutterUnit value);
|
||||||
|
ClutterUnit tidy_grid_get_column_gap (TidyGrid *self);
|
||||||
|
void tidy_grid_set_valign (TidyGrid *self,
|
||||||
|
gdouble value);
|
||||||
|
gdouble tidy_grid_get_valign (TidyGrid *self);
|
||||||
|
void tidy_grid_set_halign (TidyGrid *self,
|
||||||
|
gdouble value);
|
||||||
|
gdouble tidy_grid_get_halign (TidyGrid *self);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __TIDY_GRID_H__ */
|
8
src/tidy/tidy-marshal.list
Normal file
8
src/tidy/tidy-marshal.list
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
VOID:OBJECT
|
||||||
|
VOID:VOID
|
||||||
|
VOID:PARAM
|
||||||
|
VOID:POINTER
|
||||||
|
VOID:UINT
|
||||||
|
VOID:UINT,UINT
|
||||||
|
VOID:OBJECT,OBJECT
|
||||||
|
VOID:STRING,OBJECT
|
40
src/tidy/tidy-private.h
Normal file
40
src/tidy/tidy-private.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/* tidy-private.h: Private declarations
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 OpenedHand
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __TIDY_PRIVATE_H__
|
||||||
|
#define __TIDY_PRIVATE_H__
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define I_(str) (g_intern_static_string ((str)))
|
||||||
|
|
||||||
|
#define TIDY_PARAM_READABLE \
|
||||||
|
(G_PARAM_READABLE | \
|
||||||
|
G_PARAM_STATIC_NICK | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB)
|
||||||
|
|
||||||
|
#define TIDY_PARAM_READWRITE \
|
||||||
|
(G_PARAM_READABLE | G_PARAM_WRITABLE | \
|
||||||
|
G_PARAM_STATIC_NICK | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB)
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __TIDY_PRIVATE_H__ */
|
789
src/tidy/tidy-stylable.c
Normal file
789
src/tidy/tidy-stylable.c
Normal file
@ -0,0 +1,789 @@
|
|||||||
|
/* tidy-stylable.c: Interface for stylable objects
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:tidy-stylable
|
||||||
|
* @short_description: Interface for stylable objects
|
||||||
|
*
|
||||||
|
* Stylable objects are classes that can have "style properties", that is
|
||||||
|
* properties that can be changed by attaching a #TidyStyle to them.
|
||||||
|
*
|
||||||
|
* Objects can choose to subclass #TidyActor, and thus inherit all the
|
||||||
|
* #TidyActor style properties; or they can subclass #TidyActor and
|
||||||
|
* reimplement the #TidyStylable interface to add new style properties
|
||||||
|
* specific for them (and their subclasses); or, finally, they can simply
|
||||||
|
* subclass #GObject and implement #TidyStylable to install new properties.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <gobject/gvaluecollector.h>
|
||||||
|
#include <gobject/gobjectnotifyqueue.c>
|
||||||
|
|
||||||
|
#include "tidy-marshal.h"
|
||||||
|
#include "tidy-private.h"
|
||||||
|
#include "tidy-stylable.h"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
STYLE_SET,
|
||||||
|
STYLE_NOTIFY,
|
||||||
|
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
static GObjectNotifyContext property_notify_context = { 0, };
|
||||||
|
|
||||||
|
static GParamSpecPool *style_property_spec_pool = NULL;
|
||||||
|
|
||||||
|
static GQuark quark_real_owner = 0;
|
||||||
|
static GQuark quark_style = 0;
|
||||||
|
|
||||||
|
static guint stylable_signals[LAST_SIGNAL] = { 0, };
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_stylable_notify_dispatcher (GObject *gobject,
|
||||||
|
guint n_pspecs,
|
||||||
|
GParamSpec **pspecs)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < n_pspecs; i++)
|
||||||
|
g_signal_emit (gobject, stylable_signals[STYLE_NOTIFY],
|
||||||
|
g_quark_from_string (pspecs[i]->name),
|
||||||
|
pspecs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_stylable_base_finalize (gpointer g_iface)
|
||||||
|
{
|
||||||
|
GList *list, *node;
|
||||||
|
|
||||||
|
list = g_param_spec_pool_list_owned (style_property_spec_pool,
|
||||||
|
G_TYPE_FROM_INTERFACE (g_iface));
|
||||||
|
|
||||||
|
for (node = list; node; node = node->next)
|
||||||
|
{
|
||||||
|
GParamSpec *pspec = node->data;
|
||||||
|
|
||||||
|
g_param_spec_pool_remove (style_property_spec_pool, pspec);
|
||||||
|
g_param_spec_unref (pspec);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_list_free (list);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_stylable_base_init (gpointer g_iface)
|
||||||
|
{
|
||||||
|
static gboolean initialised = FALSE;
|
||||||
|
|
||||||
|
if (G_UNLIKELY (!initialised))
|
||||||
|
{
|
||||||
|
GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
|
||||||
|
|
||||||
|
initialised = TRUE;
|
||||||
|
|
||||||
|
quark_real_owner = g_quark_from_static_string ("tidy-stylable-real-owner-quark");
|
||||||
|
quark_style = g_quark_from_static_string ("tidy-stylable-style-quark");
|
||||||
|
|
||||||
|
style_property_spec_pool = g_param_spec_pool_new (FALSE);
|
||||||
|
|
||||||
|
property_notify_context.quark_notify_queue = g_quark_from_static_string ("TidyStylable-style-property-notify-queue");
|
||||||
|
property_notify_context.dispatcher = tidy_stylable_notify_dispatcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TidyStylable:style:
|
||||||
|
*
|
||||||
|
* The #TidyStyle attached to a stylable object.
|
||||||
|
*/
|
||||||
|
g_object_interface_install_property (g_iface,
|
||||||
|
g_param_spec_object ("style",
|
||||||
|
"Style",
|
||||||
|
"A style object",
|
||||||
|
TIDY_TYPE_STYLE,
|
||||||
|
TIDY_PARAM_READWRITE));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TidyStylable::style-set:
|
||||||
|
* @stylable: the #TidyStylable that received the signal
|
||||||
|
* @old_style: the previously set #TidyStyle for @stylable
|
||||||
|
*
|
||||||
|
* The ::style-set signal is emitted each time the #TidyStyle attached
|
||||||
|
* to @stylable has been changed.
|
||||||
|
*/
|
||||||
|
stylable_signals[STYLE_SET] =
|
||||||
|
g_signal_new (I_("style-set"),
|
||||||
|
iface_type,
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (TidyStylableIface, style_set),
|
||||||
|
NULL, NULL,
|
||||||
|
_tidy_marshal_VOID__OBJECT,
|
||||||
|
G_TYPE_NONE, 1,
|
||||||
|
TIDY_TYPE_STYLE);
|
||||||
|
stylable_signals[STYLE_NOTIFY] =
|
||||||
|
g_signal_new (I_("style-notify"),
|
||||||
|
iface_type,
|
||||||
|
G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS | G_SIGNAL_ACTION,
|
||||||
|
G_STRUCT_OFFSET (TidyStylableIface, style_notify),
|
||||||
|
NULL, NULL,
|
||||||
|
_tidy_marshal_VOID__PARAM,
|
||||||
|
G_TYPE_NONE, 1,
|
||||||
|
G_TYPE_PARAM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GType
|
||||||
|
tidy_stylable_get_type (void)
|
||||||
|
{
|
||||||
|
static GType our_type = 0;
|
||||||
|
|
||||||
|
if (G_UNLIKELY (our_type == 0))
|
||||||
|
{
|
||||||
|
GTypeInfo stylable_info = {
|
||||||
|
sizeof (TidyStylableIface),
|
||||||
|
tidy_stylable_base_init,
|
||||||
|
tidy_stylable_base_finalize
|
||||||
|
};
|
||||||
|
|
||||||
|
our_type = g_type_register_static (G_TYPE_INTERFACE,
|
||||||
|
I_("TidyStylable"),
|
||||||
|
&stylable_info, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return our_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tidy_stylable_freeze_notify (TidyStylable *stylable)
|
||||||
|
{
|
||||||
|
g_return_if_fail (TIDY_IS_STYLABLE (stylable));
|
||||||
|
|
||||||
|
g_object_ref (stylable);
|
||||||
|
g_object_notify_queue_freeze (G_OBJECT (stylable), &property_notify_context);
|
||||||
|
g_object_unref (stylable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tidy_stylable_thaw_notify (TidyStylable *stylable)
|
||||||
|
{
|
||||||
|
GObjectNotifyQueue *nqueue;
|
||||||
|
|
||||||
|
g_return_if_fail (TIDY_IS_STYLABLE (stylable));
|
||||||
|
|
||||||
|
g_object_ref (stylable);
|
||||||
|
|
||||||
|
nqueue = g_object_notify_queue_from_object (G_OBJECT (stylable),
|
||||||
|
&property_notify_context);
|
||||||
|
|
||||||
|
if (!nqueue || !nqueue->freeze_count)
|
||||||
|
g_warning ("%s: property-changed notification for %s(%p) is not frozen",
|
||||||
|
G_STRFUNC, G_OBJECT_TYPE_NAME (stylable), stylable);
|
||||||
|
else
|
||||||
|
g_object_notify_queue_thaw (G_OBJECT (stylable), nqueue);
|
||||||
|
|
||||||
|
g_object_unref (stylable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tidy_stylable_notify (TidyStylable *stylable,
|
||||||
|
const gchar *property_name)
|
||||||
|
{
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
g_return_if_fail (TIDY_IS_STYLABLE (stylable));
|
||||||
|
g_return_if_fail (property_name != NULL);
|
||||||
|
|
||||||
|
g_object_ref (stylable);
|
||||||
|
|
||||||
|
pspec = g_param_spec_pool_lookup (style_property_spec_pool,
|
||||||
|
property_name,
|
||||||
|
G_OBJECT_TYPE (stylable),
|
||||||
|
TRUE);
|
||||||
|
|
||||||
|
if (!pspec)
|
||||||
|
g_warning ("%s: object class `%s' has no style property named `%s'",
|
||||||
|
G_STRFUNC,
|
||||||
|
G_OBJECT_TYPE_NAME (stylable),
|
||||||
|
property_name);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GObjectNotifyQueue *nqueue;
|
||||||
|
|
||||||
|
nqueue = g_object_notify_queue_freeze (G_OBJECT (stylable),
|
||||||
|
&property_notify_context);
|
||||||
|
g_object_notify_queue_add (G_OBJECT (stylable), nqueue, pspec);
|
||||||
|
g_object_notify_queue_thaw (G_OBJECT (stylable), nqueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref (stylable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tidy_stylable_iface_install_property:
|
||||||
|
* @iface: a #TidyStylableIface
|
||||||
|
* @owner_type: #GType of the style property owner
|
||||||
|
* @pspec: a #GParamSpec
|
||||||
|
*
|
||||||
|
* Installs a property for @owner_type using @pspec as the property
|
||||||
|
* description.
|
||||||
|
*
|
||||||
|
* This function should be used inside the #TidyStylableIface initialization
|
||||||
|
* function of a class, for instance:
|
||||||
|
*
|
||||||
|
* <informalexample><programlisting>
|
||||||
|
* G_DEFINE_TYPE_WITH_CODE (FooActor, foo_actor, CLUTTER_TYPE_ACTOR,
|
||||||
|
* G_IMPLEMENT_INTERFACE (TIDY_TYPE_STYLABLE,
|
||||||
|
* tidy_stylable_init));
|
||||||
|
* ...
|
||||||
|
* static void
|
||||||
|
* tidy_stylable_init (TidyStylableIface *iface)
|
||||||
|
* {
|
||||||
|
* static gboolean is_initialized = FALSE;
|
||||||
|
*
|
||||||
|
* if (!is_initialized)
|
||||||
|
* {
|
||||||
|
* ...
|
||||||
|
* tidy_stylable_iface_install_property (stylable,
|
||||||
|
* FOO_TYPE_ACTOR,
|
||||||
|
* g_param_spec_int ("x-spacing",
|
||||||
|
* "X Spacing",
|
||||||
|
* "Horizontal spacing",
|
||||||
|
* -1, G_MAXINT,
|
||||||
|
* 2,
|
||||||
|
* G_PARAM_READWRITE));
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* </programlisting></informalexample>
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tidy_stylable_iface_install_property (TidyStylableIface *iface,
|
||||||
|
GType owner_type,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
g_return_if_fail (TIDY_IS_STYLABLE_IFACE (iface));
|
||||||
|
g_return_if_fail (owner_type != G_TYPE_INVALID);
|
||||||
|
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
|
||||||
|
g_return_if_fail (pspec->flags & G_PARAM_READABLE);
|
||||||
|
g_return_if_fail (!(pspec->flags & (G_PARAM_CONSTRUCT_ONLY | G_PARAM_CONSTRUCT
|
||||||
|
)));
|
||||||
|
|
||||||
|
if (g_param_spec_pool_lookup (style_property_spec_pool, pspec->name,
|
||||||
|
owner_type,
|
||||||
|
FALSE))
|
||||||
|
{
|
||||||
|
g_warning ("%s: class `%s' already contains a style property named `%s'",
|
||||||
|
G_STRLOC,
|
||||||
|
g_type_name (owner_type),
|
||||||
|
pspec->name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_param_spec_ref_sink (pspec);
|
||||||
|
g_param_spec_set_qdata_full (pspec, quark_real_owner,
|
||||||
|
g_strdup (g_type_name (owner_type)),
|
||||||
|
g_free);
|
||||||
|
|
||||||
|
g_param_spec_pool_insert (style_property_spec_pool,
|
||||||
|
pspec,
|
||||||
|
owner_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tidy_stylable_list_properties:
|
||||||
|
* @stylable: a #TidyStylable
|
||||||
|
* @n_props: return location for the number of properties, or %NULL
|
||||||
|
*
|
||||||
|
* Retrieves all the #GParamSpec<!-- -->s installed by @stylable.
|
||||||
|
*
|
||||||
|
* Return value: an array of #GParamSpec<!-- -->s. Free it with
|
||||||
|
* g_free() when done.
|
||||||
|
*/
|
||||||
|
GParamSpec **
|
||||||
|
tidy_stylable_list_properties (TidyStylable *stylable,
|
||||||
|
guint *n_props)
|
||||||
|
{
|
||||||
|
GParamSpec **pspecs = NULL;
|
||||||
|
guint n;
|
||||||
|
|
||||||
|
g_return_val_if_fail (TIDY_IS_STYLABLE (stylable), NULL);
|
||||||
|
|
||||||
|
pspecs = g_param_spec_pool_list (style_property_spec_pool,
|
||||||
|
G_OBJECT_TYPE (stylable),
|
||||||
|
&n);
|
||||||
|
if (n_props)
|
||||||
|
*n_props = n;
|
||||||
|
|
||||||
|
return pspecs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tidy_stylable_find_property:
|
||||||
|
* @stylable: a #TidyStylable
|
||||||
|
* @property_name: the name of the property to find
|
||||||
|
*
|
||||||
|
* Finds the #GParamSpec installed by @stylable for the property
|
||||||
|
* with @property_name.
|
||||||
|
*
|
||||||
|
* Return value: a #GParamSpec for the given property, or %NULL if
|
||||||
|
* no property with that name was found
|
||||||
|
*/
|
||||||
|
GParamSpec *
|
||||||
|
tidy_stylable_find_property (TidyStylable *stylable,
|
||||||
|
const gchar *property_name)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (TIDY_IS_STYLABLE (stylable), NULL);
|
||||||
|
g_return_val_if_fail (property_name != NULL, NULL);
|
||||||
|
|
||||||
|
return g_param_spec_pool_lookup (style_property_spec_pool,
|
||||||
|
property_name,
|
||||||
|
G_OBJECT_TYPE (stylable),
|
||||||
|
TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
tidy_stylable_set_property_internal (TidyStylable *stylable,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
const GValue *value,
|
||||||
|
GObjectNotifyQueue *nqueue)
|
||||||
|
{
|
||||||
|
GValue tmp_value = { 0, };
|
||||||
|
|
||||||
|
g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||||
|
|
||||||
|
if (!g_value_transform (value, &tmp_value))
|
||||||
|
g_warning ("unable to set property `%s' of type `%s' from value of type `%s'",
|
||||||
|
pspec->name,
|
||||||
|
g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
|
||||||
|
G_VALUE_TYPE_NAME (value));
|
||||||
|
else if (g_param_value_validate (pspec, &tmp_value) &&
|
||||||
|
!(pspec->flags & G_PARAM_LAX_VALIDATION))
|
||||||
|
{
|
||||||
|
gchar *contents = g_strdup_value_contents (value);
|
||||||
|
|
||||||
|
g_warning ("value \"%s\" of type `%s' is invalid or out of range for property `%s' of type `%s'",
|
||||||
|
contents,
|
||||||
|
G_VALUE_TYPE_NAME (value),
|
||||||
|
pspec->name,
|
||||||
|
g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
|
||||||
|
g_free (contents);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TidyStyle *style = tidy_stylable_get_style (stylable);
|
||||||
|
gchar *real_name;
|
||||||
|
|
||||||
|
real_name = g_strconcat (g_param_spec_get_qdata (pspec, quark_real_owner),
|
||||||
|
"::",
|
||||||
|
pspec->name,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (!tidy_style_has_property (style, real_name))
|
||||||
|
tidy_style_add_property (style, real_name,
|
||||||
|
G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||||
|
|
||||||
|
tidy_style_set_property (style, real_name, &tmp_value);
|
||||||
|
g_object_notify_queue_add (G_OBJECT (stylable), nqueue, pspec);
|
||||||
|
|
||||||
|
g_free (real_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_value_unset (&tmp_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
tidy_stylable_get_property_internal (TidyStylable *stylable,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
GValue *value)
|
||||||
|
{
|
||||||
|
TidyStyle *style;
|
||||||
|
GValue real_value = { 0, };
|
||||||
|
gchar *real_name;
|
||||||
|
|
||||||
|
real_name = g_strconcat (g_param_spec_get_qdata (pspec, quark_real_owner),
|
||||||
|
"::",
|
||||||
|
pspec->name,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
style = tidy_stylable_get_style (stylable);
|
||||||
|
if (!tidy_style_has_property (style, real_name))
|
||||||
|
{
|
||||||
|
/* the style has no property set, use the default value
|
||||||
|
* from the GParamSpec
|
||||||
|
*/
|
||||||
|
g_param_value_set_default (pspec, value);
|
||||||
|
g_free (real_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tidy_style_get_property (style, real_name, &real_value);
|
||||||
|
|
||||||
|
g_value_copy (&real_value, value);
|
||||||
|
g_value_unset (&real_value);
|
||||||
|
|
||||||
|
g_free (real_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tidy_stylable_get_property:
|
||||||
|
* @stylable: a #TidyStylable
|
||||||
|
* @property_name: the name of the property
|
||||||
|
* @value: return location for an empty #GValue
|
||||||
|
*
|
||||||
|
* Retrieves the value of @property_name for @stylable, and puts it
|
||||||
|
* into @value.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tidy_stylable_get_property (TidyStylable *stylable,
|
||||||
|
const gchar *property_name,
|
||||||
|
GValue *value)
|
||||||
|
{
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
g_return_if_fail (TIDY_IS_STYLABLE (stylable));
|
||||||
|
g_return_if_fail (property_name != NULL);
|
||||||
|
g_return_if_fail (value != NULL);
|
||||||
|
|
||||||
|
pspec = tidy_stylable_find_property (stylable, property_name);
|
||||||
|
if (!pspec)
|
||||||
|
{
|
||||||
|
g_warning ("Stylable class `%s' doesn't have a property named `%s'",
|
||||||
|
g_type_name (G_OBJECT_TYPE (stylable)),
|
||||||
|
property_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(pspec->flags & G_PARAM_READABLE))
|
||||||
|
{
|
||||||
|
g_warning ("Style property `%s' of class `%s' is not readable",
|
||||||
|
pspec->name,
|
||||||
|
g_type_name (G_OBJECT_TYPE (stylable)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (G_VALUE_TYPE (value) != G_PARAM_SPEC_VALUE_TYPE (pspec))
|
||||||
|
{
|
||||||
|
g_warning ("Passed value is not of the requested type `%s' for "
|
||||||
|
"the style property `%s' of class `%s'",
|
||||||
|
g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
|
||||||
|
pspec->name,
|
||||||
|
g_type_name (G_OBJECT_TYPE (stylable)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tidy_stylable_get_property_internal (stylable, pspec, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tidy_stylable_set_property:
|
||||||
|
* @stylable: a #TidyStylable
|
||||||
|
* @property_name: the name of the property to set
|
||||||
|
* @value: an initialized #GValue
|
||||||
|
*
|
||||||
|
* Sets the property @property_name with @value.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tidy_stylable_set_property (TidyStylable *stylable,
|
||||||
|
const gchar *property_name,
|
||||||
|
const GValue *value)
|
||||||
|
{
|
||||||
|
GObjectNotifyQueue *nqueue;
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
g_return_if_fail (TIDY_IS_STYLABLE (stylable));
|
||||||
|
g_return_if_fail (property_name != NULL);
|
||||||
|
g_return_if_fail (value != NULL);
|
||||||
|
|
||||||
|
g_object_ref (stylable);
|
||||||
|
|
||||||
|
nqueue = g_object_notify_queue_freeze (G_OBJECT (stylable),
|
||||||
|
&property_notify_context);
|
||||||
|
|
||||||
|
pspec = tidy_stylable_find_property (stylable, property_name);
|
||||||
|
if (!pspec)
|
||||||
|
{
|
||||||
|
g_warning ("Stylable class `%s' doesn't have a property named `%s'",
|
||||||
|
g_type_name (G_OBJECT_TYPE (stylable)),
|
||||||
|
property_name);
|
||||||
|
}
|
||||||
|
else if (!(pspec->flags & G_PARAM_WRITABLE))
|
||||||
|
{
|
||||||
|
g_warning ("Style property `%s' of class `%s' is not readable",
|
||||||
|
pspec->name,
|
||||||
|
g_type_name (G_OBJECT_TYPE (stylable)));
|
||||||
|
}
|
||||||
|
else if (G_VALUE_TYPE (value) != G_PARAM_SPEC_VALUE_TYPE (pspec))
|
||||||
|
{
|
||||||
|
g_warning ("Passed value is not of the requested type `%s' for "
|
||||||
|
"the style property `%s' of class `%s'",
|
||||||
|
g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
|
||||||
|
pspec->name,
|
||||||
|
g_type_name (G_OBJECT_TYPE (stylable)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tidy_stylable_set_property_internal (stylable, pspec, value, nqueue);
|
||||||
|
|
||||||
|
g_object_notify_queue_thaw (G_OBJECT (stylable), nqueue);
|
||||||
|
g_object_unref (stylable);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_stylable_get_valist (TidyStylable *stylable,
|
||||||
|
const gchar *first_property_name,
|
||||||
|
va_list varargs)
|
||||||
|
{
|
||||||
|
const gchar *name;
|
||||||
|
|
||||||
|
g_object_ref (stylable);
|
||||||
|
|
||||||
|
name = first_property_name;
|
||||||
|
|
||||||
|
while (name)
|
||||||
|
{
|
||||||
|
GParamSpec *pspec;
|
||||||
|
GValue value = { 0, };
|
||||||
|
gchar *error;
|
||||||
|
|
||||||
|
pspec = tidy_stylable_find_property (stylable, name);
|
||||||
|
if (!pspec)
|
||||||
|
{
|
||||||
|
g_warning ("%s: no style property named `%s' found for class `%s'",
|
||||||
|
G_STRLOC,
|
||||||
|
name,
|
||||||
|
g_type_name (G_OBJECT_TYPE (stylable)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(pspec->flags & G_PARAM_READABLE))
|
||||||
|
{
|
||||||
|
g_warning ("Style property `%s' of class `%s' is not readable",
|
||||||
|
pspec->name,
|
||||||
|
g_type_name (G_OBJECT_TYPE (stylable)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||||
|
tidy_stylable_get_property_internal (stylable, pspec, &value);
|
||||||
|
|
||||||
|
G_VALUE_LCOPY (&value, varargs, 0, &error);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
g_warning ("%s: %s", G_STRLOC, error);
|
||||||
|
g_free (error);
|
||||||
|
g_value_unset (&value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_value_unset (&value);
|
||||||
|
|
||||||
|
name = va_arg (varargs, gchar*);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref (stylable);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_stylable_set_valist (TidyStylable *stylable,
|
||||||
|
const gchar *first_property_name,
|
||||||
|
va_list varargs)
|
||||||
|
{
|
||||||
|
GObjectNotifyQueue *nqueue;
|
||||||
|
const gchar *name;
|
||||||
|
|
||||||
|
g_object_ref (stylable);
|
||||||
|
|
||||||
|
nqueue = g_object_notify_queue_freeze (G_OBJECT (stylable),
|
||||||
|
&property_notify_context);
|
||||||
|
|
||||||
|
name = first_property_name;
|
||||||
|
|
||||||
|
while (name)
|
||||||
|
{
|
||||||
|
GParamSpec *pspec;
|
||||||
|
GValue value = { 0, };
|
||||||
|
gchar *error;
|
||||||
|
|
||||||
|
pspec = tidy_stylable_find_property (stylable, name);
|
||||||
|
if (!pspec)
|
||||||
|
{
|
||||||
|
g_warning ("%s: no style property named `%s' found for class `%s'",
|
||||||
|
G_STRLOC,
|
||||||
|
name,
|
||||||
|
g_type_name (G_OBJECT_TYPE (stylable)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(pspec->flags & G_PARAM_WRITABLE) ||
|
||||||
|
(pspec->flags & G_PARAM_CONSTRUCT_ONLY))
|
||||||
|
{
|
||||||
|
g_warning ("Style property `%s' of class `%s' is not writable",
|
||||||
|
pspec->name,
|
||||||
|
g_type_name (G_OBJECT_TYPE (stylable)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||||
|
|
||||||
|
G_VALUE_COLLECT (&value, varargs, 0, &error);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
g_warning ("%s: %s", G_STRLOC, error);
|
||||||
|
g_free (error);
|
||||||
|
g_value_unset (&value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tidy_stylable_set_property_internal (stylable, pspec, &value, nqueue);
|
||||||
|
g_value_unset (&value);
|
||||||
|
|
||||||
|
name = va_arg (varargs, gchar*);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_notify_queue_thaw (G_OBJECT (stylable), nqueue);
|
||||||
|
g_object_unref (stylable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tidy_stylable_get:
|
||||||
|
* @stylable: a #TidyStylable
|
||||||
|
* @first_property_name: name of the first property to get
|
||||||
|
* @Varargs: return location for the first property, followed optionally
|
||||||
|
* by more name/return location pairs, followed by %NULL
|
||||||
|
*
|
||||||
|
* Gets the style properties for @stylable.
|
||||||
|
*
|
||||||
|
* In general, a copy is made of the property contents and the called
|
||||||
|
* is responsible for freeing the memory in the appropriate manner for
|
||||||
|
* the property type.
|
||||||
|
*
|
||||||
|
* <example>
|
||||||
|
* <title>Using tidy_stylable_get(<!-- -->)</title>
|
||||||
|
* <para>An example of using tidy_stylable_get() to get the contents of
|
||||||
|
* two style properties - one of type #G_TYPE_INT and one of type
|
||||||
|
* #CLUTTER_TYPE_COLOR:</para>
|
||||||
|
* <programlisting>
|
||||||
|
* gint x_spacing;
|
||||||
|
* ClutterColor *bg_color;
|
||||||
|
*
|
||||||
|
* tidy_stylable_get (stylable,
|
||||||
|
* "x-spacing", &x_spacing,
|
||||||
|
* "bg-color", &bg_color,
|
||||||
|
* NULL);
|
||||||
|
*
|
||||||
|
* /<!-- -->* do something with x_spacing and bg_color *<!-- -->/
|
||||||
|
*
|
||||||
|
* clutter_color_free (bg_color);
|
||||||
|
* </programlisting>
|
||||||
|
* </example>
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tidy_stylable_get (TidyStylable *stylable,
|
||||||
|
const gchar *first_property_name,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
g_return_if_fail (TIDY_IS_STYLABLE (stylable));
|
||||||
|
g_return_if_fail (first_property_name != NULL);
|
||||||
|
|
||||||
|
va_start (args, first_property_name);
|
||||||
|
tidy_stylable_get_valist (stylable, first_property_name, args);
|
||||||
|
va_end (args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tidy_stylable_set:
|
||||||
|
* @stylable: a #TidyStylable
|
||||||
|
* @first_property_name: name of the first property to set
|
||||||
|
* @Varargs: value for the first property, followed optionally by
|
||||||
|
* more name/value pairs, followed by %NULL
|
||||||
|
*
|
||||||
|
* Sets the style properties of @stylable.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tidy_stylable_set (TidyStylable *stylable,
|
||||||
|
const gchar *first_property_name,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
g_return_if_fail (TIDY_IS_STYLABLE (stylable));
|
||||||
|
g_return_if_fail (first_property_name != NULL);
|
||||||
|
|
||||||
|
va_start (args, first_property_name);
|
||||||
|
tidy_stylable_set_valist (stylable, first_property_name, args);
|
||||||
|
va_end (args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tidy_stylable_get_style:
|
||||||
|
* @stylable: a #TidyStylable
|
||||||
|
*
|
||||||
|
* Retrieves the #TidyStyle used by @stylable. This function does not
|
||||||
|
* alter the reference count of the returned object.
|
||||||
|
*
|
||||||
|
* Return value: a #TidyStyle
|
||||||
|
*/
|
||||||
|
TidyStyle *
|
||||||
|
tidy_stylable_get_style (TidyStylable *stylable)
|
||||||
|
{
|
||||||
|
TidyStylableIface *iface;
|
||||||
|
|
||||||
|
g_return_val_if_fail (TIDY_IS_STYLABLE (stylable), NULL);
|
||||||
|
|
||||||
|
iface = TIDY_STYLABLE_GET_IFACE (stylable);
|
||||||
|
if (iface->get_style)
|
||||||
|
return iface->get_style (stylable);
|
||||||
|
|
||||||
|
return g_object_get_data (G_OBJECT (stylable), "tidy-stylable-style");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tidy_stylable_set_style:
|
||||||
|
* @stylable: a #TidyStylable
|
||||||
|
* @style: a #TidyStyle
|
||||||
|
*
|
||||||
|
* Sets @style as the new #TidyStyle to be used by @stylable.
|
||||||
|
*
|
||||||
|
* The #TidyStylable will take ownership of the passed #TidyStyle.
|
||||||
|
*
|
||||||
|
* After the #TidyStle has been set, the TidyStylable::style-set signal
|
||||||
|
* will be emitted.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tidy_stylable_set_style (TidyStylable *stylable,
|
||||||
|
TidyStyle *style)
|
||||||
|
{
|
||||||
|
TidyStylableIface *iface;
|
||||||
|
TidyStyle *old_style;
|
||||||
|
|
||||||
|
g_return_if_fail (TIDY_IS_STYLABLE (stylable));
|
||||||
|
g_return_if_fail (TIDY_IS_STYLE (style));
|
||||||
|
|
||||||
|
iface = TIDY_STYLABLE_GET_IFACE (stylable);
|
||||||
|
|
||||||
|
old_style = tidy_stylable_get_style (stylable);
|
||||||
|
g_object_ref (old_style);
|
||||||
|
|
||||||
|
if (iface->set_style)
|
||||||
|
iface->set_style (stylable, style);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_object_set_qdata_full (G_OBJECT (stylable),
|
||||||
|
quark_style,
|
||||||
|
g_object_ref_sink (style),
|
||||||
|
g_object_unref);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_signal_emit (stylable, stylable_signals[STYLE_SET], 0, old_style);
|
||||||
|
g_object_unref (old_style);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (stylable), "style");
|
||||||
|
}
|
69
src/tidy/tidy-stylable.h
Normal file
69
src/tidy/tidy-stylable.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#ifndef __TIDY_STYLABLE_H__
|
||||||
|
#define __TIDY_STYLABLE_H__
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <tidy/tidy-style.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define TIDY_TYPE_STYLABLE (tidy_stylable_get_type ())
|
||||||
|
#define TIDY_STYLABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TIDY_TYPE_STYLABLE, TidyStylable))
|
||||||
|
#define TIDY_IS_STYLABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TIDY_TYPE_STYLABLE))
|
||||||
|
#define TIDY_STYLABLE_IFACE(iface) (G_TYPE_CHECK_CLASS_CAST ((iface), TIDY_TYPE_STYLABLE, TidyStylableIface))
|
||||||
|
#define TIDY_IS_STYLABLE_IFACE(iface) (G_TYPE_CHECK_CLASS_TYPE ((iface), TIDY_TYPE_STYLABLE))
|
||||||
|
#define TIDY_STYLABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TIDY_TYPE_STYLABLE, TidyStylableIface))
|
||||||
|
|
||||||
|
typedef struct _TidyStylable TidyStylable; /* dummy typedef */
|
||||||
|
typedef struct _TidyStylableIface TidyStylableIface;
|
||||||
|
|
||||||
|
struct _TidyStylableIface
|
||||||
|
{
|
||||||
|
GTypeInterface g_iface;
|
||||||
|
|
||||||
|
/* virtual functions */
|
||||||
|
TidyStyle *(* get_style) (TidyStylable *stylable);
|
||||||
|
void (* set_style) (TidyStylable *stylable,
|
||||||
|
TidyStyle *style);
|
||||||
|
|
||||||
|
/* signals, not vfuncs */
|
||||||
|
void (* style_notify) (TidyStylable *stylable,
|
||||||
|
GParamSpec *pspec);
|
||||||
|
|
||||||
|
void (* style_set) (TidyStylable *stylable,
|
||||||
|
TidyStyle *old_style);
|
||||||
|
};
|
||||||
|
|
||||||
|
GType tidy_stylable_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
void tidy_stylable_iface_install_property (TidyStylableIface *iface,
|
||||||
|
GType owner_type,
|
||||||
|
GParamSpec *pspec);
|
||||||
|
|
||||||
|
void tidy_stylable_freeze_notify (TidyStylable *stylable);
|
||||||
|
void tidy_stylable_notify (TidyStylable *stylable,
|
||||||
|
const gchar *property_name);
|
||||||
|
void tidy_stylable_thaw_notify (TidyStylable *stylable);
|
||||||
|
GParamSpec **tidy_stylable_list_properties (TidyStylable *stylable,
|
||||||
|
guint *n_props);
|
||||||
|
GParamSpec * tidy_stylable_find_property (TidyStylable *stylable,
|
||||||
|
const gchar *property_name);
|
||||||
|
void tidy_stylable_set_style (TidyStylable *stylable,
|
||||||
|
TidyStyle *style);
|
||||||
|
TidyStyle * tidy_stylable_get_style (TidyStylable *stylable);
|
||||||
|
|
||||||
|
void tidy_stylable_set (TidyStylable *stylable,
|
||||||
|
const gchar *first_property_name,
|
||||||
|
...) G_GNUC_NULL_TERMINATED;
|
||||||
|
void tidy_stylable_get (TidyStylable *stylable,
|
||||||
|
const gchar *first_property_name,
|
||||||
|
...) G_GNUC_NULL_TERMINATED;
|
||||||
|
void tidy_stylable_set_property (TidyStylable *stylable,
|
||||||
|
const gchar *property_name,
|
||||||
|
const GValue *value);
|
||||||
|
void tidy_stylable_get_property (TidyStylable *stylable,
|
||||||
|
const gchar *property_name,
|
||||||
|
GValue *value);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __TIDY_STYLABLE_H__ */
|
653
src/tidy/tidy-style.c
Normal file
653
src/tidy/tidy-style.c
Normal file
@ -0,0 +1,653 @@
|
|||||||
|
#ifndef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <gobject/gvaluecollector.h>
|
||||||
|
|
||||||
|
#include <clutter/clutter-behaviour.h>
|
||||||
|
#include <clutter/clutter-color.h>
|
||||||
|
|
||||||
|
#include "tidy-style.h"
|
||||||
|
#include "tidy-marshal.h"
|
||||||
|
#include "tidy-debug.h"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CHANGED,
|
||||||
|
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TIDY_STYLE_GET_PRIVATE(obj) \
|
||||||
|
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), TIDY_TYPE_STYLE, TidyStylePrivate))
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GType value_type;
|
||||||
|
gchar *value_name;
|
||||||
|
GValue value;
|
||||||
|
} StyleProperty;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
gchar *name;
|
||||||
|
GType behaviour_type;
|
||||||
|
GArray *parameters;
|
||||||
|
guint duration;
|
||||||
|
ClutterAlphaFunc alpha_func;
|
||||||
|
} StyleEffect;
|
||||||
|
|
||||||
|
struct _TidyStylePrivate
|
||||||
|
{
|
||||||
|
GHashTable *properties;
|
||||||
|
GHashTable *effects;
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint style_signals[LAST_SIGNAL] = { 0, };
|
||||||
|
|
||||||
|
static const gchar *tidy_default_font_name = "Sans 12px";
|
||||||
|
static const ClutterColor tidy_default_text_color = { 0x00, 0x00, 0x00, 0xff };
|
||||||
|
static const ClutterColor tidy_default_bg_color = { 0xcc, 0xcc, 0xcc, 0xff };
|
||||||
|
static const ClutterColor tidy_default_active_color = { 0xf5, 0x79, 0x00, 0xff };
|
||||||
|
|
||||||
|
static TidyStyle *default_style = NULL;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (TidyStyle, tidy_style, G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
static StyleProperty *
|
||||||
|
style_property_new (const gchar *value_name,
|
||||||
|
GType value_type)
|
||||||
|
{
|
||||||
|
StyleProperty *retval;
|
||||||
|
|
||||||
|
retval = g_slice_new0 (StyleProperty);
|
||||||
|
retval->value_type = value_type;
|
||||||
|
retval->value_name = g_strdup (value_name);
|
||||||
|
g_value_init (&retval->value, value_type);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
style_property_free (gpointer data)
|
||||||
|
{
|
||||||
|
if (G_LIKELY (data))
|
||||||
|
{
|
||||||
|
StyleProperty *sp = data;
|
||||||
|
|
||||||
|
g_free (sp->value_name);
|
||||||
|
g_value_unset (&sp->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static StyleEffect *
|
||||||
|
style_effect_new (const gchar *name)
|
||||||
|
{
|
||||||
|
StyleEffect *retval;
|
||||||
|
|
||||||
|
retval = g_slice_new0 (StyleEffect);
|
||||||
|
retval->name = g_strdup (name);
|
||||||
|
retval->behaviour_type = G_TYPE_INVALID;
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
style_effect_free (gpointer data)
|
||||||
|
{
|
||||||
|
if (G_LIKELY (data))
|
||||||
|
{
|
||||||
|
StyleEffect *effect = data;
|
||||||
|
|
||||||
|
g_free (effect->name);
|
||||||
|
|
||||||
|
if (effect->parameters)
|
||||||
|
{
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
for (i = 0; i < effect->parameters->len; i++)
|
||||||
|
{
|
||||||
|
GParameter *param;
|
||||||
|
|
||||||
|
param = &g_array_index (effect->parameters, GParameter, i);
|
||||||
|
|
||||||
|
g_free ((gchar *) param->name);
|
||||||
|
g_value_unset (¶m->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_array_free (effect->parameters, TRUE);
|
||||||
|
effect->parameters = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_slice_free (StyleEffect, effect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_defaults (TidyStyle *style)
|
||||||
|
{
|
||||||
|
TidyStylePrivate *priv = style->priv;
|
||||||
|
|
||||||
|
{
|
||||||
|
StyleProperty *sp;
|
||||||
|
|
||||||
|
sp = style_property_new (TIDY_FONT_NAME, G_TYPE_STRING);
|
||||||
|
g_value_set_string (&sp->value, tidy_default_font_name);
|
||||||
|
|
||||||
|
g_hash_table_insert (priv->properties, sp->value_name, sp);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
StyleProperty *sp;
|
||||||
|
|
||||||
|
sp = style_property_new (TIDY_BACKGROUND_COLOR, CLUTTER_TYPE_COLOR);
|
||||||
|
g_value_set_boxed (&sp->value, &tidy_default_bg_color);
|
||||||
|
|
||||||
|
g_hash_table_insert (priv->properties, sp->value_name, sp);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
StyleProperty *sp;
|
||||||
|
|
||||||
|
sp = style_property_new (TIDY_ACTIVE_COLOR, CLUTTER_TYPE_COLOR);
|
||||||
|
g_value_set_boxed (&sp->value, &tidy_default_active_color);
|
||||||
|
|
||||||
|
g_hash_table_insert (priv->properties, sp->value_name, sp);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
StyleProperty *sp;
|
||||||
|
|
||||||
|
sp = style_property_new (TIDY_TEXT_COLOR, CLUTTER_TYPE_COLOR);
|
||||||
|
g_value_set_boxed (&sp->value, &tidy_default_text_color);
|
||||||
|
|
||||||
|
g_hash_table_insert (priv->properties, sp->value_name, sp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
tidy_style_load_from_file (TidyStyle *style,
|
||||||
|
const gchar *filename,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GKeyFile *rc_file;
|
||||||
|
GError *internal_error;
|
||||||
|
|
||||||
|
rc_file = g_key_file_new ();
|
||||||
|
|
||||||
|
internal_error = NULL;
|
||||||
|
g_key_file_load_from_file (rc_file, filename, 0, &internal_error);
|
||||||
|
if (internal_error)
|
||||||
|
{
|
||||||
|
g_key_file_free (rc_file);
|
||||||
|
/* if the specified files does not exist then just ignore it
|
||||||
|
* and fall back to the default values; if, instead, the file
|
||||||
|
* is not accessible or is malformed, propagate the error
|
||||||
|
*/
|
||||||
|
if (internal_error->domain == G_FILE_ERROR &&
|
||||||
|
internal_error->code == G_FILE_ERROR_NOENT)
|
||||||
|
{
|
||||||
|
g_error_free (internal_error);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_propagate_error (error, internal_error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_key_file_free (rc_file);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_style_load (TidyStyle *style)
|
||||||
|
{
|
||||||
|
const gchar *env_var;
|
||||||
|
gchar *rc_file = NULL;
|
||||||
|
GError *error;
|
||||||
|
|
||||||
|
init_defaults (style);
|
||||||
|
|
||||||
|
env_var = g_getenv ("TIDY_RC_FILE");
|
||||||
|
if (env_var && *env_var)
|
||||||
|
rc_file = g_strdup (env_var);
|
||||||
|
|
||||||
|
if (!rc_file)
|
||||||
|
rc_file = g_build_filename (g_get_user_config_dir (),
|
||||||
|
"tidy",
|
||||||
|
"tidyrc",
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
error = NULL;
|
||||||
|
if (!tidy_style_load_from_file (style, rc_file, &error))
|
||||||
|
{
|
||||||
|
g_critical ("Unable to load resource file `%s': %s",
|
||||||
|
rc_file,
|
||||||
|
error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (rc_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_style_finalize (GObject *gobject)
|
||||||
|
{
|
||||||
|
TidyStylePrivate *priv = TIDY_STYLE (gobject)->priv;
|
||||||
|
|
||||||
|
g_hash_table_destroy (priv->properties);
|
||||||
|
g_hash_table_destroy (priv->effects);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (tidy_style_parent_class)->finalize (gobject);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_style_class_init (TidyStyleClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
g_type_class_add_private (klass, sizeof (TidyStylePrivate));
|
||||||
|
|
||||||
|
gobject_class->finalize = tidy_style_finalize;
|
||||||
|
|
||||||
|
style_signals[CHANGED] =
|
||||||
|
g_signal_new ("changed",
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (TidyStyleClass, changed),
|
||||||
|
NULL, NULL,
|
||||||
|
_tidy_marshal_VOID__VOID,
|
||||||
|
G_TYPE_NONE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_style_init (TidyStyle *style)
|
||||||
|
{
|
||||||
|
TidyStylePrivate *priv;
|
||||||
|
|
||||||
|
style->priv = priv = TIDY_STYLE_GET_PRIVATE (style);
|
||||||
|
|
||||||
|
priv->properties = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
|
NULL,
|
||||||
|
style_property_free);
|
||||||
|
priv->effects = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
|
NULL,
|
||||||
|
style_effect_free);
|
||||||
|
|
||||||
|
tidy_style_load (style);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* need to unref */
|
||||||
|
TidyStyle *
|
||||||
|
tidy_style_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (TIDY_TYPE_STYLE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* never ref/unref */
|
||||||
|
TidyStyle *
|
||||||
|
tidy_style_get_default (void)
|
||||||
|
{
|
||||||
|
if (G_LIKELY (default_style))
|
||||||
|
return default_style;
|
||||||
|
|
||||||
|
default_style = g_object_new (TIDY_TYPE_STYLE, NULL);
|
||||||
|
|
||||||
|
return default_style;
|
||||||
|
}
|
||||||
|
|
||||||
|
static StyleProperty *
|
||||||
|
tidy_style_find_property (TidyStyle *style,
|
||||||
|
const gchar *property_name)
|
||||||
|
{
|
||||||
|
return g_hash_table_lookup (style->priv->properties, property_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
tidy_style_has_property (TidyStyle *style,
|
||||||
|
const gchar *property_name)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (TIDY_IS_STYLE (style), FALSE);
|
||||||
|
g_return_val_if_fail (property_name != NULL, FALSE);
|
||||||
|
|
||||||
|
return (tidy_style_find_property (style, property_name) != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tidy_style_add_property (TidyStyle *style,
|
||||||
|
const gchar *property_name,
|
||||||
|
GType property_type)
|
||||||
|
{
|
||||||
|
StyleProperty *property;
|
||||||
|
|
||||||
|
g_return_if_fail (TIDY_IS_STYLE (style));
|
||||||
|
g_return_if_fail (property_name != NULL);
|
||||||
|
g_return_if_fail (property_type != G_TYPE_INVALID);
|
||||||
|
|
||||||
|
property = tidy_style_find_property (style, property_name);
|
||||||
|
if (G_UNLIKELY (property))
|
||||||
|
{
|
||||||
|
g_warning ("A property named `%s', with type %s already exists.",
|
||||||
|
property->value_name,
|
||||||
|
g_type_name (property->value_type));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
property = style_property_new (property_name, property_type);
|
||||||
|
g_hash_table_insert (style->priv->properties, property->value_name, property);
|
||||||
|
|
||||||
|
g_signal_emit (style, style_signals[CHANGED], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tidy_style_get_property (TidyStyle *style,
|
||||||
|
const gchar *property_name,
|
||||||
|
GValue *value)
|
||||||
|
{
|
||||||
|
StyleProperty *property;
|
||||||
|
|
||||||
|
g_return_if_fail (TIDY_IS_STYLE (style));
|
||||||
|
g_return_if_fail (property_name != NULL);
|
||||||
|
g_return_if_fail (value != NULL);
|
||||||
|
|
||||||
|
property = tidy_style_find_property (style, property_name);
|
||||||
|
if (!property)
|
||||||
|
{
|
||||||
|
g_warning ("No style property named `%s' found.", property_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_value_init (value, property->value_type);
|
||||||
|
g_value_copy (&property->value, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tidy_style_set_property (TidyStyle *style,
|
||||||
|
const gchar *property_name,
|
||||||
|
const GValue *value)
|
||||||
|
{
|
||||||
|
StyleProperty *property;
|
||||||
|
|
||||||
|
g_return_if_fail (TIDY_IS_STYLE (style));
|
||||||
|
g_return_if_fail (property_name != NULL);
|
||||||
|
g_return_if_fail (value != NULL);
|
||||||
|
|
||||||
|
property = tidy_style_find_property (style, property_name);
|
||||||
|
if (!property)
|
||||||
|
{
|
||||||
|
g_warning ("No style property named `%s' found.", property_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_value_copy (value, &property->value);
|
||||||
|
|
||||||
|
g_signal_emit (style, style_signals[CHANGED], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static StyleEffect *
|
||||||
|
tidy_style_find_effect (TidyStyle *style,
|
||||||
|
const gchar *effect_name)
|
||||||
|
{
|
||||||
|
return g_hash_table_lookup (style->priv->effects, effect_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tidy_style_add_effect (TidyStyle *style,
|
||||||
|
const gchar *effect_name)
|
||||||
|
{
|
||||||
|
StyleEffect *effect;
|
||||||
|
|
||||||
|
effect = tidy_style_find_effect (style, effect_name);
|
||||||
|
if (G_UNLIKELY (effect))
|
||||||
|
{
|
||||||
|
g_warning ("An effect named `%s', with type %s already exists.",
|
||||||
|
effect->name,
|
||||||
|
g_type_name (effect->behaviour_type));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
effect = style_effect_new (effect_name);
|
||||||
|
g_hash_table_replace (style->priv->effects,
|
||||||
|
effect->name,
|
||||||
|
effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
tidy_style_has_effect (TidyStyle *style,
|
||||||
|
const gchar *effect_name)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (TIDY_IS_STYLE (style), FALSE);
|
||||||
|
g_return_val_if_fail (effect_name != NULL, FALSE);
|
||||||
|
|
||||||
|
return (tidy_style_find_effect (style, effect_name) != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tidy_style_set_effect_valist (TidyStyle *style,
|
||||||
|
StyleEffect *effect,
|
||||||
|
const gchar *first_property_name,
|
||||||
|
va_list varargs)
|
||||||
|
{
|
||||||
|
GObjectClass *klass;
|
||||||
|
const gchar *name;
|
||||||
|
|
||||||
|
klass = g_type_class_ref (effect->behaviour_type);
|
||||||
|
if (G_UNLIKELY (!klass))
|
||||||
|
return;
|
||||||
|
|
||||||
|
name = first_property_name;
|
||||||
|
while (name)
|
||||||
|
{
|
||||||
|
GParamSpec *pspec;
|
||||||
|
GParameter param = { 0, };
|
||||||
|
GValue value = { 0, };
|
||||||
|
gchar *error = NULL;
|
||||||
|
|
||||||
|
pspec = g_object_class_find_property (klass, name);
|
||||||
|
if (!pspec)
|
||||||
|
{
|
||||||
|
g_warning ("Unable to find the property `%s' for the "
|
||||||
|
"behaviour of type `%s'",
|
||||||
|
name,
|
||||||
|
g_type_name (effect->behaviour_type));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(pspec->flags & G_PARAM_WRITABLE))
|
||||||
|
{
|
||||||
|
g_warning ("The property `%s' for the behaviour of type "
|
||||||
|
"`%s' is not writable",
|
||||||
|
pspec->name,
|
||||||
|
g_type_name (effect->behaviour_type));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
param.name = g_strdup (pspec->name);
|
||||||
|
|
||||||
|
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||||
|
|
||||||
|
G_VALUE_COLLECT (&value, varargs, 0, &error);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
g_warning ("%s: %s", G_STRLOC, error);
|
||||||
|
g_free (error);
|
||||||
|
g_value_unset (&value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_value_init (&(param.value), G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||||
|
g_value_copy (&value, &(param.value));
|
||||||
|
g_value_unset (&value);
|
||||||
|
|
||||||
|
name = va_arg (varargs, gchar*);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_type_class_unref (klass);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tidy_style_set_effect (TidyStyle *style,
|
||||||
|
const gchar *effect_name,
|
||||||
|
guint duration,
|
||||||
|
GType behaviour_type,
|
||||||
|
ClutterAlphaFunc alpha_func,
|
||||||
|
const gchar *first_property_name,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
StyleEffect *effect;
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
effect = tidy_style_find_effect (style, effect_name);
|
||||||
|
if (!effect)
|
||||||
|
{
|
||||||
|
g_warning ("No effect named `%s' found.", effect_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (effect->parameters)
|
||||||
|
{
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
for (i = 0; i < effect->parameters->len; i++)
|
||||||
|
{
|
||||||
|
GParameter *param;
|
||||||
|
|
||||||
|
param = &g_array_index (effect->parameters, GParameter, i);
|
||||||
|
|
||||||
|
g_free ((gchar *) param->name);
|
||||||
|
g_value_unset (¶m->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_array_free (effect->parameters, TRUE);
|
||||||
|
effect->parameters = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
effect->duration = duration;
|
||||||
|
effect->behaviour_type = behaviour_type;
|
||||||
|
effect->alpha_func = alpha_func;
|
||||||
|
effect->parameters = g_array_new (FALSE, FALSE, sizeof (GParameter));
|
||||||
|
|
||||||
|
va_start (args, first_property_name);
|
||||||
|
tidy_style_set_effect_valist (style, effect, first_property_name, args);
|
||||||
|
va_end (args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tidy_style_set_effectv (TidyStyle *style,
|
||||||
|
const gchar *effect_name,
|
||||||
|
guint duration,
|
||||||
|
GType behaviour_type,
|
||||||
|
ClutterAlphaFunc alpha_func,
|
||||||
|
guint n_parameters,
|
||||||
|
GParameter *parameters)
|
||||||
|
{
|
||||||
|
StyleEffect *effect;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
effect = tidy_style_find_effect (style, effect_name);
|
||||||
|
if (!effect)
|
||||||
|
{
|
||||||
|
g_warning ("No effect named `%s' found.", effect_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (effect->parameters)
|
||||||
|
{
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
for (i = 0; i < effect->parameters->len; i++)
|
||||||
|
{
|
||||||
|
GParameter *param;
|
||||||
|
|
||||||
|
param = &g_array_index (effect->parameters, GParameter, i);
|
||||||
|
|
||||||
|
g_free ((gchar *) param->name);
|
||||||
|
g_value_unset (¶m->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_array_free (effect->parameters, TRUE);
|
||||||
|
effect->parameters = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
effect->duration = duration;
|
||||||
|
effect->behaviour_type = behaviour_type;
|
||||||
|
effect->alpha_func = alpha_func;
|
||||||
|
effect->parameters = g_array_new (FALSE, FALSE, sizeof (GParameter));
|
||||||
|
|
||||||
|
for (i = 0; i < n_parameters; i++)
|
||||||
|
{
|
||||||
|
GParameter param = { NULL, };
|
||||||
|
|
||||||
|
param.name = g_strdup (parameters[i].name);
|
||||||
|
|
||||||
|
g_value_init (¶m.value, G_VALUE_TYPE (¶meters[i].value));
|
||||||
|
g_value_copy (¶meters[i].value, ¶m.value);
|
||||||
|
|
||||||
|
g_array_append_val (effect->parameters, param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ClutterBehaviour *
|
||||||
|
tidy_style_construct_effect (TidyStyle *style,
|
||||||
|
const gchar *effect_name)
|
||||||
|
{
|
||||||
|
ClutterTimeline *timeline;
|
||||||
|
ClutterAlpha *alpha;
|
||||||
|
ClutterBehaviour *behaviour;
|
||||||
|
StyleEffect *effect;
|
||||||
|
|
||||||
|
effect = tidy_style_find_effect (style, effect_name);
|
||||||
|
if (!effect)
|
||||||
|
{
|
||||||
|
g_warning ("No effect named `%s' found.", effect_name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
timeline = clutter_timeline_new_for_duration (effect->duration);
|
||||||
|
|
||||||
|
alpha = clutter_alpha_new_full (timeline, effect->alpha_func, NULL, NULL);
|
||||||
|
g_object_unref (timeline);
|
||||||
|
|
||||||
|
behaviour = g_object_newv (effect->behaviour_type,
|
||||||
|
effect->parameters->len,
|
||||||
|
(GParameter *) effect->parameters->data);
|
||||||
|
|
||||||
|
clutter_behaviour_set_alpha (behaviour, alpha);
|
||||||
|
|
||||||
|
/* we just unref the behaviour, which will take care of cleaning
|
||||||
|
* up everything (alpha+timeline)
|
||||||
|
*/
|
||||||
|
g_signal_connect_swapped (timeline,
|
||||||
|
"completed", G_CALLBACK (g_object_unref),
|
||||||
|
behaviour);
|
||||||
|
|
||||||
|
return behaviour;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClutterTimeline *
|
||||||
|
tidy_style_get_effect (TidyStyle *style,
|
||||||
|
const gchar *effect_name,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ClutterBehaviour *behaviour;
|
||||||
|
ClutterAlpha *alpha;
|
||||||
|
ClutterTimeline *timeline;
|
||||||
|
|
||||||
|
g_return_val_if_fail (TIDY_IS_STYLE (style), NULL);
|
||||||
|
g_return_val_if_fail (effect_name != NULL, NULL);
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL);
|
||||||
|
|
||||||
|
behaviour = tidy_style_construct_effect (style, effect_name);
|
||||||
|
if (!behaviour)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
clutter_behaviour_apply (behaviour, actor);
|
||||||
|
|
||||||
|
alpha = clutter_behaviour_get_alpha (behaviour);
|
||||||
|
timeline = clutter_alpha_get_timeline (alpha);
|
||||||
|
|
||||||
|
return timeline;
|
||||||
|
}
|
85
src/tidy/tidy-style.h
Normal file
85
src/tidy/tidy-style.h
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#ifndef __TIDY_STYLE_H__
|
||||||
|
#define __TIDY_STYLE_H__
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <clutter/clutter-actor.h>
|
||||||
|
#include <clutter/clutter-alpha.h>
|
||||||
|
#include <clutter/clutter-timeline.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define TIDY_TYPE_STYLE (tidy_style_get_type ())
|
||||||
|
#define TIDY_STYLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TIDY_TYPE_STYLE, TidyStyle))
|
||||||
|
#define TIDY_IS_STYLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TIDY_TYPE_STYLE))
|
||||||
|
#define TIDY_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TIDY_TYPE_STYLE, TidyStyleClass))
|
||||||
|
#define TIDY_IS_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TIDY_TYPE_STYLE))
|
||||||
|
#define TIDY_STYLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TIDY_TYPE_STYLE, TidyStyleClass))
|
||||||
|
|
||||||
|
/* Default properties */
|
||||||
|
#define TIDY_FONT_NAME "TidyActor::font-name"
|
||||||
|
#define TIDY_BACKGROUND_COLOR "TidyActor::bg-color"
|
||||||
|
#define TIDY_ACTIVE_COLOR "TidyActor::active-color"
|
||||||
|
#define TIDY_TEXT_COLOR "TidyActor::text-color"
|
||||||
|
|
||||||
|
typedef struct _TidyStyle TidyStyle;
|
||||||
|
typedef struct _TidyStylePrivate TidyStylePrivate;
|
||||||
|
typedef struct _TidyStyleClass TidyStyleClass;
|
||||||
|
|
||||||
|
struct _TidyStyle
|
||||||
|
{
|
||||||
|
GObject parent_instance;
|
||||||
|
|
||||||
|
TidyStylePrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _TidyStyleClass
|
||||||
|
{
|
||||||
|
GObjectClass parent_class;
|
||||||
|
|
||||||
|
void (* changed) (TidyStyle *style);
|
||||||
|
};
|
||||||
|
|
||||||
|
GType tidy_style_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
TidyStyle * tidy_style_get_default (void);
|
||||||
|
TidyStyle * tidy_style_new (void);
|
||||||
|
|
||||||
|
gboolean tidy_style_has_property (TidyStyle *style,
|
||||||
|
const gchar *property_name);
|
||||||
|
gboolean tidy_style_has_effect (TidyStyle *style,
|
||||||
|
const gchar *effect_name);
|
||||||
|
void tidy_style_add_property (TidyStyle *style,
|
||||||
|
const gchar *property_name,
|
||||||
|
GType property_type);
|
||||||
|
void tidy_style_add_effect (TidyStyle *style,
|
||||||
|
const gchar *effect_name);
|
||||||
|
|
||||||
|
void tidy_style_get_property (TidyStyle *style,
|
||||||
|
const gchar *property_name,
|
||||||
|
GValue *value);
|
||||||
|
void tidy_style_set_property (TidyStyle *style,
|
||||||
|
const gchar *property_name,
|
||||||
|
const GValue *value);
|
||||||
|
|
||||||
|
ClutterTimeline *tidy_style_get_effect (TidyStyle *style,
|
||||||
|
const gchar *effect_name,
|
||||||
|
ClutterActor *actor);
|
||||||
|
void tidy_style_set_effectv (TidyStyle *style,
|
||||||
|
const gchar *effect_name,
|
||||||
|
guint duration,
|
||||||
|
GType behaviour_type,
|
||||||
|
ClutterAlphaFunc alpha_func,
|
||||||
|
guint n_parameters,
|
||||||
|
GParameter *parameters);
|
||||||
|
void tidy_style_set_effect (TidyStyle *style,
|
||||||
|
const gchar *effect_name,
|
||||||
|
guint duration,
|
||||||
|
GType behaviour_type,
|
||||||
|
ClutterAlphaFunc alpha_func,
|
||||||
|
const gchar *first_property_name,
|
||||||
|
...) G_GNUC_NULL_TERMINATED;
|
||||||
|
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __TIDY_STYLE_H__ */
|
25
src/tidy/tidy-types.h
Normal file
25
src/tidy/tidy-types.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef __TIDY_TYPES_H__
|
||||||
|
#define __TIDY_TYPES_H__
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <clutter/clutter-units.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define TIDY_TYPE_PADDING (tidy_padding_get_type ())
|
||||||
|
|
||||||
|
typedef struct _TidyPadding TidyPadding;
|
||||||
|
|
||||||
|
struct _TidyPadding
|
||||||
|
{
|
||||||
|
ClutterUnit top;
|
||||||
|
ClutterUnit right;
|
||||||
|
ClutterUnit bottom;
|
||||||
|
ClutterUnit left;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType tidy_padding_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __TIDY_TYPES_H__ */
|
37
src/tidy/tidy-util.c
Normal file
37
src/tidy/tidy-util.c
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#include "tidy-util.h"
|
||||||
|
|
||||||
|
/* Hack to (mostly) fill glyph cache, useful on MBX.
|
||||||
|
*
|
||||||
|
* FIXME: untested
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tidy_util_preload_glyphs (char *font, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start (args, font);
|
||||||
|
|
||||||
|
while (font)
|
||||||
|
{
|
||||||
|
/* Hold on to your hat.. */
|
||||||
|
ClutterActor *foo;
|
||||||
|
ClutterColor text_color = { 0xff, 0xff, 0xff, 0xff };
|
||||||
|
|
||||||
|
foo = clutter_label_new_full
|
||||||
|
(font,
|
||||||
|
"abcdefghijklmnopqrstuvwxyz"
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
"1234567890&()*.,';:-_+=[]{}#@?><\"!`%\\|/ ",
|
||||||
|
&text_color);
|
||||||
|
if (foo)
|
||||||
|
{
|
||||||
|
clutter_actor_realize(foo);
|
||||||
|
clutter_actor_paint(foo);
|
||||||
|
g_object_unref (foo);
|
||||||
|
}
|
||||||
|
|
||||||
|
font = va_arg (args, char*);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end (args);
|
||||||
|
}
|
9
src/tidy/tidy-util.h
Normal file
9
src/tidy/tidy-util.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifndef _TIDY_UTIL
|
||||||
|
#define _TIDY_UTIL
|
||||||
|
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
tidy_util_preload_glyphs (char *font, ...);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user