Commit 03a12e74 authored by Colomban Wendling's avatar Colomban Wendling
Browse files

Make board widget render a true board.

parent 4fe471d7
......@@ -19,19 +19,38 @@
#include "board-widget.h"
#include <gtk/gtk.h>
#include <ovcc/board.h>
#include "tiles.h"
typedef struct _OVCCGtkBoardPrivate OVCCGtkBoardPrivate;
#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OVCCGTK_BOARD_TYPE, OVCCGtkBoardPrivate))
struct _OVCCGtkBoardPrivate
{
/*OVCCBoard *board;*/
OVCCBoard *board;
};
enum
{
PROP_0,
PROP_BOARD
};
static void ovccgtk_board_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void ovccgtk_board_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void ovccgtk_board_realize (GtkWidget *self);
static void ovccgtk_board_size_request (GtkWidget *widget,
GtkRequisition *requisition);
static gboolean ovccgtk_board_expose (GtkWidget *self,
GdkEventExpose *event);
static gboolean ovccgtk_board_button_release (GtkWidget *self,
GdkEventButton *event);
static void ovccgtk_board_set_scroll_adjustments (OVCCGtkBoard *board,
GtkAdjustment *hadjustment,
GtkAdjustment *vadjustment);
......@@ -41,11 +60,27 @@ G_DEFINE_TYPE (OVCCGtkBoard, ovccgtk_board, GTK_TYPE_DRAWING_AREA)
static void ovccgtk_board_class_init (OVCCGtkBoardClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
widget_class->expose_event = ovccgtk_board_expose;
object_class->set_property = ovccgtk_board_set_property;
object_class->get_property = ovccgtk_board_get_property;
widget_class->realize = ovccgtk_board_realize;
widget_class->size_request = ovccgtk_board_size_request;
widget_class->expose_event = ovccgtk_board_expose;
widget_class->button_release_event = ovccgtk_board_button_release;
klass->set_scroll_adjustments = ovccgtk_board_set_scroll_adjustments;
g_object_class_install_property (
object_class, PROP_BOARD,
g_param_spec_pointer (
"board",
"Board",
"The underlying OVCCBoard",
G_PARAM_READWRITE
)
);
/*widget_class->set_scroll_adjustments_signal =
g_signal_new ("set-scroll-adjustments",
G_OBJECT_CLASS_TYPE (klass),
......@@ -57,12 +92,12 @@ static void ovccgtk_board_class_init (OVCCGtkBoardClass *klass)
GTK_TYPE_ADJUSTMENT,
GTK_TYPE_ADJUSTMENT);*/
/*g_type_class_add_private ((gpointer)klass, sizeof(OVCCGtkBoardPrivate));*/
g_type_class_add_private ((gpointer)klass, sizeof(OVCCGtkBoardPrivate));
}
static void ovccgtk_board_init (OVCCGtkBoard *self)
{
self->priv = GET_PRIVATE (self);
}
static void
......@@ -73,42 +108,298 @@ ovccgtk_board_set_scroll_adjustments (OVCCGtkBoard *board,
}
static void
ovccgtk_board_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
OVCCGtkBoard *board;
board = OVCCGTK_BOARD (object);
switch (prop_id) {
case PROP_BOARD:
ovccgtk_board_set_board (board, g_value_get_pointer (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
ovccgtk_board_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
OVCCGtkBoard *board;
board = OVCCGTK_BOARD (object);
switch (prop_id) {
case PROP_BOARD:
g_value_set_pointer (value, ovccgtk_board_get_board (board));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
ovccgtk_board_realize (GtkWidget *widget)
{
GdkWindowAttr attributes;
guint attributes_mask;
GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
attributes.window_type = GDK_WINDOW_CHILD;
attributes.x = widget->allocation.x;
attributes.y = widget->allocation.y;
attributes.width = widget->allocation.width;
attributes.height = widget->allocation.height;
attributes.wclass = GDK_INPUT_OUTPUT;
attributes.event_mask = gtk_widget_get_events (widget) |
GDK_EXPOSURE_MASK |
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
attributes_mask = GDK_WA_X | GDK_WA_Y;
widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
&attributes, attributes_mask);
gdk_window_set_user_data (widget->window, widget);
widget->style = gtk_style_attach (widget->style, widget->window);
gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
}
static void
ovccgtk_board_size_request (GtkWidget *widget,
GtkRequisition *requisition)
{
OVCCGtkBoard *self = OVCCGTK_BOARD (widget);
ovcc_board_get_bounds (self->priv->board, NULL, NULL, NULL, NULL,
&requisition->width, &requisition->height);
g_debug ("req (board size): [%u,%u]", requisition->width, requisition->height);
requisition->width *= TILE_SIZE + 1;
requisition->height *= TILE_SIZE + 1;
/* add half a tile of borders */
requisition->width += TILE_SIZE;
requisition->height += TILE_SIZE;
g_debug ("req: [%u,%u]", requisition->width, requisition->height);
}
static GdkPixbuf *
procedural_tile (OVCCTile *tile)
{
GdkPixbuf *pixbuf;
GdkPixmap *pixmap;
OVCCTileSide *side;
GdkPoint points[3] = {
{0,0},
{0,0},
{TILE_SIZE / 2,TILE_SIZE / 2}
};
GdkGC *gc;
GdkColor city = { 0, 65535, 0, 0 };
GdkColor field = { 0, 0, 65535, 0 };
GdkColor path = { 0, 0, 0, 65535 };
GdkColor unknown = { 0, 0, 0, 0 };
gint i = 0;
pixmap = gdk_pixmap_new (NULL, TILE_SIZE, TILE_SIZE, 24);
gc = gdk_gc_new (GDK_DRAWABLE (pixmap));
for (i = 0; i < OVCC_TILE_SIDE_NUM; i++) {
side = ovcc_tile_get_side (tile, i);
switch (i) {
case OVCC_TILE_SIDE_POS_LEFT:
points[0].x = 0;
points[0].y = 0;
points[1].x = 0;
points[1].y = TILE_SIZE - 1;
break;
case OVCC_TILE_SIDE_POS_TOP:
points[0].x = 0;
points[0].y = 0;
points[1].x = TILE_SIZE - 1;
points[1].y = 0;
break;
case OVCC_TILE_SIDE_POS_RIGHT:
points[0].x = TILE_SIZE - 1;
points[0].y = 0;
points[1].x = TILE_SIZE - 1;
points[1].y = TILE_SIZE - 1;
break;
case OVCC_TILE_SIDE_POS_BOTTOM:
points[0].x = 0;
points[0].y = TILE_SIZE - 1;
points[1].x = TILE_SIZE - 1;
points[1].y = TILE_SIZE - 1;
break;
}
switch (ovcc_tile_side_get_type (side)) {
case OVCC_TILE_CONTENT_TYPE_CITY: gdk_gc_set_background (gc, &city);
gdk_gc_set_foreground (gc, &city); break;
case OVCC_TILE_CONTENT_TYPE_FIELD: gdk_gc_set_background (gc, &field);
gdk_gc_set_foreground (gc, &field); break;
case OVCC_TILE_CONTENT_TYPE_PATH: gdk_gc_set_background (gc, &path);
gdk_gc_set_foreground (gc, &path); break;
default: gdk_gc_set_background (gc, &unknown);
gdk_gc_set_foreground (gc, &unknown);
}
gdk_draw_polygon (GDK_DRAWABLE (pixmap), gc, TRUE,
points, G_N_ELEMENTS (points));
}
pixbuf = gdk_pixbuf_get_from_drawable (NULL, GDK_DRAWABLE (pixmap),
gdk_colormap_get_system (),
0, 0, 0, 0, TILE_SIZE, TILE_SIZE);
g_object_unref (pixmap);
return pixbuf;
}
static gboolean
ovccgtk_board_expose (GtkWidget *self,
ovccgtk_board_expose (GtkWidget *widget,
GdkEventExpose *event)
{
GdkGC *gc = self->style->fg_gc[GTK_WIDGET_STATE (self)];
GdkGC *gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
#if 0
guint x, y;
gdk_gc_set_clip_region (gc, event->region);
/*gdk_draw_arc (self->window, gc,
/*gdk_draw_arc (widget->window, gc,
TRUE,
0, 0, self->allocation.width, self->allocation.height,
0, 0, widget->allocation.width, widegt->allocation.height,
0, 64 * 360);*/
for (x = 0; x < self->allocation.width; ) {
for (x = 0; x < widget->allocation.width; ) {
guint w = 0;
for (y = 0; y < self->allocation.height; ) {
for (y = 0; y < widget->allocation.height; ) {
GdkPixbuf *pix;
guint h;
pix = tile_get_pixbuf (/*g_random_int_range (1, 72)*/
(((x+1) * (y+1)) % 72) + 1);
(((x+1) * (y+1)) % 74) + 1);
w = gdk_pixbuf_get_width (pix);
h = gdk_pixbuf_get_height (pix);
gdk_draw_pixbuf (self->window, gc, pix, 0, 0, x, y, w, h,
gdk_draw_pixbuf (widget->window, gc, pix, 0, 0, x, y, w, h,
GDK_RGB_DITHER_NORMAL, 0, 0);
y += h + 1;
}
x += w + 1;
}
#else
OVCCGtkBoard *self = OVCCGTK_BOARD (widget);
gint base_x, base_y, max_x, max_y, width, height;
gint x, y;
gint center_x, center_y;
gdk_gc_set_clip_region (gc, event->region);
ovcc_board_get_bounds (self->priv->board,
&base_x, &base_y, &max_x, &max_y, &width, &height);
center_x = max_x * (TILE_SIZE + 1)
+ ((widget->allocation.width - ((width + 1) * (TILE_SIZE + 1))) / 2);
center_y = max_y * (TILE_SIZE + 1)
+ ((widget->allocation.height - ((height + 1) * (TILE_SIZE + 1))) / 2);
for (x = base_x; x <= max_x; x ++) {
for (y = base_y; y <= max_y; y ++) {
OVCCPosition pos;
OVCCTile *tile;
pos.x = x;
pos.y = y;
tile = ovcc_board_get_tile (self->priv->board, &pos);
if (tile) {
GdkPixbuf *pix;
gint dest_x, dest_y;
gint rotation;
pix = tile_get_pixbuf (ovcc_tile_get_id (tile));
rotation = ovcc_tile_get_rotation (tile);
if (rotation > 0) {
GdkPixbuf *new;
new = gdk_pixbuf_rotate_simple (pix, (360 - 90*rotation + 180) % 360);
g_object_unref (pix);
pix = new;
}
dest_x = center_x - (x * (TILE_SIZE + 1)) - (TILE_SIZE / 2);
dest_y = center_y - (y * (TILE_SIZE + 1)) - (TILE_SIZE / 2);
gdk_draw_pixbuf (widget->window, gc, pix,
0, 0, dest_x, dest_y,
TILE_SIZE, TILE_SIZE,
GDK_RGB_DITHER_NORMAL, 0, 0);
g_object_unref (pix);
/*pix = procedural_tile (tile);
gdk_draw_pixbuf (widget->window, gc, pix,
0, 0, dest_x, dest_y,
TILE_SIZE, TILE_SIZE,
GDK_RGB_DITHER_NORMAL, 0, 0);
g_object_unref (pix);*/
if (x == 0 && y == 0) {
gdk_draw_arc (widget->window, gc,
FALSE,
dest_x + TILE_SIZE / 4,
dest_y + TILE_SIZE / 4,
(TILE_SIZE / 2), (TILE_SIZE / 2),
0, 64 * 360);
}
}
}
}
/*gdk_draw_arc (widget->window, gc,
FALSE,
(widget->allocation.width - TILE_SIZE) / 2,
(widget->allocation.height - TILE_SIZE) / 2,
TILE_SIZE, TILE_SIZE,
0, 64 * 360);*/
#endif
return TRUE;
}
static gboolean
ovccgtk_board_button_release (GtkWidget *self,
GdkEventButton *event)
{
if (event->button == 1) {
g_debug ("[%u,%u]", (guint)(event->x / 65) + 1, (guint)(event->y / 65) + 1);
}
return TRUE;
}
GtkWidget *ovccgtk_board_new (void)
GtkWidget *
ovccgtk_board_new (OVCCBoard *board)
{
return g_object_new (OVCCGTK_BOARD_TYPE, "board", board);
}
void
ovccgtk_board_set_board (OVCCGtkBoard *self,
OVCCBoard *board)
{
return g_object_new (OVCCGTK_BOARD_TYPE, NULL);
g_return_if_fail (OVCCGTK_IS_BOARD (self));
g_return_if_fail (board != NULL);
self->priv->board = board;
}
OVCCBoard *
ovccgtk_board_get_board (OVCCGtkBoard *self)
{
g_return_val_if_fail (OVCCGTK_IS_BOARD (self), NULL);
return self->priv->board;
}
......@@ -23,6 +23,7 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <ovcc/board.h>
G_BEGIN_DECLS
......@@ -30,17 +31,20 @@ G_BEGIN_DECLS
#define OVCCGTK_BOARD_TYPE (ovccgtk_board_get_type ())
#define OVCCGTK_BOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OVCCGTK_BOARD_TYPE, OVCCGtkBoard))
#define OVCCGTK_BOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OVCCGTK_BOARD_TYPE, OVCCGtkBoardClass))
#define IS_OVCCGTK_BOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OVCCGTK_BOARD_TYPE))
#define IS_OVCCGTK_BOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OVCCGTK_BOARD_TYPE))
#define OVCCGTK_IS_BOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OVCCGTK_BOARD_TYPE))
#define OVCCGTK_IS_BOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OVCCGTK_BOARD_TYPE))
typedef struct _OVCCGtkBoard OVCCGtkBoard;
typedef struct _OVCCGtkBoardClass OVCCGtkBoardClass;
typedef struct _OVCCGtkBoardPrivate OVCCGtkBoardPrivate;
struct _OVCCGtkBoard
{
GtkDrawingArea parent;
/*<private>*/
OVCCGtkBoardPrivate *priv;
};
struct _OVCCGtkBoardClass
......@@ -54,8 +58,10 @@ struct _OVCCGtkBoardClass
GType ovccgtk_board_get_type (void) G_GNUC_CONST;
GtkWidget *ovccgtk_board_new (void);
GtkWidget *ovccgtk_board_new (OVCCBoard *board);
void ovccgtk_board_set_board (OVCCGtkBoard *self,
OVCCBoard *board);
OVCCBoard *ovccgtk_board_get_board (OVCCGtkBoard *self);
G_END_DECLS
......
......@@ -6,7 +6,122 @@
#include "board-widget.h"
#define UI_FILE "ovcc-gtk.ui"
#define UI_FILE "ovcc-gtk.ui"
#define GAME_TILES "tiles.xml"
#define GAME_TILESET "tileset.xml"
/* bad copy of the bot implemented in libovcc's test */
static gboolean
do_try_place_tile (OVCCBoard *board,
OVCCPosition *pos,
OVCCTile *tile,
gpointer user_data)
{
gsize i;
gboolean keep_doing = TRUE;
OVCCTile *new_tile = user_data;
g_return_val_if_fail (new_tile != NULL, FALSE);
for (i = 0; keep_doing && i < OVCC_TILE_SIDE_NUM; i++) {
OVCCPosition npos = *pos;
int r;
switch (i) {
case OVCC_TILE_SIDE_POS_TOP: npos.y--; break;
case OVCC_TILE_SIDE_POS_BOTTOM: npos.y++; break;
case OVCC_TILE_SIDE_POS_LEFT: npos.x--; break;
case OVCC_TILE_SIDE_POS_RIGHT: npos.x++; break;
}
for (r = 0; keep_doing && r < OVCC_TILE_SIDE_NUM; r++) {
ovcc_tile_rotate (new_tile, 1);
if (ovcc_board_add_tile_check (board, new_tile, &npos)) {
ovcc_board_add_tile (board, new_tile, &npos);
keep_doing = FALSE;
}
}
}
return keep_doing;
}
static gboolean
try_place_tile (OVCCBoard *board,
OVCCTile *tile)
{
return ovcc_board_foreach (board, do_try_place_tile, tile) == FALSE;
}
static gboolean
test_board (OVCCBoard *board,
OVCCStack *stack)
{
OVCCTile *tile;
gsize n_success = 0;
gsize n_failed = 0;
while (NULL != (tile = ovcc_stack_pop (stack))) {
if (! try_place_tile (board, tile)) {
g_warning ("Failed to place tile %u", ovcc_tile_get_id (tile));
n_failed ++;
} else {
n_success ++;
}
ovcc_tile_unref (tile);
}
g_debug ("%zu tiles over %zu placed (%.3u%%)",
n_success, (n_success + n_failed),
n_success * 100 / (n_success + n_failed));
return n_failed == 0;
}
static OVCCBoard *
create_board (void)
{
gchar *path;
OVCCTilesDef *tiles;
GFile *tiles_file;
OVCCTileSet *set;
GFile *set_file;
OVCCStack *stack;
OVCCBoard *board = NULL;
GError *err = NULL;
tiles = ovcc_tilesdef_new ();
path = data_get_path (GAME_TILES);
tiles_file = g_file_new_for_path (path);
g_free (path);
if (! ovcc_tilesdef_load (tiles, tiles_file, &err)) {
msg_error (_("Failed to load tiles: %s"), err->message);
g_error_free (err);
} else {
set = ovcc_tileset_new ();
path = data_get_path (GAME_TILESET);
set_file = g_file_new_for_path (path);
g_free (path);
if (! ovcc_tileset_load (set, tiles, set_file, &err)) {
msg_error (_("Failed to load tile set: %s"), err->message);
g_error_free (err);
} else {
stack = ovcc_stack_new_from_tileset (set);
board = ovcc_board_new (stack);
test_board (board, stack);
ovcc_stack_free (stack);
}
g_object_unref (set_file);
ovcc_tileset_free (set);
}
g_object_unref (tiles_file);
ovcc_tilesdef_free (tiles);
return board;
}
/* end of bad game fake */
......@@ -70,7 +185,7 @@ ovcc_gtk (int argc,
GtkWidget *viewport;
viewport = gtk_viewport_new (NULL, NULL);
gtk_container_add (GTK_CONTAINER (viewport), ovccgtk_board_new ());
gtk_container_add (GTK_CONTAINER (viewport), ovccgtk_board_new (create_board ()));
gtk_container_add (GTK_CONTAINER (board_cnt), viewport);
}
gtk_image_set_from_pixbuf (GTK_IMAGE (current_tile_image),
......
......@@ -114,8 +114,10 @@ get_tile_path (OVCCTileID id)
gchar *path;
gchar *file;
file = g_strdup_printf ("tiles/carso%u.gif", id);
/*file = g_strdup_printf ("tiles/carso%u.gif", id);*/
file = g_strdup_printf ("default/tiles/tile%u.gif", id);
path = data_get_path (file);
g_debug ("Path for tile #%u is '%s'", id, path);
g_free (file);
return path;
......@@ -154,7 +156,7 @@ tile_get_pixbuf (OVCCTileID id)
pixbuf = load_tile (id);
}
return pixbuf;
return g_object_ref (pixbuf);
}
gboolean
......
......@@ -27,6 +27,8 @@
G_BEGIN_DECLS
#define TILE_SIZE 64
GdkPixbuf *tile_get_pixbuf (OVCCTileID id);
gboolean tile_exists (OVCCTileID id);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment