[five-or-more/gsoc-vala-port: 10/29] Port preview widget



commit 0895ae63f1b3c8fcd3283558dcaf8d3b3940673a
Author: ruxandraS <ruxandrasimion93 gmail com>
Date:   Thu Jun 28 11:39:27 2018 +0000

    Port preview widget

 meson.build                      |  3 +-
 src-vala/config.vapi             |  4 +--
 src-vala/game.vala               | 44 ++++++++++++++++++++++-
 src-vala/main.vala               | 10 +++---
 src-vala/meson.build             |  7 ++++
 src-vala/next-pieces-widget.vala | 74 +++++++++++++++++++++++++++++++++++++++
 src-vala/piece-generator.vala    | 37 ++++++++++++++++++++
 src-vala/piece.vala              | 14 ++++++++
 src-vala/preferences-dialog.vala |  5 +++
 src-vala/theme-renderer.vala     | 75 ++++++++++++++++++++++++++++++++++++++++
 src-vala/view.vala               | 43 +++++++++++++++++++++++
 src-vala/window.vala             | 42 ++++++++++++++++++----
 src/five-or-more.c               |  2 +-
 13 files changed, 344 insertions(+), 16 deletions(-)
---
diff --git a/meson.build b/meson.build
index 06747c5..ec8e8c7 100644
--- a/meson.build
+++ b/meson.build
@@ -15,6 +15,7 @@ pkgdata_dir = join_paths (data_dir, 'five-or-more')
 # Dependencies
 glib_min_version = '2.32'
 
+gee_dep = dependency('gee-0.8')
 gio_dep = dependency('gio-2.0', version: '>= ' + glib_min_version)
 glib_dep = dependency('glib-2.0', version: '>= ' + glib_min_version)
 gmodule_export_dep = dependency('gmodule-export-2.0')
@@ -30,7 +31,7 @@ libmath_dep = cc.find_library('m')
 conf = configuration_data()
 
 conf.set_quoted('GETTEXT_PACKAGE', meson.project_name())
-conf.set_quoted('LOCALEDIR', locale_dir)
+conf.set_quoted('LOCALE_DIRECTORY', locale_dir)
 conf.set_quoted('DATA_DIRECTORY', pkgdata_dir)
 conf.set_quoted('VERSION', meson.project_version())
 
diff --git a/src-vala/config.vapi b/src-vala/config.vapi
index e567943..3f2ffc5 100644
--- a/src-vala/config.vapi
+++ b/src-vala/config.vapi
@@ -1,4 +1,4 @@
-public const string DATADIR;
+public const string DATA_DIRECTORY;
 public const string GETTEXT_PACKAGE;
-public const string LOCALEDIR;
+public const string LOCALE_DIRECTORY;
 public const string VERSION;
diff --git a/src-vala/game.vala b/src-vala/game.vala
index 1634878..5ce6af7 100644
--- a/src-vala/game.vala
+++ b/src-vala/game.vala
@@ -1,9 +1,32 @@
-public class Game
+namespace FiveOrMore
 {
+
+public class Game : Object
+{
+    public const int N_TYPES = 7;
+    public const int N_ANIMATIONS = 4;
+
     private Settings settings;
 
     private Gdk.RGBA background_color;
     private int size;
+    private NextPiecesGenerator next_pieces_generator;
+
+    public signal Gee.ArrayList<Piece> set_next_pieces_queue (Gee.ArrayList<Piece> next_pieces_queue);
+
+    private Gee.ArrayList<Piece> _next_pieces_queue;
+    public Gee.ArrayList<Piece> next_pieces_queue
+    {
+        get { return _next_pieces_queue; }
+        set { _next_pieces_queue = set_next_pieces_queue (value); }
+    }
+
+    const GameDifficulty[] game_difficulty = {
+        { -1, -1, -1, -1 },
+        { 7, 7, 5, 3 },
+        { 9, 9, 7, 3 },
+        { 20, 15, 7, 7 }
+    };
 
     public Game (Settings settings)
     {
@@ -21,6 +44,15 @@ public class Game
         settings.changed[FiveOrMoreApp.KEY_SIZE].connect (() => {
             size = settings.get_int (FiveOrMoreApp.KEY_SIZE);
         });
+
+        next_pieces_generator = new NextPiecesGenerator (game_difficulty[size].n_next_pieces,
+                                                         game_difficulty[size].n_types);
+        next_pieces_queue = null;
+    }
+
+    public void generate_next_pieces ()
+    {
+        next_pieces_queue = next_pieces_generator.yield_next_pieces ();
     }
 }
 
@@ -32,3 +64,13 @@ enum BoardSize
     LARGE = 3,
     MAX_SIZE = 4,
 }
+
+struct GameDifficulty
+{
+    public int n_cols;
+    public int n_rows;
+    public int n_types;
+    public int n_next_pieces;
+}
+
+} // namespace FiveOrMore
diff --git a/src-vala/main.vala b/src-vala/main.vala
index 1bd3116..1ea2441 100644
--- a/src-vala/main.vala
+++ b/src-vala/main.vala
@@ -1,3 +1,5 @@
+namespace FiveOrMore
+{
 public class FiveOrMoreApp: Gtk.Application
 {
     public const string KEY_SIZE = "size";
@@ -8,8 +10,6 @@ public class FiveOrMoreApp: Gtk.Application
     private Gtk.ApplicationWindow window;
     private PreferencesDialog? preferences_dialog = null;
 
-    private Game? game = null;
-
     private const GLib.ActionEntry action_entries[] =
     {
         {"new-game", new_game_cb        },
@@ -27,7 +27,6 @@ public class FiveOrMoreApp: Gtk.Application
 
     public override void activate ()
     {
-        window = new FiveOrMore.Window (this);
         window.present ();
     }
 
@@ -36,8 +35,7 @@ public class FiveOrMoreApp: Gtk.Application
         base.startup ();
 
         settings = new Settings ("org.gnome.five-or-more");
-
-        game = new Game (settings);
+        window = new FiveOrMore.Window (this, settings);
 
         add_action_entries (action_entries, this);
     }
@@ -128,3 +126,5 @@ public class FiveOrMoreApp: Gtk.Application
                                "website", "https://wiki.gnome.org/Apps/Five%20or%20more";);
     }
 }
+
+} // namespace FiveOrMore
diff --git a/src-vala/meson.build b/src-vala/meson.build
index 7b31d1a..123ac7d 100644
--- a/src-vala/meson.build
+++ b/src-vala/meson.build
@@ -4,14 +4,21 @@ five_or_more_sources = [
   'config.vapi',
   'game.vala',
   'main.vala',
+  'next-pieces-widget.vala',
+  'piece.vala',
+  'piece-generator.vala',
   'preferences-dialog.vala',
+  'theme-renderer.vala',
+  'view.vala',
   'window.vala',
   resources,
 ]
 
 five_or_more_deps = [
+  gee_dep,
   gio_dep,
   gtk_dep,
+  librsvg_dep,
 ]
 
 five_or_more_vala_args = [
diff --git a/src-vala/next-pieces-widget.vala b/src-vala/next-pieces-widget.vala
new file mode 100644
index 0000000..3a3e3bf
--- /dev/null
+++ b/src-vala/next-pieces-widget.vala
@@ -0,0 +1,74 @@
+namespace FiveOrMore
+{
+
+public class NextPiecesWidget : Gtk.DrawingArea
+{
+    private Game? game;
+    private ThemeRenderer? theme;
+
+    private Gee.ArrayList<Piece> local_pieces_queue;
+    private int widget_height = 0;
+    private bool queue_resized = false;
+
+    public NextPiecesWidget (Game game, ThemeRenderer theme)
+    {
+        this.game = game;
+        this.theme = theme;
+
+        game.set_next_pieces_queue.connect (queue_changed);
+    }
+
+    private Gee.ArrayList<Piece> queue_changed (Gee.ArrayList<Piece> next_pieces_queue)
+    {
+        if (!queue_resized)
+        {
+            this.set_size_request (ThemeRenderer.ELEM_WIDTH * next_pieces_queue.size, 
ThemeRenderer.ELEM_HEIGHT);
+            queue_resized = true;
+        }
+
+        local_pieces_queue = next_pieces_queue;
+        queue_draw ();
+
+        int i;
+        for (i = 0; i < next_pieces_queue.size; i++)
+        {
+            stderr.printf ("[DEBUG] %d\n", local_pieces_queue[i].id);
+        }
+        stderr.printf ("\n");
+
+        return next_pieces_queue;
+    }
+
+    public override bool draw (Cairo.Context cr)
+    {
+        if (theme == null)
+            return false;
+
+        if (widget_height == 0)
+        {
+            widget_height = this.get_allocated_height ();
+        }
+
+        Gdk.RGBA background_color = Gdk.RGBA ();
+        background_color.red = background_color.green = background_color.blue = background_color.alpha = 0;
+        Gdk.cairo_set_source_rgba (cr, background_color);
+        cr.paint ();
+
+        int i;
+        for (i = 0; i < local_pieces_queue.size; i++)
+        {
+            theme.render_element (cr,
+                                  local_pieces_queue[i].id,
+                                  0,
+                                  i * ThemeRenderer.ELEM_WIDTH,
+                                  (widget_height / 2.0f) - (ThemeRenderer.ELEM_HEIGHT / 2.0f));
+
+        }
+
+        cr.stroke ();
+
+        return true;
+    }
+}
+
+} // namespace FiveOrMore
diff --git a/src-vala/piece-generator.vala b/src-vala/piece-generator.vala
new file mode 100644
index 0000000..1da2073
--- /dev/null
+++ b/src-vala/piece-generator.vala
@@ -0,0 +1,37 @@
+namespace FiveOrMore
+{
+
+public class NextPiecesGenerator
+{
+    private int n_types;
+    private int n_next_pieces;
+    private Gee.ArrayList<Piece> pieces;
+
+    public NextPiecesGenerator (int n_next_pieces, int n_types)
+    {
+        this.pieces = new Gee.ArrayList<Piece> ();
+        this.n_next_pieces = n_next_pieces;
+        this.n_types = n_types;
+    }
+
+    private int yield_next_piece ()
+    {
+        return GLib.Random.int_range (0, this.n_types);
+    }
+
+    public Gee.ArrayList<Piece> yield_next_pieces ()
+    {
+        this.pieces.clear ();
+
+        int i;
+        for (i = 0; i < this.n_next_pieces; i++)
+        {
+            int id = yield_next_piece ();
+            this.pieces.add (new Piece (id));
+        }
+
+        return this.pieces;
+    }
+}
+
+} // namespace FiveOrMore
diff --git a/src-vala/piece.vala b/src-vala/piece.vala
new file mode 100644
index 0000000..31d0024
--- /dev/null
+++ b/src-vala/piece.vala
@@ -0,0 +1,14 @@
+namespace FiveOrMore
+{
+
+public class Piece
+{
+    public int id;
+
+    public Piece (int id)
+    {
+        this.id = id;
+    }
+}
+
+} // namespace FiveOrMore
diff --git a/src-vala/preferences-dialog.vala b/src-vala/preferences-dialog.vala
index 0c3bdbe..b49398c 100644
--- a/src-vala/preferences-dialog.vala
+++ b/src-vala/preferences-dialog.vala
@@ -1,3 +1,6 @@
+namespace FiveOrMore
+{
+
 [GtkTemplate (ui = "/org/gnome/five-or-more/ui/preferences-dialog.ui")]
 public class PreferencesDialog : Gtk.Dialog
 {
@@ -59,3 +62,5 @@ public class PreferencesDialog : Gtk.Dialog
         radiobutton_large.toggled.connect (() => { size_cb (LARGE); });
     }
 }
+
+} // namespace FiveOrMore
diff --git a/src-vala/theme-renderer.vala b/src-vala/theme-renderer.vala
new file mode 100644
index 0000000..e7fb505
--- /dev/null
+++ b/src-vala/theme-renderer.vala
@@ -0,0 +1,75 @@
+namespace FiveOrMore
+{
+
+public class ThemeRenderer
+{
+    public const string THEME = "balls.svg";
+    public const int ELEM_WIDTH = 20;
+    public const int ELEM_HEIGHT = 20;
+
+    private Rsvg.Handle? theme = null;
+    private float width;
+    private float height;
+
+    private Cairo.Pattern? tile_pattern = null;
+    private Gdk.Rectangle? preview_rect = null;
+
+    public ThemeRenderer (string theme_file)
+    {
+        try
+        {
+            theme = new Rsvg.Handle.from_file (theme_file);
+            var dimensions = theme.get_dimensions ();
+            width = dimensions.width;
+            height = dimensions.height;
+        }
+        catch (Error e)
+        {
+            GLib.warning ("Unable to load theme\n");
+        }
+
+        preview_rect = Gdk.Rectangle ();
+        preview_rect.x = 0;
+        preview_rect.y = 0;
+        preview_rect.width = ELEM_WIDTH;
+        preview_rect.height = ELEM_HEIGHT;
+    }
+
+    public void render_element (Cairo.Context cr, int type, int animation, double x, double y)
+    {
+        if (tile_pattern == null)
+        {
+            var preview_surface = new Cairo.Surface.similar (cr.get_target (),
+                                                             Cairo.Content.COLOR_ALPHA,
+                                                             Game.N_ANIMATIONS * ELEM_HEIGHT,
+                                                             Game.N_TYPES * ELEM_HEIGHT);
+            var cr_preview = new Cairo.Context (preview_surface);
+            tile_pattern = new Cairo.Pattern.for_surface (preview_surface);
+
+            Cairo.Matrix matrix = Cairo.Matrix.identity ();
+            matrix.scale (Game.N_ANIMATIONS * ELEM_WIDTH / width ,
+                          Game.N_TYPES * ELEM_HEIGHT / height);
+            cr_preview.set_matrix (matrix);
+            theme.render_cairo (cr_preview);
+        }
+
+        cr.set_source (tile_pattern);
+
+        int texture_x, texture_y;
+        get_texture_pos (type, animation, out texture_x, out texture_y);
+
+        var m = Cairo.Matrix.identity ();
+        m.translate (texture_x - x, texture_y - y);
+        tile_pattern.set_matrix (m);
+
+        cr.rectangle (x, y, ELEM_WIDTH, ELEM_HEIGHT);
+        cr.fill ();
+    }
+
+    private void get_texture_pos (int type, int animation, out int texture_x, out int texture_y)
+    {
+        texture_x = ELEM_WIDTH * animation;;
+        texture_y = ELEM_HEIGHT * type;
+    }
+}
+} // namespace FiveOrMore
\ No newline at end of file
diff --git a/src-vala/view.vala b/src-vala/view.vala
new file mode 100644
index 0000000..c765079
--- /dev/null
+++ b/src-vala/view.vala
@@ -0,0 +1,43 @@
+namespace FiveOrMore
+{
+
+public class View : Gtk.DrawingArea
+{
+    private Game? game = null;
+    private ThemeRenderer? theme = null;
+
+    public View (Game game, ThemeRenderer theme)
+    {
+        this.game = game;
+        this.theme = theme;
+
+        add_events (Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.BUTTON_RELEASE_MASK);
+    }
+
+    public override bool button_press_event (Gdk.EventButton event)
+    {
+
+        if (game == null)
+            return false;
+
+        /* Ignore the 2BUTTON and 3BUTTON events. */
+        if (event.type != Gdk.EventType.BUTTON_PRESS)
+            return false;
+
+        game.generate_next_pieces ();
+
+        return true;
+    }
+
+    public override bool draw (Cairo.Context cr)
+    {
+        if (theme == null)
+            return false;
+
+        // theme.render_element (cr, 1, 0, 0, 0);
+
+        return true;
+    }
+}
+
+} // namespace FiveOrMore
diff --git a/src-vala/window.vala b/src-vala/window.vala
index 67e87d3..68fd268 100644
--- a/src-vala/window.vala
+++ b/src-vala/window.vala
@@ -1,9 +1,39 @@
-namespace FiveOrMore {
-    [GtkTemplate (ui = "/org/gnome/five-or-more/ui/five-or-more-vala.ui")]
-    public class Window : Gtk.ApplicationWindow {
+namespace FiveOrMore
+{
+
+[GtkTemplate (ui = "/org/gnome/five-or-more/ui/five-or-more-vala.ui")]
+public class Window : Gtk.ApplicationWindow
+{
+    [GtkChild]
+    private Gtk.Box preview_hbox;
+
+    [GtkChild]
+    private Gtk.Box hbox;
+
+    private Game? game = null;
+    private ThemeRenderer? theme = null;
+
+    public Window (Gtk.Application app, Settings settings)
+    {
+        Object (application: app);
+
+        game = new Game (settings);
+
+        var theme_file = Path.build_filename (DATA_DIRECTORY, "themes", ThemeRenderer.THEME);
+        theme = new ThemeRenderer (theme_file);
+
+        NextPiecesWidget next_pieces_widget = new NextPiecesWidget (game, theme);
+
+        game.generate_next_pieces ();
+        preview_hbox.pack_start (next_pieces_widget);
+        next_pieces_widget.realize ();
+        next_pieces_widget.set_visible (true);
+
+        View game_view = new View (game, theme);
+        hbox.pack_start (game_view);
+        game_view.set_visible (true);
 
-        public Window (Gtk.Application app) {
-            Object (application: app);
-        }
     }
 }
+
+} // namespace FiveOrMore
diff --git a/src/five-or-more.c b/src/five-or-more.c
index 4723885..df2a53c 100644
--- a/src/five-or-more.c
+++ b/src/five-or-more.c
@@ -47,7 +47,7 @@ main (int argc, char *argv[])
   GError *error = NULL;
 
   setlocale (LC_ALL, "");
-  bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+  bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIRECTORY);
   bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
   textdomain (GETTEXT_PACKAGE);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]