summaryrefslogtreecommitdiff
path: root/saedit/spritedrawingarea
diff options
context:
space:
mode:
Diffstat (limited to 'saedit/spritedrawingarea')
-rw-r--r--saedit/spritedrawingarea/sdalayer.c271
-rw-r--r--saedit/spritedrawingarea/sdalayer.h54
-rw-r--r--saedit/spritedrawingarea/sdalayerprivate.h19
-rw-r--r--saedit/spritedrawingarea/spritedrawingarea.c437
-rw-r--r--saedit/spritedrawingarea/spritedrawingarea.h71
5 files changed, 852 insertions, 0 deletions
diff --git a/saedit/spritedrawingarea/sdalayer.c b/saedit/spritedrawingarea/sdalayer.c
new file mode 100644
index 0000000..9794b80
--- /dev/null
+++ b/saedit/spritedrawingarea/sdalayer.c
@@ -0,0 +1,271 @@
+#include "spritedrawingarea.h"
+#include "sdalayer.h"
+#include "sdalayerprivate.h"
+
+enum {
+ PROP_0,
+ PROP_VISIBLE,
+ PROP_OFFSET_X,
+ PROP_OFFSET_Y,
+ PROP_DRAW_FUNC,
+ PROP_USER_DATA,
+ PROP_Z_INDEX,
+ PROP_COUNT
+};
+
+static void
+sda_layer_get_property (
+ GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec
+) {
+ SDALayer *layer = SDA_LAYER (object);
+ SDALayerPrivate *priv = layer->priv;
+
+ switch (prop_id) {
+ case PROP_VISIBLE:
+ g_value_set_boolean (
+ value, priv->visible
+ );
+ break;
+
+ case PROP_OFFSET_X:
+ g_value_set_int (
+ value, priv->offset_x
+ );
+ break;
+
+ case PROP_OFFSET_Y:
+ g_value_set_int (
+ value, priv->offset_y
+ );
+ break;
+
+ case PROP_Z_INDEX:
+ g_value_set_int (
+ value, priv->z_index
+ );
+ break;
+
+ case PROP_DRAW_FUNC:
+ g_value_set_pointer (
+ value, (gpointer) priv->draw_func
+ );
+ break;
+
+ case PROP_USER_DATA:
+ g_value_set_pointer (
+ value, priv->user_data
+ );
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+sda_layer_set_property (
+ GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec
+) {
+ SDALayer *layer = SDA_LAYER (object);
+ SDALayerPrivate *priv = layer->priv;
+
+ switch (prop_id) {
+ case PROP_VISIBLE:
+ priv->visible = g_value_get_boolean (value);
+ break;
+
+ case PROP_OFFSET_X:
+ priv->offset_x = g_value_get_int (value);
+ break;
+
+ case PROP_OFFSET_Y:
+ priv->offset_y = g_value_get_int (value);
+ break;
+
+ case PROP_Z_INDEX:
+ priv->z_index = g_value_get_int (value);
+ break;
+
+ case PROP_DRAW_FUNC:
+ priv->draw_func = (SDALayerDrawFunc) g_value_get_pointer (value);
+ break;
+
+ case PROP_USER_DATA:
+ priv->user_data = g_value_get_pointer (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+void
+sda_layer_init (
+ SDALayer *layer,
+ SDALayerClass *class
+) {
+ layer->priv = G_TYPE_INSTANCE_GET_PRIVATE (
+ layer,
+ SDA_TYPE_LAYER,
+ SDALayerPrivate
+ );
+
+ layer->priv->draw_func = NULL;
+ layer->priv->user_data = NULL;
+}
+
+void
+sda_layer_class_init (
+ SDALayerClass *klass,
+ gpointer class_data
+) {
+ GObjectClass *object_class;
+
+ g_type_class_add_private (klass, sizeof (SDALayerPrivate));
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->set_property = sda_layer_set_property;
+ object_class->get_property = sda_layer_get_property;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_VISIBLE,
+ g_param_spec_boolean (
+ "visible",
+ "Visible",
+ "Whether this layer is visible",
+ TRUE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT
+ )
+ );
+
+ g_object_class_install_property (
+ object_class,
+ PROP_OFFSET_X,
+ g_param_spec_int (
+ "offset-x",
+ "Offset X",
+ "The X coordinate of the layer offset",
+ -SPRITE_DRAWING_AREA_FIELD_SIZE,
+ SPRITE_DRAWING_AREA_FIELD_SIZE,
+ 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT
+ )
+ );
+
+ g_object_class_install_property (
+ object_class,
+ PROP_OFFSET_Y,
+ g_param_spec_int (
+ "offset-y",
+ "Offset y",
+ "The Y coordinate of the layer offset",
+ -SPRITE_DRAWING_AREA_FIELD_SIZE,
+ SPRITE_DRAWING_AREA_FIELD_SIZE,
+ 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT
+ )
+ );
+
+ g_object_class_install_property (
+ object_class,
+ PROP_DRAW_FUNC,
+ g_param_spec_pointer (
+ "draw-func",
+ "Draw function",
+ "A function invoked to draw the layer",
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
+ )
+ );
+
+ g_object_class_install_property (
+ object_class,
+ PROP_USER_DATA,
+ g_param_spec_pointer (
+ "user-data",
+ "User data",
+ "Data that will be propagated to the draw"
+ " function upon call",
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT
+ )
+ );
+
+ g_object_class_install_property (
+ object_class,
+ PROP_Z_INDEX,
+ g_param_spec_int (
+ "z-index",
+ "Z-index",
+ "Z-index of the layer",
+ -1024, 1024, 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT
+ )
+ );
+}
+
+GType
+sda_layer_get_type (void) {
+ static GType sda_layer_type = 0;
+
+ if (sda_layer_type == 0) {
+ const GTypeInfo sda_layer_info = {
+ sizeof (SDALayerClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) sda_layer_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (SDALayer),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) sda_layer_init,
+ NULL, /* value_table */
+ };
+
+ sda_layer_type = g_type_register_static (
+ G_TYPE_OBJECT,
+ "SDALayer",
+ &sda_layer_info,
+ 0
+ );
+ }
+
+ return sda_layer_type;
+}
+
+SDALayer *sda_layer_new (
+ SDALayerDrawFunc draw_func,
+ gpointer user_data
+) {
+ return g_object_new (
+ SDA_TYPE_LAYER,
+ "draw-func", draw_func,
+ "user-data", user_data,
+ NULL
+ );
+}
+
+gint
+sda_layer_compare_by_z_index (
+ const SDALayer *a,
+ const SDALayer *b
+) {
+ return a->priv->z_index - b->priv->z_index;
+}
+
+void
+sda_layer_set_z_index (SDALayer *layer, gint z_index) {
+ g_object_set (layer, "z-index", z_index, NULL);
+}
+
+void
+sda_layer_set_visible (SDALayer *layer, gboolean visible) {
+ g_object_set (layer, "visible", visible, NULL);
+}
diff --git a/saedit/spritedrawingarea/sdalayer.h b/saedit/spritedrawingarea/sdalayer.h
new file mode 100644
index 0000000..e1bac04
--- /dev/null
+++ b/saedit/spritedrawingarea/sdalayer.h
@@ -0,0 +1,54 @@
+#ifndef _SDALAYER_H_
+#define _SDALAYER_H_
+
+#include <glib-object.h>
+#include <cairo.h>
+
+G_BEGIN_DECLS
+
+#define SDA_TYPE_LAYER (sda_layer_get_type ())
+#define SDA_LAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SDA_TYPE_LAYER, SDALayer))
+#define SDA_LAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SDA_TYPE_LAYER, SDALayerClass))
+#define IS_SDA_LAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SDA_TYPE_LAYER))
+#define IS_SDA_LAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SDA_TYPE_LAYER))
+#define SDA_LAYER_GET_CLASS(obj) ((obj), SDA_TYPE_LAYER, SDALayerClass)
+
+typedef struct _SDALayer SDALayer;
+typedef struct _SDALayerClass SDALayerClass;
+typedef struct _SDALayerPrivate SDALayerPrivate;
+
+struct _SDALayerClass {
+ GObjectClass parent_class;
+};
+
+GType
+sda_layer_get_type (void);
+
+typedef void
+(* SDALayerDrawFunc) (
+ SDALayer *layer,
+ cairo_t *cr,
+ gpointer user_data
+);
+
+SDALayer *
+sda_layer_new (
+ SDALayerDrawFunc draw_func,
+ gpointer user_data
+);
+
+gint
+sda_layer_compare_by_z_index (
+ const SDALayer *a,
+ const SDALayer *b
+);
+
+void
+sda_layer_set_z_index (SDALayer *layer, gint z_index);
+
+void
+sda_layer_set_visible (SDALayer *layer, gboolean visible);
+
+G_END_DECLS
+
+#endif
diff --git a/saedit/spritedrawingarea/sdalayerprivate.h b/saedit/spritedrawingarea/sdalayerprivate.h
new file mode 100644
index 0000000..daf47bc
--- /dev/null
+++ b/saedit/spritedrawingarea/sdalayerprivate.h
@@ -0,0 +1,19 @@
+#ifndef _SDALAYERPRIVATE_H_
+#define _SDALAYERPRIVATE_H_
+
+struct _SDALayerPrivate {
+ gboolean visible;
+ gint offset_x, offset_y;
+ gint z_index;
+
+ SDALayerDrawFunc draw_func;
+ gpointer user_data;
+};
+
+struct _SDALayer {
+ GObject object;
+
+ SDALayerPrivate *priv;
+};
+
+#endif
diff --git a/saedit/spritedrawingarea/spritedrawingarea.c b/saedit/spritedrawingarea/spritedrawingarea.c
new file mode 100644
index 0000000..376c8e1
--- /dev/null
+++ b/saedit/spritedrawingarea/spritedrawingarea.c
@@ -0,0 +1,437 @@
+#include "spritedrawingarea.h"
+#include "sdalayer.h"
+#include "sdalayerprivate.h"
+
+struct _SpriteDrawingAreaPrivate {
+ gint center_x, center_y;
+ gdouble scale_factor;
+
+ gboolean drag_active;
+ gdouble drag_x, drag_y;
+
+ GList *layers;
+};
+
+enum {
+ PROP_0,
+ PROP_CENTER_X,
+ PROP_CENTER_Y,
+ PROP_SCALE_FACTOR,
+ PROP_COUNT
+};
+
+void
+sprite_drawing_area_get_center (
+ SpriteDrawingArea *sdarea,
+ gint *center_x,
+ gint *center_y
+) {
+ g_object_get (
+ sdarea,
+ "center-x", center_x,
+ "center-y", center_y,
+ NULL
+ );
+}
+
+void
+sprite_drawing_area_set_center (
+ SpriteDrawingArea *sdarea,
+ gint center_x,
+ gint center_y
+) {
+ g_object_set (
+ sdarea,
+ "center-x", center_x,
+ "center-y", center_y,
+ NULL
+ );
+}
+
+gdouble
+sprite_drawing_area_get_scale_factor (
+ SpriteDrawingArea *sdarea
+) {
+ gdouble result;
+
+ g_object_get (
+ sdarea,
+ "scale-factor", &result,
+ NULL
+ );
+
+ return result;
+}
+
+void
+sprite_drawing_area_set_scale_factor (
+ SpriteDrawingArea *sdarea,
+ gdouble scale_factor
+) {
+ g_object_set (
+ sdarea,
+ "scale-factor", scale_factor,
+ NULL
+ );
+}
+
+static gboolean
+_sprite_drawing_area_draw_handler (
+ GtkWidget *widget,
+ cairo_t *cr,
+ gpointer user_data
+) {
+ SpriteDrawingArea *sdarea = SPRITE_DRAWING_AREA (widget);
+ GList *l;
+
+ gint width = gtk_widget_get_allocated_width (widget);
+ gint height = gtk_widget_get_allocated_height (widget);
+
+ gdouble scale = sprite_drawing_area_get_scale_factor (sdarea);
+
+ gint center_x, center_y;
+
+ sprite_drawing_area_get_center (sdarea, &center_x, &center_y);
+
+ cairo_translate (
+ cr,
+ 0.5 * (gdouble) width,
+ 0.5 * (gdouble) height
+ );
+
+ cairo_scale (cr, scale, scale);
+
+ cairo_translate (
+ cr,
+ -center_x,
+ -center_y
+ );
+
+ sdarea->priv->layers = g_list_sort (
+ sdarea->priv->layers,
+ (GCompareFunc) sda_layer_compare_by_z_index
+ );
+
+ for (l = sdarea->priv->layers; l != NULL; l = l->next) {
+ SDALayer *layer = SDA_LAYER (l->data);
+
+ if (!layer->priv->visible)
+ continue;
+
+ cairo_save (cr);
+
+ cairo_translate (
+ cr,
+ layer->priv->offset_x,
+ layer->priv->offset_y
+ );
+
+ if (layer->priv->draw_func != NULL)
+ layer->priv->draw_func (layer, cr, layer->priv->user_data);
+
+ cairo_restore (cr);
+ }
+
+ return FALSE;
+}
+
+static void
+sprite_drawing_area_get_property (
+ GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec
+) {
+ SpriteDrawingArea *sdarea = SPRITE_DRAWING_AREA (object);
+
+ switch (prop_id) {
+ case PROP_CENTER_X:
+ g_value_set_int (
+ value, sdarea->priv->center_x
+ );
+ break;
+
+ case PROP_CENTER_Y:
+ g_value_set_int (
+ value, sdarea->priv->center_y
+ );
+ break;
+
+ case PROP_SCALE_FACTOR:
+ g_value_set_double (
+ value, sdarea->priv->scale_factor
+ );
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+sprite_drawing_area_set_property (
+ GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec
+) {
+ SpriteDrawingArea *sdarea = SPRITE_DRAWING_AREA (object);
+
+ switch (prop_id) {
+ case PROP_CENTER_X:
+ sdarea->priv->center_x = g_value_get_int (value);
+ break;
+
+ case PROP_CENTER_Y:
+ sdarea->priv->center_y = g_value_get_int (value);
+ break;
+
+ case PROP_SCALE_FACTOR:
+ sdarea->priv->scale_factor = g_value_get_double (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+gboolean
+_sprite_drawing_area_drag_start_callback (
+ GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data
+) {
+ SpriteDrawingArea *sdarea = SPRITE_DRAWING_AREA (widget);
+
+ if (event->button.button != 1)
+ return FALSE;
+
+ sdarea->priv->drag_active = TRUE;
+ sdarea->priv->drag_x = event->button.x;
+ sdarea->priv->drag_y = event->button.y;
+
+ return FALSE;
+}
+
+gboolean
+_sprite_drawing_area_drag_end_callback (
+ GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data
+) {
+ SpriteDrawingArea *sdarea = SPRITE_DRAWING_AREA (widget);
+
+ if (event->button.button != 1)
+ return FALSE;
+
+ sdarea->priv->drag_active = FALSE;
+ return FALSE;
+}
+
+gboolean
+_sprite_drawing_area_drag_motion_callback (
+ GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data
+) {
+ SpriteDrawingArea *sdarea = SPRITE_DRAWING_AREA (widget);
+
+ gdouble event_x, event_y;
+
+ gint center_x, center_y;
+ gint delta_x, delta_y;
+
+ gdouble scale_factor;
+
+ if ((event->motion.state & GDK_BUTTON1_MASK) == 0)
+ return FALSE;
+
+ if (!sdarea->priv->drag_active)
+ return FALSE;
+
+ event_x = event->motion.x;
+ event_y = event->motion.y;
+
+ sprite_drawing_area_get_center (sdarea, &center_x, &center_y);
+
+ scale_factor = sprite_drawing_area_get_scale_factor (sdarea);
+
+ delta_x =
+ (gint) (event_x / scale_factor + 0.5) - (gint) (sdarea->priv->drag_x / scale_factor + 0.5);
+ delta_y =
+ (gint) (event_y / scale_factor + 0.5) - (gint) (sdarea->priv->drag_y / scale_factor + 0.5);
+
+ sprite_drawing_area_set_center (
+ sdarea,
+ center_x - delta_x,
+ center_y - delta_y
+ );
+
+ sdarea->priv->drag_x = event_x;
+ sdarea->priv->drag_y = event_y;
+
+ gtk_widget_queue_draw (widget);
+ return FALSE;
+}
+
+static void
+sprite_drawing_area_init (
+ SpriteDrawingArea *sdarea,
+ SpriteDrawingAreaClass *klass
+) {
+ /* Setting up private */
+ sdarea->priv = G_TYPE_INSTANCE_GET_PRIVATE (
+ sdarea,
+ TYPE_SPRITE_DRAWING_AREA,
+ SpriteDrawingAreaPrivate
+ );
+
+ sdarea->priv->layers = NULL;
+
+ g_signal_connect (
+ sdarea,
+ "button-press-event",
+ (GCallback) _sprite_drawing_area_drag_start_callback,
+ NULL
+ );
+
+ g_signal_connect (
+ sdarea,
+ "button-release-event",
+ (GCallback) _sprite_drawing_area_drag_end_callback,
+ NULL
+ );
+
+ g_signal_connect (
+ sdarea,
+ "motion-notify-event",
+ (GCallback) _sprite_drawing_area_drag_motion_callback,
+ NULL
+ );
+}
+
+static void
+sprite_drawing_area_class_init (
+ SpriteDrawingAreaClass *klass,
+ gpointer class_data
+) {
+ GObjectClass *object_class;
+
+ g_type_class_add_private (klass, sizeof (SpriteDrawingAreaPrivate));
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->set_property = sprite_drawing_area_set_property;
+ object_class->get_property = sprite_drawing_area_get_property;
+
+ g_signal_override_class_handler (
+ "draw",
+ TYPE_SPRITE_DRAWING_AREA,
+ (GCallback) _sprite_drawing_area_draw_handler
+ );
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CENTER_X,
+ g_param_spec_int (
+ "center-x",
+ "Center X",
+ "The X coordinate of the point on the field "
+ "camera is centered on, in pixels",
+ -SPRITE_DRAWING_AREA_FIELD_SIZE,
+ SPRITE_DRAWING_AREA_FIELD_SIZE,
+ 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT
+ )
+ );
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CENTER_Y,
+ g_param_spec_int (
+ "center-y",
+ "Center Y",
+ "The Y coordinate of the point on the field "
+ "camera is centered on, in pixels",
+ -SPRITE_DRAWING_AREA_FIELD_SIZE,
+ SPRITE_DRAWING_AREA_FIELD_SIZE,
+ 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT
+ )
+ );
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SCALE_FACTOR,
+ g_param_spec_double (
+ "scale-factor",
+ "Scale factor",
+ "The scaling factor that is used in making "
+ "the camera zooming effect",
+ 0.01, 100.0, 1.0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT
+ )
+ );
+}
+
+GType
+sprite_drawing_area_get_type (void) {
+ static GType sdarea_type = 0;
+
+ if (sdarea_type == 0) {
+ const GTypeInfo sdarea_info = {
+ sizeof (SpriteDrawingAreaClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) sprite_drawing_area_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (SpriteDrawingArea),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) sprite_drawing_area_init,
+ NULL, /* value_table */
+ };
+
+ sdarea_type = g_type_register_static (
+ GTK_TYPE_DRAWING_AREA,
+ "SpriteDrawingArea",
+ &sdarea_info,
+ 0
+ );
+
+ }
+
+ return sdarea_type;
+}
+
+GtkWidget *
+sprite_drawing_area_new (void) {
+ GtkWidget *sdarea = GTK_WIDGET (
+ g_object_new (TYPE_SPRITE_DRAWING_AREA, NULL)
+ );
+ return sdarea;
+}
+
+void
+sprite_drawing_area_add_layer (
+ SpriteDrawingArea *sdarea,
+ SDALayer *layer
+) {
+ sdarea->priv->layers = g_list_insert_sorted (
+ sdarea->priv->layers,
+ layer,
+ (GCompareFunc) sda_layer_compare_by_z_index
+ );
+}
+
+void
+sprite_drawing_area_remove_layer (
+ SpriteDrawingArea *sdarea,
+ SDALayer *layer
+) {
+ sdarea->priv->layers = g_list_remove (
+ sdarea->priv->layers,
+ layer
+ );
+}
diff --git a/saedit/spritedrawingarea/spritedrawingarea.h b/saedit/spritedrawingarea/spritedrawingarea.h
new file mode 100644
index 0000000..ee3aa6d
--- /dev/null
+++ b/saedit/spritedrawingarea/spritedrawingarea.h
@@ -0,0 +1,71 @@
+#ifndef __SPRITE_DRAWING_AREA_H__
+#define __SPRITE_DRAWING_AREA_H__
+
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+#include "sdalayer.h"
+
+G_BEGIN_DECLS
+
+#define TYPE_SPRITE_DRAWING_AREA (sprite_drawing_area_get_type ())
+#define SPRITE_DRAWING_AREA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_SPRITE_DRAWING_AREA, SpriteDrawingArea))
+#define SPRITE_DRAWING_AREA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_SPRITE_DRAWING_AREA, SpriteDrawingAreaClass))
+#define IS_SPRITE_DRAWING_AREA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_SPRITE_DRAWING_AREA))
+#define IS_SPRITE_DRAWING_AREA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_SPRITE_DRAWING_AREA))
+#define SPRITE_DRAWING_AREA_GET_CLASS(obj) ((obj), TYPE_SPRITE_DRAWING_AREA, SpriteDrawingAreaClass)
+
+typedef struct _SpriteDrawingArea SpriteDrawingArea;
+typedef struct _SpriteDrawingAreaPrivate SpriteDrawingAreaPrivate;
+typedef struct _SpriteDrawingAreaClass SpriteDrawingAreaClass;
+
+struct _SpriteDrawingArea {
+ GtkDrawingArea darea;
+
+ SpriteDrawingAreaPrivate *priv;
+};
+
+struct _SpriteDrawingAreaClass {
+ GtkDrawingAreaClass darea_class;
+
+ void (* draw_field) (
+ GtkWidget *sdarea,
+ gpointer data
+ );
+};
+
+static const gint SPRITE_DRAWING_AREA_FIELD_SIZE = 1024;
+
+GType
+sprite_drawing_area_get_type (void);
+
+GtkWidget*
+sprite_drawing_area_new (void);
+
+void
+sprite_drawing_area_set_scale_factor (
+ SpriteDrawingArea *sdarea,
+ gdouble scale_factor
+);
+
+void
+sprite_drawing_area_add_layer (
+ SpriteDrawingArea *sdarea,
+ SDALayer *layer
+);
+
+void
+sprite_drawing_area_remove_layer (
+ SpriteDrawingArea *sdarea,
+ SDALayer *layer
+);
+
+void
+sprite_drawing_area_set_center (
+ SpriteDrawingArea *sdarea,
+ gint center_x,
+ gint center_y
+);
+
+G_END_DECLS
+
+#endif