Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAgustin Zubiaga <aguz@sugarlabs.org>2012-05-01 05:10:11 (GMT)
committer Agustin Zubiaga <aguz@sugarlabs.org>2012-05-01 05:10:11 (GMT)
commitd1efc500e3c61e7233acc256b18ad3a59600db4a (patch)
treea823ace8404d91bfde6810b9be4fdcd0fa40d880
parent9cb73e89099c1ab0aac704da3594f3725a6ae2f9 (diff)
Save, read and show scores ;)
-rw-r--r--dialogs.py142
-rw-r--r--icons/score.svg132
-rw-r--r--terronesweeper.py39
3 files changed, 312 insertions, 1 deletions
diff --git a/dialogs.py b/dialogs.py
new file mode 100644
index 0000000..f82de0b
--- /dev/null
+++ b/dialogs.py
@@ -0,0 +1,142 @@
+# -*- coding: utf-8 -*-
+
+# From Ingenium Machina by Gonzalo Odiard and Manuel QuiƱones
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+from gettext import gettext as _
+import os
+
+import gobject
+import gtk
+import webkit
+
+from sugar.graphics import style
+from sugar.graphics.toolbutton import ToolButton
+from sugar.graphics.icon import Icon
+
+
+class _DialogWindow(gtk.Window):
+
+ # A base class for a modal dialog window.
+
+ def __init__(self, icon_name, title):
+ super(_DialogWindow, self).__init__()
+
+ self.set_border_width(style.LINE_WIDTH)
+ offset = style.GRID_CELL_SIZE
+ width = gtk.gdk.screen_width() - style.GRID_CELL_SIZE * 2
+ height = gtk.gdk.screen_height() - style.GRID_CELL_SIZE * 2
+ self.set_size_request(width, height)
+ self.set_position(gtk.WIN_POS_CENTER_ALWAYS)
+ self.set_decorated(False)
+ self.set_resizable(False)
+ self.set_modal(True)
+
+ vbox = gtk.VBox()
+ self.add(vbox)
+
+ toolbar = _DialogToolbar(icon_name, title)
+ toolbar.connect('stop-clicked', self._stop_clicked_cb)
+ vbox.pack_start(toolbar, False)
+
+ self.content_vbox = gtk.VBox()
+ self.content_vbox.set_border_width(style.DEFAULT_SPACING)
+ vbox.add(self.content_vbox)
+
+ self.connect('realize', self._realize_cb)
+
+ def _stop_clicked_cb(self, source):
+ self.destroy()
+
+ def _realize_cb(self, source):
+ self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
+ self.window.set_accept_focus(True)
+
+
+class _DialogToolbar(gtk.Toolbar):
+
+ # Displays a dialog window's toolbar, with title, icon, and close box.
+
+ __gsignals__ = {
+ 'stop-clicked': (gobject.SIGNAL_RUN_LAST, None, ()),
+ }
+
+ def __init__(self, icon_name, title):
+ super(_DialogToolbar, self).__init__()
+
+ if icon_name is not None:
+ sep = gtk.SeparatorToolItem()
+ sep.set_draw(False)
+ self._add_widget(sep)
+ icon = Icon()
+ icon.set_from_icon_name(icon_name, gtk.ICON_SIZE_LARGE_TOOLBAR)
+ self._add_widget(icon)
+
+ self._add_separator()
+
+ label = gtk.Label(title)
+ self._add_widget(label)
+
+ self._add_separator(expand=True)
+
+ stop = ToolButton(icon_name='dialog-cancel')
+ stop.set_tooltip(_('Done'))
+ stop.connect('clicked', self._stop_clicked_cb)
+ self.add(stop)
+
+ def _add_separator(self, expand=False):
+ separator = gtk.SeparatorToolItem()
+ separator.set_expand(expand)
+ separator.set_draw(False)
+ self.add(separator)
+
+ def _add_widget(self, widget):
+ tool_item = gtk.ToolItem()
+ tool_item.add(widget)
+ self.add(tool_item)
+
+ def _stop_clicked_cb(self, button):
+ self.emit('stop-clicked')
+
+
+class ScoreDialog(_DialogWindow):
+
+ __gtype_name__ = 'ScoreDialog'
+
+ def __init__(self, scores):
+
+ super(ScoreDialog, self).__init__("score", _('Score'))
+
+ scrollwin = gtk.ScrolledWindow()
+ scrollwin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+ self.content_vbox.pack_start(scrollwin)
+
+ liststore = gtk.ListStore(str)
+ treeview = gtk.TreeView(liststore)
+
+ time_cell = gtk.CellRendererText()
+ time_column = gtk.TreeViewColumn(_("Time"))
+
+ time_column.pack_start(time_cell)
+ time_column.set_attributes(time_cell, text=0)
+
+ treeview.append_column(time_column)
+ scores.sort()
+
+ for i in scores:
+ liststore.append([i])
+
+ scrollwin.add_with_viewport(treeview)
diff --git a/icons/score.svg b/icons/score.svg
new file mode 100644
index 0000000..4742299
--- /dev/null
+++ b/icons/score.svg
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.0"
+ width="84.862267"
+ height="78.095123"
+ id="svg4502"
+ style="display:inline"
+ inkscape:version="0.48.3.1 r9886"
+ sodipodi:docname="score.svg">
+ <metadata
+ id="metadata20">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1215"
+ inkscape:window-height="776"
+ id="namedview18"
+ showgrid="false"
+ inkscape:zoom="1"
+ inkscape:cx="-103.03863"
+ inkscape:cy="41.700533"
+ inkscape:window-x="65"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="g4395"
+ fit-margin-top="2"
+ fit-margin-left="2"
+ fit-margin-right="2"
+ fit-margin-bottom="2" />
+ <defs
+ id="defs4504">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 100 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="200 : 100 : 1"
+ inkscape:persp3d-origin="100 : 66.666667 : 1"
+ id="perspective22" />
+ </defs>
+ <g
+ transform="translate(-10.082352,65.657527)"
+ id="terron"
+ style="display:inline">
+ <g
+ id="g4395">
+ <rect
+ style="fill:none;stroke:#f7f7f7;stroke-width:5.3431983;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3049"
+ width="75.519066"
+ height="36.633076"
+ x="14.753951"
+ y="-30.1754" />
+ <rect
+ style="fill:none;stroke:#ffffff;stroke-width:5.35777044;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3819"
+ width="38.422394"
+ height="30.206703"
+ x="33.302288"
+ y="-60.978642" />
+ <text
+ xml:space="preserve"
+ style="font-size:19.42981148px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="49.897705"
+ y="-35.294449"
+ id="text3821"
+ sodipodi:linespacing="125%"
+ transform="scale(0.92818218,1.0773747)"><tspan
+ sodipodi:role="line"
+ id="tspan3823"
+ x="49.897705"
+ y="-35.294449">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:19.42981148px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="26.645958"
+ y="-5.1744781"
+ id="text3821-4"
+ sodipodi:linespacing="125%"
+ transform="scale(0.92818218,1.0773747)"><tspan
+ sodipodi:role="line"
+ id="tspan3823-1"
+ x="26.645958"
+ y="-5.1744781">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:19.42981148px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="73.573051"
+ y="-5.0112777"
+ id="text3821-4-1"
+ sodipodi:linespacing="125%"
+ transform="scale(0.92818218,1.0773747)"><tspan
+ sodipodi:role="line"
+ id="tspan3823-1-2"
+ x="73.573051"
+ y="-5.0112777">3</tspan><tspan
+ sodipodi:role="line"
+ x="73.573051"
+ y="19.275986"
+ id="tspan3879" /></text>
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:5.3431983;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 51.949911,-31.483726 0,39.249726 z"
+ id="path3881"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+</svg>
diff --git a/terronesweeper.py b/terronesweeper.py
index ac9a5f5..fb70379 100644
--- a/terronesweeper.py
+++ b/terronesweeper.py
@@ -34,6 +34,7 @@ import random
import gtk
import pango
import gobject
+import json
from sugar.activity import activity
from sugar.graphics.toolbarbox import ToolbarBox
@@ -43,6 +44,7 @@ from sugar.graphics.menuitem import MenuItem
from sugar.graphics.alert import Alert
from timer import Timer
+from dialogs import ScoreDialog
NUM_COLORS = {1: gtk.gdk.Color("#0092D0"),
2: gtk.gdk.Color("#00C51C"),
@@ -404,12 +406,17 @@ class TerronesWeeper(activity.Activity):
def time_changed(self, timer, time):
self.label.set_text(("%s: " % _("Time")) + time)
+ self.time = time
def game_over(self, table, winner):
if winner:
self.terron_button.set_icon("terron-glasses")
self.timer.stop()
self.label.set_text(self.label.get_text())
+
+ # Save score:
+ self.score.append(self.time)
+
self.alerting = self._alert_user(_("CONGRATULATIONS"),
_("You won"))
else:
@@ -429,8 +436,12 @@ class TerronesWeeper(activity.Activity):
self._flags,
self._terrones))
+ def _show_score_dialog(self, button):
+ score_dialog = ScoreDialog(self.score)
+ score_dialog.show_all()
+
def __init__(self, handle):
- activity.Activity.__init__(self, handle, False)
+ activity.Activity.__init__(self, handle, True)
self.alerting = None
self.set_title(_("TerronesWeeper"))
@@ -438,6 +449,9 @@ class TerronesWeeper(activity.Activity):
self.icon = gtk.ICON_SIZE_LARGE_TOOLBAR
self.toolbarbox = ToolbarBox()
+ self.score = []
+ self.time = None
+
self.timer = Timer()
self.timer.connect("time-changed", self.time_changed)
@@ -462,6 +476,10 @@ class TerronesWeeper(activity.Activity):
separator.set_expand(True)
self.toolbarbox.toolbar.insert(separator, -1)
+ score_btn = ToolButton("score")
+ score_btn.connect("clicked", self._show_score_dialog)
+ self.toolbarbox.toolbar.insert(score_btn, -1)
+
exit = StopButton(self)
self.toolbarbox.toolbar.insert(exit, -1)
@@ -496,3 +514,22 @@ class TerronesWeeper(activity.Activity):
self.set_canvas(self.vbox)
self.show_all()
+
+ def read_file(self, file_path):
+ jfile = open(file_path)
+ try:
+ self.score = json.load(jfile)
+ except:
+ jfile.close()
+
+ # To list
+ self.score = list(self.score)
+
+ def write_file(self, file_path):
+ jfile = open(file_path, "w")
+
+ try:
+ json.dump(tuple(self.score), jfile)
+ finally:
+ jfile.close()
+