gnome-control-center/panels/wacom/calibrator/cc-clock-actor.c
2014-01-29 11:27:38 +01:00

185 lines
5.6 KiB
C

/*
* Copyright © 2013 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
* Author: Joaquim Rocha <jrocha@redhat.com>
*/
#include <math.h>
#include "cc-clock-actor.h"
#define CLOCK_RADIUS 50
#define CLOCK_LINE_WIDTH 10
#define CLOCK_LINE_PADDING 10
#define CLOCK_SIZE_EXTRA
#define ANGLE "angle"
#define EXTRA_SPACE 2
G_DEFINE_TYPE (CcClockActor, cc_clock_actor, CLUTTER_TYPE_ACTOR);
enum {
PROP_0,
PROP_ANGLE,
N_PROPERTIES
};
static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
static void
draw_clock (ClutterCairoTexture *texture,
cairo_t *cr,
gint width,
gint height,
CcClockActor *self)
{
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
cairo_paint (cr);
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
/* Draw the clock background */
cairo_arc (cr, width / 2, height / 2, CLOCK_RADIUS / 2, 0.0, 2.0 * M_PI);
cairo_set_source_rgb (cr, 0.5, 0.5, 0.5);
cairo_fill_preserve (cr);
cairo_stroke (cr);
cairo_set_line_width (cr, CLOCK_LINE_WIDTH);
cairo_arc (cr,
width / 2,
height / 2,
(CLOCK_RADIUS - CLOCK_LINE_WIDTH - CLOCK_LINE_PADDING) / 2,
3 * M_PI_2,
3 * M_PI_2 + self->angle * M_PI / 180.0);
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
cairo_stroke (cr);
}
static void
cc_clock_actor_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
CcClockActor *self = CC_CLOCK_ACTOR (object);
ClutterContent *content;
content = clutter_actor_get_content (CLUTTER_ACTOR (self));
switch (property_id)
{
case PROP_ANGLE:
self->angle = g_value_get_float (value);
if (content)
clutter_content_invalidate (content);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
cc_clock_actor_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
CcClockActor *self = CC_CLOCK_ACTOR (object);
switch (property_id)
{
case PROP_ANGLE:
g_value_set_float (value, self->angle);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
cc_clock_actor_init (CcClockActor *self)
{
self->angle = 0;
ClutterContent *content;
content = clutter_canvas_new ();
/* Extra space is needed because when drawing without it,
it will miss 1 pixel in each of the edges */
clutter_canvas_set_size (CLUTTER_CANVAS (content),
CLOCK_RADIUS + EXTRA_SPACE,
CLOCK_RADIUS + EXTRA_SPACE);
clutter_actor_set_content (CLUTTER_ACTOR (self), content);
g_signal_connect (CLUTTER_CANVAS (content),
"draw",
G_CALLBACK (draw_clock),
self);
g_object_unref (content);
}
static void
cc_clock_actor_get_preferred_width (ClutterActor *actor,
gfloat for_height,
gfloat *min_width_p,
gfloat *natural_width_p)
{
*min_width_p = CLOCK_RADIUS + EXTRA_SPACE;
*natural_width_p = CLOCK_RADIUS + EXTRA_SPACE;
}
static void
cc_clock_actor_get_preferred_height (ClutterActor *actor,
gfloat for_width,
gfloat *min_height_p,
gfloat *natural_height_p)
{
*min_height_p = CLOCK_RADIUS + EXTRA_SPACE;
*natural_height_p = CLOCK_RADIUS + EXTRA_SPACE;
}
static void
cc_clock_actor_class_init (CcClockActorClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
ClutterActorClass *clutter_actor_class = CLUTTER_ACTOR_CLASS (klass);
gobject_class->set_property = cc_clock_actor_set_property;
gobject_class->get_property = cc_clock_actor_get_property;
clutter_actor_class->get_preferred_width = cc_clock_actor_get_preferred_width;
clutter_actor_class->get_preferred_height = cc_clock_actor_get_preferred_height;
obj_properties[PROP_ANGLE] =
g_param_spec_float (ANGLE,
"The angle of the clock's progress",
"Set the angle of the clock's progress",
.0,
360.0,
.0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class,
N_PROPERTIES,
obj_properties);
}
ClutterActor *
cc_clock_actor_new (void)
{
return g_object_new (CC_CLOCK_ACTOR_TYPE, NULL);
}