[gnome-klotski] Replaced Game Menu with ToggleButton/TreeView for levels list.
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-klotski] Replaced Game Menu with ToggleButton/TreeView for levels list.
- Date: Mon, 4 Nov 2013 04:10:40 +0000 (UTC)
commit 42308e52661b903e0949ea06123f8ffa7ceeca84
Author: Isaac Lenton <isaac isuniversal com>
Date: Sun Nov 3 19:24:13 2013 +1000
Replaced Game Menu with ToggleButton/TreeView for levels list.
https://bugzilla.gnome.org/show_bug.cgi?id=711327
src/gnome-klotski.vala | 325 +++++++++++++++++++++++++++++-------------------
1 files changed, 195 insertions(+), 130 deletions(-)
---
diff --git a/src/gnome-klotski.vala b/src/gnome-klotski.vala
index 4336dea..0caf1fb 100644
--- a/src/gnome-klotski.vala
+++ b/src/gnome-klotski.vala
@@ -34,8 +34,12 @@ public class Klotski : Gtk.Application
private bool is_fullscreen;
private bool is_maximized;
- private Gtk.MenuItem next_menu_item;
- private Gtk.MenuItem prev_menu_item;
+ private Gtk.Box puzzles_panel;
+
+ private Gtk.Button next_button;
+ private Gtk.Button prev_button;
+ private SimpleAction next_level_action;
+ private SimpleAction prev_level_action;
private PuzzleView view;
@@ -51,9 +55,8 @@ public class Klotski : Gtk.Application
private History history;
/* The "puzzle name" remarks provide context for translation. */
- private Gtk.SizeGroup groups[3];
- private Gtk.Image[] level_images;
- private Gtk.RadioMenuItem[] level_items;
+ private Gtk.TreeStore puzzles;
+ private Gtk.TreeIter[] puzzles_items;
public const LevelInfo level[] =
{
/* puzzle name */
@@ -431,7 +434,10 @@ public class Klotski : Gtk.Application
private const GLib.ActionEntry[] action_entries =
{
{ "new-game", restart_level_cb },
+ { "show-puzzles", toggle_puzzles_cb },
{ "fullscreen", fullscreen_cb },
+ { "next-level", next_level_cb },
+ { "prev-level", prev_level_cb },
{ "scores", scores_cb },
{ "help", help_cb },
{ "about", about_cb },
@@ -453,10 +459,18 @@ public class Klotski : Gtk.Application
Gtk.Window.set_default_icon_name ("gnome-klotski");
- add_accelerator ("F11", "app.fullscreen", null);
+ add_action_entries (action_entries, this);
+ next_level_action = lookup_action ("next-level") as SimpleAction;
+ next_level_action.set_enabled (current_level < level.length - 1);
+ prev_level_action = lookup_action ("prev-level") as SimpleAction;
+ prev_level_action.set_enabled (current_level > 0);
- level_items = new Gtk.RadioMenuItem[level.length];
- level_images = new Gtk.Image[level.length];
+ add_accelerator ("<Primary>n", "app.new-game", null);
+ add_accelerator ("<Primary>q", "app.quit", null);
+ add_accelerator ("F1", "app.help", null);
+ add_accelerator ("F11", "app.fullscreen", null);
+ add_accelerator ("Page_Up", "app.next-level", null);
+ add_accelerator ("Page_Down", "app.prev-level", null);
string histfile = Path.build_filename (Environment.get_user_data_dir (), "gnome-klotski", "history");
@@ -464,17 +478,14 @@ public class Klotski : Gtk.Application
history.load ();
window = new Gtk.ApplicationWindow (this);
- window.set_title (_("Klotski"));
+ window.title = _("Klotski");
window.configure_event.connect (window_configure_event_cb);
window.window_state_event.connect (window_state_event_cb);
- int ww = settings.get_int ("window-width");
- int wh = settings.get_int ("window-height");
- if (ww < MINWIDTH)
- ww = MINWIDTH;
- if (wh < MINHEIGHT)
- wh = MINHEIGHT;
+ int ww = int.max (settings.get_int ("window-width"), MINWIDTH);
+ int wh = int.max (settings.get_int ("window-height"), MINHEIGHT);
window.set_default_size (ww, wh);
+
if (settings.get_boolean ("window-is-fullscreen"))
window.fullscreen ();
else if (settings.get_boolean ("window-is-maximized"))
@@ -495,7 +506,6 @@ public class Klotski : Gtk.Application
<item>
<attribute name='label' translatable='yes'>_New Game</attribute>
<attribute name='action'>app.new-game</attribute>
- <attribute name='accel'><Primary>n</attribute>
</item>
<item>
<attribute name='label' translatable='yes'>_Scores</attribute>
@@ -506,7 +516,6 @@ public class Klotski : Gtk.Application
<item>
<attribute name='label' translatable='yes'>_Help</attribute>
<attribute name='action'>app.help</attribute>
- <attribute name='accel'>F1</attribute>
</item>
<item>
<attribute name='label' translatable='yes'>_About</attribute>
@@ -517,7 +526,6 @@ public class Klotski : Gtk.Application
<item>
<attribute name='label' translatable='yes'>_Quit</attribute>
<attribute name='action'>app.quit</attribute>
- <attribute name='accel'><Primary>q</attribute>
</item>
</section>
</menu>
@@ -538,107 +546,6 @@ public class Klotski : Gtk.Application
set_app_menu (builder.get_object ("app-menu") as MenuModel);
- var menubar = new Gtk.MenuBar ();
- menubar.visible = true;
- vbox.pack_start (menubar, false, false, 0);
-
- var game_item = new Gtk.MenuItem ();
- game_item.label = _("_Game");
- game_item.use_underline = true;
- game_item.visible = true;
- menubar.append (game_item);
- game_item.submenu = new Gtk.Menu ();
-
- var accel_group = new Gtk.AccelGroup ();
- window.add_accel_group (accel_group);
-
- var item = new Gtk.MenuItem ();
- item.label = _("_Restart Puzzle");
- item.use_underline = true;
- item.activate.connect (restart_level_cb);
- item.add_accelerator ("activate", accel_group, Gdk.Key.R, Gdk.ModifierType.CONTROL_MASK,
Gtk.AccelFlags.VISIBLE);
- item.visible = true;
- game_item.submenu.append (item);
-
- next_menu_item = new Gtk.MenuItem ();
- next_menu_item.label = _("Next Puzzle");
- next_menu_item.activate.connect (next_level_cb);
- next_menu_item.add_accelerator ("activate", accel_group, Gdk.Key.Page_Down, 0,
Gtk.AccelFlags.VISIBLE);
- next_menu_item.visible = true;
- game_item.submenu.append (next_menu_item);
-
- prev_menu_item = new Gtk.MenuItem ();
- prev_menu_item.label = _("Previous Puzzle");
- prev_menu_item.activate.connect (prev_level_cb);
- prev_menu_item.add_accelerator ("activate", accel_group, Gdk.Key.Page_Up, 0, Gtk.AccelFlags.VISIBLE);
- prev_menu_item.visible = true;
- game_item.submenu.append (prev_menu_item);
-
- item = new Gtk.SeparatorMenuItem ();
- item.visible = true;
- game_item.submenu.append (item);
-
- var huarong_item = new Gtk.MenuItem ();
- huarong_item.label = _("HuaRong Trail");
- huarong_item.visible = true;
- huarong_item.submenu = new Gtk.Menu ();
- game_item.submenu.append (huarong_item);
-
- var challenge_item = new Gtk.MenuItem ();
- challenge_item.label = _("Challenge Pack");
- challenge_item.visible = true;
- challenge_item.submenu = new Gtk.Menu ();
- game_item.submenu.append (challenge_item);
-
- var skill_item = new Gtk.MenuItem ();
- skill_item.label = _("Skill Pack");
- skill_item.visible = true;
- skill_item.submenu = new Gtk.Menu ();
- game_item.submenu.append (skill_item);
-
- unowned SList group = null;
- for (var i = 0; i < level.length; i++)
- {
- var label = _(level[i].name);
-
- level_items[i] = new Gtk.RadioMenuItem (group);
- group = level_items[i].get_group ();
- level_items[i].visible = true;
- level_items[i].activate.connect (level_cb);
- level_items[i].set_data<int> ("level-id", i);
- switch (level[i].group)
- {
- case 0:
- huarong_item.submenu.append (level_items[i]);
- break;
- case 1:
- challenge_item.submenu.append (level_items[i]);
- break;
- case 2:
- skill_item.submenu.append (level_items[i]);
- break;
- }
-
- /* Create a label and image for the menu item */
- var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
- var labelw = new Gtk.Label (label);
- labelw.set_alignment (0.0f, 0.5f);
- var image = new Gtk.Image ();
- box.pack_start (labelw, true, true, 0);
- box.pack_start (image, false, true, 0);
-
- /* Keep all elements the same size */
- if (groups[level[i].group] == null)
- groups[level[i].group] = new Gtk.SizeGroup (Gtk.SizeGroupMode.BOTH);
- groups[level[i].group].add_widget (box);
-
- /* Replace the label with the new one */
- level_items[i].add (box);
- box.show_all ();
-
- level_images[i] = image;
- }
-
var status_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 10);
status_box.show ();
@@ -665,6 +572,14 @@ public class Klotski : Gtk.Application
new_game_button.show ();
toolbar.insert (new_game_button, -1);
+ var puzzles_button = new Gtk.ToggleToolButton ();
+ puzzles_button.action_name = "app.show-puzzles";
+ puzzles_button.label = _("_Puzzles");
+ puzzles_button.use_underline = true;
+ puzzles_button.is_important = true;
+ puzzles_button.show ();
+ toolbar.insert (puzzles_button, -1);
+
fullscreen_button = new Gtk.ToolButton (null, _("_Fullscreen"));
fullscreen_button.icon_name = "view-fullscreen";
fullscreen_button.use_underline = true;
@@ -685,10 +600,90 @@ public class Klotski : Gtk.Application
vbox.pack_start (toolbar, false, false, 0);
+ var hbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
+ hbox.show();
+
+ puzzles = new Gtk.TreeStore (3, typeof (string), typeof (bool), typeof (int));
+
+ Gtk.TreeIter huarong_item;
+ puzzles.append (out huarong_item, null);
+ puzzles.set (huarong_item, 0, "HuaRong Trail", 2, -1, -1);
+
+ Gtk.TreeIter challenge_item;
+ puzzles.append (out challenge_item, null);
+ puzzles.set (challenge_item, 0, "Challenge Pack", 2, -1, -1);
+
+ Gtk.TreeIter skill_item;
+ puzzles.append (out skill_item, null);
+ puzzles.set (skill_item, 0, "Skill Pack", 2, -1, -1);
+
+ puzzles_items = new Gtk.TreeIter[level.length];
+
+ for (var i = 0; i < level.length; i++)
+ {
+ switch (level[i].group)
+ {
+ case 0:
+ puzzles.append (out puzzles_items[i], huarong_item);
+ puzzles.set (puzzles_items[i], 0, _(level[i].name), 1, false, 2, i, -1);
+ break;
+ case 1:
+ puzzles.append (out puzzles_items[i], challenge_item);
+ puzzles.set (puzzles_items[i], 0, _(level[i].name), 1, false, 2, i, -1);
+ break;
+ case 2:
+ puzzles.append (out puzzles_items[i], skill_item);
+ puzzles.set (puzzles_items[i], 0, _(level[i].name), 1, false, 2, i, -1);
+ break;
+ }
+ }
+
+ puzzles_panel = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
+ puzzles_panel.visible = false;
+
+ var puzzles_view = new Gtk.TreeView.with_model (puzzles);
+ puzzles_view.set_headers_visible (false);
+
+ var cell = new Gtk.CellRendererText ();
+ var col = new Gtk.TreeViewColumn.with_attributes ("Puzzle", cell, "text", 0, null);
+ col.set_data<Klotski> ("app", this);
+ col.set_cell_data_func (cell, (Gtk.CellLayoutDataFunc) render_puzzle_name);
+ puzzles_view.append_column (col);
+
+ puzzles_view.insert_column_with_attributes (-1, "Complete", new CellRendererLevel (), "visible", 1,
null);
+ puzzles_view.row_activated.connect (level_cb);
+ puzzles_view.show_all ();
+
+ var scroll = new Gtk.ScrolledWindow (null, null);
+ scroll.set_policy (Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
+ scroll.add (puzzles_view);
+ scroll.show ();
+ puzzles_panel.pack_start (scroll, true, true, 0);
+
+ var bbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
+ bbox.show();
+
+ prev_button = new Gtk.Button.with_label (_("Previous Puzzle"));
+ prev_button.clicked.connect (prev_level_cb);
+ prev_button.sensitive = current_level > 0;
+ prev_button.show ();
+ bbox.add (prev_button);
+
+ next_button = new Gtk.Button.with_label (_("Next Puzzle"));
+ next_button.clicked.connect (next_level_cb);
+ next_button.sensitive = current_level < level.length - 1;
+ next_button.show ();
+ bbox.add (next_button);
+
+ puzzles_panel.pack_start (bbox, false, true, 0);
+ hbox.pack_start (puzzles_panel, false, true, 0);
+
view = new PuzzleView ();
view.set_size_request (MINWIDTH, MINHEIGHT);
view.show ();
- vbox.pack_start (view, true, true, 0);
+ hbox.pack_start (view, true, true, 0);
+
+ vbox.pack_start (hbox, true, true, 0);
vbox.pack_start (new Gtk.Separator (Gtk.Orientation.HORIZONTAL), false, false, 0);
@@ -698,6 +693,19 @@ public class Klotski : Gtk.Application
new_game (startup_level);
}
+ private static void render_puzzle_name (Gtk.CellLayout cell_layout, Gtk.CellRendererText cell,
+ Gtk.TreeModel tree_model, Gtk.TreeIter iter)
+ {
+ Value val;
+ tree_model.get_value (iter, 2, out val);
+ int selected_level = (int) val;
+ Klotski app = cell_layout.get_data<Klotski> ("app");
+ if (app.current_level == selected_level)
+ cell.weight = 700;
+ else
+ cell.weight = 400;
+ }
+
private bool window_configure_event_cb (Gdk.EventConfigure event)
{
if (!is_maximized && !is_fullscreen)
@@ -760,7 +768,7 @@ public class Klotski : Gtk.Application
{
}
- level_images[current_level].set_from_icon_name ("gtk-yes", Gtk.IconSize.MENU);
+ puzzles.set (puzzles_items[current_level], 1, true, -1);
var date = new DateTime.now_local ();
var entry = new HistoryEntry (date, current_level, puzzle.moves);
@@ -830,18 +838,19 @@ public class Klotski : Gtk.Application
catch (Error e)
{
}
- if (value)
- level_images[i].set_from_icon_name ("gtk-yes", Gtk.IconSize.MENU);
+ puzzles.set (puzzles_items[i], 1, value, -1);
}
}
private void update_menu_state ()
{
- /* Puzzle Radio Action */
- level_items[current_level].active = true;
+ puzzles_panel.queue_draw ();
- next_menu_item.sensitive = current_level < level.length - 1;
- prev_menu_item.sensitive = current_level > 0;
+ next_button.sensitive = current_level < level.length - 1;
+ prev_button.sensitive = current_level > 0;
+
+ next_level_action.set_enabled (current_level < level.length - 1);
+ prev_level_action.set_enabled (current_level > 0);
update_moves_label ();
}
@@ -879,11 +888,18 @@ public class Klotski : Gtk.Application
window.destroy ();
}
- private void level_cb (Gtk.MenuItem item)
+ private void level_cb (Gtk.TreePath path, Gtk.TreeViewColumn column)
{
- if (!(item as Gtk.RadioMenuItem).active)
+ Gtk.TreeIter iter;
+ Value val;
+
+ puzzles.get_iter (out iter, path);
+ puzzles.get_value (iter, 2, out val);
+
+ int requested_level = (int) val;
+ if (requested_level < 0)
return;
- var requested_level = item.get_data<int> ("level-id");
+
if (current_level != requested_level)
new_game (requested_level);
}
@@ -893,6 +909,11 @@ public class Klotski : Gtk.Application
new_game (current_level);
}
+ private void toggle_puzzles_cb ()
+ {
+ puzzles_panel.visible = !puzzles_panel.visible;
+ }
+
private void next_level_cb ()
{
new_game (current_level + 1);
@@ -1147,3 +1168,47 @@ public class ScoreDialog : Gtk.Dialog
}
}
}
+
+private class CellRendererLevel : Gtk.CellRenderer
+{
+ private const int icon_size = 10;
+
+ public CellRendererLevel ()
+ {
+ GLib.Object ();
+ }
+
+ public override void get_size (Gtk.Widget widget, Gdk.Rectangle? cell_area,
+ out int x_offset, out int y_offset,
+ out int width, out int height)
+ {
+ x_offset = 0;
+ y_offset = 0;
+ width = height = icon_size;
+ }
+
+ public override void render (Cairo.Context ctx, Gtk.Widget widget,
+ Gdk.Rectangle background_area,
+ Gdk.Rectangle cell_area,
+ Gtk.CellRendererState flags)
+ {
+ Gdk.cairo_rectangle (ctx, background_area);
+
+ try
+ {
+ var icon_theme = Gtk.IconTheme.get_default ();
+ var icon = icon_theme.load_icon ("gtk-yes", icon_size, 0);
+
+ int x = background_area.x + (background_area.width - icon_size)/2;
+ int y = background_area.y + (background_area.height - icon_size)/2;
+ Gdk.cairo_set_source_pixbuf (ctx, icon, x, y);
+ }
+ catch (Error e)
+ {
+ warning (e.message);
+ }
+
+ ctx.fill ();
+ }
+}
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]