Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * SECTION:ttk-box
- * @Short_Description: An actor to display a rounded edge box
- *
- * Use this actor to display a rounded edged box of a given
- * outline color and fill color.
- *
- * Note that the fill/outline colors are both optional
- */
- #ifdef HAVE_CONFIG_H
- # include <config.h>
- #endif
- #include <glib-object.h>
- #include <math.h>
- #include <ttktransport/ttktransport.h>
- #include "ttk-box.h"
- #include "ttk-client.h"
- /* GObjectClass */
- static void ttk_box_class_init (TTKBoxClass *klass);
- static void ttk_box_init (TTKBox *box);
- static void ttk_box_constructed (GObject *object);
- static void ttk_box_finalize (GObject *object);
- static void ttk_box_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
- static void ttk_box_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
- /* ClutterCairoTextureClass */
- static gboolean ttk_box_draw (ClutterCairoTexture *texture,
- cairo_t *cr);
- /* ClutterScriptableIface */
- static void ttk_box_scriptable_iface_init (ClutterScriptableIface *iface);
- static gboolean ttk_box_parse_custom_node (ClutterScriptable *scriptable,
- ClutterScript *script,
- GValue *value,
- const gchar *name,
- JsonNode *node);
- static void ttk_box_set_custom_property (ClutterScriptable *scriptable,
- ClutterScript *script,
- const gchar *name,
- const GValue *value);
- static void ttk_box_invalidate (TTKBox *box);
- struct _TTKBoxPrivate {
- ClutterColor *fill_color;
- ClutterColor *outline_color;
- gdouble outline_width;
- guint repaint_id;
- gboolean constructed;
- };
- enum {
- PROP_0,
- PROP_FILL_COLOR,
- PROP_OUTLINE_COLOR,
- PROP_OUTLINE_WIDTH,
- PROP_INIT_WIDTH,
- PROP_INIT_HEIGHT,
- };
- static ClutterScriptableIface *parent_scriptable_iface;
- G_DEFINE_TYPE_WITH_CODE (TTKBox, ttk_box, CLUTTER_TYPE_CAIRO_TEXTURE,
- G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_SCRIPTABLE,
- ttk_box_scriptable_iface_init));
- /************************************************************************
- * GObjectClass *
- ************************************************************************/
- static void
- ttk_box_class_init (TTKBoxClass *klass)
- {
- GObjectClass *object_class;
- ClutterCairoTextureClass *cairo_texture_class;
- object_class = G_OBJECT_CLASS (klass);
- cairo_texture_class = CLUTTER_CAIRO_TEXTURE_CLASS (klass);
- object_class->constructed = ttk_box_constructed;
- object_class->finalize = ttk_box_finalize;
- object_class->get_property = ttk_box_get_property;
- object_class->set_property = ttk_box_set_property;
- cairo_texture_class->draw = ttk_box_draw;
- /**
- * TTKBox:fill-color:
- *
- * The color to fill the box with, if no fill color is
- * specified, or after the fill color is explicitly set to %NULL,
- * then the box will not be filled at all.
- */
- g_object_class_install_property (object_class, PROP_FILL_COLOR,
- g_param_spec_boxed ("fill-color", "Fill Color",
- "The color to fill the box with",
- CLUTTER_TYPE_COLOR,
- G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
- /**
- * TTKBox:outline-color:
- *
- * The color to outline the box with, if no outline color is
- * specified, or after the outline color is explicitly set to %NULL,
- * then no outline will be draw.
- */
- g_object_class_install_property (object_class, PROP_OUTLINE_COLOR,
- g_param_spec_boxed ("outline-color", "Outline Color",
- "The color to outline the box with",
- CLUTTER_TYPE_COLOR,
- G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
- /**
- * TTKBox:outline-width:
- *
- * The width of the outline to draw
- */
- g_object_class_install_property (object_class, PROP_OUTLINE_WIDTH,
- g_param_spec_double ("outline-width", "Outline Width",
- "The width of the outline to draw",
- 0.0F, G_MAXDOUBLE, 2.0F,
- G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
- /**
- * TTKBox:init-width:
- *
- * The texture width to initialize with
- */
- g_object_class_install_property (object_class, PROP_INIT_WIDTH,
- g_param_spec_uint ("init-width", "Initial width",
- "The texture width to initialize with",
- 0, G_MAXUINT, 0,
- G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
- /**
- * TTKBox:init-height:
- *
- * The texture height to initialize with
- */
- g_object_class_install_property (object_class, PROP_INIT_HEIGHT,
- g_param_spec_uint ("init-height", "Initial height",
- "The texture height to initialize with",
- 0, G_MAXUINT, 0,
- G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
- g_type_class_add_private (object_class, sizeof (TTKBoxPrivate));
- }
- static void
- ttk_box_init (TTKBox *box)
- {
- box->priv = G_TYPE_INSTANCE_GET_PRIVATE (box, TTK_TYPE_BOX, TTKBoxPrivate);
- box->priv->outline_width = 2.0F;
- //clutter_cairo_texture_set_auto_resize (CLUTTER_CAIRO_TEXTURE (box), TRUE);
- }
- static void
- ttk_box_constructed (GObject *object)
- {
- TTKBox *box = TTK_BOX (object);
- TTKBoxPrivate *priv = box->priv;
- G_OBJECT_CLASS (ttk_box_parent_class)->constructed (object);
- TTK_NOTE (BOX, g_print ("TTKBox: Constructed, invalidating\n"));
- if (priv->repaint_id > 0)
- clutter_threads_remove_repaint_func (priv->repaint_id);
- priv->constructed = TRUE;
- ttk_box_invalidate (box);
- }
- static void
- ttk_box_finalize (GObject *object)
- {
- TTKBox *box = TTK_BOX (object);
- TTKBoxPrivate *priv = box->priv;
- ttk_box_set_fill_color (box, NULL);
- ttk_box_set_outline_color (box, NULL);
- if (priv->repaint_id > 0)
- clutter_threads_remove_repaint_func (priv->repaint_id);
- G_OBJECT_CLASS (ttk_box_parent_class)->finalize (object);
- }
- static void
- ttk_box_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
- {
- TTKBox *box = TTK_BOX (object);
- switch (prop_id)
- {
- case PROP_FILL_COLOR:
- g_value_set_boxed (value, ttk_box_get_fill_color (box));
- break;
- case PROP_OUTLINE_COLOR:
- g_value_set_boxed (value, ttk_box_get_outline_color (box));
- break;
- case PROP_OUTLINE_WIDTH:
- g_value_set_double (value, ttk_box_get_outline_width (box));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
- }
- static void
- ttk_box_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
- {
- TTKBox *box = TTK_BOX (object);
- switch (prop_id)
- {
- case PROP_FILL_COLOR:
- ttk_box_set_fill_color (box, g_value_get_boxed (value));
- break;
- case PROP_OUTLINE_COLOR:
- ttk_box_set_outline_color (box, g_value_get_boxed (value));
- break;
- case PROP_OUTLINE_WIDTH:
- ttk_box_set_outline_width (box, g_value_get_double (value));
- break;
- case PROP_INIT_WIDTH:
- {
- guint width = 0, height = 0;
- clutter_cairo_texture_get_surface_size (CLUTTER_CAIRO_TEXTURE (box), &width, &height);
- width = g_value_get_uint (value);
- clutter_cairo_texture_set_surface_size (CLUTTER_CAIRO_TEXTURE (box), width, height);
- }
- break;
- case PROP_INIT_HEIGHT:
- {
- guint width = 0, height = 0;
- clutter_cairo_texture_get_surface_size (CLUTTER_CAIRO_TEXTURE (box), &width, &height);
- height = g_value_get_uint (value);
- clutter_cairo_texture_set_surface_size (CLUTTER_CAIRO_TEXTURE (box), width, height);
- }
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
- }
- /************************************************************************
- * ClutterCairoTextureClass *
- ************************************************************************/
- static gboolean
- ttk_box_draw (ClutterCairoTexture *texture,
- cairo_t *cr)
- {
- TTKBox *box = TTK_BOX (texture);
- TTKBoxPrivate *priv = box->priv;
- gdouble x, y, width, height, radius, degrees;
- guint texture_width = 0, texture_height = 0;
- clutter_cairo_texture_get_surface_size (texture, &texture_width, &texture_height);
- TTK_NOTE (BOX, g_print ("TTKBox: Drawing with width %d and height %d\n", texture_width, texture_height));
- clutter_cairo_texture_clear (texture);
- x = priv->outline_width / 2;
- y = priv->outline_width / 2;
- width = texture_width - priv->outline_width;
- height = texture_height - priv->outline_width;
- radius = height / 10.0F;
- degrees = M_PI / 180.0F;
- cairo_new_sub_path (cr);
- cairo_arc (cr, x + width - radius, y + radius, radius, -90 * degrees, 0 * degrees);
- cairo_arc (cr, x + width - radius, y + height - radius, radius, 0 * degrees, 90 * degrees);
- cairo_arc (cr, x + radius, y + height - radius, radius, 90 * degrees, 180 * degrees);
- cairo_arc (cr, x + radius, y + radius, radius, 180 * degrees, 270 * degrees);
- cairo_close_path (cr);
- /* First draw the fill color */
- if (priv->fill_color)
- {
- clutter_cairo_set_source_color (cr, priv->fill_color);
- cairo_fill_preserve (cr);
- }
- /* Now the outline (if any is set) */
- if (priv->outline_color)
- {
- clutter_cairo_set_source_color (cr, priv->outline_color);
- cairo_set_line_width (cr, priv->outline_width);
- cairo_stroke (cr);
- }
- return FALSE;
- }
- static gboolean
- ttk_box_do_invalidate (gpointer data)
- {
- TTKBox *box = (TTKBox *)data;
- TTKBoxPrivate *priv = box->priv;
- ClutterCairoTexture *texture = CLUTTER_CAIRO_TEXTURE (box);
- clutter_cairo_texture_invalidate (texture);
- priv->repaint_id = 0;
- return FALSE;
- }
- /* We use a repaint function to invalidate redraw the rectangle
- * at the last minute before actually drawing.
- *
- * In this way we avoid redrawing the box with cairo multiple
- * times in a row for multiple property settings
- */
- static void
- ttk_box_invalidate (TTKBox *box)
- {
- TTKBoxPrivate *priv = box->priv;
- /* if (priv->repaint_id == 0) */
- /* priv->repaint_id = */
- /* clutter_threads_add_repaint_func (ttk_box_do_invalidate, box, NULL); */
- if (!priv->constructed)
- return;
- ttk_box_do_invalidate (box);
- clutter_actor_queue_redraw (CLUTTER_ACTOR (box));
- }
- /************************************************************************
- * ClutterScriptableIface *
- ************************************************************************/
- static gboolean
- ttk_box_parse_custom_node (ClutterScriptable *scriptable,
- ClutterScript *script,
- GValue *value,
- const gchar *name,
- JsonNode *node)
- {
- gboolean success = FALSE;
- if (ttk_actor_parse_custom_node (scriptable, script, value, name, node, &success))
- return success;
- return parent_scriptable_iface->parse_custom_node (scriptable, script, value, name, node);
- }
- static void
- ttk_box_set_custom_property (ClutterScriptable *scriptable,
- ClutterScript *script,
- const gchar *name,
- const GValue *value)
- {
- if (!ttk_actor_set_custom_property (scriptable, script, name, value))
- parent_scriptable_iface->set_custom_property (scriptable, script, name, value);
- }
- static void
- ttk_box_scriptable_iface_init (ClutterScriptableIface *iface)
- {
- parent_scriptable_iface = g_type_interface_peek_parent (iface);
- iface->parse_custom_node = ttk_box_parse_custom_node;
- iface->set_custom_property = ttk_box_set_custom_property;
- }
- /************************************************************************
- * API *
- ************************************************************************/
- /**
- * ttk_box_new:
- *
- * Creates a TTKBox actor.
- *
- * Returns: (transfer full): A newly created #TTKBox
- */
- ClutterActor *
- ttk_box_new (void)
- {
- return g_object_new (TTK_TYPE_BOX, NULL);
- }
- /**
- * ttk_box_new_full:
- * @surface_width: The width for the texture
- * @surface_height: The height for the texture
- * @fill_color: (allow-none): The color to use to draw the box
- * @outline_color: (allow-none): The outline color for the box
- *
- * Creates a fully parameterized TTKBox actor.
- */
- ClutterActor *
- ttk_box_new_full (guint surface_width,
- guint surface_height,
- const ClutterColor *fill_color,
- const ClutterColor *outline_color)
- {
- return g_object_new (TTK_TYPE_BOX,
- "init-width", surface_width,
- "init-height", surface_height,
- "fill-color", fill_color,
- "outline-color", outline_color,
- NULL);
- }
- /**
- * ttk_box_set_fill_color:
- * @box: A #TTKBox actor
- * @fill_color: (allow-none): The color to fill the box with
- *
- * Sets @fill_color as the color to fill the box with
- */
- void
- ttk_box_set_fill_color (TTKBox *box,
- const ClutterColor *fill_color)
- {
- TTKBoxPrivate *priv;
- g_return_if_fail (TTK_IS_BOX (box));
- priv = box->priv;
- if (priv->fill_color)
- {
- clutter_color_free (priv->fill_color);
- priv->fill_color = NULL;
- }
- if (fill_color)
- priv->fill_color = clutter_color_copy (fill_color);
- TTK_NOTE (BOX, g_print ("TTKBox: invalidating for color setting\n"));
- ttk_box_invalidate (box);
- g_object_notify (G_OBJECT (box), "fill-color");
- }
- /**
- * ttk_box_get_fill_color:
- * @box: A #TTKBox actor
- *
- * Fetches the color used to fill the box with
- *
- * Returns: (transfer none): The color used to fill the box with
- */
- const ClutterColor *
- ttk_box_get_fill_color (TTKBox *box)
- {
- TTKBoxPrivate *priv;
- g_return_val_if_fail (TTK_IS_BOX (box), NULL);
- priv = box->priv;
- return priv->fill_color;
- }
- /**
- * ttk_box_set_outline_color:
- * @box: A #TTKBox actor
- * @outline_color: (allow-none): The color to outline the box with
- *
- * Sets @outline_color as the color to outline the box with
- */
- void
- ttk_box_set_outline_color (TTKBox *box,
- const ClutterColor *outline_color)
- {
- TTKBoxPrivate *priv;
- g_return_if_fail (TTK_IS_BOX (box));
- priv = box->priv;
- if (priv->outline_color)
- {
- clutter_color_free (priv->outline_color);
- priv->outline_color = NULL;
- }
- if (outline_color)
- priv->outline_color = clutter_color_copy (outline_color);
- TTK_NOTE (BOX, g_print ("TTKBox: invalidating for outline color setting\n"));
- ttk_box_invalidate (box);
- g_object_notify (G_OBJECT (box), "outline-color");
- }
- /**
- * ttk_box_get_outline_color:
- * @box: A #TTKBox actor
- *
- * Fetches the color used to outline the box with
- *
- * Returns: (transfer none): The color used to outline the box with
- */
- const ClutterColor *
- ttk_box_get_outline_color (TTKBox *box)
- {
- TTKBoxPrivate *priv;
- g_return_val_if_fail (TTK_IS_BOX (box), NULL);
- priv = box->priv;
- return priv->outline_color;
- }
- /**
- * ttk_box_set_outline_width:
- * @box: A #TTKBox actor
- * @width: The width of the outline
- *
- * Sets the outline width, the outline width will
- * be used to call cairo_set_line_width() before
- * drawing the box outline.
- */
- void
- ttk_box_set_outline_width (TTKBox *box,
- gdouble width)
- {
- TTKBoxPrivate *priv;
- g_return_if_fail (TTK_IS_BOX (box));
- priv = box->priv;
- if (priv->outline_width != width)
- {
- priv->outline_width = width;
- TTK_NOTE (BOX, g_print ("TTKBox: invalidating for outline width setting\n"));
- ttk_box_invalidate (box);
- g_object_notify (G_OBJECT (box), "outline-width");
- }
- }
- /**
- * ttk_box_get_outline_width:
- * @box: A #TTKBox actor
- *
- * Fetches the width that will be used to
- * draw the box outline with cairo.
- */
- gdouble
- ttk_box_get_outline_width (TTKBox *box)
- {
- TTKBoxPrivate *priv;
- g_return_val_if_fail (TTK_IS_BOX (box), 0.0F);
- priv = box->priv;
- return priv->outline_width;
- }
Add Comment
Please, Sign In to add comment