Import NbtkScrollView and dependencies
https://bugzilla.gnome.org/show_bug.cgi?id=591245
This commit is contained in:
parent
9f79296276
commit
271e4ca07e
@ -64,8 +64,13 @@ nbtk-enum-types.c: stamp-nbtk-enum-types.h nbtk/nbtk-enum-types.c.in
|
|||||||
|
|
||||||
# please, keep this sorted alphabetically
|
# please, keep this sorted alphabetically
|
||||||
nbtk_source_h = \
|
nbtk_source_h = \
|
||||||
|
nbtk/nbtk-adjustment.h \
|
||||||
nbtk/nbtk-bin.h \
|
nbtk/nbtk-bin.h \
|
||||||
|
nbtk/nbtk-button.h \
|
||||||
nbtk/nbtk-private.h \
|
nbtk/nbtk-private.h \
|
||||||
|
nbtk/nbtk-scrollable.h \
|
||||||
|
nbtk/nbtk-scroll-bar.h \
|
||||||
|
nbtk/nbtk-scroll-view.h \
|
||||||
nbtk/nbtk-stylable.h \
|
nbtk/nbtk-stylable.h \
|
||||||
nbtk/nbtk-style.h \
|
nbtk/nbtk-style.h \
|
||||||
nbtk/nbtk-subtexture.h \
|
nbtk/nbtk-subtexture.h \
|
||||||
@ -73,19 +78,26 @@ nbtk_source_h = \
|
|||||||
nbtk/nbtk-texture-frame.h \
|
nbtk/nbtk-texture-frame.h \
|
||||||
nbtk/nbtk-tooltip.h \
|
nbtk/nbtk-tooltip.h \
|
||||||
nbtk/nbtk-types.h \
|
nbtk/nbtk-types.h \
|
||||||
|
nbtk/nbtk-viewport.h \
|
||||||
nbtk/nbtk-widget.h \
|
nbtk/nbtk-widget.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
# please, keep this sorted alphabetically
|
# please, keep this sorted alphabetically
|
||||||
nbtk_source_c = \
|
nbtk_source_c = \
|
||||||
|
nbtk/nbtk-adjustment.c \
|
||||||
nbtk/nbtk-bin.c \
|
nbtk/nbtk-bin.c \
|
||||||
|
nbtk/nbtk-button.c \
|
||||||
nbtk/nbtk-private.c \
|
nbtk/nbtk-private.c \
|
||||||
|
nbtk/nbtk-scrollable.c \
|
||||||
|
nbtk/nbtk-scroll-bar.c \
|
||||||
|
nbtk/nbtk-scroll-view.c \
|
||||||
nbtk/nbtk-stylable.c \
|
nbtk/nbtk-stylable.c \
|
||||||
nbtk/nbtk-style.c \
|
nbtk/nbtk-style.c \
|
||||||
nbtk/nbtk-subtexture.c \
|
nbtk/nbtk-subtexture.c \
|
||||||
nbtk/nbtk-texture-cache.c \
|
nbtk/nbtk-texture-cache.c \
|
||||||
nbtk/nbtk-texture-frame.c \
|
nbtk/nbtk-texture-frame.c \
|
||||||
nbtk/nbtk-tooltip.c \
|
nbtk/nbtk-tooltip.c \
|
||||||
|
nbtk/nbtk-viewport.c \
|
||||||
nbtk/nbtk-widget.c \
|
nbtk/nbtk-widget.c \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
768
src/nbtk/nbtk-adjustment.c
Normal file
768
src/nbtk/nbtk-adjustment.c
Normal file
@ -0,0 +1,768 @@
|
|||||||
|
/*
|
||||||
|
* nbtk-adjustment.c: Adjustment object
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 OpenedHand
|
||||||
|
* Copyright (c) 2009 Intel Corporation.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU Lesser General Public License,
|
||||||
|
* version 2.1, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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 program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Written by: Chris Lord <chris@openedhand.com>, inspired by GtkAdjustment
|
||||||
|
* Port to Nbtk by: Robert Staudinger <robsta@openedhand.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
|
#include "nbtk-adjustment.h"
|
||||||
|
#include "nbtk-marshal.h"
|
||||||
|
#include "nbtk-private.h"
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (NbtkAdjustment, nbtk_adjustment, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
#define ADJUSTMENT_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NBTK_TYPE_ADJUSTMENT, NbtkAdjustmentPrivate))
|
||||||
|
|
||||||
|
struct _NbtkAdjustmentPrivate
|
||||||
|
{
|
||||||
|
/* Do not sanity-check values while constructing,
|
||||||
|
* not all properties may be set yet. */
|
||||||
|
gboolean is_constructing : 1;
|
||||||
|
|
||||||
|
gdouble lower;
|
||||||
|
gdouble upper;
|
||||||
|
gdouble value;
|
||||||
|
gdouble step_increment;
|
||||||
|
gdouble page_increment;
|
||||||
|
gdouble page_size;
|
||||||
|
|
||||||
|
/* For interpolation */
|
||||||
|
ClutterTimeline *interpolation;
|
||||||
|
gdouble old_position;
|
||||||
|
gdouble new_position;
|
||||||
|
|
||||||
|
/* For elasticity */
|
||||||
|
gboolean elastic;
|
||||||
|
guint bounce_source;
|
||||||
|
ClutterAlpha *bounce_alpha;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
|
||||||
|
PROP_LOWER,
|
||||||
|
PROP_UPPER,
|
||||||
|
PROP_VALUE,
|
||||||
|
PROP_STEP_INC,
|
||||||
|
PROP_PAGE_INC,
|
||||||
|
PROP_PAGE_SIZE,
|
||||||
|
|
||||||
|
PROP_ELASTIC,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CHANGED,
|
||||||
|
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint signals[LAST_SIGNAL] = { 0, };
|
||||||
|
|
||||||
|
static gboolean nbtk_adjustment_set_lower (NbtkAdjustment *adjustment,
|
||||||
|
gdouble lower);
|
||||||
|
static gboolean nbtk_adjustment_set_upper (NbtkAdjustment *adjustment,
|
||||||
|
gdouble upper);
|
||||||
|
static gboolean nbtk_adjustment_set_step_increment (NbtkAdjustment *adjustment,
|
||||||
|
gdouble step);
|
||||||
|
static gboolean nbtk_adjustment_set_page_increment (NbtkAdjustment *adjustment,
|
||||||
|
gdouble page);
|
||||||
|
static gboolean nbtk_adjustment_set_page_size (NbtkAdjustment *adjustment,
|
||||||
|
gdouble size);
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_adjustment_constructed (GObject *object)
|
||||||
|
{
|
||||||
|
GObjectClass *g_class;
|
||||||
|
NbtkAdjustment *self = NBTK_ADJUSTMENT (object);
|
||||||
|
|
||||||
|
g_class = G_OBJECT_CLASS (nbtk_adjustment_parent_class);
|
||||||
|
/* The docs say we're suppose to chain up, but would crash without
|
||||||
|
* some extra care. */
|
||||||
|
if (g_class && g_class->constructed &&
|
||||||
|
g_class->constructed != nbtk_adjustment_constructed)
|
||||||
|
{
|
||||||
|
g_class->constructed (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
NBTK_ADJUSTMENT (self)->priv->is_constructing = FALSE;
|
||||||
|
nbtk_adjustment_clamp_page (self, self->priv->lower, self->priv->upper);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_adjustment_get_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
NbtkAdjustmentPrivate *priv = NBTK_ADJUSTMENT (gobject)->priv;
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_LOWER:
|
||||||
|
g_value_set_double (value, priv->lower);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_UPPER:
|
||||||
|
g_value_set_double (value, priv->upper);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_VALUE:
|
||||||
|
g_value_set_double (value, priv->value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_STEP_INC:
|
||||||
|
g_value_set_double (value, priv->step_increment);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_PAGE_INC:
|
||||||
|
g_value_set_double (value, priv->page_increment);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_PAGE_SIZE:
|
||||||
|
g_value_set_double (value, priv->page_size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_ELASTIC:
|
||||||
|
g_value_set_boolean (value, priv->elastic);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_adjustment_set_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
NbtkAdjustment *adj = NBTK_ADJUSTMENT (gobject);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_LOWER:
|
||||||
|
nbtk_adjustment_set_lower (adj, g_value_get_double (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_UPPER:
|
||||||
|
nbtk_adjustment_set_upper (adj, g_value_get_double (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_VALUE:
|
||||||
|
nbtk_adjustment_set_value (adj, g_value_get_double (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_STEP_INC:
|
||||||
|
nbtk_adjustment_set_step_increment (adj, g_value_get_double (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_PAGE_INC:
|
||||||
|
nbtk_adjustment_set_page_increment (adj, g_value_get_double (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_PAGE_SIZE:
|
||||||
|
nbtk_adjustment_set_page_size (adj, g_value_get_double (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_ELASTIC:
|
||||||
|
nbtk_adjustment_set_elastic (adj, g_value_get_boolean (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
stop_interpolation (NbtkAdjustment *adjustment)
|
||||||
|
{
|
||||||
|
NbtkAdjustmentPrivate *priv = adjustment->priv;
|
||||||
|
|
||||||
|
if (priv->interpolation)
|
||||||
|
{
|
||||||
|
clutter_timeline_stop (priv->interpolation);
|
||||||
|
g_object_unref (priv->interpolation);
|
||||||
|
priv->interpolation = NULL;
|
||||||
|
|
||||||
|
if (priv->bounce_alpha)
|
||||||
|
{
|
||||||
|
g_object_unref (priv->bounce_alpha);
|
||||||
|
priv->bounce_alpha = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->bounce_source)
|
||||||
|
{
|
||||||
|
g_source_remove (priv->bounce_source);
|
||||||
|
priv->bounce_source = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_adjustment_dispose (GObject *object)
|
||||||
|
{
|
||||||
|
stop_interpolation (NBTK_ADJUSTMENT (object));
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (nbtk_adjustment_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_adjustment_class_init (NbtkAdjustmentClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
g_type_class_add_private (klass, sizeof (NbtkAdjustmentPrivate));
|
||||||
|
|
||||||
|
object_class->constructed = nbtk_adjustment_constructed;
|
||||||
|
object_class->get_property = nbtk_adjustment_get_property;
|
||||||
|
object_class->set_property = nbtk_adjustment_set_property;
|
||||||
|
object_class->dispose = nbtk_adjustment_dispose;
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_LOWER,
|
||||||
|
g_param_spec_double ("lower",
|
||||||
|
"Lower",
|
||||||
|
"Lower bound",
|
||||||
|
-G_MAXDOUBLE,
|
||||||
|
G_MAXDOUBLE,
|
||||||
|
0.0,
|
||||||
|
NBTK_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT));
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_UPPER,
|
||||||
|
g_param_spec_double ("upper",
|
||||||
|
"Upper",
|
||||||
|
"Upper bound",
|
||||||
|
-G_MAXDOUBLE,
|
||||||
|
G_MAXDOUBLE,
|
||||||
|
0.0,
|
||||||
|
NBTK_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT));
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_VALUE,
|
||||||
|
g_param_spec_double ("value",
|
||||||
|
"Value",
|
||||||
|
"Current value",
|
||||||
|
-G_MAXDOUBLE,
|
||||||
|
G_MAXDOUBLE,
|
||||||
|
0.0,
|
||||||
|
NBTK_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT));
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_STEP_INC,
|
||||||
|
g_param_spec_double ("step-increment",
|
||||||
|
"Step Increment",
|
||||||
|
"Step increment",
|
||||||
|
0.0,
|
||||||
|
G_MAXDOUBLE,
|
||||||
|
0.0,
|
||||||
|
NBTK_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT));
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_PAGE_INC,
|
||||||
|
g_param_spec_double ("page-increment",
|
||||||
|
"Page Increment",
|
||||||
|
"Page increment",
|
||||||
|
0.0,
|
||||||
|
G_MAXDOUBLE,
|
||||||
|
0.0,
|
||||||
|
NBTK_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT));
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_PAGE_SIZE,
|
||||||
|
g_param_spec_double ("page-size",
|
||||||
|
"Page Size",
|
||||||
|
"Page size",
|
||||||
|
0.0,
|
||||||
|
G_MAXDOUBLE,
|
||||||
|
0.0,
|
||||||
|
NBTK_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT));
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_ELASTIC,
|
||||||
|
g_param_spec_boolean ("elastic",
|
||||||
|
"Elastic",
|
||||||
|
"Make interpolation "
|
||||||
|
"behave in an "
|
||||||
|
"'elastic' way and "
|
||||||
|
"stop clamping value.",
|
||||||
|
FALSE,
|
||||||
|
NBTK_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NbtkAdjustment::changed:
|
||||||
|
*
|
||||||
|
* Emitted when any of the adjustment values have changed
|
||||||
|
*/
|
||||||
|
signals[CHANGED] =
|
||||||
|
g_signal_new ("changed",
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (NbtkAdjustmentClass, changed),
|
||||||
|
NULL, NULL,
|
||||||
|
_nbtk_marshal_VOID__VOID,
|
||||||
|
G_TYPE_NONE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_adjustment_init (NbtkAdjustment *self)
|
||||||
|
{
|
||||||
|
self->priv = ADJUSTMENT_PRIVATE (self);
|
||||||
|
|
||||||
|
self->priv->is_constructing = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
NbtkAdjustment *
|
||||||
|
nbtk_adjustment_new (gdouble value,
|
||||||
|
gdouble lower,
|
||||||
|
gdouble upper,
|
||||||
|
gdouble step_increment,
|
||||||
|
gdouble page_increment,
|
||||||
|
gdouble page_size)
|
||||||
|
{
|
||||||
|
return g_object_new (NBTK_TYPE_ADJUSTMENT,
|
||||||
|
"value", value,
|
||||||
|
"lower", lower,
|
||||||
|
"upper", upper,
|
||||||
|
"step-increment", step_increment,
|
||||||
|
"page-increment", page_increment,
|
||||||
|
"page-size", page_size,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
gdouble
|
||||||
|
nbtk_adjustment_get_value (NbtkAdjustment *adjustment)
|
||||||
|
{
|
||||||
|
NbtkAdjustmentPrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (NBTK_IS_ADJUSTMENT (adjustment), 0);
|
||||||
|
|
||||||
|
priv = adjustment->priv;
|
||||||
|
|
||||||
|
if (priv->interpolation)
|
||||||
|
{
|
||||||
|
return MAX (priv->lower,
|
||||||
|
MIN (priv->upper - priv->page_size,
|
||||||
|
priv->new_position));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return priv->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nbtk_adjustment_set_value (NbtkAdjustment *adjustment,
|
||||||
|
gdouble value)
|
||||||
|
{
|
||||||
|
NbtkAdjustmentPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (NBTK_IS_ADJUSTMENT (adjustment));
|
||||||
|
|
||||||
|
priv = adjustment->priv;
|
||||||
|
|
||||||
|
stop_interpolation (adjustment);
|
||||||
|
|
||||||
|
/* Defer clamp until after construction. */
|
||||||
|
if (!priv->is_constructing)
|
||||||
|
{
|
||||||
|
if (!priv->elastic)
|
||||||
|
value = CLAMP (value,
|
||||||
|
priv->lower,
|
||||||
|
MAX (priv->lower, priv->upper - priv->page_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->value != value)
|
||||||
|
{
|
||||||
|
priv->value = value;
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (adjustment), "value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nbtk_adjustment_clamp_page (NbtkAdjustment *adjustment,
|
||||||
|
gdouble lower,
|
||||||
|
gdouble upper)
|
||||||
|
{
|
||||||
|
NbtkAdjustmentPrivate *priv;
|
||||||
|
gboolean changed;
|
||||||
|
|
||||||
|
g_return_if_fail (NBTK_IS_ADJUSTMENT (adjustment));
|
||||||
|
|
||||||
|
priv = adjustment->priv;
|
||||||
|
|
||||||
|
stop_interpolation (adjustment);
|
||||||
|
|
||||||
|
lower = CLAMP (lower, priv->lower, priv->upper - priv->page_size);
|
||||||
|
upper = CLAMP (upper, priv->lower + priv->page_size, priv->upper);
|
||||||
|
|
||||||
|
changed = FALSE;
|
||||||
|
|
||||||
|
if (priv->value + priv->page_size > upper)
|
||||||
|
{
|
||||||
|
priv->value = upper - priv->page_size;
|
||||||
|
changed = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->value < lower)
|
||||||
|
{
|
||||||
|
priv->value = lower;
|
||||||
|
changed = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
g_object_notify (G_OBJECT (adjustment), "value");
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
nbtk_adjustment_set_lower (NbtkAdjustment *adjustment,
|
||||||
|
gdouble lower)
|
||||||
|
{
|
||||||
|
NbtkAdjustmentPrivate *priv = adjustment->priv;
|
||||||
|
|
||||||
|
if (priv->lower != lower)
|
||||||
|
{
|
||||||
|
priv->lower = lower;
|
||||||
|
|
||||||
|
g_signal_emit (adjustment, signals[CHANGED], 0);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (adjustment), "lower");
|
||||||
|
|
||||||
|
/* Defer clamp until after construction. */
|
||||||
|
if (!priv->is_constructing)
|
||||||
|
nbtk_adjustment_clamp_page (adjustment, priv->lower, priv->upper);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
nbtk_adjustment_set_upper (NbtkAdjustment *adjustment,
|
||||||
|
gdouble upper)
|
||||||
|
{
|
||||||
|
NbtkAdjustmentPrivate *priv = adjustment->priv;
|
||||||
|
|
||||||
|
if (priv->upper != upper)
|
||||||
|
{
|
||||||
|
priv->upper = upper;
|
||||||
|
|
||||||
|
g_signal_emit (adjustment, signals[CHANGED], 0);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (adjustment), "upper");
|
||||||
|
|
||||||
|
/* Defer clamp until after construction. */
|
||||||
|
if (!priv->is_constructing)
|
||||||
|
nbtk_adjustment_clamp_page (adjustment, priv->lower, priv->upper);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
nbtk_adjustment_set_step_increment (NbtkAdjustment *adjustment,
|
||||||
|
gdouble step)
|
||||||
|
{
|
||||||
|
NbtkAdjustmentPrivate *priv = adjustment->priv;
|
||||||
|
|
||||||
|
if (priv->step_increment != step)
|
||||||
|
{
|
||||||
|
priv->step_increment = step;
|
||||||
|
|
||||||
|
g_signal_emit (adjustment, signals[CHANGED], 0);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (adjustment), "step-increment");
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
nbtk_adjustment_set_page_increment (NbtkAdjustment *adjustment,
|
||||||
|
gdouble page)
|
||||||
|
{
|
||||||
|
NbtkAdjustmentPrivate *priv = adjustment->priv;
|
||||||
|
|
||||||
|
if (priv->page_increment != page)
|
||||||
|
{
|
||||||
|
priv->page_increment = page;
|
||||||
|
|
||||||
|
g_signal_emit (adjustment, signals[CHANGED], 0);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (adjustment), "page-increment");
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
nbtk_adjustment_set_page_size (NbtkAdjustment *adjustment,
|
||||||
|
gdouble size)
|
||||||
|
{
|
||||||
|
NbtkAdjustmentPrivate *priv = adjustment->priv;
|
||||||
|
|
||||||
|
if (priv->page_size != size)
|
||||||
|
{
|
||||||
|
priv->page_size = size;
|
||||||
|
|
||||||
|
g_signal_emit (adjustment, signals[CHANGED], 0);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (adjustment), "page_size");
|
||||||
|
|
||||||
|
/* Well explicitely clamp after construction. */
|
||||||
|
if (!priv->is_constructing)
|
||||||
|
nbtk_adjustment_clamp_page (adjustment, priv->lower, priv->upper);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nbtk_adjustment_set_values (NbtkAdjustment *adjustment,
|
||||||
|
gdouble value,
|
||||||
|
gdouble lower,
|
||||||
|
gdouble upper,
|
||||||
|
gdouble step_increment,
|
||||||
|
gdouble page_increment,
|
||||||
|
gdouble page_size)
|
||||||
|
{
|
||||||
|
NbtkAdjustmentPrivate *priv;
|
||||||
|
gboolean emit_changed = FALSE;
|
||||||
|
|
||||||
|
g_return_if_fail (NBTK_IS_ADJUSTMENT (adjustment));
|
||||||
|
g_return_if_fail (page_size >= 0 && page_size <= G_MAXDOUBLE);
|
||||||
|
g_return_if_fail (step_increment >= 0 && step_increment <= G_MAXDOUBLE);
|
||||||
|
g_return_if_fail (page_increment >= 0 && page_increment <= G_MAXDOUBLE);
|
||||||
|
|
||||||
|
priv = adjustment->priv;
|
||||||
|
|
||||||
|
stop_interpolation (adjustment);
|
||||||
|
|
||||||
|
emit_changed = FALSE;
|
||||||
|
|
||||||
|
g_object_freeze_notify (G_OBJECT (adjustment));
|
||||||
|
|
||||||
|
emit_changed |= nbtk_adjustment_set_lower (adjustment, lower);
|
||||||
|
emit_changed |= nbtk_adjustment_set_upper (adjustment, upper);
|
||||||
|
emit_changed |= nbtk_adjustment_set_step_increment (adjustment, step_increment);
|
||||||
|
emit_changed |= nbtk_adjustment_set_page_increment (adjustment, page_increment);
|
||||||
|
emit_changed |= nbtk_adjustment_set_page_size (adjustment, page_size);
|
||||||
|
|
||||||
|
if (value != priv->value)
|
||||||
|
{
|
||||||
|
nbtk_adjustment_set_value (adjustment, value);
|
||||||
|
emit_changed = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (emit_changed)
|
||||||
|
g_signal_emit (G_OBJECT (adjustment), signals[CHANGED], 0);
|
||||||
|
|
||||||
|
g_object_thaw_notify (G_OBJECT (adjustment));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nbtk_adjustment_get_values (NbtkAdjustment *adjustment,
|
||||||
|
gdouble *value,
|
||||||
|
gdouble *lower,
|
||||||
|
gdouble *upper,
|
||||||
|
gdouble *step_increment,
|
||||||
|
gdouble *page_increment,
|
||||||
|
gdouble *page_size)
|
||||||
|
{
|
||||||
|
NbtkAdjustmentPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (NBTK_IS_ADJUSTMENT (adjustment));
|
||||||
|
|
||||||
|
priv = adjustment->priv;
|
||||||
|
|
||||||
|
if (lower)
|
||||||
|
*lower = priv->lower;
|
||||||
|
|
||||||
|
if (upper)
|
||||||
|
*upper = priv->upper;
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
*value = nbtk_adjustment_get_value (adjustment);
|
||||||
|
|
||||||
|
if (step_increment)
|
||||||
|
*step_increment = priv->step_increment;
|
||||||
|
|
||||||
|
if (page_increment)
|
||||||
|
*page_increment = priv->page_increment;
|
||||||
|
|
||||||
|
if (page_size)
|
||||||
|
*page_size = priv->page_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
interpolation_new_frame_cb (ClutterTimeline *timeline,
|
||||||
|
guint msecs,
|
||||||
|
NbtkAdjustment *adjustment)
|
||||||
|
{
|
||||||
|
NbtkAdjustmentPrivate *priv = adjustment->priv;
|
||||||
|
|
||||||
|
priv->interpolation = NULL;
|
||||||
|
|
||||||
|
if (priv->elastic)
|
||||||
|
{
|
||||||
|
gdouble progress = clutter_alpha_get_alpha (priv->bounce_alpha) / 1.0;
|
||||||
|
gdouble dx = priv->old_position
|
||||||
|
+ (priv->new_position - priv->old_position)
|
||||||
|
* progress;
|
||||||
|
|
||||||
|
nbtk_adjustment_set_value (adjustment, dx);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
nbtk_adjustment_set_value (adjustment,
|
||||||
|
priv->old_position +
|
||||||
|
(priv->new_position - priv->old_position) *
|
||||||
|
clutter_timeline_get_progress (timeline));
|
||||||
|
|
||||||
|
priv->interpolation = timeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
interpolation_completed_cb (ClutterTimeline *timeline,
|
||||||
|
NbtkAdjustment *adjustment)
|
||||||
|
{
|
||||||
|
NbtkAdjustmentPrivate *priv = adjustment->priv;
|
||||||
|
|
||||||
|
stop_interpolation (adjustment);
|
||||||
|
nbtk_adjustment_set_value (adjustment, priv->new_position);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note, there's super-optimal code that does a similar thing in
|
||||||
|
* clutter-alpha.c
|
||||||
|
*
|
||||||
|
* Tried this instead of CLUTTER_ALPHA_SINE_INC, but I think SINE_INC looks
|
||||||
|
* better. Leaving code here in case this is revisited.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
static guint32
|
||||||
|
bounce_alpha_func (ClutterAlpha *alpha,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
ClutterFixed progress, angle;
|
||||||
|
ClutterTimeline *timeline = clutter_alpha_get_timeline (alpha);
|
||||||
|
|
||||||
|
progress = clutter_timeline_get_progressx (timeline);
|
||||||
|
angle = clutter_qmulx (CFX_PI_2 + CFX_PI_4/2, progress);
|
||||||
|
|
||||||
|
return clutter_sinx (angle) +
|
||||||
|
(CFX_ONE - clutter_sinx (CFX_PI_2 + CFX_PI_4/2));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
nbtk_adjustment_interpolate (NbtkAdjustment *adjustment,
|
||||||
|
gdouble value,
|
||||||
|
guint duration)
|
||||||
|
{
|
||||||
|
NbtkAdjustmentPrivate *priv = adjustment->priv;
|
||||||
|
|
||||||
|
stop_interpolation (adjustment);
|
||||||
|
|
||||||
|
if (duration <= 1)
|
||||||
|
{
|
||||||
|
nbtk_adjustment_set_value (adjustment, value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->old_position = priv->value;
|
||||||
|
priv->new_position = value;
|
||||||
|
|
||||||
|
priv->interpolation = clutter_timeline_new (duration);
|
||||||
|
|
||||||
|
if (priv->elastic)
|
||||||
|
priv->bounce_alpha = clutter_alpha_new_full (priv->interpolation,
|
||||||
|
CLUTTER_LINEAR);
|
||||||
|
|
||||||
|
g_signal_connect (priv->interpolation,
|
||||||
|
"new-frame",
|
||||||
|
G_CALLBACK (interpolation_new_frame_cb),
|
||||||
|
adjustment);
|
||||||
|
g_signal_connect (priv->interpolation,
|
||||||
|
"completed",
|
||||||
|
G_CALLBACK (interpolation_completed_cb),
|
||||||
|
adjustment);
|
||||||
|
|
||||||
|
clutter_timeline_start (priv->interpolation);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
nbtk_adjustment_get_elastic (NbtkAdjustment *adjustment)
|
||||||
|
{
|
||||||
|
return adjustment->priv->elastic;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nbtk_adjustment_set_elastic (NbtkAdjustment *adjustment,
|
||||||
|
gboolean elastic)
|
||||||
|
{
|
||||||
|
adjustment->priv->elastic = elastic;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
nbtk_adjustment_clamp (NbtkAdjustment *adjustment,
|
||||||
|
gboolean interpolate,
|
||||||
|
guint duration)
|
||||||
|
{
|
||||||
|
NbtkAdjustmentPrivate *priv = adjustment->priv;
|
||||||
|
gdouble dest = priv->value;
|
||||||
|
|
||||||
|
if (priv->value < priv->lower)
|
||||||
|
dest = priv->lower;
|
||||||
|
|
||||||
|
if (priv->value > priv->upper - priv->page_size)
|
||||||
|
dest = priv->upper - priv->page_size;
|
||||||
|
|
||||||
|
if (dest != priv->value)
|
||||||
|
{
|
||||||
|
if (interpolate)
|
||||||
|
nbtk_adjustment_interpolate (adjustment, dest, duration);
|
||||||
|
else
|
||||||
|
nbtk_adjustment_set_value (adjustment, dest);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
121
src/nbtk/nbtk-adjustment.h
Normal file
121
src/nbtk/nbtk-adjustment.h
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* nbtk-adjustment.h: Adjustment object
|
||||||
|
*
|
||||||
|
* Copyright 2008 OpenedHand
|
||||||
|
* Copyright 2009 Intel Corporation.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU Lesser General Public License,
|
||||||
|
* version 2.1, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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 program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Written by: Chris Lord <chris@openedhand.com>, inspired by GtkAdjustment
|
||||||
|
* Port to Nbtk by: Robert Staudinger <robsta@openedhand.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(NBTK_H_INSIDE) && !defined(NBTK_COMPILATION)
|
||||||
|
#error "Only <nbtk/nbtk.h> can be included directly.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __NBTK_ADJUSTMENT_H__
|
||||||
|
#define __NBTK_ADJUSTMENT_H__
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define NBTK_TYPE_ADJUSTMENT (nbtk_adjustment_get_type())
|
||||||
|
#define NBTK_ADJUSTMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NBTK_TYPE_ADJUSTMENT, NbtkAdjustment))
|
||||||
|
#define NBTK_IS_ADJUSTMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NBTK_TYPE_ADJUSTMENT))
|
||||||
|
#define NBTK_ADJUSTMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NBTK_TYPE_ADJUSTMENT, NbtkAdjustmentClass))
|
||||||
|
#define NBTK_IS_ADJUSTMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NBTK_TYPE_ADJUSTMENT))
|
||||||
|
#define NBTK_ADJUSTMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NBTK_TYPE_ADJUSTMENT, NbtkAdjustmentClass))
|
||||||
|
|
||||||
|
typedef struct _NbtkAdjustment NbtkAdjustment;
|
||||||
|
typedef struct _NbtkAdjustmentPrivate NbtkAdjustmentPrivate;
|
||||||
|
typedef struct _NbtkAdjustmentClass NbtkAdjustmentClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NbtkAdjustment:
|
||||||
|
*
|
||||||
|
* Class for handling an interval between to values. The contents of
|
||||||
|
* the #NbtkAdjustment are private and should be accessed using the
|
||||||
|
* public API.
|
||||||
|
*/
|
||||||
|
struct _NbtkAdjustment
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
GObject parent_instance;
|
||||||
|
|
||||||
|
NbtkAdjustmentPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NbtkAdjustmentClass
|
||||||
|
* @changed: Class handler for the ::changed signal.
|
||||||
|
*
|
||||||
|
* Base class for #NbtkAdjustment.
|
||||||
|
*/
|
||||||
|
struct _NbtkAdjustmentClass
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
GObjectClass parent_class;
|
||||||
|
|
||||||
|
/*< public >*/
|
||||||
|
void (* changed) (NbtkAdjustment *adjustment);
|
||||||
|
};
|
||||||
|
|
||||||
|
GType nbtk_adjustment_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
NbtkAdjustment *nbtk_adjustment_new (gdouble value,
|
||||||
|
gdouble lower,
|
||||||
|
gdouble upper,
|
||||||
|
gdouble step_increment,
|
||||||
|
gdouble page_increment,
|
||||||
|
gdouble page_size);
|
||||||
|
gdouble nbtk_adjustment_get_value (NbtkAdjustment *adjustment);
|
||||||
|
void nbtk_adjustment_set_value (NbtkAdjustment *adjustment,
|
||||||
|
gdouble value);
|
||||||
|
void nbtk_adjustment_clamp_page (NbtkAdjustment *adjustment,
|
||||||
|
gdouble lower,
|
||||||
|
gdouble upper);
|
||||||
|
void nbtk_adjustment_set_values (NbtkAdjustment *adjustment,
|
||||||
|
gdouble value,
|
||||||
|
gdouble lower,
|
||||||
|
gdouble upper,
|
||||||
|
gdouble step_increment,
|
||||||
|
gdouble page_increment,
|
||||||
|
gdouble page_size);
|
||||||
|
void nbtk_adjustment_get_values (NbtkAdjustment *adjustment,
|
||||||
|
gdouble *value,
|
||||||
|
gdouble *lower,
|
||||||
|
gdouble *upper,
|
||||||
|
gdouble *step_increment,
|
||||||
|
gdouble *page_increment,
|
||||||
|
gdouble *page_size);
|
||||||
|
|
||||||
|
void nbtk_adjustment_interpolate (NbtkAdjustment *adjustment,
|
||||||
|
gdouble value,
|
||||||
|
guint duration);
|
||||||
|
|
||||||
|
gboolean nbtk_adjustment_get_elastic (NbtkAdjustment *adjustment);
|
||||||
|
void nbtk_adjustment_set_elastic (NbtkAdjustment *adjustment,
|
||||||
|
gboolean elastic);
|
||||||
|
|
||||||
|
gboolean nbtk_adjustment_clamp (NbtkAdjustment *adjustment,
|
||||||
|
gboolean interpolate,
|
||||||
|
guint duration);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __NBTK_ADJUSTMENT_H__ */
|
759
src/nbtk/nbtk-button.c
Normal file
759
src/nbtk/nbtk-button.c
Normal file
@ -0,0 +1,759 @@
|
|||||||
|
/*
|
||||||
|
* nbtk-button.c: Plain button actor
|
||||||
|
*
|
||||||
|
* Copyright 2007 OpenedHand
|
||||||
|
* Copyright 2008, 2009 Intel Corporation.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU Lesser General Public License,
|
||||||
|
* version 2.1, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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 program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Written by: Emmanuele Bassi <ebassi@openedhand.com>
|
||||||
|
* Thomas Wood <thomas@linux.intel.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:nbtk-button
|
||||||
|
* @short_description: Button widget
|
||||||
|
*
|
||||||
|
* A button widget with support for either a text label or icon, toggle mode
|
||||||
|
* and transitions effects between states.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
|
#include "nbtk-button.h"
|
||||||
|
|
||||||
|
#include "nbtk-marshal.h"
|
||||||
|
#include "nbtk-stylable.h"
|
||||||
|
#include "nbtk-style.h"
|
||||||
|
#include "nbtk-texture-frame.h"
|
||||||
|
#include "nbtk-texture-cache.h"
|
||||||
|
#include "nbtk-private.h"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
|
||||||
|
PROP_LABEL,
|
||||||
|
PROP_TOGGLE,
|
||||||
|
PROP_ACTIVE,
|
||||||
|
PROP_TRANSITION
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CLICKED,
|
||||||
|
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NBTK_BUTTON_GET_PRIVATE(obj) \
|
||||||
|
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), NBTK_TYPE_BUTTON, NbtkButtonPrivate))
|
||||||
|
|
||||||
|
struct _NbtkButtonPrivate
|
||||||
|
{
|
||||||
|
gchar *text;
|
||||||
|
|
||||||
|
ClutterActor *old_bg;
|
||||||
|
gboolean old_bg_parented; /* TRUE if we have adopted old_bg */
|
||||||
|
|
||||||
|
guint8 old_opacity;
|
||||||
|
|
||||||
|
guint is_pressed : 1;
|
||||||
|
guint is_hover : 1;
|
||||||
|
guint is_checked : 1;
|
||||||
|
guint is_toggle : 1;
|
||||||
|
|
||||||
|
gint transition_duration;
|
||||||
|
|
||||||
|
ClutterAnimation *animation;
|
||||||
|
|
||||||
|
gint spacing;
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint button_signals[LAST_SIGNAL] = { 0, };
|
||||||
|
|
||||||
|
static void nbtk_stylable_iface_init (NbtkStylableIface *iface);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_CODE (NbtkButton, nbtk_button, NBTK_TYPE_BIN,
|
||||||
|
G_IMPLEMENT_INTERFACE (NBTK_TYPE_STYLABLE,
|
||||||
|
nbtk_stylable_iface_init));
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_stylable_iface_init (NbtkStylableIface *iface)
|
||||||
|
{
|
||||||
|
static gboolean is_initialized = FALSE;
|
||||||
|
|
||||||
|
if (G_UNLIKELY (!is_initialized))
|
||||||
|
{
|
||||||
|
ClutterColor bg_color = { 0xcc, 0xcc, 0xcc, 0x00 };
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
is_initialized = TRUE;
|
||||||
|
|
||||||
|
pspec = g_param_spec_int ("border-spacing",
|
||||||
|
"Border Spacing",
|
||||||
|
"Spacing between internal elements",
|
||||||
|
0, G_MAXINT, 6,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
nbtk_stylable_iface_install_property (iface, NBTK_TYPE_BUTTON, pspec);
|
||||||
|
|
||||||
|
|
||||||
|
is_initialized = TRUE;
|
||||||
|
|
||||||
|
pspec = clutter_param_spec_color ("background-color",
|
||||||
|
"Background Color",
|
||||||
|
"The background color of an actor",
|
||||||
|
&bg_color,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
nbtk_stylable_iface_install_property (iface, NBTK_TYPE_BUTTON, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_button_update_label_style (NbtkButton *button)
|
||||||
|
{
|
||||||
|
ClutterColor *real_color = NULL;
|
||||||
|
gchar *font_string = NULL;
|
||||||
|
gchar *font_name = NULL;
|
||||||
|
gint font_size = 0;
|
||||||
|
ClutterActor *label;
|
||||||
|
|
||||||
|
label = nbtk_bin_get_child ((NbtkBin*) button);
|
||||||
|
|
||||||
|
/* check the child is really a label */
|
||||||
|
if (!CLUTTER_IS_TEXT (label))
|
||||||
|
return;
|
||||||
|
|
||||||
|
nbtk_stylable_get (NBTK_STYLABLE (button),
|
||||||
|
"color", &real_color,
|
||||||
|
"font-family", &font_name,
|
||||||
|
"font-size", &font_size,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (font_name || font_size)
|
||||||
|
{
|
||||||
|
if (font_name && font_size)
|
||||||
|
font_string = g_strdup_printf ("%s %dpx", font_name, font_size);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (font_size)
|
||||||
|
font_string = g_strdup_printf ("%dpx", font_size);
|
||||||
|
else
|
||||||
|
font_string = font_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_text_set_font_name (CLUTTER_TEXT (label), font_string);
|
||||||
|
|
||||||
|
if (font_string != font_name)
|
||||||
|
g_free (font_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (font_name);
|
||||||
|
|
||||||
|
if (real_color)
|
||||||
|
{
|
||||||
|
clutter_text_set_color (CLUTTER_TEXT (label), real_color);
|
||||||
|
clutter_color_free (real_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_button_dispose_old_bg (NbtkButton *button)
|
||||||
|
{
|
||||||
|
NbtkButtonPrivate *priv = button->priv;
|
||||||
|
|
||||||
|
if (priv->old_bg)
|
||||||
|
{
|
||||||
|
if (priv->old_bg_parented)
|
||||||
|
{
|
||||||
|
clutter_actor_unparent (priv->old_bg);
|
||||||
|
priv->old_bg_parented = FALSE;
|
||||||
|
}
|
||||||
|
g_object_unref (priv->old_bg);
|
||||||
|
priv->old_bg = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_button_stylable_changed (NbtkStylable *stylable)
|
||||||
|
{
|
||||||
|
NbtkButton *button = NBTK_BUTTON (stylable);
|
||||||
|
ClutterActor *bg_image;
|
||||||
|
|
||||||
|
nbtk_button_dispose_old_bg (button);
|
||||||
|
|
||||||
|
bg_image = nbtk_widget_get_border_image ((NbtkWidget*) button);
|
||||||
|
if (bg_image)
|
||||||
|
button->priv->old_bg = g_object_ref (bg_image);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_animation_completed (ClutterAnimation *animation,
|
||||||
|
NbtkButton *button)
|
||||||
|
{
|
||||||
|
nbtk_button_dispose_old_bg (button);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_button_style_changed (NbtkWidget *widget)
|
||||||
|
{
|
||||||
|
NbtkButton *button = NBTK_BUTTON (widget);
|
||||||
|
NbtkButtonPrivate *priv = button->priv;
|
||||||
|
NbtkButtonClass *button_class = NBTK_BUTTON_GET_CLASS (button);
|
||||||
|
|
||||||
|
/* get the spacing value */
|
||||||
|
nbtk_stylable_get (NBTK_STYLABLE (widget),
|
||||||
|
"border-spacing", &priv->spacing,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* update the label styling */
|
||||||
|
nbtk_button_update_label_style (button);
|
||||||
|
|
||||||
|
/* run a transition if applicable */
|
||||||
|
if (button_class->transition)
|
||||||
|
{
|
||||||
|
button_class->transition (button, priv->old_bg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (priv->old_bg &&
|
||||||
|
(!nbtk_widget_get_style_pseudo_class (widget)))
|
||||||
|
{
|
||||||
|
ClutterAnimation *animation;
|
||||||
|
if (!clutter_actor_get_parent (priv->old_bg))
|
||||||
|
{
|
||||||
|
clutter_actor_set_parent (priv->old_bg, (ClutterActor*) widget);
|
||||||
|
priv->old_bg_parented = TRUE;
|
||||||
|
}
|
||||||
|
if (priv->transition_duration > 0)
|
||||||
|
{
|
||||||
|
animation = clutter_actor_animate (priv->old_bg,
|
||||||
|
CLUTTER_LINEAR,
|
||||||
|
priv->transition_duration,
|
||||||
|
"opacity", 0,
|
||||||
|
NULL);
|
||||||
|
g_signal_connect (animation, "completed",
|
||||||
|
G_CALLBACK (nbtk_animation_completed), button);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nbtk_button_dispose_old_bg (button);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_button_real_pressed (NbtkButton *button)
|
||||||
|
{
|
||||||
|
nbtk_widget_set_style_pseudo_class ((NbtkWidget*) button, "active");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_button_real_released (NbtkButton *button)
|
||||||
|
{
|
||||||
|
NbtkButtonPrivate *priv = button->priv;
|
||||||
|
|
||||||
|
if (priv->is_checked)
|
||||||
|
nbtk_widget_set_style_pseudo_class ((NbtkWidget*) button, "checked");
|
||||||
|
else if (!priv->is_hover)
|
||||||
|
nbtk_widget_set_style_pseudo_class ((NbtkWidget*) button, NULL);
|
||||||
|
else
|
||||||
|
nbtk_widget_set_style_pseudo_class ((NbtkWidget*) button, "hover");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
nbtk_button_button_press (ClutterActor *actor,
|
||||||
|
ClutterButtonEvent *event)
|
||||||
|
{
|
||||||
|
nbtk_widget_hide_tooltip (NBTK_WIDGET (actor));
|
||||||
|
|
||||||
|
if (event->button == 1)
|
||||||
|
{
|
||||||
|
NbtkButton *button = NBTK_BUTTON (actor);
|
||||||
|
NbtkButtonClass *klass = NBTK_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
|
||||||
|
nbtk_button_button_release (ClutterActor *actor,
|
||||||
|
ClutterButtonEvent *event)
|
||||||
|
{
|
||||||
|
if (event->button == 1)
|
||||||
|
{
|
||||||
|
NbtkButton *button = NBTK_BUTTON (actor);
|
||||||
|
NbtkButtonClass *klass = NBTK_BUTTON_GET_CLASS (button);
|
||||||
|
|
||||||
|
if (!button->priv->is_pressed)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
clutter_ungrab_pointer ();
|
||||||
|
|
||||||
|
if (button->priv->is_toggle)
|
||||||
|
{
|
||||||
|
nbtk_button_set_checked (button, !button->priv->is_checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
nbtk_button_enter (ClutterActor *actor,
|
||||||
|
ClutterCrossingEvent *event)
|
||||||
|
{
|
||||||
|
NbtkButton *button = NBTK_BUTTON (actor);
|
||||||
|
|
||||||
|
if (!button->priv->is_checked)
|
||||||
|
nbtk_widget_set_style_pseudo_class ((NbtkWidget*) button, "hover");
|
||||||
|
|
||||||
|
button->priv->is_hover = 1;
|
||||||
|
|
||||||
|
return CLUTTER_ACTOR_CLASS (nbtk_button_parent_class)->enter_event (actor, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
nbtk_button_leave (ClutterActor *actor,
|
||||||
|
ClutterCrossingEvent *event)
|
||||||
|
{
|
||||||
|
NbtkButton *button = NBTK_BUTTON (actor);
|
||||||
|
|
||||||
|
button->priv->is_hover = 0;
|
||||||
|
|
||||||
|
if (button->priv->is_pressed)
|
||||||
|
{
|
||||||
|
NbtkButtonClass *klass = NBTK_BUTTON_GET_CLASS (button);
|
||||||
|
|
||||||
|
clutter_ungrab_pointer ();
|
||||||
|
|
||||||
|
button->priv->is_pressed = FALSE;
|
||||||
|
|
||||||
|
if (klass->released)
|
||||||
|
klass->released (button);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (button->priv->is_checked)
|
||||||
|
nbtk_widget_set_style_pseudo_class ((NbtkWidget*) button, "checked");
|
||||||
|
else
|
||||||
|
nbtk_widget_set_style_pseudo_class ((NbtkWidget*) button, NULL);
|
||||||
|
|
||||||
|
return CLUTTER_ACTOR_CLASS (nbtk_button_parent_class)->leave_event (actor, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_button_set_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
NbtkButton *button = NBTK_BUTTON (gobject);
|
||||||
|
NbtkButtonPrivate *priv = NBTK_BUTTON (gobject)->priv;
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_LABEL:
|
||||||
|
nbtk_button_set_label (button, g_value_get_string (value));
|
||||||
|
break;
|
||||||
|
case PROP_TOGGLE:
|
||||||
|
nbtk_button_set_toggle_mode (button, g_value_get_boolean (value));
|
||||||
|
break;
|
||||||
|
case PROP_ACTIVE:
|
||||||
|
nbtk_button_set_checked (button, g_value_get_boolean (value));
|
||||||
|
break;
|
||||||
|
case PROP_TRANSITION:
|
||||||
|
priv->transition_duration = g_value_get_int (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_button_get_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
NbtkButtonPrivate *priv = NBTK_BUTTON (gobject)->priv;
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_LABEL:
|
||||||
|
g_value_set_string (value, priv->text);
|
||||||
|
break;
|
||||||
|
case PROP_TOGGLE:
|
||||||
|
g_value_set_boolean (value, priv->is_toggle);
|
||||||
|
break;
|
||||||
|
case PROP_ACTIVE:
|
||||||
|
g_value_set_boolean (value, priv->is_checked);
|
||||||
|
break;
|
||||||
|
case PROP_TRANSITION:
|
||||||
|
g_value_set_int (value, priv->transition_duration);
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_button_finalize (GObject *gobject)
|
||||||
|
{
|
||||||
|
NbtkButtonPrivate *priv = NBTK_BUTTON (gobject)->priv;
|
||||||
|
|
||||||
|
g_free (priv->text);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (nbtk_button_parent_class)->finalize (gobject);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_button_dispose (GObject *gobject)
|
||||||
|
{
|
||||||
|
nbtk_button_dispose_old_bg (NBTK_BUTTON (gobject));
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (nbtk_button_parent_class)->dispose (gobject);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_button_map (ClutterActor *self)
|
||||||
|
{
|
||||||
|
NbtkButtonPrivate *priv = NBTK_BUTTON (self)->priv;
|
||||||
|
|
||||||
|
CLUTTER_ACTOR_CLASS (nbtk_button_parent_class)->map (self);
|
||||||
|
|
||||||
|
if (priv->old_bg && priv->old_bg_parented)
|
||||||
|
clutter_actor_map (priv->old_bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_button_unmap (ClutterActor *self)
|
||||||
|
{
|
||||||
|
NbtkButtonPrivate *priv = NBTK_BUTTON (self)->priv;
|
||||||
|
|
||||||
|
CLUTTER_ACTOR_CLASS (nbtk_button_parent_class)->unmap (self);
|
||||||
|
|
||||||
|
if (priv->old_bg && priv->old_bg_parented)
|
||||||
|
clutter_actor_unmap (priv->old_bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_button_draw_background (NbtkWidget *widget,
|
||||||
|
ClutterActor *background,
|
||||||
|
const ClutterColor *color)
|
||||||
|
{
|
||||||
|
NbtkButtonPrivate *priv;
|
||||||
|
|
||||||
|
NBTK_WIDGET_CLASS (nbtk_button_parent_class)->draw_background (widget, background, color);
|
||||||
|
|
||||||
|
priv = NBTK_BUTTON (widget)->priv;
|
||||||
|
|
||||||
|
if (priv->old_bg && priv->old_bg_parented)
|
||||||
|
clutter_actor_paint (priv->old_bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_button_class_init (NbtkButtonClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||||
|
NbtkWidgetClass *widget_class = NBTK_WIDGET_CLASS (klass);
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
g_type_class_add_private (klass, sizeof (NbtkButtonPrivate));
|
||||||
|
|
||||||
|
klass->pressed = nbtk_button_real_pressed;
|
||||||
|
klass->released = nbtk_button_real_released;
|
||||||
|
|
||||||
|
gobject_class->set_property = nbtk_button_set_property;
|
||||||
|
gobject_class->get_property = nbtk_button_get_property;
|
||||||
|
gobject_class->dispose = nbtk_button_dispose;
|
||||||
|
gobject_class->finalize = nbtk_button_finalize;
|
||||||
|
|
||||||
|
actor_class->button_press_event = nbtk_button_button_press;
|
||||||
|
actor_class->button_release_event = nbtk_button_button_release;
|
||||||
|
actor_class->enter_event = nbtk_button_enter;
|
||||||
|
actor_class->leave_event = nbtk_button_leave;
|
||||||
|
|
||||||
|
actor_class->map = nbtk_button_map;
|
||||||
|
actor_class->unmap = nbtk_button_unmap;
|
||||||
|
|
||||||
|
widget_class->draw_background = nbtk_button_draw_background;
|
||||||
|
|
||||||
|
pspec = g_param_spec_string ("label",
|
||||||
|
"Label",
|
||||||
|
"Label of the button",
|
||||||
|
NULL, G_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_LABEL, pspec);
|
||||||
|
|
||||||
|
pspec = g_param_spec_boolean ("toggle-mode",
|
||||||
|
"Toggle Mode",
|
||||||
|
"Enable or disable toggling",
|
||||||
|
FALSE, G_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_TOGGLE, pspec);
|
||||||
|
|
||||||
|
pspec = g_param_spec_boolean ("checked",
|
||||||
|
"Checked",
|
||||||
|
"Indicates if a toggle button is \"on\""
|
||||||
|
" or \"off\"",
|
||||||
|
FALSE, G_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_ACTIVE, pspec);
|
||||||
|
|
||||||
|
pspec = g_param_spec_int ("transition-duration",
|
||||||
|
"Transition Duration",
|
||||||
|
"Duration of the state transition effect",
|
||||||
|
0, G_MAXINT, 120, G_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_TRANSITION, pspec);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NbtkButton::clicked:
|
||||||
|
* @button: the object that received the signal
|
||||||
|
*
|
||||||
|
* Emitted when the user activates the button, either with a mouse press and
|
||||||
|
* release or with the keyboard.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button_signals[CLICKED] =
|
||||||
|
g_signal_new ("clicked",
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (NbtkButtonClass, clicked),
|
||||||
|
NULL, NULL,
|
||||||
|
_nbtk_marshal_VOID__VOID,
|
||||||
|
G_TYPE_NONE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_button_init (NbtkButton *button)
|
||||||
|
{
|
||||||
|
button->priv = NBTK_BUTTON_GET_PRIVATE (button);
|
||||||
|
button->priv->transition_duration = 120;
|
||||||
|
button->priv->spacing = 6;
|
||||||
|
|
||||||
|
clutter_actor_set_reactive ((ClutterActor *) button, TRUE);
|
||||||
|
|
||||||
|
g_signal_connect (button, "style-changed",
|
||||||
|
G_CALLBACK (nbtk_button_style_changed), NULL);
|
||||||
|
|
||||||
|
g_signal_connect (button, "stylable-changed",
|
||||||
|
G_CALLBACK (nbtk_button_stylable_changed), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nbtk_button_new:
|
||||||
|
*
|
||||||
|
* Create a new button
|
||||||
|
*
|
||||||
|
* Returns: a new #NbtkButton
|
||||||
|
*/
|
||||||
|
NbtkWidget *
|
||||||
|
nbtk_button_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (NBTK_TYPE_BUTTON, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nbtk_button_new_with_label:
|
||||||
|
* @text: text to set the label to
|
||||||
|
*
|
||||||
|
* Create a new #NbtkButton with the specified label
|
||||||
|
*
|
||||||
|
* Returns: a new #NbtkButton
|
||||||
|
*/
|
||||||
|
NbtkWidget *
|
||||||
|
nbtk_button_new_with_label (const gchar *text)
|
||||||
|
{
|
||||||
|
return g_object_new (NBTK_TYPE_BUTTON, "label", text, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nbtk_button_get_label:
|
||||||
|
* @button: a #NbtkButton
|
||||||
|
*
|
||||||
|
* Get the text displayed on the button
|
||||||
|
*
|
||||||
|
* Returns: the text for the button. This must not be freed by the application
|
||||||
|
*/
|
||||||
|
G_CONST_RETURN gchar *
|
||||||
|
nbtk_button_get_label (NbtkButton *button)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (NBTK_IS_BUTTON (button), NULL);
|
||||||
|
|
||||||
|
return button->priv->text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nbtk_button_set_label:
|
||||||
|
* @button: a #Nbtkbutton
|
||||||
|
* @text: text to set the label to
|
||||||
|
*
|
||||||
|
* Sets the text displayed on the button
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
nbtk_button_set_label (NbtkButton *button,
|
||||||
|
const gchar *text)
|
||||||
|
{
|
||||||
|
NbtkButtonPrivate *priv;
|
||||||
|
ClutterActor *label;
|
||||||
|
|
||||||
|
g_return_if_fail (NBTK_IS_BUTTON (button));
|
||||||
|
|
||||||
|
priv = button->priv;
|
||||||
|
|
||||||
|
g_free (priv->text);
|
||||||
|
|
||||||
|
if (text)
|
||||||
|
priv->text = g_strdup (text);
|
||||||
|
else
|
||||||
|
priv->text = g_strdup ("");
|
||||||
|
|
||||||
|
label = nbtk_bin_get_child ((NbtkBin*) button);
|
||||||
|
|
||||||
|
if (label && CLUTTER_IS_TEXT (label))
|
||||||
|
{
|
||||||
|
clutter_text_set_text (CLUTTER_TEXT (label), priv->text);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
label = g_object_new (CLUTTER_TYPE_TEXT,
|
||||||
|
"text", priv->text,
|
||||||
|
"line-alignment", PANGO_ALIGN_CENTER,
|
||||||
|
"ellipsize", PANGO_ELLIPSIZE_END,
|
||||||
|
"use-markup", TRUE,
|
||||||
|
NULL);
|
||||||
|
nbtk_bin_set_child ((NbtkBin*) button, label);
|
||||||
|
}
|
||||||
|
|
||||||
|
nbtk_stylable_changed ((NbtkStylable*) button);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (button), "label");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nbtk_button_get_toggle_mode:
|
||||||
|
* @button: a #NbtkButton
|
||||||
|
*
|
||||||
|
* Get the toggle mode status of the button.
|
||||||
|
*
|
||||||
|
* Returns: #TRUE if toggle mode is set, otherwise #FALSE
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
nbtk_button_get_toggle_mode (NbtkButton *button)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (NBTK_IS_BUTTON (button), FALSE);
|
||||||
|
|
||||||
|
return button->priv->is_toggle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nbtk_button_set_toggle_mode:
|
||||||
|
* @button: a #Nbtkbutton
|
||||||
|
* @toggle: #TRUE or #FALSE
|
||||||
|
*
|
||||||
|
* Enables or disables toggle mode for the button. In toggle mode, the active
|
||||||
|
* state will be "toggled" when the user clicks the button.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
nbtk_button_set_toggle_mode (NbtkButton *button,
|
||||||
|
gboolean toggle)
|
||||||
|
{
|
||||||
|
g_return_if_fail (NBTK_IS_BUTTON (button));
|
||||||
|
|
||||||
|
button->priv->is_toggle = toggle;
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (button), "toggle-mode");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nbtk_button_get_checked:
|
||||||
|
* @button: a #NbtkButton
|
||||||
|
*
|
||||||
|
* Get the state of the button that is in toggle mode.
|
||||||
|
*
|
||||||
|
* Returns: #TRUE if the button is checked, or #FALSE if not
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
nbtk_button_get_checked (NbtkButton *button)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (NBTK_IS_BUTTON (button), FALSE);
|
||||||
|
|
||||||
|
return button->priv->is_checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nbtk_button_set_checked:
|
||||||
|
* @button: a #Nbtkbutton
|
||||||
|
* @checked: #TRUE or #FALSE
|
||||||
|
*
|
||||||
|
* Sets the pressed state of the button. This is only really useful if the
|
||||||
|
* button has #toggle-mode mode set to #TRUE.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
nbtk_button_set_checked (NbtkButton *button,
|
||||||
|
gboolean checked)
|
||||||
|
{
|
||||||
|
g_return_if_fail (NBTK_IS_BUTTON (button));
|
||||||
|
|
||||||
|
if (button->priv->is_checked != checked)
|
||||||
|
{
|
||||||
|
button->priv->is_checked = checked;
|
||||||
|
|
||||||
|
if (checked)
|
||||||
|
nbtk_widget_set_style_pseudo_class ((NbtkWidget*) button, "checked");
|
||||||
|
else
|
||||||
|
if (button->priv->is_hover)
|
||||||
|
nbtk_widget_set_style_pseudo_class ((NbtkWidget*) button, "hover");
|
||||||
|
else
|
||||||
|
nbtk_widget_set_style_pseudo_class ((NbtkWidget*) button, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (button), "checked");
|
||||||
|
}
|
90
src/nbtk/nbtk-button.h
Normal file
90
src/nbtk/nbtk-button.h
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* nbtk-button.h: Plain button actor
|
||||||
|
*
|
||||||
|
* Copyright 2007 OpenedHand
|
||||||
|
* Copyright 2008, 2009 Intel Corporation.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU Lesser General Public License,
|
||||||
|
* version 2.1, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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 program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Written by: Emmanuele Bassi <ebassi@openedhand.com>
|
||||||
|
* Thomas Wood <thomas@linux.intel.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(NBTK_H_INSIDE) && !defined(NBTK_COMPILATION)
|
||||||
|
#error "Only <nbtk/nbtk.h> can be included directly.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __NBTK_BUTTON_H__
|
||||||
|
#define __NBTK_BUTTON_H__
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#include <nbtk/nbtk-bin.h>
|
||||||
|
|
||||||
|
#define NBTK_TYPE_BUTTON (nbtk_button_get_type ())
|
||||||
|
#define NBTK_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NBTK_TYPE_BUTTON, NbtkButton))
|
||||||
|
#define NBTK_IS_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NBTK_TYPE_BUTTON))
|
||||||
|
#define NBTK_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NBTK_TYPE_BUTTON, NbtkButtonClass))
|
||||||
|
#define NBTK_IS_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NBTK_TYPE_BUTTON))
|
||||||
|
#define NBTK_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NBTK_TYPE_BUTTON, NbtkButtonClass))
|
||||||
|
|
||||||
|
typedef struct _NbtkButton NbtkButton;
|
||||||
|
typedef struct _NbtkButtonPrivate NbtkButtonPrivate;
|
||||||
|
typedef struct _NbtkButtonClass NbtkButtonClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NbtkButton:
|
||||||
|
*
|
||||||
|
* The contents of this structure is private and should only be accessed using
|
||||||
|
* the provided API.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct _NbtkButton
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
NbtkBin parent_instance;
|
||||||
|
|
||||||
|
NbtkButtonPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _NbtkButtonClass
|
||||||
|
{
|
||||||
|
NbtkBinClass parent_class;
|
||||||
|
|
||||||
|
/* vfuncs, not signals */
|
||||||
|
void (* pressed) (NbtkButton *button);
|
||||||
|
void (* released) (NbtkButton *button);
|
||||||
|
void (* transition) (NbtkButton *button, ClutterActor *old_bg);
|
||||||
|
|
||||||
|
/* signals */
|
||||||
|
void (* clicked) (NbtkButton *button);
|
||||||
|
};
|
||||||
|
|
||||||
|
GType nbtk_button_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
NbtkWidget * nbtk_button_new (void);
|
||||||
|
NbtkWidget * nbtk_button_new_with_label (const gchar *text);
|
||||||
|
G_CONST_RETURN gchar *nbtk_button_get_label (NbtkButton *button);
|
||||||
|
void nbtk_button_set_label (NbtkButton *button,
|
||||||
|
const gchar *text);
|
||||||
|
void nbtk_button_set_toggle_mode (NbtkButton *button, gboolean toggle);
|
||||||
|
gboolean nbtk_button_get_toggle_mode (NbtkButton *button);
|
||||||
|
void nbtk_button_set_checked (NbtkButton *button, gboolean checked);
|
||||||
|
gboolean nbtk_button_get_checked (NbtkButton *button);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __NBTK_BUTTON_H__ */
|
1094
src/nbtk/nbtk-scroll-bar.c
Normal file
1094
src/nbtk/nbtk-scroll-bar.c
Normal file
File diff suppressed because it is too large
Load Diff
81
src/nbtk/nbtk-scroll-bar.h
Normal file
81
src/nbtk/nbtk-scroll-bar.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* nbtk-scroll-bar.h: Scroll bar actor
|
||||||
|
*
|
||||||
|
* Copyright 2008 OpenedHand
|
||||||
|
* Copyright 2009 Intel Corporation.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU Lesser General Public License,
|
||||||
|
* version 2.1, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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 program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Written by: Chris Lord <chris@openedhand.com>
|
||||||
|
* Port to Nbtk by: Robert Staudinger <robsta@openedhand.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(NBTK_H_INSIDE) && !defined(NBTK_COMPILATION)
|
||||||
|
#error "Only <nbtk/nbtk.h> can be included directly.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __NBTK_SCROLL_BAR_H__
|
||||||
|
#define __NBTK_SCROLL_BAR_H__
|
||||||
|
|
||||||
|
#include <nbtk/nbtk-adjustment.h>
|
||||||
|
#include <nbtk/nbtk-bin.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define NBTK_TYPE_SCROLL_BAR (nbtk_scroll_bar_get_type())
|
||||||
|
#define NBTK_SCROLL_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NBTK_TYPE_SCROLL_BAR, NbtkScrollBar))
|
||||||
|
#define NBTK_IS_SCROLL_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NBTK_TYPE_SCROLL_BAR))
|
||||||
|
#define NBTK_SCROLL_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NBTK_TYPE_SCROLL_BAR, NbtkScrollBarClass))
|
||||||
|
#define NBTK_IS_SCROLL_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NBTK_TYPE_SCROLL_BAR))
|
||||||
|
#define NBTK_SCROLL_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NBTK_TYPE_SCROLL_BAR, NbtkScrollBarClass))
|
||||||
|
|
||||||
|
typedef struct _NbtkScrollBar NbtkScrollBar;
|
||||||
|
typedef struct _NbtkScrollBarPrivate NbtkScrollBarPrivate;
|
||||||
|
typedef struct _NbtkScrollBarClass NbtkScrollBarClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NbtkScrollBar:
|
||||||
|
*
|
||||||
|
* The contents of this structure are private and should only be accessed
|
||||||
|
* through the public API.
|
||||||
|
*/
|
||||||
|
struct _NbtkScrollBar
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
NbtkBin parent_instance;
|
||||||
|
|
||||||
|
NbtkScrollBarPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _NbtkScrollBarClass
|
||||||
|
{
|
||||||
|
NbtkBinClass parent_class;
|
||||||
|
|
||||||
|
/* signals */
|
||||||
|
void (*scroll_start) (NbtkScrollBar *bar);
|
||||||
|
void (*scroll_stop) (NbtkScrollBar *bar);
|
||||||
|
};
|
||||||
|
|
||||||
|
GType nbtk_scroll_bar_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
NbtkWidget * nbtk_scroll_bar_new (NbtkAdjustment *adjustment);
|
||||||
|
void nbtk_scroll_bar_set_adjustment (NbtkScrollBar *bar,
|
||||||
|
NbtkAdjustment *adjustment);
|
||||||
|
NbtkAdjustment *nbtk_scroll_bar_get_adjustment (NbtkScrollBar *bar);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __NBTK_SCROLL_BAR_H__ */
|
836
src/nbtk/nbtk-scroll-view.c
Normal file
836
src/nbtk/nbtk-scroll-view.c
Normal file
@ -0,0 +1,836 @@
|
|||||||
|
/*
|
||||||
|
* nbtk-scroll-view.h: Container with scroll-bars
|
||||||
|
*
|
||||||
|
* Copyright 2008 OpenedHand
|
||||||
|
* Copyright 2009 Intel Corporation.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU Lesser General Public License,
|
||||||
|
* version 2.1, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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 program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Written by: Chris Lord <chris@openedhand.com>
|
||||||
|
* Port to Nbtk by: Robert Staudinger <robsta@openedhand.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nbtk-scroll-view.h"
|
||||||
|
#include "nbtk-marshal.h"
|
||||||
|
#include "nbtk-scroll-bar.h"
|
||||||
|
#include "nbtk-scrollable.h"
|
||||||
|
#include "nbtk-stylable.h"
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
|
static void clutter_container_iface_init (ClutterContainerIface *iface);
|
||||||
|
static void nbtk_stylable_iface_init (NbtkStylableIface *iface);
|
||||||
|
|
||||||
|
static ClutterContainerIface *nbtk_scroll_view_parent_iface = NULL;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_CODE (NbtkScrollView, nbtk_scroll_view, NBTK_TYPE_BIN,
|
||||||
|
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER,
|
||||||
|
clutter_container_iface_init)
|
||||||
|
G_IMPLEMENT_INTERFACE (NBTK_TYPE_STYLABLE,
|
||||||
|
nbtk_stylable_iface_init))
|
||||||
|
|
||||||
|
#define SCROLL_VIEW_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
|
||||||
|
NBTK_TYPE_SCROLL_VIEW, \
|
||||||
|
NbtkScrollViewPrivate))
|
||||||
|
|
||||||
|
struct _NbtkScrollViewPrivate
|
||||||
|
{
|
||||||
|
/* a pointer to the child; this is actually stored
|
||||||
|
* inside NbtkBin:child, but we keep it to avoid
|
||||||
|
* calling nbtk_bin_get_child() every time we need it
|
||||||
|
*/
|
||||||
|
ClutterActor *child;
|
||||||
|
|
||||||
|
ClutterActor *hscroll;
|
||||||
|
ClutterActor *vscroll;
|
||||||
|
|
||||||
|
gfloat row_size;
|
||||||
|
gfloat column_size;
|
||||||
|
|
||||||
|
gboolean row_size_set : 1;
|
||||||
|
gboolean column_size_set : 1;
|
||||||
|
guint mouse_scroll : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PROP_0,
|
||||||
|
|
||||||
|
PROP_HSCROLL,
|
||||||
|
PROP_VSCROLL,
|
||||||
|
PROP_MOUSE_SCROLL
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_scroll_view_get_property (GObject *object, guint property_id,
|
||||||
|
GValue *value, GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
NbtkScrollViewPrivate *priv = ((NbtkScrollView *)object)->priv;
|
||||||
|
|
||||||
|
switch (property_id)
|
||||||
|
{
|
||||||
|
case PROP_HSCROLL :
|
||||||
|
g_value_set_object (value, priv->hscroll);
|
||||||
|
break;
|
||||||
|
case PROP_VSCROLL :
|
||||||
|
g_value_set_object (value, priv->vscroll);
|
||||||
|
break;
|
||||||
|
case PROP_MOUSE_SCROLL:
|
||||||
|
g_value_set_boolean (value, priv->mouse_scroll);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_scroll_view_set_property (GObject *object, guint property_id,
|
||||||
|
const GValue *value, GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
switch (property_id)
|
||||||
|
{
|
||||||
|
case PROP_MOUSE_SCROLL:
|
||||||
|
nbtk_scroll_view_set_mouse_scrolling ((NbtkScrollView *) object,
|
||||||
|
g_value_get_boolean (value));
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_scroll_view_dispose (GObject *object)
|
||||||
|
{
|
||||||
|
NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (object)->priv;
|
||||||
|
|
||||||
|
priv->child = NULL;
|
||||||
|
|
||||||
|
if (priv->vscroll)
|
||||||
|
{
|
||||||
|
clutter_actor_unparent (priv->vscroll);
|
||||||
|
priv->vscroll = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->hscroll)
|
||||||
|
{
|
||||||
|
clutter_actor_unparent (priv->hscroll);
|
||||||
|
priv->hscroll = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (nbtk_scroll_view_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_scroll_view_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
G_OBJECT_CLASS (nbtk_scroll_view_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_scroll_view_paint (ClutterActor *actor)
|
||||||
|
{
|
||||||
|
NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (actor)->priv;
|
||||||
|
|
||||||
|
/* NbtkBin will paint the child */
|
||||||
|
CLUTTER_ACTOR_CLASS (nbtk_scroll_view_parent_class)->paint (actor);
|
||||||
|
|
||||||
|
/* paint our custom children */
|
||||||
|
if (CLUTTER_ACTOR_IS_VISIBLE (priv->hscroll))
|
||||||
|
clutter_actor_paint (priv->hscroll);
|
||||||
|
if (CLUTTER_ACTOR_IS_VISIBLE (priv->vscroll))
|
||||||
|
clutter_actor_paint (priv->vscroll);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_scroll_view_pick (ClutterActor *actor, const ClutterColor *color)
|
||||||
|
{
|
||||||
|
NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (actor)->priv;
|
||||||
|
|
||||||
|
/* Chain up so we get a bounding box pained (if we are reactive) */
|
||||||
|
CLUTTER_ACTOR_CLASS (nbtk_scroll_view_parent_class)->pick (actor, color);
|
||||||
|
|
||||||
|
/* paint our custom children */
|
||||||
|
if (CLUTTER_ACTOR_IS_VISIBLE (priv->hscroll))
|
||||||
|
clutter_actor_paint (priv->hscroll);
|
||||||
|
if (CLUTTER_ACTOR_IS_VISIBLE (priv->vscroll))
|
||||||
|
clutter_actor_paint (priv->vscroll);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_scroll_view_get_preferred_width (ClutterActor *actor,
|
||||||
|
gfloat for_height,
|
||||||
|
gfloat *min_width_p,
|
||||||
|
gfloat *natural_width_p)
|
||||||
|
{
|
||||||
|
NbtkPadding padding;
|
||||||
|
guint xthickness;
|
||||||
|
|
||||||
|
NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (actor)->priv;
|
||||||
|
|
||||||
|
if (!priv->child)
|
||||||
|
return;
|
||||||
|
|
||||||
|
nbtk_widget_get_padding (NBTK_WIDGET (actor), &padding);
|
||||||
|
nbtk_stylable_get (NBTK_STYLABLE (actor),
|
||||||
|
"scrollbar-width", &xthickness,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* Our natural width is the natural width of the child */
|
||||||
|
clutter_actor_get_preferred_width (priv->child,
|
||||||
|
for_height,
|
||||||
|
NULL,
|
||||||
|
natural_width_p);
|
||||||
|
|
||||||
|
/* Add space for the scroll-bar if we can determine it will be necessary */
|
||||||
|
if ((for_height >= 0) && natural_width_p)
|
||||||
|
{
|
||||||
|
gfloat natural_height;
|
||||||
|
|
||||||
|
clutter_actor_get_preferred_height (priv->child, -1.0,
|
||||||
|
NULL,
|
||||||
|
&natural_height);
|
||||||
|
if (for_height < natural_height)
|
||||||
|
*natural_width_p += xthickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add space for padding */
|
||||||
|
if (min_width_p)
|
||||||
|
*min_width_p = padding.left + padding.right;
|
||||||
|
|
||||||
|
if (natural_width_p)
|
||||||
|
*natural_width_p += padding.left + padding.right;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_scroll_view_get_preferred_height (ClutterActor *actor,
|
||||||
|
gfloat for_width,
|
||||||
|
gfloat *min_height_p,
|
||||||
|
gfloat *natural_height_p)
|
||||||
|
{
|
||||||
|
NbtkPadding padding;
|
||||||
|
guint ythickness;
|
||||||
|
|
||||||
|
NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (actor)->priv;
|
||||||
|
|
||||||
|
if (!priv->child)
|
||||||
|
return;
|
||||||
|
|
||||||
|
nbtk_widget_get_padding (NBTK_WIDGET (actor), &padding);
|
||||||
|
nbtk_stylable_get (NBTK_STYLABLE (actor),
|
||||||
|
"scrollbar-height", &ythickness,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* Our natural height is the natural height of the child */
|
||||||
|
clutter_actor_get_preferred_height (priv->child,
|
||||||
|
for_width,
|
||||||
|
NULL,
|
||||||
|
natural_height_p);
|
||||||
|
|
||||||
|
/* Add space for the scroll-bar if we can determine it will be necessary */
|
||||||
|
if ((for_width >= 0) && natural_height_p)
|
||||||
|
{
|
||||||
|
gfloat natural_width;
|
||||||
|
|
||||||
|
clutter_actor_get_preferred_width (priv->child, -1.0,
|
||||||
|
NULL,
|
||||||
|
&natural_width);
|
||||||
|
if (for_width < natural_width)
|
||||||
|
*natural_height_p += ythickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add space for padding */
|
||||||
|
if (min_height_p)
|
||||||
|
*min_height_p = padding.top + padding.bottom;
|
||||||
|
|
||||||
|
if (natural_height_p)
|
||||||
|
*natural_height_p += padding.top + padding.bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_scroll_view_allocate (ClutterActor *actor,
|
||||||
|
const ClutterActorBox *box,
|
||||||
|
ClutterAllocationFlags flags)
|
||||||
|
{
|
||||||
|
NbtkPadding padding;
|
||||||
|
ClutterActorBox child_box;
|
||||||
|
ClutterActorClass *parent_parent_class;
|
||||||
|
gfloat avail_width, avail_height, sb_width, sb_height;
|
||||||
|
|
||||||
|
NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (actor)->priv;
|
||||||
|
|
||||||
|
/* Chain up to the parent's parent class
|
||||||
|
*
|
||||||
|
* We do this because we do not want NbtkBin to allocate the child, as we
|
||||||
|
* give it a different allocation later, depending on whether the scrollbars
|
||||||
|
* are visible
|
||||||
|
*/
|
||||||
|
parent_parent_class
|
||||||
|
= g_type_class_peek_parent (nbtk_scroll_view_parent_class);
|
||||||
|
|
||||||
|
CLUTTER_ACTOR_CLASS (parent_parent_class)->
|
||||||
|
allocate (actor, box, flags);
|
||||||
|
|
||||||
|
|
||||||
|
nbtk_widget_get_padding (NBTK_WIDGET (actor), &padding);
|
||||||
|
|
||||||
|
avail_width = (box->x2 - box->x1) - padding.left - padding.right;
|
||||||
|
avail_height = (box->y2 - box->y1) - padding.top - padding.bottom;
|
||||||
|
|
||||||
|
nbtk_stylable_get (NBTK_STYLABLE (actor),
|
||||||
|
"scrollbar-width", &sb_width,
|
||||||
|
"scrollbar-height", &sb_height,
|
||||||
|
NULL);
|
||||||
|
sb_width = 28;
|
||||||
|
sb_height = 28;
|
||||||
|
|
||||||
|
if (!CLUTTER_ACTOR_IS_VISIBLE (priv->vscroll))
|
||||||
|
sb_width = 0;
|
||||||
|
|
||||||
|
if (!CLUTTER_ACTOR_IS_VISIBLE (priv->hscroll))
|
||||||
|
sb_height = 0;
|
||||||
|
|
||||||
|
/* Vertical scrollbar */
|
||||||
|
if (CLUTTER_ACTOR_IS_VISIBLE (priv->vscroll))
|
||||||
|
{
|
||||||
|
child_box.x1 = avail_width - sb_width;
|
||||||
|
child_box.y1 = padding.top;
|
||||||
|
child_box.x2 = avail_width;
|
||||||
|
child_box.y2 = child_box.y1 + avail_height - sb_height;
|
||||||
|
|
||||||
|
clutter_actor_allocate (priv->vscroll, &child_box, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Horizontal scrollbar */
|
||||||
|
if (CLUTTER_ACTOR_IS_VISIBLE (priv->hscroll))
|
||||||
|
{
|
||||||
|
child_box.x1 = padding.left;
|
||||||
|
child_box.x2 = child_box.x1 + avail_width - sb_width;
|
||||||
|
child_box.y1 = avail_height - sb_height;
|
||||||
|
child_box.y2 = avail_height;
|
||||||
|
|
||||||
|
clutter_actor_allocate (priv->hscroll, &child_box, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Child */
|
||||||
|
child_box.x1 = padding.left;
|
||||||
|
child_box.x2 = avail_width - sb_width;
|
||||||
|
child_box.y1 = padding.top;
|
||||||
|
child_box.y2 = avail_height - sb_height;
|
||||||
|
|
||||||
|
if (priv->child)
|
||||||
|
clutter_actor_allocate (priv->child, &child_box, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_scroll_view_style_changed (NbtkWidget *widget)
|
||||||
|
{
|
||||||
|
NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (widget)->priv;
|
||||||
|
|
||||||
|
nbtk_stylable_changed ((NbtkStylable *) priv->hscroll);
|
||||||
|
nbtk_stylable_changed ((NbtkStylable *) priv->vscroll);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
nbtk_scroll_view_scroll_event (ClutterActor *self,
|
||||||
|
ClutterScrollEvent *event)
|
||||||
|
{
|
||||||
|
NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (self)->priv;
|
||||||
|
gdouble lower, value, upper, step;
|
||||||
|
NbtkAdjustment *vadjustment, *hadjustment;
|
||||||
|
|
||||||
|
/* don't handle scroll events if requested not to */
|
||||||
|
if (!priv->mouse_scroll)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
hadjustment = nbtk_scroll_bar_get_adjustment (NBTK_SCROLL_BAR(priv->hscroll));
|
||||||
|
vadjustment = nbtk_scroll_bar_get_adjustment (NBTK_SCROLL_BAR(priv->vscroll));
|
||||||
|
|
||||||
|
switch (event->direction)
|
||||||
|
{
|
||||||
|
case CLUTTER_SCROLL_UP:
|
||||||
|
case CLUTTER_SCROLL_DOWN:
|
||||||
|
if (vadjustment)
|
||||||
|
g_object_get (vadjustment,
|
||||||
|
"lower", &lower,
|
||||||
|
"step-increment", &step,
|
||||||
|
"value", &value,
|
||||||
|
"upper", &upper,
|
||||||
|
NULL);
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
break;
|
||||||
|
case CLUTTER_SCROLL_LEFT:
|
||||||
|
case CLUTTER_SCROLL_RIGHT:
|
||||||
|
if (vadjustment)
|
||||||
|
g_object_get (hadjustment,
|
||||||
|
"lower", &lower,
|
||||||
|
"step-increment", &step,
|
||||||
|
"value", &value,
|
||||||
|
"upper", &upper,
|
||||||
|
NULL);
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (event->direction)
|
||||||
|
{
|
||||||
|
case CLUTTER_SCROLL_UP:
|
||||||
|
if (value == lower)
|
||||||
|
return FALSE;
|
||||||
|
else
|
||||||
|
nbtk_adjustment_set_value (vadjustment, value - step);
|
||||||
|
break;
|
||||||
|
case CLUTTER_SCROLL_DOWN:
|
||||||
|
if (value == upper)
|
||||||
|
return FALSE;
|
||||||
|
else
|
||||||
|
nbtk_adjustment_set_value (vadjustment, value + step);
|
||||||
|
break;
|
||||||
|
case CLUTTER_SCROLL_LEFT:
|
||||||
|
if (value == lower)
|
||||||
|
return FALSE;
|
||||||
|
else
|
||||||
|
nbtk_adjustment_set_value (hadjustment, value - step);
|
||||||
|
break;
|
||||||
|
case CLUTTER_SCROLL_RIGHT:
|
||||||
|
if (value == upper)
|
||||||
|
return FALSE;
|
||||||
|
else
|
||||||
|
nbtk_adjustment_set_value (hadjustment, value + step);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_scroll_view_class_init (NbtkScrollViewClass *klass)
|
||||||
|
{
|
||||||
|
GParamSpec *pspec;
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||||
|
|
||||||
|
g_type_class_add_private (klass, sizeof (NbtkScrollViewPrivate));
|
||||||
|
|
||||||
|
object_class->get_property = nbtk_scroll_view_get_property;
|
||||||
|
object_class->set_property = nbtk_scroll_view_set_property;
|
||||||
|
object_class->dispose= nbtk_scroll_view_dispose;
|
||||||
|
object_class->finalize = nbtk_scroll_view_finalize;
|
||||||
|
|
||||||
|
actor_class->paint = nbtk_scroll_view_paint;
|
||||||
|
actor_class->pick = nbtk_scroll_view_pick;
|
||||||
|
actor_class->get_preferred_width = nbtk_scroll_view_get_preferred_width;
|
||||||
|
actor_class->get_preferred_height = nbtk_scroll_view_get_preferred_height;
|
||||||
|
actor_class->allocate = nbtk_scroll_view_allocate;
|
||||||
|
actor_class->scroll_event = nbtk_scroll_view_scroll_event;
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_HSCROLL,
|
||||||
|
g_param_spec_object ("hscroll",
|
||||||
|
"NbtkScrollBar",
|
||||||
|
"Horizontal scroll indicator",
|
||||||
|
NBTK_TYPE_SCROLL_BAR,
|
||||||
|
G_PARAM_READABLE));
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_VSCROLL,
|
||||||
|
g_param_spec_object ("vscroll",
|
||||||
|
"NbtkScrollBar",
|
||||||
|
"Vertical scroll indicator",
|
||||||
|
NBTK_TYPE_SCROLL_BAR,
|
||||||
|
G_PARAM_READABLE));
|
||||||
|
|
||||||
|
pspec = g_param_spec_boolean ("enable-mouse-scrolling",
|
||||||
|
"Enable Mouse Scrolling",
|
||||||
|
"Enable automatic mouse wheel scrolling",
|
||||||
|
TRUE,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_MOUSE_SCROLL,
|
||||||
|
pspec);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_stylable_iface_init (NbtkStylableIface *iface)
|
||||||
|
{
|
||||||
|
static gboolean is_initialized = FALSE;
|
||||||
|
|
||||||
|
if (!is_initialized)
|
||||||
|
{
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
is_initialized = TRUE;
|
||||||
|
|
||||||
|
pspec = g_param_spec_uint ("scrollbar-width",
|
||||||
|
"Vertical scroll-bar thickness",
|
||||||
|
"Thickness of vertical scrollbar, in px",
|
||||||
|
0, G_MAXUINT, 24,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
nbtk_stylable_iface_install_property (iface, NBTK_TYPE_SCROLL_VIEW, pspec);
|
||||||
|
|
||||||
|
pspec = g_param_spec_uint ("scrollbar-height",
|
||||||
|
"Horizontal scroll-bar thickness",
|
||||||
|
"Thickness of horizontal scrollbar, in px",
|
||||||
|
0, G_MAXUINT, 24,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
nbtk_stylable_iface_install_property (iface, NBTK_TYPE_SCROLL_VIEW, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
child_adjustment_changed_cb (NbtkAdjustment *adjustment,
|
||||||
|
ClutterActor *bar)
|
||||||
|
{
|
||||||
|
NbtkScrollView *scroll;
|
||||||
|
gdouble lower, upper, page_size;
|
||||||
|
|
||||||
|
scroll = NBTK_SCROLL_VIEW (clutter_actor_get_parent (bar));
|
||||||
|
|
||||||
|
/* Determine if this scroll-bar should be visible */
|
||||||
|
nbtk_adjustment_get_values (adjustment, NULL,
|
||||||
|
&lower, &upper,
|
||||||
|
NULL, NULL,
|
||||||
|
&page_size);
|
||||||
|
|
||||||
|
if ((upper - lower) > page_size)
|
||||||
|
clutter_actor_show (bar);
|
||||||
|
else
|
||||||
|
clutter_actor_hide (bar);
|
||||||
|
|
||||||
|
/* Request a resize */
|
||||||
|
clutter_actor_queue_relayout (CLUTTER_ACTOR (scroll));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
child_hadjustment_notify_cb (GObject *gobject,
|
||||||
|
GParamSpec *arg1,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
NbtkAdjustment *hadjust;
|
||||||
|
|
||||||
|
ClutterActor *actor = CLUTTER_ACTOR (gobject);
|
||||||
|
NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (user_data)->priv;
|
||||||
|
|
||||||
|
hadjust = nbtk_scroll_bar_get_adjustment (NBTK_SCROLL_BAR(priv->hscroll));
|
||||||
|
if (hadjust)
|
||||||
|
g_signal_handlers_disconnect_by_func (hadjust,
|
||||||
|
child_adjustment_changed_cb,
|
||||||
|
priv->hscroll);
|
||||||
|
|
||||||
|
nbtk_scrollable_get_adjustments (NBTK_SCROLLABLE (actor), &hadjust, NULL);
|
||||||
|
if (hadjust)
|
||||||
|
{
|
||||||
|
/* Force scroll step if neede. */
|
||||||
|
if (priv->column_size_set)
|
||||||
|
{
|
||||||
|
g_object_set (hadjust,
|
||||||
|
"step-increment", priv->column_size,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
nbtk_scroll_bar_set_adjustment (NBTK_SCROLL_BAR(priv->hscroll), hadjust);
|
||||||
|
g_signal_connect (hadjust, "changed", G_CALLBACK (
|
||||||
|
child_adjustment_changed_cb), priv->hscroll);
|
||||||
|
child_adjustment_changed_cb (hadjust, priv->hscroll);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
child_vadjustment_notify_cb (GObject *gobject,
|
||||||
|
GParamSpec *arg1,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
NbtkAdjustment *vadjust;
|
||||||
|
|
||||||
|
ClutterActor *actor = CLUTTER_ACTOR (gobject);
|
||||||
|
NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (user_data)->priv;
|
||||||
|
|
||||||
|
vadjust = nbtk_scroll_bar_get_adjustment (NBTK_SCROLL_BAR(priv->vscroll));
|
||||||
|
if (vadjust)
|
||||||
|
g_signal_handlers_disconnect_by_func (vadjust,
|
||||||
|
child_adjustment_changed_cb,
|
||||||
|
priv->vscroll);
|
||||||
|
|
||||||
|
nbtk_scrollable_get_adjustments (NBTK_SCROLLABLE(actor), NULL, &vadjust);
|
||||||
|
if (vadjust)
|
||||||
|
{
|
||||||
|
/* Force scroll step if neede. */
|
||||||
|
if (priv->row_size_set)
|
||||||
|
{
|
||||||
|
g_object_set (vadjust,
|
||||||
|
"step-increment", priv->row_size,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
nbtk_scroll_bar_set_adjustment (NBTK_SCROLL_BAR(priv->vscroll), vadjust);
|
||||||
|
g_signal_connect (vadjust, "changed", G_CALLBACK (
|
||||||
|
child_adjustment_changed_cb), priv->vscroll);
|
||||||
|
child_adjustment_changed_cb (vadjust, priv->vscroll);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_scroll_view_init (NbtkScrollView *self)
|
||||||
|
{
|
||||||
|
NbtkScrollViewPrivate *priv = self->priv = SCROLL_VIEW_PRIVATE (self);
|
||||||
|
|
||||||
|
priv->hscroll = CLUTTER_ACTOR (nbtk_scroll_bar_new (NULL));
|
||||||
|
priv->vscroll = g_object_new (NBTK_TYPE_SCROLL_BAR, "vertical", TRUE, NULL);
|
||||||
|
|
||||||
|
clutter_actor_set_parent (priv->hscroll, CLUTTER_ACTOR (self));
|
||||||
|
clutter_actor_set_parent (priv->vscroll, CLUTTER_ACTOR (self));
|
||||||
|
|
||||||
|
/* mouse scroll is enabled by default, so we also need to be reactive */
|
||||||
|
priv->mouse_scroll = TRUE;
|
||||||
|
g_object_set (G_OBJECT (self), "reactive", TRUE, "clip-to-allocation", TRUE,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
g_signal_connect (self, "style-changed",
|
||||||
|
G_CALLBACK (nbtk_scroll_view_style_changed), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_scroll_view_add (ClutterContainer *container,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
NbtkScrollView *self = NBTK_SCROLL_VIEW (container);
|
||||||
|
NbtkScrollViewPrivate *priv = self->priv;
|
||||||
|
|
||||||
|
if (NBTK_IS_SCROLLABLE (actor))
|
||||||
|
{
|
||||||
|
priv->child = actor;
|
||||||
|
|
||||||
|
/* chain up to NbtkBin::add() */
|
||||||
|
nbtk_scroll_view_parent_iface->add (container, actor);
|
||||||
|
|
||||||
|
/* Get adjustments for scroll-bars */
|
||||||
|
g_signal_connect (actor, "notify::hadjustment",
|
||||||
|
G_CALLBACK (child_hadjustment_notify_cb),
|
||||||
|
container);
|
||||||
|
g_signal_connect (actor, "notify::vadjustment",
|
||||||
|
G_CALLBACK (child_vadjustment_notify_cb),
|
||||||
|
container);
|
||||||
|
child_hadjustment_notify_cb (G_OBJECT (actor), NULL, container);
|
||||||
|
child_vadjustment_notify_cb (G_OBJECT (actor), NULL, container);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_warning ("Attempting to add an actor of type %s to "
|
||||||
|
"a NbtkScrollView, but the actor does "
|
||||||
|
"not implement NbtkScrollable.",
|
||||||
|
g_type_name (G_OBJECT_TYPE (actor)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_scroll_view_remove (ClutterContainer *container,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (container)->priv;
|
||||||
|
|
||||||
|
if (actor == priv->child)
|
||||||
|
{
|
||||||
|
g_object_ref (priv->child);
|
||||||
|
|
||||||
|
/* chain up to NbtkBin::remove() */
|
||||||
|
nbtk_scroll_view_parent_iface->remove (container, actor);
|
||||||
|
|
||||||
|
g_signal_handlers_disconnect_by_func (priv->child,
|
||||||
|
child_hadjustment_notify_cb,
|
||||||
|
container);
|
||||||
|
g_signal_handlers_disconnect_by_func (priv->child,
|
||||||
|
child_vadjustment_notify_cb,
|
||||||
|
container);
|
||||||
|
nbtk_scrollable_set_adjustments ((NbtkScrollable*) priv->child, NULL, NULL);
|
||||||
|
|
||||||
|
g_object_unref (priv->child);
|
||||||
|
priv->child = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_scroll_view_foreach_with_internals (ClutterContainer *container,
|
||||||
|
ClutterCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (container)->priv;
|
||||||
|
|
||||||
|
if (priv->child != NULL)
|
||||||
|
callback (priv->child, user_data);
|
||||||
|
|
||||||
|
if (priv->hscroll != NULL)
|
||||||
|
callback (priv->hscroll, user_data);
|
||||||
|
|
||||||
|
if (priv->vscroll != NULL)
|
||||||
|
callback (priv->vscroll, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_container_iface_init (ClutterContainerIface *iface)
|
||||||
|
{
|
||||||
|
/* store a pointer to the NbtkBin implementation of
|
||||||
|
* ClutterContainer so that we can chain up when
|
||||||
|
* overriding the methods
|
||||||
|
*/
|
||||||
|
nbtk_scroll_view_parent_iface = g_type_interface_peek_parent (iface);
|
||||||
|
|
||||||
|
iface->add = nbtk_scroll_view_add;
|
||||||
|
iface->remove = nbtk_scroll_view_remove;
|
||||||
|
iface->foreach_with_internals = nbtk_scroll_view_foreach_with_internals;
|
||||||
|
}
|
||||||
|
|
||||||
|
NbtkWidget *
|
||||||
|
nbtk_scroll_view_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (NBTK_TYPE_SCROLL_VIEW, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClutterActor *
|
||||||
|
nbtk_scroll_view_get_hscroll_bar (NbtkScrollView *scroll)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (NBTK_IS_SCROLL_VIEW (scroll), NULL);
|
||||||
|
|
||||||
|
return scroll->priv->hscroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClutterActor *
|
||||||
|
nbtk_scroll_view_get_vscroll_bar (NbtkScrollView *scroll)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (NBTK_IS_SCROLL_VIEW (scroll), NULL);
|
||||||
|
|
||||||
|
return scroll->priv->vscroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfloat
|
||||||
|
nbtk_scroll_view_get_column_size (NbtkScrollView *scroll)
|
||||||
|
{
|
||||||
|
NbtkAdjustment *adjustment;
|
||||||
|
gdouble column_size;
|
||||||
|
|
||||||
|
g_return_val_if_fail (scroll, 0);
|
||||||
|
|
||||||
|
adjustment = nbtk_scroll_bar_get_adjustment (
|
||||||
|
NBTK_SCROLL_BAR (scroll->priv->hscroll));
|
||||||
|
g_object_get (adjustment,
|
||||||
|
"step-increment", &column_size,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
return column_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nbtk_scroll_view_set_column_size (NbtkScrollView *scroll,
|
||||||
|
gfloat column_size)
|
||||||
|
{
|
||||||
|
NbtkAdjustment *adjustment;
|
||||||
|
|
||||||
|
g_return_if_fail (scroll);
|
||||||
|
|
||||||
|
if (column_size < 0)
|
||||||
|
{
|
||||||
|
scroll->priv->column_size_set = FALSE;
|
||||||
|
scroll->priv->column_size = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scroll->priv->column_size_set = TRUE;
|
||||||
|
scroll->priv->column_size = column_size;
|
||||||
|
|
||||||
|
adjustment = nbtk_scroll_bar_get_adjustment (
|
||||||
|
NBTK_SCROLL_BAR (scroll->priv->hscroll));
|
||||||
|
|
||||||
|
if (adjustment)
|
||||||
|
g_object_set (adjustment,
|
||||||
|
"step-increment", (gdouble) scroll->priv->column_size,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gfloat
|
||||||
|
nbtk_scroll_view_get_row_size (NbtkScrollView *scroll)
|
||||||
|
{
|
||||||
|
NbtkAdjustment *adjustment;
|
||||||
|
gdouble row_size;
|
||||||
|
|
||||||
|
g_return_val_if_fail (scroll, 0);
|
||||||
|
|
||||||
|
adjustment = nbtk_scroll_bar_get_adjustment (
|
||||||
|
NBTK_SCROLL_BAR (scroll->priv->vscroll));
|
||||||
|
g_object_get (adjustment,
|
||||||
|
"step-increment", &row_size,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
return row_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nbtk_scroll_view_set_row_size (NbtkScrollView *scroll,
|
||||||
|
gfloat row_size)
|
||||||
|
{
|
||||||
|
NbtkAdjustment *adjustment;
|
||||||
|
|
||||||
|
g_return_if_fail (scroll);
|
||||||
|
|
||||||
|
if (row_size < 0)
|
||||||
|
{
|
||||||
|
scroll->priv->row_size_set = FALSE;
|
||||||
|
scroll->priv->row_size = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scroll->priv->row_size_set = TRUE;
|
||||||
|
scroll->priv->row_size = row_size;
|
||||||
|
|
||||||
|
adjustment = nbtk_scroll_bar_get_adjustment (
|
||||||
|
NBTK_SCROLL_BAR (scroll->priv->vscroll));
|
||||||
|
|
||||||
|
if (adjustment)
|
||||||
|
g_object_set (adjustment,
|
||||||
|
"step-increment", (gdouble) scroll->priv->row_size,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nbtk_scroll_view_set_mouse_scrolling (NbtkScrollView *scroll,
|
||||||
|
gboolean enabled)
|
||||||
|
{
|
||||||
|
NbtkScrollViewPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (NBTK_IS_SCROLL_VIEW (scroll));
|
||||||
|
|
||||||
|
priv = NBTK_SCROLL_VIEW (scroll)->priv;
|
||||||
|
|
||||||
|
if (priv->mouse_scroll != enabled)
|
||||||
|
{
|
||||||
|
priv->mouse_scroll = enabled;
|
||||||
|
|
||||||
|
/* make sure we can receive mouse wheel events */
|
||||||
|
if (enabled)
|
||||||
|
clutter_actor_set_reactive ((ClutterActor *) scroll, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
nbtk_scroll_view_get_mouse_scrolling (NbtkScrollView *scroll)
|
||||||
|
{
|
||||||
|
NbtkScrollViewPrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (NBTK_IS_SCROLL_VIEW (scroll), FALSE);
|
||||||
|
|
||||||
|
priv = NBTK_SCROLL_VIEW (scroll)->priv;
|
||||||
|
|
||||||
|
return priv->mouse_scroll;
|
||||||
|
}
|
88
src/nbtk/nbtk-scroll-view.h
Normal file
88
src/nbtk/nbtk-scroll-view.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* nbtk-scroll-view.h: Container with scroll-bars
|
||||||
|
*
|
||||||
|
* Copyright 2008 OpenedHand
|
||||||
|
* Copyright 2009 Intel Corporation.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU Lesser General Public License,
|
||||||
|
* version 2.1, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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 program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Written by: Chris Lord <chris@openedhand.com>
|
||||||
|
* Port to Nbtk by: Robert Staudinger <robsta@openedhand.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(NBTK_H_INSIDE) && !defined(NBTK_COMPILATION)
|
||||||
|
#error "Only <nbtk/nbtk.h> can be included directly.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __NBTK_SCROLL_VIEW_H__
|
||||||
|
#define __NBTK_SCROLL_VIEW_H__
|
||||||
|
|
||||||
|
#include <nbtk/nbtk-bin.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define NBTK_TYPE_SCROLL_VIEW (nbtk_scroll_view_get_type())
|
||||||
|
#define NBTK_SCROLL_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NBTK_TYPE_SCROLL_VIEW, NbtkScrollView))
|
||||||
|
#define NBTK_IS_SCROLL_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NBTK_TYPE_SCROLL_VIEW))
|
||||||
|
#define NBTK_SCROLL_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NBTK_TYPE_SCROLL_VIEW, NbtkScrollViewClass))
|
||||||
|
#define NBTK_IS_SCROLL_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NBTK_TYPE_SCROLL_VIEW))
|
||||||
|
#define NBTK_SCROLL_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NBTK_TYPE_SCROLL_VIEW, NbtkScrollViewClass))
|
||||||
|
|
||||||
|
typedef struct _NbtkScrollView NbtkScrollView;
|
||||||
|
typedef struct _NbtkScrollViewPrivate NbtkScrollViewPrivate;
|
||||||
|
typedef struct _NbtkScrollViewClass NbtkScrollViewClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NbtkScrollView:
|
||||||
|
*
|
||||||
|
* The contents of this structure are private and should only be accessed
|
||||||
|
* through the public API.
|
||||||
|
*/
|
||||||
|
struct _NbtkScrollView
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
NbtkBin parent_instance;
|
||||||
|
|
||||||
|
NbtkScrollViewPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _NbtkScrollViewClass
|
||||||
|
{
|
||||||
|
NbtkBinClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType nbtk_scroll_view_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
NbtkWidget * nbtk_scroll_view_new (void);
|
||||||
|
|
||||||
|
ClutterActor * nbtk_scroll_view_get_hscroll_bar (NbtkScrollView *scroll);
|
||||||
|
ClutterActor * nbtk_scroll_view_get_vscroll_bar (NbtkScrollView *scroll);
|
||||||
|
ClutterActor * nbtk_scroll_view_get_child (NbtkScrollView *scroll);
|
||||||
|
|
||||||
|
gfloat nbtk_scroll_view_get_column_size (NbtkScrollView *scroll);
|
||||||
|
void nbtk_scroll_view_set_column_size (NbtkScrollView *scroll,
|
||||||
|
gfloat column_size);
|
||||||
|
|
||||||
|
gfloat nbtk_scroll_view_get_row_size (NbtkScrollView *scroll);
|
||||||
|
void nbtk_scroll_view_set_row_size (NbtkScrollView *scroll,
|
||||||
|
gfloat row_size);
|
||||||
|
|
||||||
|
void nbtk_scroll_view_set_mouse_scrolling (NbtkScrollView *scroll, gboolean enabled);
|
||||||
|
gboolean nbtk_scroll_view_get_mouse_scrolling (NbtkScrollView *scroll);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __NBTK_SCROLL_VIEW_H__ */
|
88
src/nbtk/nbtk-scrollable.c
Normal file
88
src/nbtk/nbtk-scrollable.c
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* nbtk-scrollable.c: Scrollable interface
|
||||||
|
*
|
||||||
|
* Copyright 2008 OpenedHand
|
||||||
|
* Copyright 2009 Intel Corporation.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU Lesser General Public License,
|
||||||
|
* version 2.1, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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 program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Written by: Chris Lord <chris@openedhand.com>
|
||||||
|
* Port to Nbtk by: Robert Staudinger <robsta@openedhand.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nbtk-scrollable.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_scrollable_base_init (gpointer g_iface)
|
||||||
|
{
|
||||||
|
static gboolean initialized = FALSE;
|
||||||
|
|
||||||
|
if (!initialized)
|
||||||
|
{
|
||||||
|
g_object_interface_install_property (g_iface,
|
||||||
|
g_param_spec_object ("hadjustment",
|
||||||
|
"NbtkAdjustment",
|
||||||
|
"Horizontal adjustment",
|
||||||
|
NBTK_TYPE_ADJUSTMENT,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
|
||||||
|
g_object_interface_install_property (g_iface,
|
||||||
|
g_param_spec_object ("vadjustment",
|
||||||
|
"NbtkAdjustment",
|
||||||
|
"Vertical adjustment",
|
||||||
|
NBTK_TYPE_ADJUSTMENT,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
|
||||||
|
initialized = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GType
|
||||||
|
nbtk_scrollable_get_type (void)
|
||||||
|
{
|
||||||
|
static GType type = 0;
|
||||||
|
if (type == 0)
|
||||||
|
{
|
||||||
|
static const GTypeInfo info =
|
||||||
|
{
|
||||||
|
sizeof (NbtkScrollableInterface),
|
||||||
|
nbtk_scrollable_base_init, /* base_init */
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
type = g_type_register_static (G_TYPE_INTERFACE,
|
||||||
|
"NbtkScrollable", &info, 0);
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nbtk_scrollable_set_adjustments (NbtkScrollable *scrollable,
|
||||||
|
NbtkAdjustment *hadjustment,
|
||||||
|
NbtkAdjustment *vadjustment)
|
||||||
|
{
|
||||||
|
NBTK_SCROLLABLE_GET_INTERFACE (scrollable)->set_adjustments (scrollable,
|
||||||
|
hadjustment,
|
||||||
|
vadjustment);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nbtk_scrollable_get_adjustments (NbtkScrollable *scrollable,
|
||||||
|
NbtkAdjustment **hadjustment,
|
||||||
|
NbtkAdjustment **vadjustment)
|
||||||
|
{
|
||||||
|
NBTK_SCROLLABLE_GET_INTERFACE (scrollable)->get_adjustments (scrollable,
|
||||||
|
hadjustment,
|
||||||
|
vadjustment);
|
||||||
|
}
|
69
src/nbtk/nbtk-scrollable.h
Normal file
69
src/nbtk/nbtk-scrollable.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* nbtk-scrollable.h: Scrollable interface
|
||||||
|
*
|
||||||
|
* Copyright 2008 OpenedHand
|
||||||
|
* Copyright 2009 Intel Corporation.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU Lesser General Public License,
|
||||||
|
* version 2.1, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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 program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Written by: Chris Lord <chris@openedhand.com>
|
||||||
|
* Port to Nbtk by: Robert Staudinger <robsta@openedhand.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(NBTK_H_INSIDE) && !defined(NBTK_COMPILATION)
|
||||||
|
#error "Only <nbtk/nbtk.h> can be included directly.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __NBTK_SCROLLABLE_H__
|
||||||
|
#define __NBTK_SCROLLABLE_H__
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <nbtk/nbtk-adjustment.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define NBTK_TYPE_SCROLLABLE (nbtk_scrollable_get_type ())
|
||||||
|
#define NBTK_SCROLLABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NBTK_TYPE_SCROLLABLE, NbtkScrollable))
|
||||||
|
#define NBTK_IS_SCROLLABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NBTK_TYPE_SCROLLABLE))
|
||||||
|
#define NBTK_SCROLLABLE_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), NBTK_TYPE_SCROLLABLE, NbtkScrollableInterface))
|
||||||
|
|
||||||
|
typedef struct _NbtkScrollable NbtkScrollable; /* Dummy object */
|
||||||
|
typedef struct _NbtkScrollableInterface NbtkScrollableInterface;
|
||||||
|
|
||||||
|
struct _NbtkScrollableInterface
|
||||||
|
{
|
||||||
|
GTypeInterface parent;
|
||||||
|
|
||||||
|
void (* set_adjustments) (NbtkScrollable *scrollable,
|
||||||
|
NbtkAdjustment *hadjustment,
|
||||||
|
NbtkAdjustment *vadjustment);
|
||||||
|
void (* get_adjustments) (NbtkScrollable *scrollable,
|
||||||
|
NbtkAdjustment **hadjustment,
|
||||||
|
NbtkAdjustment **vadjustment);
|
||||||
|
};
|
||||||
|
|
||||||
|
GType nbtk_scrollable_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
void nbtk_scrollable_set_adjustments (NbtkScrollable *scrollable,
|
||||||
|
NbtkAdjustment *hadjustment,
|
||||||
|
NbtkAdjustment *vadjustment);
|
||||||
|
void nbtk_scrollable_get_adjustments (NbtkScrollable *scrollable,
|
||||||
|
NbtkAdjustment **hadjustment,
|
||||||
|
NbtkAdjustment **vadjustment);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __NBTK_SCROLLABLE_H__ */
|
668
src/nbtk/nbtk-viewport.c
Normal file
668
src/nbtk/nbtk-viewport.c
Normal file
@ -0,0 +1,668 @@
|
|||||||
|
/*
|
||||||
|
* nbtk-viewport.c: Viewport actor
|
||||||
|
*
|
||||||
|
* Copyright 2008 OpenedHand
|
||||||
|
* Copyright 2009 Intel Corporation.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU Lesser General Public License,
|
||||||
|
* version 2.1, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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 program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Written by: Chris Lord <chris@openedhand.com>
|
||||||
|
* Port to Nbtk by: Robert Staudinger <robsta@openedhand.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
|
#include "nbtk-viewport.h"
|
||||||
|
#include "nbtk-adjustment.h"
|
||||||
|
#include "nbtk-scrollable.h"
|
||||||
|
#include "nbtk-private.h"
|
||||||
|
#include "nbtk-bin.h"
|
||||||
|
|
||||||
|
static void scrollable_interface_init (NbtkScrollableInterface *iface);
|
||||||
|
|
||||||
|
static void scrollable_set_adjustments (NbtkScrollable *scrollable,
|
||||||
|
NbtkAdjustment *hadjustment,
|
||||||
|
NbtkAdjustment *vadjustment);
|
||||||
|
|
||||||
|
static void scrollable_get_adjustments (NbtkScrollable *scrollable,
|
||||||
|
NbtkAdjustment **hadjustment,
|
||||||
|
NbtkAdjustment **vadjustment);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_CODE (NbtkViewport, nbtk_viewport, NBTK_TYPE_BIN,
|
||||||
|
G_IMPLEMENT_INTERFACE (NBTK_TYPE_SCROLLABLE,
|
||||||
|
scrollable_interface_init))
|
||||||
|
|
||||||
|
#define VIEWPORT_PRIVATE(o) \
|
||||||
|
(G_TYPE_INSTANCE_GET_PRIVATE ((o), NBTK_TYPE_VIEWPORT, \
|
||||||
|
NbtkViewportPrivate))
|
||||||
|
|
||||||
|
struct _NbtkViewportPrivate
|
||||||
|
{
|
||||||
|
gfloat x;
|
||||||
|
gfloat y;
|
||||||
|
gfloat z;
|
||||||
|
|
||||||
|
NbtkAdjustment *hadjustment;
|
||||||
|
NbtkAdjustment *vadjustment;
|
||||||
|
|
||||||
|
gboolean sync_adjustments;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
|
||||||
|
PROP_X_ORIGIN,
|
||||||
|
PROP_Y_ORIGIN,
|
||||||
|
PROP_Z_ORIGIN,
|
||||||
|
PROP_HADJUST,
|
||||||
|
PROP_VADJUST,
|
||||||
|
PROP_SYNC_ADJUST
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_viewport_get_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
NbtkAdjustment *adjustment;
|
||||||
|
|
||||||
|
NbtkViewportPrivate *priv = NBTK_VIEWPORT (object)->priv;
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_X_ORIGIN:
|
||||||
|
g_value_set_int (value, (int) priv->x);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_Y_ORIGIN:
|
||||||
|
g_value_set_int (value, (int) priv->y);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_Z_ORIGIN:
|
||||||
|
g_value_set_int (value, (int) priv->z);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_HADJUST :
|
||||||
|
scrollable_get_adjustments (NBTK_SCROLLABLE (object), &adjustment, NULL);
|
||||||
|
g_value_set_object (value, adjustment);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_VADJUST :
|
||||||
|
scrollable_get_adjustments (NBTK_SCROLLABLE (object), NULL, &adjustment);
|
||||||
|
g_value_set_object (value, adjustment);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_SYNC_ADJUST :
|
||||||
|
g_value_set_boolean (value, priv->sync_adjustments);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_viewport_set_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
NbtkViewport *viewport = NBTK_VIEWPORT (object);
|
||||||
|
NbtkViewportPrivate *priv = viewport->priv;
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_X_ORIGIN:
|
||||||
|
nbtk_viewport_set_originu (viewport,
|
||||||
|
g_value_get_int (value),
|
||||||
|
priv->y,
|
||||||
|
priv->z);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_Y_ORIGIN:
|
||||||
|
nbtk_viewport_set_originu (viewport,
|
||||||
|
priv->x,
|
||||||
|
g_value_get_int (value),
|
||||||
|
priv->z);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_Z_ORIGIN:
|
||||||
|
nbtk_viewport_set_originu (viewport,
|
||||||
|
priv->x,
|
||||||
|
priv->y,
|
||||||
|
g_value_get_int (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_HADJUST :
|
||||||
|
scrollable_set_adjustments (NBTK_SCROLLABLE (object),
|
||||||
|
g_value_get_object (value),
|
||||||
|
priv->vadjustment);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_VADJUST :
|
||||||
|
scrollable_set_adjustments (NBTK_SCROLLABLE (object),
|
||||||
|
priv->hadjustment,
|
||||||
|
g_value_get_object (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_SYNC_ADJUST :
|
||||||
|
priv->sync_adjustments = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_viewport_dispose (GObject *gobject)
|
||||||
|
{
|
||||||
|
NbtkViewportPrivate *priv = NBTK_VIEWPORT (gobject)->priv;
|
||||||
|
|
||||||
|
if (priv->hadjustment)
|
||||||
|
{
|
||||||
|
g_object_unref (priv->hadjustment);
|
||||||
|
priv->hadjustment = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->vadjustment)
|
||||||
|
{
|
||||||
|
g_object_unref (priv->vadjustment);
|
||||||
|
priv->vadjustment = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (nbtk_viewport_parent_class)->dispose (gobject);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ClutterActor *
|
||||||
|
get_child_and_natural_size (NbtkViewport *self,
|
||||||
|
gfloat *natural_width,
|
||||||
|
gfloat *natural_height)
|
||||||
|
{
|
||||||
|
/* NbtkBin is a single-child container,
|
||||||
|
* let it grow as big as it wants. */
|
||||||
|
ClutterActor *child;
|
||||||
|
ClutterRequestMode mode;
|
||||||
|
|
||||||
|
child = nbtk_bin_get_child (NBTK_BIN (self));
|
||||||
|
if (child)
|
||||||
|
{
|
||||||
|
|
||||||
|
g_object_get (G_OBJECT (child), "request-mode", &mode, NULL);
|
||||||
|
if (mode == CLUTTER_REQUEST_HEIGHT_FOR_WIDTH)
|
||||||
|
{
|
||||||
|
clutter_actor_get_preferred_width (child, -1, NULL,
|
||||||
|
natural_width);
|
||||||
|
clutter_actor_get_preferred_height (child, *natural_width, NULL,
|
||||||
|
natural_height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clutter_actor_get_preferred_height (child, -1, NULL,
|
||||||
|
natural_height);
|
||||||
|
clutter_actor_get_preferred_width (child, *natural_height, NULL,
|
||||||
|
natural_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_viewport_paint (ClutterActor *self)
|
||||||
|
{
|
||||||
|
NbtkViewportPrivate *priv = NBTK_VIEWPORT (self)->priv;
|
||||||
|
|
||||||
|
cogl_push_matrix ();
|
||||||
|
|
||||||
|
cogl_translate ((int) priv->x * -1,
|
||||||
|
(int) priv->y * -1,
|
||||||
|
(int) priv->z * -1);
|
||||||
|
|
||||||
|
CLUTTER_ACTOR_CLASS (nbtk_viewport_parent_class)->paint (self);
|
||||||
|
|
||||||
|
cogl_pop_matrix ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_viewport_pick (ClutterActor *self,
|
||||||
|
const ClutterColor *color)
|
||||||
|
{
|
||||||
|
nbtk_viewport_paint (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_viewport_allocate (ClutterActor *self,
|
||||||
|
const ClutterActorBox *box,
|
||||||
|
ClutterAllocationFlags flags)
|
||||||
|
{
|
||||||
|
NbtkViewportPrivate *priv = NBTK_VIEWPORT (self)->priv;
|
||||||
|
ClutterActor *child;
|
||||||
|
ClutterActorBox natural_box;
|
||||||
|
gfloat natural_width, natural_height;
|
||||||
|
gfloat available_width, available_height;
|
||||||
|
|
||||||
|
/* Chain up. */
|
||||||
|
CLUTTER_ACTOR_CLASS (nbtk_viewport_parent_class)->
|
||||||
|
allocate (self, box, flags);
|
||||||
|
|
||||||
|
available_width = box->x2 - box->x1;
|
||||||
|
available_height = box->y2 - box->y1;
|
||||||
|
|
||||||
|
natural_box.x1 = 0;
|
||||||
|
natural_box.y1 = 0;
|
||||||
|
|
||||||
|
if (NULL != (child = get_child_and_natural_size (NBTK_VIEWPORT (self),
|
||||||
|
&natural_width,
|
||||||
|
&natural_height)))
|
||||||
|
{
|
||||||
|
natural_box.x2 = natural_width;
|
||||||
|
natural_box.y2 = natural_height;
|
||||||
|
clutter_actor_allocate (child, &natural_box, flags);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
natural_box.x2 = available_width;
|
||||||
|
natural_box.y2 = available_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Refresh adjustments */
|
||||||
|
if (priv->sync_adjustments)
|
||||||
|
{
|
||||||
|
gdouble prev_value;
|
||||||
|
|
||||||
|
if (priv->hadjustment)
|
||||||
|
{
|
||||||
|
g_object_set (G_OBJECT (priv->hadjustment),
|
||||||
|
"lower", 0.0,
|
||||||
|
"page-size", available_width,
|
||||||
|
"upper", natural_width,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* Make sure value is clamped */
|
||||||
|
prev_value = nbtk_adjustment_get_value (priv->hadjustment);
|
||||||
|
nbtk_adjustment_set_value (priv->hadjustment, prev_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->vadjustment)
|
||||||
|
{
|
||||||
|
g_object_set (G_OBJECT (priv->vadjustment),
|
||||||
|
"lower", 0.0,
|
||||||
|
"page-size", available_height,
|
||||||
|
"upper", natural_height,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
prev_value = nbtk_adjustment_get_value (priv->vadjustment);
|
||||||
|
nbtk_adjustment_set_value (priv->vadjustment, prev_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_viewport_class_init (NbtkViewportClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||||
|
|
||||||
|
g_type_class_add_private (klass, sizeof (NbtkViewportPrivate));
|
||||||
|
|
||||||
|
gobject_class->get_property = nbtk_viewport_get_property;
|
||||||
|
gobject_class->set_property = nbtk_viewport_set_property;
|
||||||
|
gobject_class->dispose = nbtk_viewport_dispose;
|
||||||
|
|
||||||
|
actor_class->paint = nbtk_viewport_paint;
|
||||||
|
actor_class->pick = nbtk_viewport_pick;
|
||||||
|
actor_class->allocate = nbtk_viewport_allocate;
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_X_ORIGIN,
|
||||||
|
g_param_spec_int ("x-origin",
|
||||||
|
"X Origin",
|
||||||
|
"Origin's X coordinate in pixels",
|
||||||
|
-G_MAXINT, G_MAXINT,
|
||||||
|
0,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_Y_ORIGIN,
|
||||||
|
g_param_spec_int ("y-origin",
|
||||||
|
"Y Origin",
|
||||||
|
"Origin's Y coordinate in pixels",
|
||||||
|
-G_MAXINT, G_MAXINT,
|
||||||
|
0,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_Z_ORIGIN,
|
||||||
|
g_param_spec_int ("z-origin",
|
||||||
|
"Z Origin",
|
||||||
|
"Origin's Z coordinate in pixels",
|
||||||
|
-G_MAXINT, G_MAXINT,
|
||||||
|
0,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_SYNC_ADJUST,
|
||||||
|
g_param_spec_boolean ("sync-adjustments",
|
||||||
|
"Synchronise "
|
||||||
|
"adjustments",
|
||||||
|
"Whether to "
|
||||||
|
"synchronise "
|
||||||
|
"adjustments with "
|
||||||
|
"viewport size",
|
||||||
|
TRUE,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
|
||||||
|
g_object_class_override_property (gobject_class,
|
||||||
|
PROP_HADJUST,
|
||||||
|
"hadjustment");
|
||||||
|
|
||||||
|
g_object_class_override_property (gobject_class,
|
||||||
|
PROP_VADJUST,
|
||||||
|
"vadjustment");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
hadjustment_value_notify_cb (NbtkAdjustment *adjustment,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
NbtkViewport *viewport)
|
||||||
|
{
|
||||||
|
NbtkViewportPrivate *priv = viewport->priv;
|
||||||
|
gdouble value;
|
||||||
|
|
||||||
|
value = nbtk_adjustment_get_value (adjustment);
|
||||||
|
|
||||||
|
nbtk_viewport_set_originu (viewport,
|
||||||
|
(float) (value),
|
||||||
|
priv->y,
|
||||||
|
priv->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vadjustment_value_notify_cb (NbtkAdjustment *adjustment, GParamSpec *arg1,
|
||||||
|
NbtkViewport *viewport)
|
||||||
|
{
|
||||||
|
NbtkViewportPrivate *priv = viewport->priv;
|
||||||
|
gdouble value;
|
||||||
|
|
||||||
|
value = nbtk_adjustment_get_value (adjustment);
|
||||||
|
|
||||||
|
nbtk_viewport_set_originu (viewport,
|
||||||
|
priv->x,
|
||||||
|
(float) (value),
|
||||||
|
priv->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
scrollable_set_adjustments (NbtkScrollable *scrollable,
|
||||||
|
NbtkAdjustment *hadjustment,
|
||||||
|
NbtkAdjustment *vadjustment)
|
||||||
|
{
|
||||||
|
NbtkViewportPrivate *priv = NBTK_VIEWPORT (scrollable)->priv;
|
||||||
|
|
||||||
|
if (hadjustment != priv->hadjustment)
|
||||||
|
{
|
||||||
|
if (priv->hadjustment)
|
||||||
|
{
|
||||||
|
g_signal_handlers_disconnect_by_func (priv->hadjustment,
|
||||||
|
hadjustment_value_notify_cb,
|
||||||
|
scrollable);
|
||||||
|
g_object_unref (priv->hadjustment);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hadjustment)
|
||||||
|
{
|
||||||
|
g_object_ref (hadjustment);
|
||||||
|
g_signal_connect (hadjustment, "notify::value",
|
||||||
|
G_CALLBACK (hadjustment_value_notify_cb),
|
||||||
|
scrollable);
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->hadjustment = hadjustment;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vadjustment != priv->vadjustment)
|
||||||
|
{
|
||||||
|
if (priv->vadjustment)
|
||||||
|
{
|
||||||
|
g_signal_handlers_disconnect_by_func (priv->vadjustment,
|
||||||
|
vadjustment_value_notify_cb,
|
||||||
|
scrollable);
|
||||||
|
g_object_unref (priv->vadjustment);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vadjustment)
|
||||||
|
{
|
||||||
|
g_object_ref (vadjustment);
|
||||||
|
g_signal_connect (vadjustment, "notify::value",
|
||||||
|
G_CALLBACK (vadjustment_value_notify_cb),
|
||||||
|
scrollable);
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->vadjustment = vadjustment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
scrollable_get_adjustments (NbtkScrollable *scrollable,
|
||||||
|
NbtkAdjustment **hadjustment,
|
||||||
|
NbtkAdjustment **vadjustment)
|
||||||
|
{
|
||||||
|
NbtkViewportPrivate *priv;
|
||||||
|
ClutterActor *actor, *stage;
|
||||||
|
|
||||||
|
g_return_if_fail (NBTK_IS_VIEWPORT (scrollable));
|
||||||
|
|
||||||
|
priv = ((NbtkViewport *) scrollable)->priv;
|
||||||
|
|
||||||
|
actor = CLUTTER_ACTOR (scrollable);
|
||||||
|
stage = clutter_actor_get_stage (actor);
|
||||||
|
if (G_UNLIKELY (stage == NULL))
|
||||||
|
stage = clutter_stage_get_default ();
|
||||||
|
|
||||||
|
if (hadjustment)
|
||||||
|
{
|
||||||
|
if (priv->hadjustment)
|
||||||
|
*hadjustment = priv->hadjustment;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NbtkAdjustment *adjustment;
|
||||||
|
gdouble width, stage_width, increment;
|
||||||
|
|
||||||
|
width = clutter_actor_get_width (actor);
|
||||||
|
stage_width = clutter_actor_get_width (stage);
|
||||||
|
increment = MAX (1.0, MIN (stage_width, width));
|
||||||
|
|
||||||
|
adjustment = nbtk_adjustment_new (priv->x,
|
||||||
|
0,
|
||||||
|
width,
|
||||||
|
1.0,
|
||||||
|
increment,
|
||||||
|
increment);
|
||||||
|
|
||||||
|
scrollable_set_adjustments (scrollable,
|
||||||
|
adjustment,
|
||||||
|
priv->vadjustment);
|
||||||
|
|
||||||
|
*hadjustment = adjustment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vadjustment)
|
||||||
|
{
|
||||||
|
if (priv->vadjustment)
|
||||||
|
*vadjustment = priv->vadjustment;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NbtkAdjustment *adjustment;
|
||||||
|
gdouble height, stage_height, increment;
|
||||||
|
|
||||||
|
height = clutter_actor_get_height (actor);
|
||||||
|
stage_height = clutter_actor_get_height (stage);
|
||||||
|
increment = MAX (1.0, MIN (stage_height, height));
|
||||||
|
|
||||||
|
adjustment = nbtk_adjustment_new (priv->y,
|
||||||
|
0,
|
||||||
|
height,
|
||||||
|
1.0,
|
||||||
|
increment,
|
||||||
|
increment);
|
||||||
|
|
||||||
|
scrollable_set_adjustments (scrollable,
|
||||||
|
priv->hadjustment,
|
||||||
|
adjustment);
|
||||||
|
|
||||||
|
*vadjustment = adjustment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
scrollable_interface_init (NbtkScrollableInterface *iface)
|
||||||
|
{
|
||||||
|
iface->set_adjustments = scrollable_set_adjustments;
|
||||||
|
iface->get_adjustments = scrollable_get_adjustments;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbtk_viewport_init (NbtkViewport *self)
|
||||||
|
{
|
||||||
|
self->priv = VIEWPORT_PRIVATE (self);
|
||||||
|
|
||||||
|
self->priv->sync_adjustments = TRUE;
|
||||||
|
|
||||||
|
g_object_set (G_OBJECT (self), "reactive", FALSE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
NbtkWidget *
|
||||||
|
nbtk_viewport_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (NBTK_TYPE_VIEWPORT, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nbtk_viewport_set_originu (NbtkViewport *viewport,
|
||||||
|
gfloat x,
|
||||||
|
gfloat y,
|
||||||
|
gfloat z)
|
||||||
|
{
|
||||||
|
NbtkViewportPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (NBTK_IS_VIEWPORT (viewport));
|
||||||
|
|
||||||
|
priv = viewport->priv;
|
||||||
|
|
||||||
|
g_object_freeze_notify (G_OBJECT (viewport));
|
||||||
|
|
||||||
|
if (x != priv->x)
|
||||||
|
{
|
||||||
|
priv->x = x;
|
||||||
|
g_object_notify (G_OBJECT (viewport), "x-origin");
|
||||||
|
|
||||||
|
if (priv->hadjustment)
|
||||||
|
nbtk_adjustment_set_value (priv->hadjustment,
|
||||||
|
(float) (x));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y != priv->y)
|
||||||
|
{
|
||||||
|
priv->y = y;
|
||||||
|
g_object_notify (G_OBJECT (viewport), "y-origin");
|
||||||
|
|
||||||
|
if (priv->vadjustment)
|
||||||
|
nbtk_adjustment_set_value (priv->vadjustment,
|
||||||
|
(float) (y));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (z != priv->z)
|
||||||
|
{
|
||||||
|
priv->z = z;
|
||||||
|
g_object_notify (G_OBJECT (viewport), "z-origin");
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_thaw_notify (G_OBJECT (viewport));
|
||||||
|
|
||||||
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (viewport));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nbtk_viewport_set_origin (NbtkViewport *viewport,
|
||||||
|
gint x,
|
||||||
|
gint y,
|
||||||
|
gint z)
|
||||||
|
{
|
||||||
|
g_return_if_fail (NBTK_IS_VIEWPORT (viewport));
|
||||||
|
|
||||||
|
nbtk_viewport_set_originu (viewport,
|
||||||
|
(float) (x),
|
||||||
|
(float) (y),
|
||||||
|
(float) (z));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nbtk_viewport_get_originu (NbtkViewport *viewport,
|
||||||
|
gfloat *x,
|
||||||
|
gfloat *y,
|
||||||
|
gfloat *z)
|
||||||
|
{
|
||||||
|
NbtkViewportPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (NBTK_IS_VIEWPORT (viewport));
|
||||||
|
|
||||||
|
priv = viewport->priv;
|
||||||
|
|
||||||
|
if (x)
|
||||||
|
*x = priv->x;
|
||||||
|
|
||||||
|
if (y)
|
||||||
|
*y = priv->y;
|
||||||
|
|
||||||
|
if (z)
|
||||||
|
*z = priv->z;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nbtk_viewport_get_origin (NbtkViewport *viewport,
|
||||||
|
gint *x,
|
||||||
|
gint *y,
|
||||||
|
gint *z)
|
||||||
|
{
|
||||||
|
NbtkViewportPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (NBTK_IS_VIEWPORT (viewport));
|
||||||
|
|
||||||
|
priv = viewport->priv;
|
||||||
|
|
||||||
|
if (x)
|
||||||
|
*x = (int) priv->x;
|
||||||
|
|
||||||
|
if (y)
|
||||||
|
*y = (int) priv->y;
|
||||||
|
|
||||||
|
if (z)
|
||||||
|
*z = (int) priv->z;
|
||||||
|
}
|
94
src/nbtk/nbtk-viewport.h
Normal file
94
src/nbtk/nbtk-viewport.h
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* nbtk-viewport.h: Viewport actor
|
||||||
|
*
|
||||||
|
* Copyright 2008 OpenedHand
|
||||||
|
* Copyright 2009 Intel Corporation.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU Lesser General Public License,
|
||||||
|
* version 2.1, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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 program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Written by: Chris Lord <chris@openedhand.com>
|
||||||
|
* Port to Nbtk by: Robert Staudinger <robsta@openedhand.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(NBTK_H_INSIDE) && !defined(NBTK_COMPILATION)
|
||||||
|
#error "Only <nbtk/nbtk.h> can be included directly.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __NBTK_VIEWPORT_H__
|
||||||
|
#define __NBTK_VIEWPORT_H__
|
||||||
|
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
#include <nbtk/nbtk-bin.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define NBTK_TYPE_VIEWPORT (nbtk_viewport_get_type())
|
||||||
|
#define NBTK_VIEWPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NBTK_TYPE_VIEWPORT, NbtkViewport))
|
||||||
|
#define NBTK_IS_VIEWPORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NBTK_TYPE_VIEWPORT))
|
||||||
|
#define NBTK_VIEWPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NBTK_TYPE_VIEWPORT, NbtkViewportClass))
|
||||||
|
#define NBTK_IS_VIEWPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NBTK_TYPE_VIEWPORT))
|
||||||
|
#define NBTK_VIEWPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NBTK_TYPE_VIEWPORT, NbtkViewportClass))
|
||||||
|
|
||||||
|
typedef struct _NbtkViewport NbtkViewport;
|
||||||
|
typedef struct _NbtkViewportPrivate NbtkViewportPrivate;
|
||||||
|
typedef struct _NbtkViewportClass NbtkViewportClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NbtkViewport:
|
||||||
|
*
|
||||||
|
* The contents of this structure are private and should only be accessed
|
||||||
|
* through the public API.
|
||||||
|
*/
|
||||||
|
struct _NbtkViewport
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
NbtkBin parent;
|
||||||
|
|
||||||
|
NbtkViewportPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _NbtkViewportClass
|
||||||
|
{
|
||||||
|
NbtkBinClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType nbtk_viewport_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
NbtkWidget * nbtk_viewport_new (void);
|
||||||
|
|
||||||
|
void nbtk_viewport_set_originu (NbtkViewport *viewport,
|
||||||
|
gfloat x,
|
||||||
|
gfloat y,
|
||||||
|
gfloat z);
|
||||||
|
|
||||||
|
void nbtk_viewport_set_origin (NbtkViewport *viewport,
|
||||||
|
gint x,
|
||||||
|
gint y,
|
||||||
|
gint z);
|
||||||
|
|
||||||
|
void nbtk_viewport_get_originu (NbtkViewport *viewport,
|
||||||
|
gfloat *x,
|
||||||
|
gfloat *y,
|
||||||
|
gfloat *z);
|
||||||
|
|
||||||
|
void nbtk_viewport_get_origin (NbtkViewport *viewport,
|
||||||
|
gint *x,
|
||||||
|
gint *y,
|
||||||
|
gint *z);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __NBTK_VIEWPORT_H__ */
|
Loading…
Reference in New Issue
Block a user