[gnome-games] iagno: Make window scalable
- From: Robert Ancell <rancell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-games] iagno: Make window scalable
- Date: Thu, 29 Dec 2011 05:15:57 +0000 (UTC)
commit 6684801a700fb7a5e4e025aad3324b5b0acf99e1
Author: Robert Ancell <robert ancell canonical com>
Date: Thu Dec 29 16:15:45 2011 +1100
iagno: Make window scalable
iagno/src/game-view.vala | 184 +++++++++++++++++++++++-----------------------
iagno/src/iagno.vala | 58 ++++++++++-----
2 files changed, 129 insertions(+), 113 deletions(-)
---
diff --git a/iagno/src/game-view.vala b/iagno/src/game-view.vala
index bbb4446..50f9960 100644
--- a/iagno/src/game-view.vala
+++ b/iagno/src/game-view.vala
@@ -1,23 +1,49 @@
public class GameView : Gtk.DrawingArea
{
- private const int GRIDWIDTH = 1;
- private const int PIXMAP_FLIP_DELAY = 20;
+ /* Space between tiles in pixels */
+ private const int GRID_WIDTH = 1;
- private uint tile_width = 80;
- private uint tile_height = 80;
- private uint board_width = 648;
- private uint board_height = 648;
- private double[] dash = {4.0};
+ /* Delay in milliseconds between tile flip frames */
+ private const int PIXMAP_FLIP_DELAY = 20;
- private Cairo.Surface? tiles_surface = null;
- private Cairo.Surface? background_surface = null;
+ /* Pre-rendered image */
+ private uint render_size = 0;
+ private Cairo.Pattern? tiles_pattern = null;
+ /* The images being showed on each location */
private int[,] pixmaps;
+ /* Animation timer */
private uint animate_timeout = 0;
public signal void move (int x, int y);
+ private int tile_size
+ {
+ get
+ {
+ return int.min (get_allocated_width () / 8, get_allocated_height () / (int) 8) - GRID_WIDTH;
+ }
+ }
+
+ private int x_offset
+ {
+ get
+ {
+ return (get_allocated_width () - 8 * (tile_size + GRID_WIDTH)) / 2;
+ }
+ }
+
+ private int y_offset
+ {
+ get
+ {
+ return (get_allocated_height () - 8 * (tile_size + GRID_WIDTH)) / 2;
+ }
+ }
+
+ private int board_size { get { return (tile_size + GRID_WIDTH) * 8; } }
+
public GameView ()
{
set_events (Gdk.EventMask.EXPOSURE_MASK | Gdk.EventMask.BUTTON_PRESS_MASK);
@@ -44,11 +70,11 @@ public class GameView : Gtk.DrawingArea
}
}
- private string? _tile_set = null;
- public string? tile_set
+ private GnomeGamesSupport.Preimage? _theme = null;
+ public GnomeGamesSupport.Preimage? theme
{
- get { return _tile_set; }
- set { _tile_set = value; tiles_surface = null; redraw (); }
+ get { return _theme; }
+ set { _theme = value; tiles_pattern = null; queue_draw (); }
}
private bool _show_grid;
@@ -58,50 +84,72 @@ public class GameView : Gtk.DrawingArea
set { _show_grid = value; redraw (); }
}
+ public override void get_preferred_width (out int minimum, out int natural)
+ {
+ minimum = natural = (int) (8 * (20 + GRID_WIDTH));
+ }
+
+ public override void get_preferred_height (out int minimum, out int natural)
+ {
+ minimum = natural = (int) (8 * (20 + GRID_WIDTH));
+ }
+
public override bool draw (Cairo.Context cr)
{
if (game == null)
return false;
-
- if (tiles_surface == null)
- load_pixmaps ();
-
- var p = new Cairo.Pattern.for_surface (background_surface);
- p.set_extend (Cairo.Extend.REPEAT);
- cr.set_source (p);
- cr.move_to (0, 0);
- cr.line_to (0, board_height);
- cr.line_to (board_width, board_height);
- cr.line_to (board_width, 0);
- cr.line_to (0, 0);
- cr.fill ();
+
+ if (tiles_pattern == null || render_size != tile_size)
+ {
+ render_size = tile_size;
+ var surface = new Cairo.ImageSurface (Cairo.Format.ARGB32, tile_size * 8, tile_size * 4);
+ var c = new Cairo.Context (surface);
+ var pixbuf = theme.render (tile_size * 8, tile_size * 4);
+ Gdk.cairo_set_source_pixbuf (c, pixbuf, 0, 0);
+ c.paint ();
+
+ tiles_pattern = new Cairo.Pattern.for_surface (surface);
+ }
for (var x = 0; x < 8; x++)
{
for (var y = 0; y < 8; y++)
{
- var tile_surface_x = x * (int) (tile_width + GRIDWIDTH) - (pixmaps[x, y] % 8) * (int) tile_width;
- var tile_surface_y = y * (int) (tile_height + GRIDWIDTH) - (pixmaps[x, y] / 8) * (int) tile_height;
-
- cr.set_source_surface (tiles_surface, tile_surface_x, tile_surface_y);
- cr.rectangle (x * (tile_width + GRIDWIDTH), y * (tile_height + GRIDWIDTH), tile_width, tile_height);
+ var tile_x = x_offset + x * (tile_size + GRID_WIDTH);
+ var tile_y = y_offset + y * (tile_size + GRID_WIDTH);
+ var texture_x = (pixmaps[x, y] % 8) * tile_size;
+ var texture_y = (pixmaps[x, y] / 8) * tile_size;
+
+ var matrix = Cairo.Matrix.identity ();
+ matrix.translate (texture_x - tile_x, texture_y - tile_y);
+ tiles_pattern.set_matrix (matrix);
+ cr.set_source (tiles_pattern);
+ cr.rectangle (tile_x, tile_y, tile_size, tile_size);
cr.fill ();
}
}
if (show_grid)
{
+ /* Make sure the dash width evenly subdivides the tile height, and is at least 4 pixels long.
+ * This makes the dash crossings always cross in the same place, which looks nicer. */
+ var dash_count = (tile_size + GRID_WIDTH) / 4;
+ if (dash_count % 2 != 0)
+ dash_count--;
+ double dash[1];
+ dash[0] = ((double)(tile_size + GRID_WIDTH)) / dash_count;
+ cr.set_dash (dash, 2.5);
+
cr.set_source_rgb (1.0, 1.0, 1.0);
cr.set_operator (Cairo.Operator.DIFFERENCE);
- cr.set_dash (dash, 2.5);
- cr.set_line_width (GRIDWIDTH);
+ cr.set_line_width (GRID_WIDTH);
for (var i = 1; i < 8; i++)
{
- cr.move_to (i * board_width / 8 - 0.5, 0);
- cr.line_to (i * board_width / 8 - 0.5, board_height);
+ cr.move_to (x_offset + i * board_size / 8 - 0.5, y_offset);
+ cr.rel_line_to (0, board_size);
- cr.move_to (0, i * board_height / 8 - 0.5);
- cr.line_to (board_width, i * board_height / 8 - 0.5);
+ cr.move_to (x_offset, y_offset + i * board_size / 8 - 0.5);
+ cr.rel_line_to (board_size, 0);
}
cr.stroke ();
@@ -110,60 +158,9 @@ public class GameView : Gtk.DrawingArea
return false;
}
- private void load_pixmaps ()
- {
- var dname = GnomeGamesSupport.runtime_get_directory (GnomeGamesSupport.RuntimeDirectory.GAME_PIXMAP_DIRECTORY);
- var fname = Path.build_filename (dname, tile_set);
-
- /* fall back to default tileset if chosen set not found */
- if (!FileUtils.test (fname, FileTest.EXISTS | FileTest.IS_REGULAR))
- fname = Path.build_filename (dname, "sun_and_star.svg");
-
- if (!FileUtils.test (fname, FileTest.EXISTS | FileTest.IS_REGULAR))
- {
- stderr.printf (_("Could not find \'%s\' pixmap file\n"), fname);
- Posix.exit (Posix.EXIT_FAILURE);
- }
-
- Gdk.Pixbuf image;
- try
- {
- image = new Gdk.Pixbuf.from_file (fname);
- }
- catch (Error e)
- {
- warning ("gdk-pixbuf error %s\n", e.message);
- return;
- }
-
- tile_width = image.get_width () / 8;
- tile_height = image.get_height () / 4;
-
- /* Make sure the dash width evenly subdivides the tile height, and is at least 4 pixels long.
- * This makes the dash crossings always cross in the same place, which looks nicer. */
- var dash_count = (tile_height + GRIDWIDTH) / 4;
- if (dash_count % 2 != 0)
- dash_count--;
- dash[0] = ((double)(tile_height + GRIDWIDTH)) / dash_count;
-
- board_width = (tile_width + GRIDWIDTH) * 8;
- board_height = (tile_height + GRIDWIDTH) * 8;
- set_size_request ((int) board_width, (int) board_height);
-
- tiles_surface = get_window ().create_similar_surface (Cairo.Content.COLOR_ALPHA, image.get_width (), image.get_height ());
- var cr = new Cairo.Context (tiles_surface);
- Gdk.cairo_set_source_pixbuf (cr, image, 0, 0);
- cr.paint ();
-
- background_surface = get_window ().create_similar_surface (Cairo.Content.COLOR_ALPHA, 1, 1);
- cr = new Cairo.Context (background_surface);
- Gdk.cairo_set_source_pixbuf (cr, image, 0, 0);
- cr.paint ();
- }
-
public void redraw ()
{
- queue_draw_area (0, 0, (int) board_width, (int) board_height);
+ queue_draw ();
}
private void square_changed_cb (int x, int y)
@@ -184,7 +181,7 @@ public class GameView : Gtk.DrawingArea
if (animate_timeout == 0)
animate_timeout = Timeout.add (PIXMAP_FLIP_DELAY, animate_cb);
}
- queue_draw_area (x * (int) (tile_width + GRIDWIDTH), y * (int) (tile_height + GRIDWIDTH), (int) tile_width, (int) tile_height);
+ queue_draw_area (x_offset + x * (int) (tile_size + GRID_WIDTH), y_offset + y * (int) (tile_size + GRID_WIDTH), tile_size, tile_size);
}
private bool animate_cb ()
@@ -229,9 +226,10 @@ public class GameView : Gtk.DrawingArea
{
if (event.button == 1)
{
- var x = (int) event.x / (int) (tile_width + GRIDWIDTH);
- var y = (int) event.y / (int) (tile_height + GRIDWIDTH);
- move (x, y);
+ var x = (int) (event.x - x_offset) / (tile_size + GRID_WIDTH);
+ var y = (int) (event.y - y_offset) / (tile_size + GRID_WIDTH);
+ if (x >= 0 && x < 8 && y >= 0 && y < 8)
+ move (x, y);
}
return true;
diff --git a/iagno/src/iagno.vala b/iagno/src/iagno.vala
index 44a8c82..c5af7e9 100644
--- a/iagno/src/iagno.vala
+++ b/iagno/src/iagno.vala
@@ -101,23 +101,22 @@ public class Iagno
var menubar = (Gtk.MenuBar) ui_manager.get_widget ("/MainMenu");
vbox.pack_start (menubar, false, false, 0);
- var notebook = new Gtk.Notebook ();
- notebook.show ();
- notebook.set_show_tabs (false);
- notebook.set_show_border (false);
-
window.delete_event.connect (window_delete_event_cb);
view = new GameView ();
view.game = game;
view.move.connect (player_move_cb);
view.show_grid = settings.get_boolean ("show-grid");
- view.tile_set = settings.get_string ("tileset");
+ var tile_set = settings.get_string ("tileset");
+ var theme = load_theme_texture (tile_set);
+ if (theme == null)
+ {
+ warning ("Unable to load theme %s, falling back to default", tile_set);
+ theme = load_theme_texture ("black_and_white.svg", true);
+ }
+ view.theme = theme;
view.show ();
-
- notebook.append_page (view, null);
- notebook.set_current_page (0);
- vbox.pack_start (notebook, false, false, 0);
+ vbox.pack_start (view, true, true, 0);
statusbar = new Gtk.Statusbar ();
statusbar.show ();
@@ -144,8 +143,6 @@ public class Iagno
light_score_label.show ();
grid.attach (light_score_label, 5, 0, 1, 1);
- window.set_resizable (false);
-
statusbar_id = statusbar.get_context_id ("iagno");
GnomeGamesSupport.sound_enable (settings.get_boolean ("sound"));
@@ -158,6 +155,21 @@ public class Iagno
window.show ();
}
+ private GnomeGamesSupport.Preimage? load_theme_texture (string filename, bool fail_on_error = false)
+ {
+ var pixmap_directory = GnomeGamesSupport.runtime_get_directory (GnomeGamesSupport.RuntimeDirectory.GAME_PIXMAP_DIRECTORY);
+ var path = Path.build_filename (pixmap_directory, filename);
+ try
+ {
+ return new GnomeGamesSupport.Preimage.from_file (path);
+ }
+ catch (Error e)
+ {
+ warning ("Failed to load theme %s: %s", filename, path);
+ return null;
+ }
+ }
+
private void quit_game_cb ()
{
Gtk.main_quit ();
@@ -413,10 +425,17 @@ public class Iagno
return true;
}
- private void set_selection (Gtk.ComboBox widget)
+ private void theme_changed_cb (Gtk.ComboBox widget)
{
- view.tile_set = theme_file_list.get_nth (widget.get_active ());
- settings.set_string ("tileset", view.tile_set);
+ var tile_set = theme_file_list.get_nth (widget.get_active ());
+ settings.set_string ("tileset", tile_set);
+
+ var theme = load_theme_texture (tile_set);
+ if (theme == null)
+ warning ("Unable to load theme %s", tile_set);
+ else
+ view.theme = theme;
+
view.redraw ();
}
@@ -544,12 +563,11 @@ public class Iagno
var dir = GnomeGamesSupport.runtime_get_directory (GnomeGamesSupport.RuntimeDirectory.GAME_PIXMAP_DIRECTORY);
theme_file_list = new GnomeGamesSupport.FileList.images (dir, null);
theme_file_list.transform_basename ();
- var option_menu = (Gtk.ComboBox) theme_file_list.create_widget (view.tile_set, GnomeGamesSupport.FILE_LIST_REMOVE_EXTENSION | GnomeGamesSupport.FILE_LIST_REPLACE_UNDERSCORES);
-
- label.set_mnemonic_widget (option_menu);
- option_menu.changed.connect (set_selection);
- hbox.pack_start (option_menu, true, true, 0);
+ var theme_combo = (Gtk.ComboBox) theme_file_list.create_widget (settings.get_string ("tileset"), GnomeGamesSupport.FILE_LIST_REMOVE_EXTENSION | GnomeGamesSupport.FILE_LIST_REPLACE_UNDERSCORES);
+ label.set_mnemonic_widget (theme_combo);
+ theme_combo.changed.connect (theme_changed_cb);
+ hbox.pack_start (theme_combo, true, true, 0);
propbox.show_all ();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]