This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch master
in repository elimine.

View the commit online.

commit 0381b8ab893c93c8984612e5658e13e5f228f479
Author: Vincent Torri <vto...@outlook.fr>
AuthorDate: Sat Aug 9 11:07:04 2025 +0200

    refactor a bit the code
---
 .gitignore          |   1 +
 src/bin/ctx.c       | 156 ++++++++++++++++++
 src/bin/ctx.h       |  55 +++++++
 src/bin/elimine.c   | 417 ++----------------------------------------------
 src/bin/elimine.h   |  34 ++--
 src/bin/grid.c      | 446 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/bin/grid.h      |  13 ++
 src/bin/icon.h      |   7 +-
 src/bin/meson.build |  13 +-
 src/bin/score.c     |   2 +-
 src/bin/score.h     |   4 +-
 11 files changed, 716 insertions(+), 432 deletions(-)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b25c15b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*~
diff --git a/src/bin/ctx.c b/src/bin/ctx.c
new file mode 100644
index 0000000..68f563d
--- /dev/null
+++ b/src/bin/ctx.c
@@ -0,0 +1,156 @@
+/*
+ * SPDX-FileCopyrightText: Vincent Torri <vincent.to...@gmail.com>
+ * SPDX-License-Identifier: MIT
+ */
+
+#include "ctx.h"
+#include "icon.h"
+
+Ctx *ctx_new(Difficulty d, int pixel_sz)
+{
+    Ctx *ctx;
+
+    if (!icon_init(pixel_sz))
+        return NULL;
+
+    ctx = (Ctx *)calloc(1, sizeof(Ctx));
+    if (!ctx)
+        return NULL;
+
+    ctx->pixel_sz = pixel_sz;
+
+    switch (d)
+    {
+        case BEGINNER:
+            ctx->nl = 9;
+            ctx->nc = 9;
+            ctx->nm = 10;
+            break;
+        case INTERMEDIATE:
+            ctx->nl = 16;
+            ctx->nc = 16;
+            ctx->nm = 40;
+            break;
+        case EXPERT:
+            ctx->nl = 16;
+            ctx->nc = 30;
+            ctx->nm = 99;
+            break;
+        default:
+            goto free_ctx;
+    }
+
+    ctx_grid_fill(ctx, ctx->nl, ctx->nc, ctx->nm);
+
+    srand(time(NULL));
+
+    ctx->finished = EINA_FALSE;
+
+    return ctx;
+
+  free_ctx:
+    free(ctx);
+    return NULL;
+}
+
+/* ctx will necessarly be not NULL */
+
+void ctx_del(Ctx *ctx)
+{
+    free(ctx->known);
+    free(ctx->state);
+    free(ctx);
+}
+
+/* inc true : ++, otherwise -- */
+void
+ctx_mine_update(Ctx *ctx, Eina_Bool inc)
+{
+    inc ? ctx->nm++ : ctx->nm--;
+    if (ctx->nm > 999) ctx->nm = 999;
+    if (ctx->nm < -99) ctx->nm = -99;
+}
+
+Eina_Bool
+ctx_grid_fill(Ctx *ctx, int nl, int nc, int nm)
+{
+    int count;
+    int l;
+
+    if ((ctx->nl != nl) || (ctx->nc != nc))
+    {
+        free(ctx->state);
+        free(ctx->known);
+        ctx->nl = nl;
+        ctx->nc = nc;
+    }
+
+    ctx->state = (int *)calloc(ctx->nl * ctx->nc, sizeof(int));
+    if (!ctx->state)
+        return EINA_FALSE;
+
+    ctx->known = (int *)calloc(ctx->nl * ctx->nc, sizeof(int));
+    if (!ctx->known)
+    {
+        free(ctx->state);
+        return EINA_FALSE;
+    }
+
+    ctx->nm = nm;
+
+    /* state */
+
+    count = 0;
+    while (count < ctx->nm)
+    {
+        int pos = rand() % (ctx->nc * ctx->nl);
+        if (ctx->state[pos] != TILE_BOMB)
+        {
+            ctx->state[pos] = TILE_BOMB;
+            count++;
+        }
+    }
+
+    for (l = 0; l < ctx->nl; l++)
+    {
+        int c;
+
+        for (c = 0; c < ctx->nc; c++)
+        {
+            if (ctx->state[lookup(l, c)] <9)
+            {
+                int j;
+
+                int n = 0;
+                for (j = -1; j <= 1; j++)
+                {
+                    int i;
+
+                    for (i = -1; i <= 1; i++)
+                    {
+                        if (is_in_board(l + j, c + i) && ! ((i == 0) && (j == 0)))
+                        {
+                            if (ctx->state[lookup(l + j, c + i)] == TILE_BOMB)
+                                n++;
+                        }
+                    }
+                }
+                ctx->state[lookup(l, c)] = n;
+            }
+        }
+    }
+
+    /* known */
+
+    for (l = 0; l < ctx->nl; l++)
+    {
+        int c;
+
+        for (c = 0; c < ctx->nc; c++)
+        {
+            ctx->known[lookup(l, c)] = TILE_UNKNOWN;
+        }
+    }
+
+    return EINA_TRUE;
+}
diff --git a/src/bin/ctx.h b/src/bin/ctx.h
new file mode 100644
index 0000000..b16b1e6
--- /dev/null
+++ b/src/bin/ctx.h
@@ -0,0 +1,55 @@
+/*
+ * SPDX-FileCopyrightText: Vincent Torri <vincent.to...@gmail.com>
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef ELIMINE_CTX_H
+#define ELIMINE_CTX_H
+
+#include <Eina.h>
+
+#define lookup(l, c) ((l) * ctx->nc + (c))
+
+#define is_in_board(l, c) ((l) >= 0) && ((c) >= 0) && ((l) < ctx->nl) && ((c) < ctx->nc)
+
+#define State(l, c) ctx->state[lookup((l), (c))]
+#define Known(l, c) ctx->known[lookup((l), (c))]
+
+/*
+ * Boards (width x height x mines):
+ * - 9x9x10
+ * - 16x16x40
+ * - 30x16x99
+ */
+
+typedef enum
+{
+    BEGINNER,
+    INTERMEDIATE,
+    EXPERT,
+    CUSTOM
+} Difficulty;
+
+typedef struct Ctx Ctx;
+
+struct Ctx
+{
+    int *state;
+    int *known;
+    int nl; /* number of lines of the board */
+    int nc; /* number of columns of the board */
+    int nm; /* number of remaining mines in the board */
+    int pixel_sz; /* size in pixels of a tile */
+
+    Eina_Bool finished;
+};
+
+Ctx *ctx_new(Difficulty d, int pixel_sz);
+
+void ctx_del(Ctx *ctx);
+
+void ctx_mine_update(Ctx *ctx, Eina_Bool inc);
+
+Eina_Bool ctx_grid_fill(Ctx *ctx, int nl, int nc, int nm);
+
+#endif /* ELIMINE_CTX_H */
diff --git a/src/bin/elimine.c b/src/bin/elimine.c
index 587407e..3565919 100644
--- a/src/bin/elimine.c
+++ b/src/bin/elimine.c
@@ -9,35 +9,12 @@
 
 #include <Elementary.h>
 
+#include "ctx.h"
 #include "icon.h"
+#include "grid.h"
 #include "score.h"
 #include "elimine.h"
 
-#define lookup(l, c) (l) * ctx->nc + (c)
-
-/*
- * Boards (width x height x mines):
- * - 9x9x10
- * - 16x16x40
- * - 30x16x99
- */
-
-typedef enum
-{
-    BEGINNER,
-    INTERMEDIATE,
-    HARD,
-    CUSTOM
-} Difficulty;
-
-static Evas_Object *cph = NULL;
-static Evas_Object *rect = NULL;
-
-static inline int in_board(Ctx *ctx, int l, int c)
-{
-    return  (l >= 0) && (c >= 0) && (l < ctx->nl) && (c < ctx->nc);
-}
-
 void display_board(Ctx *ctx)
 {
     int l;
@@ -49,328 +26,12 @@ void display_board(Ctx *ctx)
         for (c = 0; c < ctx->nc; c++)
         {
             printf("%c ",
-                   ctx->state[lookup(l,c)] == TILE_BOMB ? '*' : '0' + ctx->state[lookup(l,c)]);
+                   State(l, c) == TILE_BOMB ? '*' : '0' + State(l, c));
         }
         printf("\n");
     }
 }
 
-Ctx *ctx_new(Difficulty d, int pixel_sz)
-{
-    Ctx *ctx;
-    int count;
-    int l;
-
-    if (!icon_init(pixel_sz))
-        return NULL;
-
-    ctx = (Ctx *)calloc(1, sizeof(Ctx));
-    if (!ctx)
-        return NULL;
-
-    ctx->pixel_sz = pixel_sz;
-
-    switch (d)
-    {
-        case BEGINNER:
-            ctx->nl = 9;
-            ctx->nc = 9;
-            ctx->nm = 10;
-            break;
-        case INTERMEDIATE:
-            ctx->nl = 16;
-            ctx->nc = 16;
-            ctx->nm = 40;
-            break;
-        case HARD:
-            ctx->nl = 16;
-            ctx->nc = 30;
-            ctx->nm = 99;
-            break;
-        default:
-            free(ctx);
-            return NULL;
-    }
-
-    ctx->tiles = eina_array_new(ctx->nl * ctx->nc);
-    if (!ctx->tiles)
-        goto free_ctx;
-
-    ctx->state = (int *)calloc(ctx->nl * ctx->nc, sizeof(int));
-    if (!ctx->state)
-        goto free_tiles;
-
-    ctx->known = (int *)calloc(ctx->nl * ctx->nc, sizeof(int));
-    if (!ctx->known)
-        goto free_state;
-
-    /* state */
-
-    srand(time(NULL));
-
-    count = 0;
-    while (count < ctx->nm)
-    {
-        int pos = rand() % (ctx->nc * ctx->nl);
-        if (ctx->state[pos] != TILE_BOMB)
-        {
-            ctx->state[pos] = TILE_BOMB;
-            count++;
-        }
-    }
-
-    for (l = 0; l < ctx->nl; l++)
-    {
-        int c;
-
-        for (c = 0; c < ctx->nc; c++)
-        {
-            if (ctx->state[lookup(l, c)] <9)
-            {
-                int j;
-
-                int n = 0;
-                for (j = -1; j <= 1; j++)
-                {
-                    int i;
-
-                    for (i = -1; i <= 1; i++)
-                    {
-                        if (in_board(ctx, l + j, c + i) && ! ((i == 0) && (j == 0)))
-                        {
-                            if (ctx->state[lookup(l + j, c + i)] == TILE_BOMB)
-                                n++;
-                        }
-                    }
-                }
-                ctx->state[lookup(l, c)] = n;
-            }
-        }
-    }
-
-    /* known */
-
-    for (l = 0; l < ctx->nl; l++)
-    {
-        int c;
-
-        for (c = 0; c < ctx->nc; c++)
-        {
-            ctx->known[lookup(l, c)] = TILE_UNKNOWN;
-        }
-    }
-
-    return ctx;
-
-  free_state:
-    free(ctx->state);
-  free_tiles:
-    eina_array_free(ctx->tiles);
-  free_ctx:
-    free(ctx);
-    return NULL;
-}
-
-void ctx_del(Ctx *ctx)
-{
-    if (!ctx)
-        return;
-
-    ecore_timer_del(ctx->timer);
-    ctx->timer = NULL;
-    free(ctx->known);
-    free(ctx->state);
-    eina_array_free(ctx->tiles);
-    free(ctx);
-}
-
-
-#define TILE(t, l, c) \
-do { \
-    Evas_Object *o = eina_array_data_get(ctx->tiles, l * ctx->nc + c);  \
-    evas_object_image_data_set(o, tile_bmp_get(t));                     \
-    evas_object_image_pixels_dirty_set(o, EINA_TRUE);                   \
-} while (0)
-
-static inline int in_bounds(Ctx *ctx, int l, int c)
-{
-    return (l >= 0) && (c >= 0) && (l < ctx->nl) && (c < ctx->nc);
-}
-
-static void uncover(Ctx *ctx, int l, int c)
-{
-    int x;
-    int y;
-
-    if (ctx->state[lookup(l, c)] == TILE_BOMB)
-        return;
-
-    if ((ctx->state[lookup(l, c)] >= TILE_ONE) &&
-        (ctx->state[lookup(l, c)] <= TILE_HEIGHT))
-    {
-        ctx->known[lookup(l, c)] = ctx->state[lookup(l, c)];
-        TILE(ctx->state[lookup(l, c)], l, c);
-        return;
-    }
-
-    ctx->known[lookup(l, c)] = TILE_NOTHING;
-    TILE(TILE_NOTHING, l, c);
-
-    for (y = -1; y <= 1; y++)
-    {
-        for (x = -1; x <= 1; x++)
-        {
-            if (!((x == 0) && (y == 0)) &&
-                in_bounds(ctx, l +  y, c + x) &&
-                (ctx->known[lookup(l + y, c + x)] == TILE_UNKNOWN))
-            {
-                uncover(ctx, l + y, c + x);
-            }
-        }
-    }
-}
-
-static Eina_Bool
-_cb_time(void *ctx_)
-{
-    Ctx *ctx;
-
-    ctx = (Ctx *)ctx_;
-    ctx->time_count++;
-    if (ctx->time_count > 999)
-    {
-        ecore_timer_del(ctx->timer);
-        ctx->timer = NULL;
-        return ECORE_CALLBACK_CANCEL;
-    }
-
-    score_set(ctx->time, ctx->time_count);
-
-    return ECORE_CALLBACK_RENEW;
-}
-
-static void
-_cb_mouse_up(void *ctx_, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event_info)
-{
-    Ctx *ctx;
-    Evas_Event_Mouse_Up *ev;
-    int l;
-    int c;
-    int x;
-    int y;
-    int w;
-    int h;
-
-    ctx = (Ctx *)ctx_;
-    if (ctx->finished == EINA_TRUE)
-        return;
-
-    evas_object_geometry_get(obj, &x, &y, NULL, NULL);
-    tile_size_get(&w, &h);
-    ev = (Evas_Event_Mouse_Up *)event_info;
-    c = (ev->output.x - x) / (w * ctx->pixel_sz);
-    l = (ev->output.y - y) / (h * ctx->pixel_sz);
-    printf(" $$ %d %d\n", c, l);
-
-    if ((ev->button == 3) ||
-        ((ev->button == 1) &&
-         (evas_key_modifier_is_set(ev->modifiers, "Control"))))
-    {
-        if (ctx->known[lookup(l, c)] == TILE_UNKNOWN)
-        {
-            ctx->known[lookup(l, c)] = TILE_FLAG;
-            TILE(TILE_FLAG, l, c);
-            ctx->nm--;
-            score_set(ctx->remain, ctx->nm);
-        }
-        else if (ctx->known[lookup(l, c)] == TILE_FLAG)
-        {
-            ctx->known[lookup(l, c)] = TILE_UNKNOWN;
-            TILE(TILE_UNKNOWN, l, c);
-            ctx->nm++;
-            score_set(ctx->remain, ctx->nm);
-        }
-
-        return;
-    }
-
-    if ((ev->button == 1) && (ctx->known[lookup(l, c)] == TILE_UNKNOWN))
-    {
-        if (ctx->state[lookup(l, c)] == TILE_BOMB)
-        {
-            int y;
-
-            ecore_timer_del(ctx->timer);
-            ctx->timer = NULL;
-            ctx->finished = EINA_TRUE;
-            evas_object_image_data_set(ctx->smiley, smiley_bmp_get(SMILEY_LOST));
-            evas_object_image_pixels_dirty_set(ctx->smiley, EINA_TRUE);
-
-            for (y = 0; y < ctx->nl; y++)
-            {
-                int x;
-
-                for (x = 0; x < ctx->nc; x++)
-                {
-                    /* wrongly flagged tile */
-                    if ((ctx->known[lookup(y, x)] == TILE_FLAG) &&
-                        (ctx->state[lookup(y, x)] != TILE_BOMB))
-                    {
-                        ctx->known[lookup(y, x)] = TILE_BOMB_WRONG;
-                        TILE(TILE_BOMB_WRONG, y, x);
-                    }
-
-                    if (ctx->state[lookup(y, x)] == TILE_BOMB)
-                    {
-                        if ((x == c) && (y == l))
-                        {
-                            ctx->known[lookup(y, x)] = TILE_BOMB_EXPLODED;
-                            TILE(TILE_BOMB_EXPLODED, y, x);
-                        }
-                        else
-                        {
-                            ctx->known[lookup(y, x)] = TILE_BOMB;
-                            TILE(TILE_BOMB, y, x);
-                        }
-                    }
-                }
-            }
-        }
-        else if (ctx->state[lookup(l, c)] == TILE_NOTHING)
-        {
-            uncover(ctx, l, c);
-            evas_object_image_data_set(ctx->smiley, smiley_bmp_get(SMILEY_NORMAL));
-            evas_object_image_pixels_dirty_set(ctx->smiley, EINA_TRUE);
-        }
-        else
-        {
-            ctx->known[lookup(l, c)] = ctx->state[lookup(l, c)];
-            TILE(ctx->state[lookup(l, c)], l, c);
-            evas_object_image_data_set(ctx->smiley, smiley_bmp_get(SMILEY_NORMAL));
-            evas_object_image_pixels_dirty_set(ctx->smiley, EINA_TRUE);
-        }
-    }
-}
-
-static void
-_cb_mouse_down(void *ctx_, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
-{
-    Ctx *ctx;
-
-    ctx = (Ctx *)ctx_;
-
-    if (!ctx->timer)
-        ctx->timer = ecore_timer_add(1.0, _cb_time, ctx);
-
-    evas_object_image_data_set(ctx->smiley, smiley_bmp_get(SMILEY_SURPRISED));
-    evas_object_image_pixels_dirty_set(ctx->smiley, EINA_TRUE);
-    int x, y, w, h;
-    evas_object_geometry_get(cph, &x, &y, &w, &h);
-    printf(" ** 1 cph : %d %d %d %d\n", x, y, w, h);
-    evas_object_geometry_get(rect, &x, &y, &w, &h);
-    printf(" ** 1 cph : %d %d %d %d\n", x, y, w, h);
-}
-
 EAPI_MAIN int
 elm_main(int argc, char **argv)
 {
@@ -379,16 +40,13 @@ elm_main(int argc, char **argv)
     Evas_Object *win;
     Evas_Object *vbox;
     Evas_Object *hbox;
-    Evas_Object *tbl;
     Evas_Object *o;
     int win_w;
     int win_h;
-    int l;
 
-    ctx = ctx_new(BEGINNER, 3);
+    ctx = ctx_new(INTERMEDIATE, 3);
     if (!ctx)
         return 1;
-    printf(" $$ ctx %p %d\n", (void *)ctx, ctx->pixel_sz);
 
     elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
     elm_app_name_set("elimine");
@@ -425,13 +83,11 @@ elm_main(int argc, char **argv)
 
     o = score_add(win);
     score_set(o, ctx->nm);
-    //evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-    //evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
     evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-    evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, 0);
+    evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
     elm_box_pack_end(hbox, o);
     evas_object_show(o);
-    ctx->remain = o;
+    evas_object_data_set(win, "elimine.remain", o);
 
     int icon_w, icon_h;
 
@@ -446,17 +102,15 @@ elm_main(int argc, char **argv)
     evas_object_size_hint_max_set(o, icon_w, icon_h);
     elm_box_pack_end(hbox, o);
     evas_object_show(o);
-    ctx->smiley = o;
+    evas_object_data_set(win, "elimine.smiley", o);
 
     o = score_add(win);
     score_set(o, 0);
-    //evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-    //evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
     evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-    evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, 0);
+    evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
     elm_box_pack_end(hbox, o);
     evas_object_show(o);
-    ctx->time = o;
+    evas_object_data_set(win, "elimine.time", o);
 
     /* table */
     o = elm_table_add(win);
@@ -465,59 +119,12 @@ elm_main(int argc, char **argv)
     evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
     elm_box_pack_end(vbox, o);
     evas_object_show(o);
-    tbl = o;
+    evas_object_data_set(win, "elimine.table", o);
 
     /* grid */
-    o = elm_grid_add(win);
-    elm_grid_size_set(o, ctx->nc, ctx->nl);
-    evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-    evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
-    elm_table_pack(tbl, o, 0, 0, 1, 1);
+    o = eli_grid_add(win);
+    eli_grid_resize(o, ctx->nl, ctx->nc, ctx->nm);
     evas_object_show(o);
-    ctx->grd = o;
-
-    /* tiles in grid */
-    /* int icon_w; */
-    /* int icon_h; */
-
-    tile_size_get(&icon_w, &icon_h);
-    icon_w *= ctx->pixel_sz;
-    icon_h *= ctx->pixel_sz;
-    evas_object_size_hint_min_set(o, icon_w * ctx->nc, icon_h * ctx->nl);
-    evas_object_size_hint_max_set(o, icon_w * ctx->nc, icon_h * ctx->nl);
-
-    for (l = 0; l < ctx->nl; l++)
-    {
-        int c;
-
-        for (c = 0; c < ctx->nc; c++)
-        {
-            Evas_Object*o;
-
-            o = evas_object_image_filled_add(evas_object_evas_get(win));
-            evas_object_image_size_set(o, icon_w, icon_h);
-            evas_object_image_data_set(o, tile_bmp_get(ctx->known[lookup(l, c)]));
-            evas_object_resize(o, icon_w, icon_h);
-            evas_object_size_hint_min_set(o, icon_w, icon_h);
-            evas_object_size_hint_max_set(o, icon_w, icon_h);
-            elm_grid_pack(ctx->grd, o, c, l, 1, 1);
-            evas_object_show(o);
-            eina_array_push(ctx->tiles, o);
-        }
-    }
-
-    o = evas_object_rectangle_add(evas_object_evas_get(win));
-    evas_object_color_set(o, 0, 0, 0, 0);
-    evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-    evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
-    elm_table_pack(tbl, o, 0, 0, 1, 1);
-    evas_object_repeat_events_set(o, EINA_TRUE);
-    evas_object_show(o);
-    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP,
-                                   _cb_mouse_up, ctx);
-    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN,
-                                   _cb_mouse_down, ctx);
-    rect = o;
 
     ctx->finished = EINA_FALSE;
 
diff --git a/src/bin/elimine.h b/src/bin/elimine.h
index 2e42bfb..18497d8 100644
--- a/src/bin/elimine.h
+++ b/src/bin/elimine.h
@@ -6,24 +6,24 @@
 #ifndef ELIMINATE_H
 #define ELIMINATE_H
 
-typedef struct
-{
-    Evas_Object *remain; /* nbr of remaing bombs */
-    Evas_Object *time;
-    Evas_Object *smiley;
-    Evas_Object *grd;
-    Eina_Array *tiles;
-    Ecore_Timer *timer;
+/* typedef struct */
+/* { */
+/*     Evas_Object *remain; /\* nbr of remaing bombs *\/ */
+/*     Evas_Object *time; */
+/*     Evas_Object *smiley; */
+/*     Evas_Object *grd; */
+/*     Eina_Array *tiles; */
+/*     Ecore_Timer *timer; */
 
-    int *state;
-    int *known;
-    int nl; /* number of lines of the board */
-    int nc; /* number of columns of the board */
-    int nm; /* number of remaining mines in the board based on flagged tiles */
-    int time_count; /* time spent in game, <= 999 */
-    int pixel_sz; /* size in pixels of a tile */
+/*     int *state; */
+/*     int *known; */
+/*     int nl; /\* number of lines of the board *\/ */
+/*     int nc; /\* number of columns of the board *\/ */
+/*     int nm; /\* number of remaining mines in the board based on flagged tiles *\/ */
+/*     int time_count; /\* time spent in game, <= 999 *\/ */
+/*     int pixel_sz; /\* size in pixels of a tile *\/ */
 
-    Eina_Bool finished;
-} Ctx;
+/*     Eina_Bool finished; */
+/* } Ctx; */
 
 #endif /* ELIMINATE_H */
diff --git a/src/bin/grid.c b/src/bin/grid.c
new file mode 100644
index 0000000..9e0aaf5
--- /dev/null
+++ b/src/bin/grid.c
@@ -0,0 +1,446 @@
+/*
+ * SPDX-FileCopyrightText: Vincent Torri <vincent.to...@gmail.com>
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <Elementary.h>
+
+#include "ctx.h"
+#include "icon.h"
+#include "score.h"
+
+#define TILE(t, l, c) \
+do { \
+    Evas_Object *o = eina_list_nth(sd->tiles, l * sd->ctx->nc + c); \
+    evas_object_image_data_set(o, tile_bmp_get(t));                 \
+    evas_object_image_pixels_dirty_set(o, EINA_TRUE);               \
+} while (0)
+
+typedef struct Grid Grid;
+
+struct Grid
+{
+    /* keep these pointers */
+    Ctx *ctx;
+    Evas_Object *remain;
+    Evas_Object *smiley;
+    Evas_Object *time;
+    Evas_Object *table;
+    /* owned by this struct */
+    Evas_Object *grid;
+    Evas_Object *event;
+    Eina_List *tiles;
+    Ecore_Timer *timer;
+    int time_count;
+    Eina_Bool winner;
+};
+
+static Evas_Smart *_eli_grid_smart = NULL;
+static Evas_Smart_Class _eli_grid_parent_sc = EVAS_SMART_CLASS_INIT_NULL;
+
+static void
+uncover(Grid *sd, int l, int c)
+{
+    Ctx *ctx = sd->ctx;
+    int x;
+    int y;
+
+    if (State(l, c) == TILE_BOMB)
+        return;
+
+    if ((State(l, c) >= TILE_ONE) &&
+        (State(l, c) <= TILE_HEIGHT))
+    {
+        Known(l, c) = State(l, c);
+        TILE(State(l, c), l, c);
+        return;
+    }
+
+    Known(l, c) = TILE_NOTHING;
+    TILE(TILE_NOTHING, l, c);
+
+    for (y = -1; y <= 1; y++)
+    {
+        for (x = -1; x <= 1; x++)
+        {
+            if (!((x == 0) && (y == 0)) &&
+                is_in_board(l +  y, c + x) &&
+                (Known(l + y, c + x) == TILE_UNKNOWN))
+            {
+                uncover(sd, l + y, c + x);
+            }
+        }
+    }
+}
+
+/* time callback */
+
+static Eina_Bool
+_eli_grid_time_cb(void *data)
+{
+    Grid *sd = data;
+
+    sd->time_count++;
+    if (sd->time_count > 999)
+    {
+        ecore_timer_del(sd->timer);
+        sd->timer = NULL;
+        return ECORE_CALLBACK_CANCEL;
+    }
+
+    score_set(sd->time, sd->time_count);
+
+    return ECORE_CALLBACK_RENEW;
+}
+
+/* mouse down callback */
+
+static void
+_eli_grid_mouse_down_cb(void *sd_, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+    Grid *sd = sd_;
+
+    if (!sd->timer)
+        sd->timer = ecore_timer_add(1.0, _eli_grid_time_cb, sd);
+
+    evas_object_image_data_set(sd->smiley,
+                               smiley_bmp_get(SMILEY_SURPRISED));
+    evas_object_image_pixels_dirty_set(sd->smiley,
+                                       EINA_TRUE);
+    int x, y, w, h;
+    /* evas_object_geometry_get(cph, &x, &y, &w, &h); */
+    /* printf(" ** 1 cph : %d %d %d %d\n", x, y, w, h); */
+    evas_object_geometry_get(sd->event, &x, &y, &w, &h);
+    printf(" ** 1 cph : %d %d %d %d\n", x, y, w, h);
+}
+
+static void
+_eli_grid_mouse_up_cb(void *sd_, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event_info)
+{
+    Grid *sd = sd_;
+    Ctx *ctx;
+    Evas_Event_Mouse_Up *ev;
+    int l;
+    int c;
+    int x;
+    int y;
+    int w;
+    int h;
+
+    ctx = sd->ctx;
+    if (ctx->finished == EINA_TRUE)
+        return;
+
+    evas_object_geometry_get(obj, &x, &y, NULL, NULL);
+    tile_size_get(&w, &h);
+    ev = (Evas_Event_Mouse_Up *)event_info;
+    c = (ev->output.x - x) / (w * ctx->pixel_sz);
+    l = (ev->output.y - y) / (h * ctx->pixel_sz);
+    printf(" $$ %d %d\n", c, l);
+
+    if ((ev->button == 3) ||
+        ((ev->button == 1) &&
+         (evas_key_modifier_is_set(ev->modifiers, "Control"))))
+    {
+        if (Known(l, c) == TILE_UNKNOWN)
+        {
+            Known(l, c) = TILE_FLAG;
+            TILE(TILE_FLAG, l, c);
+            ctx->nm--;
+            score_set(sd->remain, ctx->nm);
+        }
+        else if (Known(l, c) == TILE_FLAG)
+        {
+            Known(l, c) = TILE_UNKNOWN;
+            TILE(TILE_UNKNOWN, l, c);
+            ctx->nm++;
+            score_set(sd->remain, ctx->nm);
+        }
+
+        return;
+    }
+
+    if ((ev->button == 1) && (Known(l, c) == TILE_UNKNOWN))
+    {
+        if (State(l, c) == TILE_BOMB)
+        {
+            int y;
+
+            ecore_timer_del(sd->timer);
+            sd->timer = NULL;
+            ctx->finished = EINA_TRUE;
+            evas_object_image_data_set(sd->smiley, smiley_bmp_get(SMILEY_LOST));
+            evas_object_image_pixels_dirty_set(sd->smiley, EINA_TRUE);
+
+            for (y = 0; y < ctx->nl; y++)
+            {
+                int x;
+
+                for (x = 0; x < ctx->nc; x++)
+                {
+                    /* wrongly flagged tile */
+                    if ((Known(y, x) == TILE_FLAG) &&
+                        (State(y, x) != TILE_BOMB))
+                    {
+                        Known(y, x) = TILE_BOMB_WRONG;
+                        TILE(TILE_BOMB_WRONG, y, x);
+                    }
+
+                    if (State(y, x) == TILE_BOMB)
+                    {
+                        if ((x == c) && (y == l))
+                        {
+                            Known(y, x) = TILE_BOMB_EXPLODED;
+                            TILE(TILE_BOMB_EXPLODED, y, x);
+                        }
+                        else
+                        {
+                            Known(y, x) = TILE_BOMB;
+                            TILE(TILE_BOMB, y, x);
+                        }
+                    }
+                }
+            }
+        }
+        else if (State(l, c) == TILE_NOTHING)
+        {
+            uncover(sd, l, c);
+            evas_object_image_data_set(sd->smiley, smiley_bmp_get(SMILEY_NORMAL));
+            evas_object_image_pixels_dirty_set(sd->smiley, EINA_TRUE);
+        }
+        else
+        {
+            Known(l, c) = State(l, c);
+            TILE(State(l, c), l, c);
+            evas_object_image_data_set(sd->smiley, smiley_bmp_get(SMILEY_NORMAL));
+            evas_object_image_pixels_dirty_set(sd->smiley, EINA_TRUE);
+        }
+    }
+}
+
+static void
+_eli_grid_smart_add(Evas_Object *obj)
+{
+    Grid *sd;
+
+    //INF(" * %s", __FUNCTION__);
+    printf(" * %s\n", __FUNCTION__);
+
+    sd = calloc(1, sizeof(Grid));
+    EINA_SAFETY_ON_NULL_RETURN(sd);
+
+    evas_object_smart_data_set(obj, sd);
+
+    _eli_grid_parent_sc.add(obj);
+}
+
+static void
+_eli_grid_smart_del(Evas_Object *obj)
+{
+    Grid *sd;
+    Evas_Object *o;
+
+    //INF(" * %s", __FUNCTION__);
+    printf(" * %s\n", __FUNCTION__);
+
+    sd = evas_object_smart_data_get(obj);
+    EINA_SAFETY_ON_NULL_RETURN(sd);
+
+    _eli_grid_parent_sc.del(obj);
+
+    EINA_LIST_FREE(sd->tiles, o)
+        evas_object_del(o);
+    ecore_timer_del(sd->timer);
+    evas_object_del(sd->grid);
+    evas_object_del(sd->event);
+
+    evas_object_smart_data_set(obj, NULL);
+    memset(sd, 0, sizeof(*sd));
+    free(sd);
+}
+
+static void
+_eli_grid_smart_show(Evas_Object *obj)
+{
+    Grid *sd;
+
+    //INF(" * %s", __FUNCTION__);
+    printf(" * %s begin\n", __FUNCTION__);
+    fflush(stdout);
+
+    sd = evas_object_smart_data_get(obj);
+    EINA_SAFETY_ON_NULL_RETURN(sd);
+
+    evas_object_show(sd->grid);
+    evas_object_show(sd->event);
+    printf(" * %s end\n", __FUNCTION__);
+    fflush(stdout);
+}
+
+static void
+_eli_grid_smart_hide(Evas_Object *obj)
+{
+    Grid *sd;
+
+    //INF(" * %s", __FUNCTION__);
+    printf(" * %s\n", __FUNCTION__);
+
+    sd = evas_object_smart_data_get(obj);
+    EINA_SAFETY_ON_NULL_RETURN(sd);
+
+    evas_object_hide(sd->event);
+    evas_object_hide(sd->grid);
+}
+
+static void
+_eli_grid_smart_init(void)
+{
+    static Evas_Smart_Class sc;
+
+    //INF(" * %s", __FUNCTION__);
+    printf(" * %s\n", __FUNCTION__);
+
+    evas_object_smart_clipped_smart_set(&_eli_grid_parent_sc);
+    sc           = _eli_grid_parent_sc;
+    sc.name      = "grid";
+    sc.version   = EVAS_SMART_CLASS_VERSION;
+    sc.add       = _eli_grid_smart_add;
+    sc.del       = _eli_grid_smart_del;
+//    sc.move      = _smart_move;
+//    sc.resize    = _smart_resize;
+    sc.show      = _eli_grid_smart_show;
+    sc.hide      = _eli_grid_smart_hide;
+//    sc.calculate = _smart_calculate;
+    _eli_grid_smart = evas_smart_class_new(&sc);
+}
+
+Evas_Object *
+eli_grid_add(Evas_Object *win)
+{
+    Evas *evas;
+    Evas_Object *obj;
+    Ctx *ctx;
+
+    //INF(" * %s", __FUNCTION__);
+    printf(" * %s\n", __FUNCTION__);
+
+    EINA_SAFETY_ON_NULL_RETURN_VAL(win, NULL);
+    evas = evas_object_evas_get(win);
+    if (!_eli_grid_smart) _eli_grid_smart_init();
+    obj = evas_object_smart_add(evas, _eli_grid_smart);
+
+    ctx = evas_object_data_get(win, "elimine.ctx");
+    EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
+
+    evas_object_data_set(obj, "elimine.win", win);
+
+    return obj;
+}
+
+void
+eli_grid_resize(Evas_Object *obj, int nl, int nc, int nm)
+{
+    Grid *sd;
+    Evas_Object *win;
+    Evas_Object *o;
+    int icon_w;
+    int icon_h;
+    int l;
+
+    printf(" * %s\n", __FUNCTION__);
+
+    sd = evas_object_smart_data_get(obj);
+    EINA_SAFETY_ON_NULL_RETURN(sd);
+
+    win = evas_object_data_get(obj, "elimine.win");
+    EINA_SAFETY_ON_NULL_RETURN(win);
+
+    sd->ctx = evas_object_data_get(win, "elimine.ctx");
+    EINA_SAFETY_ON_NULL_RETURN(sd->ctx);
+
+    sd->remain = evas_object_data_get(win, "elimine.remain");
+    EINA_SAFETY_ON_NULL_RETURN(sd->remain);
+
+    sd->smiley = evas_object_data_get(win, "elimine.smiley");
+    EINA_SAFETY_ON_NULL_RETURN(sd->smiley);
+
+    sd->time = evas_object_data_get(win, "elimine.time");
+    EINA_SAFETY_ON_NULL_RETURN(sd->time);
+
+    sd->table = evas_object_data_get(win, "elimine.table");
+    EINA_SAFETY_ON_NULL_RETURN(sd->table);
+
+#if 1
+    elm_grid_size_get(sd->grid, &nc, &nl);
+    if (nl != sd->ctx->nl || nc !=sd->ctx->nc)
+    {
+        if (sd->tiles)
+        {
+            Evas_Object *o;
+
+            EINA_LIST_FREE(sd->tiles, o)
+                evas_object_del(o);
+            sd->tiles = NULL;
+        }
+        ecore_timer_del(sd->timer);
+        sd->timer = NULL;
+        evas_object_del(sd->grid);
+        sd->grid = NULL;
+        evas_object_del(sd->event);
+        sd->event = NULL;
+
+        sd->ctx->nl = nl;
+        sd->ctx->nc = nc;
+        sd->ctx->nm = nm;
+    }
+
+    tile_size_get(&icon_w, &icon_h);
+    icon_w *= sd->ctx->pixel_sz;
+    icon_h *= sd->ctx->pixel_sz;
+
+    /* grid */
+    o = elm_grid_add(win);
+    printf("SIZE : %d %d\n", sd->ctx->nc, sd->ctx->nl);
+    elm_grid_size_set(o, sd->ctx->nc, sd->ctx->nl);
+    evas_object_size_hint_min_set(o, icon_w * sd->ctx->nc, icon_h * sd->ctx->nl);
+    evas_object_size_hint_max_set(o, icon_w * sd->ctx->nc, icon_h * sd->ctx->nl);
+    elm_table_pack(sd->table, o, 0, 0, 1, 1);
+    sd->grid = o;
+
+    for (l = 0; l < sd->ctx->nl; l++)
+    {
+        int c;
+
+        for (c = 0; c < sd->ctx->nc; c++)
+        {
+            Evas_Object *o;
+            Ctx *ctx = sd->ctx;
+
+            o = evas_object_image_filled_add(evas_object_evas_get(win));
+            evas_object_image_size_set(o, icon_w, icon_h);
+            evas_object_image_data_set(o, tile_bmp_get(Known(l, c)));
+            evas_object_resize(o, icon_w, icon_h);
+            evas_object_size_hint_min_set(o, icon_w, icon_h);
+            evas_object_size_hint_max_set(o, icon_w, icon_h);
+            elm_grid_pack(sd->grid, o, c, l, 1, 1);
+            /* always show the tiles */
+            evas_object_show(o);
+        }
+    }
+
+    sd->tiles = elm_grid_children_get(sd->grid);
+
+    o = evas_object_rectangle_add(evas_object_evas_get(win));
+    evas_object_color_set(o, 0, 0, 0, 0);
+    evas_object_size_hint_min_set(o, icon_w * sd->ctx->nc, icon_h * sd->ctx->nl);
+    evas_object_size_hint_max_set(o, icon_w * sd->ctx->nc, icon_h * sd->ctx->nl);
+    elm_table_pack(sd->table, o, 0, 0, 1, 1);
+    evas_object_repeat_events_set(o, EINA_TRUE);
+    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN,
+                                   _eli_grid_mouse_down_cb, sd);
+    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP,
+                                   _eli_grid_mouse_up_cb, sd);
+    sd->event = o;
+#endif
+}
+
diff --git a/src/bin/grid.h b/src/bin/grid.h
new file mode 100644
index 0000000..dbd747d
--- /dev/null
+++ b/src/bin/grid.h
@@ -0,0 +1,13 @@
+/*
+ * SPDX-FileCopyrightText: Vincent Torri <vincent.to...@gmail.com>
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef ELIMINE_GRID_H
+#define ELIMINE_GRID_H
+
+Evas_Object *eli_grid_add(Evas_Object *win);
+
+void eli_grid_resize(Evas_Object *obj, int nl, int nc, int nm);
+
+#endif /* ELIMINE_GRID_H */
diff --git a/src/bin/icon.h b/src/bin/icon.h
index 3e8d318..b5d5236 100644
--- a/src/bin/icon.h
+++ b/src/bin/icon.h
@@ -3,8 +3,8 @@
  * SPDX-License-Identifier: MIT
  */
 
-#ifndef ICON_H
-#define ICON_H
+#ifndef ELIMINE_ICON_H
+#define ELIMINE_ICON_H
 
 typedef enum
 {
@@ -65,5 +65,4 @@ void smiley_size_get(int *w, int *h);
 
 unsigned int *smiley_bmp_get(Smiley_Type t);
 
-
-#endif /* ICON_H */
+#endif /* ELIMINE_ICON_H */
diff --git a/src/bin/meson.build b/src/bin/meson.build
index 60b4785..c6fc7b2 100644
--- a/src/bin/meson.build
+++ b/src/bin/meson.build
@@ -1,10 +1,17 @@
 # SPDX-FileCopyrightText: Vincent Torri <vincent.to...@gmail.com>
 # SPDX-License-Identifier: MIT
 
+elimine_src = files([
+  'ctx.c',
+  'elimine.c',
+  'grid.c',
+  'icon.c',
+  'score.c'
+])
 
-elimine = executable('elimine',
-  files(['elimine.c', 'icon.c', 'score.c']),
-  dependencies        : [ elm_deps ],
+
+elimine = executable('elimine', elimine_src,
+  dependencies        : elm_deps,
   include_directories : config_dir,
   install             : true
 )
diff --git a/src/bin/score.c b/src/bin/score.c
index 1fba8f1..0682e44 100644
--- a/src/bin/score.c
+++ b/src/bin/score.c
@@ -5,8 +5,8 @@
 
 #include <Elementary.h>
 
+#include "ctx.h"
 #include "icon.h"
-#include "elimine.h"
 
 typedef struct Score Score;
 
diff --git a/src/bin/score.h b/src/bin/score.h
index 8ca58ef..87bd44f 100644
--- a/src/bin/score.h
+++ b/src/bin/score.h
@@ -3,8 +3,8 @@
  * SPDX-License-Identifier: MIT
  */
 
-#ifndef SCORE_H
-#define SCORE_H
+#ifndef ELIMINE_SCORE_H
+#define ELIMINE_SCORE_H
 
 Evas_Object *score_add(Evas_Object *win);
 void score_set(Evas_Object *obj, int score);

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to