Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MANIFEST62
-rw-r--r--SliderPuzzleUI.py229
-rw-r--r--SliderPuzzleWidget.py72
-rw-r--r--activity/activity.info2
-rw-r--r--icons/circle-check.svg66
-rw-r--r--icons/circle-x.svg73
-rw-r--r--images/XO's/image_XO.svg (copied from images/image_XO.svg)0
-rw-r--r--images/XO's/image_XO2.svg (copied from images/image_XO2.svg)0
-rw-r--r--images/XO's/image_XO3.svg (renamed from images/image_XO3.svg)0
-rw-r--r--images/XO's/thumb.svg (renamed from images/image_XO2.svg)0
-rw-r--r--images/default_thumb.svg (renamed from images/image_XO.svg)0
-rw-r--r--images/jumbler starter pics/image_2kgl_h250_w250_lg.gifbin0 -> 3678 bytes
-rw-r--r--images/jumbler starter pics/image_aisc_h250_w313_lg.gifbin0 -> 3727 bytes
-rw-r--r--images/jumbler starter pics/image_atih_h250_w250_lg.gifbin0 -> 2353 bytes
-rw-r--r--images/jumbler starter pics/image_atlo_h250_w333_lg.gifbin0 -> 6717 bytes
-rw-r--r--images/jumbler starter pics/image_bbhs_h250_w250_lg.gifbin0 -> 1520 bytes
-rw-r--r--images/jumbler starter pics/image_bbof_h250_w250_lg.gifbin0 -> 2039 bytes
-rw-r--r--images/jumbler starter pics/image_bgim_h250_w250_lg.gifbin0 -> 9484 bytes
-rw-r--r--images/jumbler starter pics/image_bmar_h250_w230_lg.gifbin0 -> 3983 bytes
-rw-r--r--images/jumbler starter pics/image_btfi_h250_w331_lg.gifbin0 -> 4395 bytes
-rw-r--r--images/jumbler starter pics/image_cal_h250_w165_lg.gifbin0 -> 1954 bytes
-rw-r--r--images/jumbler starter pics/image_chmk_h250_w250_lg.gifbin0 -> 3786 bytes
-rw-r--r--images/jumbler starter pics/image_clor_h250_w250_lg.gifbin0 -> 2601 bytes
-rw-r--r--images/jumbler starter pics/image_col_h250_w333_lg.gifbin0 -> 5317 bytes
-rw-r--r--images/jumbler starter pics/image_czvb_h250_w250_lg.gifbin0 -> 3306 bytes
-rw-r--r--images/jumbler starter pics/image_dan_h250_w424_lg.gifbin0 -> 14533 bytes
-rw-r--r--images/jumbler starter pics/image_devin_music_w333_lg.gifbin0 -> 15967 bytes
-rw-r--r--images/jumbler starter pics/image_djstf_h250_w411_lg.gifbin0 -> 6694 bytes
-rw-r--r--images/jumbler starter pics/image_drti_h250_w322_lg.gifbin0 -> 13408 bytes
-rw-r--r--images/jumbler starter pics/image_esim_h250_w250_lg.gifbin0 -> 1933 bytes
-rw-r--r--images/jumbler starter pics/image_evms_h250_w320_lg.gifbin0 -> 5520 bytes
-rw-r--r--images/jumbler starter pics/image_fsuw_h250_w250_lg.gifbin0 -> 5468 bytes
-rw-r--r--images/jumbler starter pics/image_higc_h250_w250_lg.gifbin0 -> 2084 bytes
-rw-r--r--images/jumbler starter pics/image_howl_h250_w250_lg.gifbin0 -> 3436 bytes
-rw-r--r--images/jumbler starter pics/image_hsnr_h250_w421_lg.gifbin0 -> 9005 bytes
-rw-r--r--images/jumbler starter pics/image_joc_h250_w333_lg.gifbin0 -> 4470 bytes
-rw-r--r--images/jumbler starter pics/image_jppr_h250_w403_lg.gifbin0 -> 11730 bytes
-rw-r--r--images/jumbler starter pics/image_justi_h250_w333_lg.gifbin0 -> 34659 bytes
-rw-r--r--images/jumbler starter pics/image_kili_h250_w387_lg.gifbin0 -> 15268 bytes
-rw-r--r--images/jumbler starter pics/image_kitty_lg.gifbin0 -> 5206 bytes
-rw-r--r--images/jumbler starter pics/image_lehf_h250_w250_lg.gifbin0 -> 1523 bytes
-rw-r--r--images/jumbler starter pics/image_mbmg_h250_w250_lg.gifbin0 -> 2808 bytes
-rw-r--r--images/jumbler starter pics/image_mdic_h250_w250_lg.gifbin0 -> 2811 bytes
-rw-r--r--images/jumbler starter pics/image_mdwl_h250_w250_lg.gifbin0 -> 1917 bytes
-rw-r--r--images/jumbler starter pics/image_mrfg_h250_w333_lg.gifbin0 -> 5206 bytes
-rw-r--r--images/jumbler starter pics/image_nimo_h250_w299_lg.gifbin0 -> 5384 bytes
-rw-r--r--images/jumbler starter pics/image_oitn_h250_w250_lg.gifbin0 -> 8963 bytes
-rw-r--r--images/jumbler starter pics/image_s1macaw_lg.gifbin0 -> 14943 bytes
-rw-r--r--images/jumbler starter pics/image_sdkc_h250_w250_lg.gifbin0 -> 2290 bytes
-rw-r--r--images/jumbler starter pics/image_skat_h250_w363_lg.gifbin0 -> 4318 bytes
-rw-r--r--images/jumbler starter pics/image_skst_h250_w253_lg.gifbin0 -> 2197 bytes
-rw-r--r--images/jumbler starter pics/image_slls_h250_w333_lg.gifbin0 -> 2853 bytes
-rw-r--r--images/jumbler starter pics/image_smrr_h250_w371_lg.gifbin0 -> 9999 bytes
-rw-r--r--images/jumbler starter pics/image_sxykitton_lg.gifbin0 -> 2639 bytes
-rw-r--r--images/jumbler starter pics/image_tbtn_h250_w365_lg.gifbin0 -> 8523 bytes
-rw-r--r--images/jumbler starter pics/image_tral_h250_w404_lg.gifbin0 -> 5899 bytes
-rw-r--r--images/jumbler starter pics/image_tsoc_h250_w421_lg.gifbin0 -> 10104 bytes
-rw-r--r--images/jumbler starter pics/image_weird_h250_w384_lg.gifbin0 -> 6679 bytes
-rw-r--r--images/jumbler starter pics/image_wpwa_h250_w250_lg.gifbin0 -> 2395 bytes
-rw-r--r--images/jumbler starter pics/image_xxmrtwigxx_lg.gifbin0 -> 2818 bytes
-rw-r--r--images/jumbler starter pics/thumb.gifbin0 -> 475 bytes
-rw-r--r--locale/org.worldwideworkshop.olpc.SliderPuzzle.pot45
-rw-r--r--locale/pt/LC_MESSAGES/org.worldwideworkshop.olpc.SliderPuzzle.mobin0 -> 736 bytes
-rw-r--r--locale/pt/LC_MESSAGES/pt.po49
-rw-r--r--utils.py82
65 files changed, 566 insertions, 114 deletions
diff --git a/MANIFEST b/MANIFEST
index 892d020..4c1f74e 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,6 +1,62 @@
SliderPuzzleActivity.py
SliderPuzzleUI.py
SliderPuzzleWidget.py
-images/image_XO.svg
-images/image_XO2.svg
-images/image_XO3.svg \ No newline at end of file
+utils.py
+icons/circle-x.svg
+icons/circle-check.svg
+images/default_thumb.svg
+images/XO's/image_XO.svg
+images/XO's/image_XO2.svg
+images/XO's/image_XO3.svg
+images/XO's/thumb.svg
+images/jumbler starter pics/image_2kgl_h250_w250_lg.gif
+images/jumbler starter pics/image_aisc_h250_w313_lg.gif
+images/jumbler starter pics/image_atih_h250_w250_lg.gif
+images/jumbler starter pics/image_atlo_h250_w333_lg.gif
+images/jumbler starter pics/image_bbhs_h250_w250_lg.gif
+images/jumbler starter pics/image_bbof_h250_w250_lg.gif
+images/jumbler starter pics/image_bgim_h250_w250_lg.gif
+images/jumbler starter pics/image_bmar_h250_w230_lg.gif
+images/jumbler starter pics/image_btfi_h250_w331_lg.gif
+images/jumbler starter pics/image_cal_h250_w165_lg.gif
+images/jumbler starter pics/image_chmk_h250_w250_lg.gif
+images/jumbler starter pics/image_clor_h250_w250_lg.gif
+images/jumbler starter pics/image_col_h250_w333_lg.gif
+images/jumbler starter pics/image_czvb_h250_w250_lg.gif
+images/jumbler starter pics/image_dan_h250_w424_lg.gif
+images/jumbler starter pics/image_devin_music_w333_lg.gif
+images/jumbler starter pics/image_djstf_h250_w411_lg.gif
+images/jumbler starter pics/image_drti_h250_w322_lg.gif
+images/jumbler starter pics/image_esim_h250_w250_lg.gif
+images/jumbler starter pics/image_evms_h250_w320_lg.gif
+images/jumbler starter pics/image_fsuw_h250_w250_lg.gif
+images/jumbler starter pics/image_higc_h250_w250_lg.gif
+images/jumbler starter pics/image_howl_h250_w250_lg.gif
+images/jumbler starter pics/image_hsnr_h250_w421_lg.gif
+images/jumbler starter pics/image_joc_h250_w333_lg.gif
+images/jumbler starter pics/image_jppr_h250_w403_lg.gif
+images/jumbler starter pics/image_justi_h250_w333_lg.gif
+images/jumbler starter pics/image_kili_h250_w387_lg.gif
+images/jumbler starter pics/image_kitty_lg.gif
+images/jumbler starter pics/image_lehf_h250_w250_lg.gif
+images/jumbler starter pics/image_mbmg_h250_w250_lg.gif
+images/jumbler starter pics/image_mdic_h250_w250_lg.gif
+images/jumbler starter pics/image_mdwl_h250_w250_lg.gif
+images/jumbler starter pics/image_mrfg_h250_w333_lg.gif
+images/jumbler starter pics/image_nimo_h250_w299_lg.gif
+images/jumbler starter pics/image_oitn_h250_w250_lg.gif
+images/jumbler starter pics/image_s1macaw_lg.gif
+images/jumbler starter pics/image_sdkc_h250_w250_lg.gif
+images/jumbler starter pics/image_skat_h250_w363_lg.gif
+images/jumbler starter pics/image_skst_h250_w253_lg.gif
+images/jumbler starter pics/image_slls_h250_w333_lg.gif
+images/jumbler starter pics/image_smrr_h250_w371_lg.gif
+images/jumbler starter pics/image_sxykitton_lg.gif
+images/jumbler starter pics/image_tbtn_h250_w365_lg.gif
+images/jumbler starter pics/image_tral_h250_w404_lg.gif
+images/jumbler starter pics/image_tsoc_h250_w421_lg.gif
+images/jumbler starter pics/image_weird_h250_w384_lg.gif
+images/jumbler starter pics/image_wpwa_h250_w250_lg.gif
+images/jumbler starter pics/image_xxmrtwigxx_lg.gif
+images/jumbler starter pics/thumb.gif
+locale/pt/LC_MESSAGES/pt.po
diff --git a/SliderPuzzleUI.py b/SliderPuzzleUI.py
index be0865b..4dfa55e 100644
--- a/SliderPuzzleUI.py
+++ b/SliderPuzzleUI.py
@@ -27,9 +27,11 @@ import pygtk
pygtk.require('2.0')
import gtk, gobject, pango
+from utils import load_image
+
from gettext import gettext as _
from glob import glob
-from SliderPuzzleWidget import SliderPuzzleWidget, calculate_relative_size
+from SliderPuzzleWidget import SliderPuzzleWidget
from time import time
import os
@@ -44,7 +46,7 @@ BORDER_ALL = BORDER_VERTICAL | BORDER_HORIZONTAL
class BorderFrame (gtk.EventBox):
def __init__ (self, border=BORDER_ALL, size=5, color="#0000FF"):
gtk.EventBox.__init__(self)
- self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
+ self.set_border_color(gtk.gdk.color_parse(color))
self.inner = gtk.EventBox()
align = gtk.Alignment(1.0,1.0,1.0,1.0)
padding = [0,0,0,0]
@@ -58,35 +60,68 @@ class BorderFrame (gtk.EventBox):
padding[3] = size
align.set_padding(*padding)
align.add(self.inner)
- #self.inner = align
gtk.EventBox.add(self, align)
+ self.stack = []
+
+ def set_border_color (self, color):
+ gtk.EventBox.modify_bg(self, gtk.STATE_NORMAL, color)
+
+ def modify_bg (self, state, color):
+ self.inner.modify_bg(state, color)
def add (self, widget):
+ self.stack.append(widget)
self.inner.add(widget)
- def do_size_request (self, requisition):
- print requisition.width, requisition.height, self.inner.child
- gtk.EventBox.do_size_request(self, requisition)
- self.inner.child.request_resize()
+ def push (self, widget):
+ widget.set_size_request(*self.inner.child.get_size_request())
+ self.inner.remove(self.inner.child)
+ self.add(widget)
+
+ def pop (self):
+ if len(self.stack) > 1:
+ self.inner.remove(self.inner.child)
+ del self.stack[-1]
+ self.inner.add(self.stack[-1])
+
+ def get_allocation (self):
+ return self.inner.get_allocation()
class TimerWidget (gtk.HBox):
def __init__ (self):
gtk.HBox.__init__(self)
- self.pack_start(gtk.Label(), True, True, 0)
- eb = gtk.EventBox()
- eb.add(gtk.Label(_("Time: ")))
- self.pack_start(eb, False)
- eb = gtk.EventBox()
+ spacer = gtk.Label()
+ spacer.set_size_request(20, -1)
+ self.counter = BorderFrame(size=1, color="#4444FF")
+ self.counter.set_size_request(100, -1)
+ self.counter.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#DD4040"))
+ hb = gtk.HBox()
+ self.counter.add(hb)
+ self.pack_start(spacer, False)
+ self.pack_start(gtk.Label(_("Time: ")), False)
+
+ #eb = gtk.EventBox()
+ self.prepare_icons()
+ self.icon = gtk.Image()
+ self.icon.set_from_pixbuf(self.icons[1])
+ hb.pack_start(self.icon, False, False, 5)
self.time_label = gtk.Label("--:--")
- eb.add(self.time_label)
- self.pack_start(eb, False)
- self.pack_end(gtk.Label(), True, True, 0)
+ hb.pack_end(self.time_label, False, False, 5)
+ self.pack_start(self.counter, False)
self.connect("button-press-event", self.process_click)
self.start_time = None
self.timer_id = None
self.finished = False
+ def prepare_icons (self):
+ self.icons = []
+ self.icons.append(load_image("icons/circle-x.svg"))
+ self.icons.append(load_image("icons/circle-check.svg"))
+
+ def modify_bg(self, state, color):
+ self.foreach(lambda x: x is not self.counter and x.modify_bg(state, color))
+
def reset (self):
self.finished = False
if self.timer_id is not None:
@@ -99,6 +134,7 @@ class TimerWidget (gtk.HBox):
def start (self):
if self.finished:
return
+ self.icon.set_from_pixbuf(self.icons[0])
if self.start_time is None:
self.start_time = time()
else:
@@ -108,6 +144,7 @@ class TimerWidget (gtk.HBox):
self.timer_id = gobject.timeout_add(1000, self.do_tick)
def stop (self, finished=False):
+ self.icon.set_from_pixbuf(self.icons[1])
if self.timer_id is not None:
gobject.source_remove(self.timer_id)
self.timer_id = None
@@ -125,7 +162,7 @@ class TimerWidget (gtk.HBox):
def do_tick (self):
t = time() - self.start_time
- self.time_label.set_text("%0.2i:%0.2i" % (t/60, t%60))
+ self.time_label.set_text("%i:%0.2i" % (t/60, t%60))
return True
class ImageSelectorWidget (gtk.Table):
@@ -149,8 +186,12 @@ class ImageSelectorWidget (gtk.Table):
self.attach(br, 2,3,1,2)
self.attach(gtk.Label(),3,4,1,2)
self.filename = None
+ self.show_all()
+ self.image.set_size_request(width, height)
def next (self, *args, **kwargs):
+ if not len(self.images):
+ return
if self.filename is None or self.filename not in self.images:
pos = -1
else:
@@ -161,6 +202,8 @@ class ImageSelectorWidget (gtk.Table):
self.load_image(self.images[pos])
def previous (self, *args, **kwargs):
+ if not len(self.images):
+ return
if self.filename is None or self.filename not in self.images:
pos = len(self.images)
else:
@@ -172,36 +215,87 @@ class ImageSelectorWidget (gtk.Table):
def set_image_dir (self, directory):
self.images = glob(os.path.join(directory, "image_*"))
- self.load_image(self.images[0])
+ if len(self.images):
+ self.load_image(self.images[0])
+# else:
+# self.load_image("activity/activity-sliderpuzzle.svg")
def load_image(self, filename):
""" Loads an image from the file """
- img = gtk.Image()
- img.set_from_file(filename)
- pb = img.get_pixbuf()
- w,h = calculate_relative_size(pb.get_width(), pb.get_height(), self.width, self.height)
- scaled_pb = pb.scale_simple(w,h, gtk.gdk.INTERP_BILINEAR)
- self.image.set_from_pixbuf(scaled_pb)
- self.filename = filename
+ self.image.set_from_pixbuf(load_image(filename, self.width, self.height))
+ if len(self.images):
+ self.filename = filename
+
+class CategorySelector (gtk.ScrolledWindow):
+ __gsignals__ = {'selected' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (str,))}
+
+ def __init__ (self, path, title=None):
+ gtk.ScrolledWindow.__init__ (self)
+ self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+
+ self.path = path
+ self.thumbs = []
+ model = self.get_model(path)
+
+ treeview = gtk.TreeView()
+ col = gtk.TreeViewColumn(title)
+ r1 = gtk.CellRendererPixbuf()
+ r2 = gtk.CellRendererText()
+ col.pack_start(r1, False)
+ col.pack_start(r2, True)
+ col.set_cell_data_func(r1, self.cell_pb)
+ col.set_attributes(r2, text=1)
+ treeview.append_column(col)
+ treeview.set_model(model)
+
+ treeview.connect("cursor-changed", self.do_select)
+ self.add(treeview)
+ self.show_all()
+
+ def cell_pb (self, tvcolumn, cell, model, it):
+ cell.set_property('pixbuf', self.thumbs[model.get_value(it, 2)])
+
+ def get_pb (self, path):
+ thumbs = glob(os.path.join(path, "thumb.*"))
+ thumbs.extend(glob(os.path.join(self.path, "default_thumb.*")))
+ thumbs = filter(lambda x: os.path.exists(x), thumbs)
+ thumbs.append(None)
+ return load_image(thumbs[0], 32,32)
+
+ def get_model (self, path):
+ # Each row is (path/dirname, pretty name, 0 based index)
+ store = gtk.ListStore(str, str, int)
+ files = [os.path.join(path, x) for x in os.listdir(path) if not x.startswith('.')]
+ i = 0
+ for fullpath, prettyname in [(x, _(os.path.basename(x))) for x in files if os.path.isdir(x)]:
+ store.append([fullpath, prettyname, len(self.thumbs)])
+ self.thumbs.append(self.get_pb(fullpath))
+ return store
+
+ def do_select (self, tree, *args, **kwargs):
+ tv, it = tree.get_selection().get_selected()
+ self.emit("selected", tv.get_value(it,0))
class SliderPuzzleUI:
def __init__(self, parent):
# Basic window settings
self.window = parent
- settings = self.window.get_settings()
- settings.set_string_property("gtk-font-name", "sans bold 10", "SliderPuzzleUI")
- self.window.set_title("Slider Puzzle Activity")
+ #settings = self.window.get_settings()
+ #settings.set_string_property("gtk-font-name", "sans bold 10", "SliderPuzzleUI")
+ self.window.set_title(_("Slider Puzzle Activity"))
+
+ bgcolor = gtk.gdk.color_parse("#DDDD40")
# The actual game widget
- self.game = SliderPuzzleWidget()
+ self.game = SliderPuzzleWidget(9, 480, 480)
self.game.connect("solved", self.do_solve)
- self.game.load_image("images/image_XO.svg", 480, 480)
+ self.window.connect("key_press_event",self.game.process_key)
# The image selector with thumbnail
- self.thumb = ImageSelectorWidget(200)
+ self.thumb = ImageSelectorWidget(200, 200)
self.thumb.set_image_dir("images")
+ self.thumb.connect("button_press_event", self.do_select_category)
#self.thumb.load_image("images/image_XO.svg")
- self.window.connect("key_press_event",self.game.process_key, None)
# Buttons for selecting the number of pieces
cutter = gtk.VBox()
@@ -223,8 +317,10 @@ class SliderPuzzleUI:
# The bottom left buttons
buttons_box = BorderFrame(BORDER_TOP)
+ buttons_box.modify_bg(gtk.STATE_NORMAL, bgcolor)
inner_buttons_box = gtk.VBox(False, 5)
- btn_add = gtk.Button(_("Add My Own Picture"))
+ inner_buttons_box.set_border_width(10)
+ btn_add = gtk.Button(_("My Own Picture"))
inner_buttons_box.add(btn_add)
btn_solve = gtk.Button(_("Solve"))
btn_solve.connect("clicked", self.do_solve)
@@ -236,19 +332,23 @@ class SliderPuzzleUI:
# The timer widget
self.timer = TimerWidget()
+ self.timer.modify_bg(gtk.STATE_NORMAL, bgcolor)
+ self.timer.set_border_width(3)
# Everything on the left side of the game widget goes here
+ event_controls_box = gtk.EventBox()
+ event_controls_box.modify_bg(gtk.STATE_NORMAL, bgcolor)
controls_box = gtk.VBox(False, 5)
- controls_box.add(self.timer)
+ controls_box.pack_start(self.timer, False, False)
controls_box.add(thumb_box)
controls_box.add(buttons_box)
-
+ event_controls_box.add(controls_box)
# This is the horizontal container that holds everything
wrapping_box = gtk.HBox()
- wrapping_box.add(controls_box)
- game_box = BorderFrame(BORDER_LEFT)
- game_box.add(self.game)
- wrapping_box.add(game_box)
+ wrapping_box.add(event_controls_box)
+ self.game_box = BorderFrame(BORDER_LEFT)
+ self.game_box.add(self.game)
+ wrapping_box.add(self.game_box)
# Put a border around the whole thing
inner = BorderFrame()
inner.add(wrapping_box)
@@ -262,31 +362,48 @@ class SliderPuzzleUI:
try:
# This fails if testing outside Sugar
self.window.set_canvas(outter)
- self.dcntr = 0
- self.window.connect("activated", do_check_resize)
- self.window.connect("deactivated", do_check_resize)
except:
self.window.add(outter)
-
+
self.window.show_all()
- self.timer.start()
+ self.do_select_category(self)
+ #self.timer.start()
def set_nr_pieces (self, btn, nr_pieces):
- self.game.load_image(self.thumb.filename)
- self.game.set_nr_pieces(nr_pieces)
- self.timer.reset()
-
- def do_jumble (self, btn):
- self.game.randomize()
- self.timer.reset()
+ if self.thumb.filename:
+ if not self.game.get_parent():
+ self.game_box.pop()
+ self.game.load_image(self.thumb.filename)
+ self.game.set_nr_pieces(nr_pieces)
+ self.timer.reset()
+
+ def do_jumble (self, *args, **kwargs):
+ if self.thumb.filename:
+ if not self.game.get_parent():
+ self.game_box.pop()
+ self.game.load_image(self.thumb.filename)
+ self.game.randomize()
+ self.timer.reset()
def do_solve (self, btn):
- self.game.show_image()
- self.timer.stop(True)
-
- def do_check_resize (self, *args, **kwargs):
- self.dbg_label.set_text("%i" % self.dcntr)
- self.dcntr += 1
+ if self.thumb.filename:
+ if not self.game.get_parent():
+ self.game_box.pop()
+ self.game.show_image()
+ self.timer.stop(True)
+
+ def do_select_category(self, owner, *args, **kwargs):
+ if isinstance(owner, CategorySelector):
+ self.thumb.set_image_dir(args[0])
+ self.game_box.pop()
+ else:
+ if self.game.get_parent():
+ s = CategorySelector("images", _("Select Image Category"))
+ s.connect("selected", self.do_select_category)
+ s.show()
+ self.game_box.push(s)
+ else:
+ self.game_box.pop()
def main():
win = gtk.Window(gtk.WINDOW_TOPLEVEL)
diff --git a/SliderPuzzleWidget.py b/SliderPuzzleWidget.py
index 1d08f30..17b5c6b 100644
--- a/SliderPuzzleWidget.py
+++ b/SliderPuzzleWidget.py
@@ -29,11 +29,11 @@ import pygtk
pygtk.require('2.0')
import gtk, gobject
-from math import sqrt, pow, ceil
+from utils import load_image, calculate_matrix, debug
+
from types import TupleType, ListType
from random import random
from time import time
-import sys
###
# General Information
@@ -49,47 +49,6 @@ SLIDE_DOWN = 2
SLIDE_LEFT = 3
SLIDE_RIGHT = 4
-DEBUG = True
-
-def debug (what):
- if DEBUG:
- print >> sys.stderr, what
-
-def calculate_matrix (pieces):
- """ Given a number of pieces, calculate the best fit 2 dimensional matrix """
- rows = int(sqrt(pieces))
- cols = int(float(pieces) / rows)
- return rows*cols, rows, cols
-
-def calculate_relative_size (orig_width, orig_height, width, height):
- """ If any of width or height is -1, the returned width or height will be in the same relative scale as the
- given part.
- >>> calculate_relative_size(100, 100, 50, -1)
- (50, 50)
- >>> calculate_relative_size(200, 100, -1, 50)
- (100, 50)
-
- If both width and height are given, the same values will be returned. If none is given, the orig_* will be returned.
- >>> calculate_relative_size(200,200,100,150)
- (100, 150)
- >>> calculate_relative_size(200,200,-1,-1)
- (200, 200)
- """
- if width < 0:
- if height >= 0:
- out_w = int(orig_width * (float(height)/orig_height))
- out_h = height
- else:
- out_w = orig_width
- out_h = orig_height
- else:
- out_w = width
- if height < 0:
- out_h = int(orig_height * (float(width)/orig_width))
- else:
- out_h = height
- return out_w, out_h
-
###
# Game Logic
###
@@ -363,13 +322,15 @@ class SliderPuzzleMap (object):
class SliderPuzzleWidget (gtk.Table):
__gsignals__ = {'solved' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ())}
- def __init__ (self, pieces=9):
+ def __init__ (self, pieces=9, width=480, height=480):
self.jumbler = SliderPuzzleMap(pieces, self.jumblermap_piece_move_cb)
# We take this from the jumbler object because it may have altered our requested value
self.nr_pieces = self.jumbler.pieces
gtk.Table.__init__(self, self.jumbler.rowsize, self.jumbler.colsize)
self.image = gtk.Image()
- self.randomize()
+ self.width = width
+ self.height = height
+ self.set_size_request(width, height)
def prepare_pieces (self):
""" set up a list of UI objects that will serve as pieces, ordered correctly """
@@ -411,7 +372,7 @@ class SliderPuzzleWidget (gtk.Table):
# i is the 1 based index of the piece
self.jumbler.do_move_piece(i)
- def process_key (self, w, e, o):
+ def process_key (self, w, e):
k = gtk.gdk.keyval_name(e.keyval)
if k in up_key:
self.jumbler.do_move(SLIDE_UP)
@@ -450,17 +411,20 @@ class SliderPuzzleWidget (gtk.Table):
self.jumbler.randomize()
self.full_refresh()
- def load_image (self, filename, width=-1, height=-1):
- """ Loads an image from the file """
+ def load_image (self, filename, width=0, height=0):
+ """ Loads an image from the file.
+ width and height are processed as follows:
+ -1 : follow the loaded image size
+ 0 : follow the size set on widget instantiation
+ * : use that specific size"""
+ if width == 0:
+ width = self.width
+ if height == 0:
+ height = self.height
if width == height == -1:
self.image.set_from_file(filename)
else:
- img = gtk.Image()
- img.set_from_file(filename)
- pb = img.get_pixbuf()
- w,h = calculate_relative_size(pb.get_width(), pb.get_height(), width, height)
- scaled_pb = pb.scale_simple(w,h, gtk.gdk.INTERP_BILINEAR)
- self.image.set_from_pixbuf(scaled_pb)
+ self.image.set_from_pixbuf(load_image(filename, width, height))
self.full_refresh()
def show_image (self):
diff --git a/activity/activity.info b/activity/activity.info
index a696bc1..53d4c92 100644
--- a/activity/activity.info
+++ b/activity/activity.info
@@ -1,5 +1,5 @@
[Activity]
-name = SliderPuzzle
+name = Slider Puzzle
service_name = org.worldwideworkshop.olpc.SliderPuzzle
class = SliderPuzzleActivity.SliderPuzzleActivity
icon = activity-sliderpuzzle
diff --git a/icons/circle-check.svg b/icons/circle-check.svg
new file mode 100644
index 0000000..2c14ef1
--- /dev/null
+++ b/icons/circle-check.svg
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ 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"
+ id="Icon"
+ width="19.997831"
+ height="19.999567"
+ viewBox="0 0 46.115 46.121"
+ overflow="visible"
+ enable-background="new 0 0 46.115 46.121"
+ xml:space="preserve"
+ sodipodi:version="0.32"
+ inkscape:version="0.45"
+ sodipodi:docname="circle-check.svg"
+ sodipodi:docbase="/home/cn/work/clients/wwworkshop/pygtk/SliderPuzzle.activity/icons"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ sodipodi:modified="true"><metadata
+ id="metadata8260"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs8258" /><sodipodi:namedview
+ inkscape:window-height="621"
+ inkscape:window-width="872"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="1"
+ guidetolerance="10.0"
+ gridtolerance="10.0"
+ objecttolerance="10.0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#5affff"
+ id="base"
+ inkscape:zoom="8.8246138"
+ inkscape:cx="23.057501"
+ inkscape:cy="23.060499"
+ inkscape:window-x="79"
+ inkscape:window-y="202"
+ inkscape:current-layer="Icon"
+ width="20px"
+ height="20px" />
+<path
+ d="M 23.056,1.75 C 34.826,1.75 44.363,11.293 44.363,23.058 C 44.363,34.826 34.826,44.37 23.056,44.37 C 11.286,44.37 1.747,34.826 1.747,23.058 C 1.748,11.293 11.287,1.75 23.056,1.75 z "
+ id="path8251"
+ style="fill:none;stroke:#ffffff;stroke-width:3.5" />
+<line
+ x1="12.000999"
+ y1="24.509001"
+ x2="19.605999"
+ y2="32.112999"
+ id="line8253"
+ style="fill:none;stroke:#ffffff;stroke-width:3.5;stroke-linecap:round" />
+<line
+ x1="19.588999"
+ y1="32.155998"
+ x2="34.802002"
+ y2="16.941"
+ id="line8255"
+ style="fill:none;stroke:#ffffff;stroke-width:3.5;stroke-linecap:round" />
+</svg> \ No newline at end of file
diff --git a/icons/circle-x.svg b/icons/circle-x.svg
new file mode 100644
index 0000000..a7333c9
--- /dev/null
+++ b/icons/circle-x.svg
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ 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"
+ id="Icon"
+ width="19.997644"
+ height="19.997644"
+ viewBox="0 0 46.119 46.121"
+ overflow="visible"
+ enable-background="new 0 0 46.119 46.121"
+ xml:space="preserve"
+ sodipodi:version="0.32"
+ inkscape:version="0.45"
+ sodipodi:docname="circle-x.svg"
+ sodipodi:docbase="/home/cn/work/clients/wwworkshop/pygtk/SliderPuzzle.activity/icons"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ sodipodi:modified="true"><metadata
+ id="metadata3355"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs3353" /><sodipodi:namedview
+ inkscape:window-height="621"
+ inkscape:window-width="872"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="1"
+ guidetolerance="10.0"
+ gridtolerance="10.0"
+ objecttolerance="10.0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#0dffff"
+ id="base"
+ inkscape:zoom="8.8246138"
+ inkscape:cx="23.0595"
+ inkscape:cy="23.060499"
+ inkscape:window-x="20"
+ inkscape:window-y="134"
+ inkscape:current-layer="Icon"
+ width="20px"
+ height="20px" />
+<circle
+ cx="23.059999"
+ cy="23.061001"
+ r="21.311001"
+ id="circle3346"
+ sodipodi:cx="23.059999"
+ sodipodi:cy="23.061001"
+ sodipodi:rx="21.311001"
+ sodipodi:ry="21.311001"
+ transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,-9.5556897,23.057075)"
+ style="fill:#ff0000;fill-opacity:0;stroke:#ffffff;stroke-width:3.5;stroke-opacity:1" />
+<line
+ x1="30.564133"
+ y1="30.765953"
+ x2="15.350733"
+ y2="15.552551"
+ id="line3348"
+ style="fill:#aaaaaa;stroke:#ffffff;stroke-width:3.5;stroke-linecap:round;stroke-opacity:1" />
+<line
+ x1="15.352855"
+ y1="30.764538"
+ x2="30.564133"
+ y2="15.551845"
+ id="line3350"
+ style="fill:#aaaaaa;fill-opacity:0;stroke:#ffffff;stroke-width:3.5;stroke-linecap:round;stroke-opacity:1" />
+</svg> \ No newline at end of file
diff --git a/images/image_XO.svg b/images/XO's/image_XO.svg
index 6e4a7b3..6e4a7b3 100644
--- a/images/image_XO.svg
+++ b/images/XO's/image_XO.svg
diff --git a/images/image_XO2.svg b/images/XO's/image_XO2.svg
index fdc6618..fdc6618 100644
--- a/images/image_XO2.svg
+++ b/images/XO's/image_XO2.svg
diff --git a/images/image_XO3.svg b/images/XO's/image_XO3.svg
index 590b077..590b077 100644
--- a/images/image_XO3.svg
+++ b/images/XO's/image_XO3.svg
diff --git a/images/image_XO2.svg b/images/XO's/thumb.svg
index fdc6618..fdc6618 100644
--- a/images/image_XO2.svg
+++ b/images/XO's/thumb.svg
diff --git a/images/image_XO.svg b/images/default_thumb.svg
index 6e4a7b3..6e4a7b3 100644
--- a/images/image_XO.svg
+++ b/images/default_thumb.svg
diff --git a/images/jumbler starter pics/image_2kgl_h250_w250_lg.gif b/images/jumbler starter pics/image_2kgl_h250_w250_lg.gif
new file mode 100644
index 0000000..f6c720f
--- /dev/null
+++ b/images/jumbler starter pics/image_2kgl_h250_w250_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_aisc_h250_w313_lg.gif b/images/jumbler starter pics/image_aisc_h250_w313_lg.gif
new file mode 100644
index 0000000..177b1cb
--- /dev/null
+++ b/images/jumbler starter pics/image_aisc_h250_w313_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_atih_h250_w250_lg.gif b/images/jumbler starter pics/image_atih_h250_w250_lg.gif
new file mode 100644
index 0000000..5979e64
--- /dev/null
+++ b/images/jumbler starter pics/image_atih_h250_w250_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_atlo_h250_w333_lg.gif b/images/jumbler starter pics/image_atlo_h250_w333_lg.gif
new file mode 100644
index 0000000..12e473e
--- /dev/null
+++ b/images/jumbler starter pics/image_atlo_h250_w333_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_bbhs_h250_w250_lg.gif b/images/jumbler starter pics/image_bbhs_h250_w250_lg.gif
new file mode 100644
index 0000000..9077ac2
--- /dev/null
+++ b/images/jumbler starter pics/image_bbhs_h250_w250_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_bbof_h250_w250_lg.gif b/images/jumbler starter pics/image_bbof_h250_w250_lg.gif
new file mode 100644
index 0000000..eb14e49
--- /dev/null
+++ b/images/jumbler starter pics/image_bbof_h250_w250_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_bgim_h250_w250_lg.gif b/images/jumbler starter pics/image_bgim_h250_w250_lg.gif
new file mode 100644
index 0000000..f10dca1
--- /dev/null
+++ b/images/jumbler starter pics/image_bgim_h250_w250_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_bmar_h250_w230_lg.gif b/images/jumbler starter pics/image_bmar_h250_w230_lg.gif
new file mode 100644
index 0000000..51f2c8f
--- /dev/null
+++ b/images/jumbler starter pics/image_bmar_h250_w230_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_btfi_h250_w331_lg.gif b/images/jumbler starter pics/image_btfi_h250_w331_lg.gif
new file mode 100644
index 0000000..b0f05e3
--- /dev/null
+++ b/images/jumbler starter pics/image_btfi_h250_w331_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_cal_h250_w165_lg.gif b/images/jumbler starter pics/image_cal_h250_w165_lg.gif
new file mode 100644
index 0000000..d020ed7
--- /dev/null
+++ b/images/jumbler starter pics/image_cal_h250_w165_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_chmk_h250_w250_lg.gif b/images/jumbler starter pics/image_chmk_h250_w250_lg.gif
new file mode 100644
index 0000000..a0f650e
--- /dev/null
+++ b/images/jumbler starter pics/image_chmk_h250_w250_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_clor_h250_w250_lg.gif b/images/jumbler starter pics/image_clor_h250_w250_lg.gif
new file mode 100644
index 0000000..5f3e045
--- /dev/null
+++ b/images/jumbler starter pics/image_clor_h250_w250_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_col_h250_w333_lg.gif b/images/jumbler starter pics/image_col_h250_w333_lg.gif
new file mode 100644
index 0000000..c2dc2a8
--- /dev/null
+++ b/images/jumbler starter pics/image_col_h250_w333_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_czvb_h250_w250_lg.gif b/images/jumbler starter pics/image_czvb_h250_w250_lg.gif
new file mode 100644
index 0000000..6517bd6
--- /dev/null
+++ b/images/jumbler starter pics/image_czvb_h250_w250_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_dan_h250_w424_lg.gif b/images/jumbler starter pics/image_dan_h250_w424_lg.gif
new file mode 100644
index 0000000..f2fc0fd
--- /dev/null
+++ b/images/jumbler starter pics/image_dan_h250_w424_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_devin_music_w333_lg.gif b/images/jumbler starter pics/image_devin_music_w333_lg.gif
new file mode 100644
index 0000000..c185ac4
--- /dev/null
+++ b/images/jumbler starter pics/image_devin_music_w333_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_djstf_h250_w411_lg.gif b/images/jumbler starter pics/image_djstf_h250_w411_lg.gif
new file mode 100644
index 0000000..e7eff4f
--- /dev/null
+++ b/images/jumbler starter pics/image_djstf_h250_w411_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_drti_h250_w322_lg.gif b/images/jumbler starter pics/image_drti_h250_w322_lg.gif
new file mode 100644
index 0000000..bd14a1d
--- /dev/null
+++ b/images/jumbler starter pics/image_drti_h250_w322_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_esim_h250_w250_lg.gif b/images/jumbler starter pics/image_esim_h250_w250_lg.gif
new file mode 100644
index 0000000..807df48
--- /dev/null
+++ b/images/jumbler starter pics/image_esim_h250_w250_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_evms_h250_w320_lg.gif b/images/jumbler starter pics/image_evms_h250_w320_lg.gif
new file mode 100644
index 0000000..3b2c45e
--- /dev/null
+++ b/images/jumbler starter pics/image_evms_h250_w320_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_fsuw_h250_w250_lg.gif b/images/jumbler starter pics/image_fsuw_h250_w250_lg.gif
new file mode 100644
index 0000000..69eb3cf
--- /dev/null
+++ b/images/jumbler starter pics/image_fsuw_h250_w250_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_higc_h250_w250_lg.gif b/images/jumbler starter pics/image_higc_h250_w250_lg.gif
new file mode 100644
index 0000000..f52c054
--- /dev/null
+++ b/images/jumbler starter pics/image_higc_h250_w250_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_howl_h250_w250_lg.gif b/images/jumbler starter pics/image_howl_h250_w250_lg.gif
new file mode 100644
index 0000000..ce77aa4
--- /dev/null
+++ b/images/jumbler starter pics/image_howl_h250_w250_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_hsnr_h250_w421_lg.gif b/images/jumbler starter pics/image_hsnr_h250_w421_lg.gif
new file mode 100644
index 0000000..566cf2d
--- /dev/null
+++ b/images/jumbler starter pics/image_hsnr_h250_w421_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_joc_h250_w333_lg.gif b/images/jumbler starter pics/image_joc_h250_w333_lg.gif
new file mode 100644
index 0000000..89da89a
--- /dev/null
+++ b/images/jumbler starter pics/image_joc_h250_w333_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_jppr_h250_w403_lg.gif b/images/jumbler starter pics/image_jppr_h250_w403_lg.gif
new file mode 100644
index 0000000..4069ada
--- /dev/null
+++ b/images/jumbler starter pics/image_jppr_h250_w403_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_justi_h250_w333_lg.gif b/images/jumbler starter pics/image_justi_h250_w333_lg.gif
new file mode 100644
index 0000000..1adccf2
--- /dev/null
+++ b/images/jumbler starter pics/image_justi_h250_w333_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_kili_h250_w387_lg.gif b/images/jumbler starter pics/image_kili_h250_w387_lg.gif
new file mode 100644
index 0000000..a61eaf0
--- /dev/null
+++ b/images/jumbler starter pics/image_kili_h250_w387_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_kitty_lg.gif b/images/jumbler starter pics/image_kitty_lg.gif
new file mode 100644
index 0000000..c197337
--- /dev/null
+++ b/images/jumbler starter pics/image_kitty_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_lehf_h250_w250_lg.gif b/images/jumbler starter pics/image_lehf_h250_w250_lg.gif
new file mode 100644
index 0000000..16c25bf
--- /dev/null
+++ b/images/jumbler starter pics/image_lehf_h250_w250_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_mbmg_h250_w250_lg.gif b/images/jumbler starter pics/image_mbmg_h250_w250_lg.gif
new file mode 100644
index 0000000..3250b7e
--- /dev/null
+++ b/images/jumbler starter pics/image_mbmg_h250_w250_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_mdic_h250_w250_lg.gif b/images/jumbler starter pics/image_mdic_h250_w250_lg.gif
new file mode 100644
index 0000000..365b0dd
--- /dev/null
+++ b/images/jumbler starter pics/image_mdic_h250_w250_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_mdwl_h250_w250_lg.gif b/images/jumbler starter pics/image_mdwl_h250_w250_lg.gif
new file mode 100644
index 0000000..5979d62
--- /dev/null
+++ b/images/jumbler starter pics/image_mdwl_h250_w250_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_mrfg_h250_w333_lg.gif b/images/jumbler starter pics/image_mrfg_h250_w333_lg.gif
new file mode 100644
index 0000000..4d8ecd4
--- /dev/null
+++ b/images/jumbler starter pics/image_mrfg_h250_w333_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_nimo_h250_w299_lg.gif b/images/jumbler starter pics/image_nimo_h250_w299_lg.gif
new file mode 100644
index 0000000..f87bc58
--- /dev/null
+++ b/images/jumbler starter pics/image_nimo_h250_w299_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_oitn_h250_w250_lg.gif b/images/jumbler starter pics/image_oitn_h250_w250_lg.gif
new file mode 100644
index 0000000..3b0f64a
--- /dev/null
+++ b/images/jumbler starter pics/image_oitn_h250_w250_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_s1macaw_lg.gif b/images/jumbler starter pics/image_s1macaw_lg.gif
new file mode 100644
index 0000000..6138e2c
--- /dev/null
+++ b/images/jumbler starter pics/image_s1macaw_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_sdkc_h250_w250_lg.gif b/images/jumbler starter pics/image_sdkc_h250_w250_lg.gif
new file mode 100644
index 0000000..3f08736
--- /dev/null
+++ b/images/jumbler starter pics/image_sdkc_h250_w250_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_skat_h250_w363_lg.gif b/images/jumbler starter pics/image_skat_h250_w363_lg.gif
new file mode 100644
index 0000000..1c2a875
--- /dev/null
+++ b/images/jumbler starter pics/image_skat_h250_w363_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_skst_h250_w253_lg.gif b/images/jumbler starter pics/image_skst_h250_w253_lg.gif
new file mode 100644
index 0000000..d16102a
--- /dev/null
+++ b/images/jumbler starter pics/image_skst_h250_w253_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_slls_h250_w333_lg.gif b/images/jumbler starter pics/image_slls_h250_w333_lg.gif
new file mode 100644
index 0000000..54cc3bb
--- /dev/null
+++ b/images/jumbler starter pics/image_slls_h250_w333_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_smrr_h250_w371_lg.gif b/images/jumbler starter pics/image_smrr_h250_w371_lg.gif
new file mode 100644
index 0000000..202eb9d
--- /dev/null
+++ b/images/jumbler starter pics/image_smrr_h250_w371_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_sxykitton_lg.gif b/images/jumbler starter pics/image_sxykitton_lg.gif
new file mode 100644
index 0000000..08a1597
--- /dev/null
+++ b/images/jumbler starter pics/image_sxykitton_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_tbtn_h250_w365_lg.gif b/images/jumbler starter pics/image_tbtn_h250_w365_lg.gif
new file mode 100644
index 0000000..05b22e3
--- /dev/null
+++ b/images/jumbler starter pics/image_tbtn_h250_w365_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_tral_h250_w404_lg.gif b/images/jumbler starter pics/image_tral_h250_w404_lg.gif
new file mode 100644
index 0000000..c70ce73
--- /dev/null
+++ b/images/jumbler starter pics/image_tral_h250_w404_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_tsoc_h250_w421_lg.gif b/images/jumbler starter pics/image_tsoc_h250_w421_lg.gif
new file mode 100644
index 0000000..96a337a
--- /dev/null
+++ b/images/jumbler starter pics/image_tsoc_h250_w421_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_weird_h250_w384_lg.gif b/images/jumbler starter pics/image_weird_h250_w384_lg.gif
new file mode 100644
index 0000000..0f603bf
--- /dev/null
+++ b/images/jumbler starter pics/image_weird_h250_w384_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_wpwa_h250_w250_lg.gif b/images/jumbler starter pics/image_wpwa_h250_w250_lg.gif
new file mode 100644
index 0000000..c7739de
--- /dev/null
+++ b/images/jumbler starter pics/image_wpwa_h250_w250_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/image_xxmrtwigxx_lg.gif b/images/jumbler starter pics/image_xxmrtwigxx_lg.gif
new file mode 100644
index 0000000..4f8a273
--- /dev/null
+++ b/images/jumbler starter pics/image_xxmrtwigxx_lg.gif
Binary files differ
diff --git a/images/jumbler starter pics/thumb.gif b/images/jumbler starter pics/thumb.gif
new file mode 100644
index 0000000..c321ecb
--- /dev/null
+++ b/images/jumbler starter pics/thumb.gif
Binary files differ
diff --git a/locale/org.worldwideworkshop.olpc.SliderPuzzle.pot b/locale/org.worldwideworkshop.olpc.SliderPuzzle.pot
new file mode 100644
index 0000000..a396ada
--- /dev/null
+++ b/locale/org.worldwideworkshop.olpc.SliderPuzzle.pot
@@ -0,0 +1,45 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-05-23 23:14+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: SliderPuzzleActivity.py:15
+msgid "SliderPuzzle"
+msgstr ""
+
+#: SliderPuzzleUI.py:91
+msgid "Time: "
+msgstr ""
+
+#: SliderPuzzleUI.py:264
+msgid "Slider Puzzle Activity"
+msgstr ""
+
+#: SliderPuzzleUI.py:298
+msgid "My Own Picture"
+msgstr ""
+
+#: SliderPuzzleUI.py:300
+msgid "Solve"
+msgstr ""
+
+#: SliderPuzzleUI.py:303
+msgid "Jumble"
+msgstr ""
+
+#: SliderPuzzleUI.py:369
+msgid "Select Image Category"
+msgstr ""
diff --git a/locale/pt/LC_MESSAGES/org.worldwideworkshop.olpc.SliderPuzzle.mo b/locale/pt/LC_MESSAGES/org.worldwideworkshop.olpc.SliderPuzzle.mo
new file mode 100644
index 0000000..6bcbcb7
--- /dev/null
+++ b/locale/pt/LC_MESSAGES/org.worldwideworkshop.olpc.SliderPuzzle.mo
Binary files differ
diff --git a/locale/pt/LC_MESSAGES/pt.po b/locale/pt/LC_MESSAGES/pt.po
new file mode 100644
index 0000000..0d916cc
--- /dev/null
+++ b/locale/pt/LC_MESSAGES/pt.po
@@ -0,0 +1,49 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-05-23 23:14+0100\n"
+"PO-Revision-Date: 2007-05-23 10:48+0100\n"
+"Last-Translator: Carlos Neves <cn@sueste>\n"
+"Language-Team: Portuguese <info@worldwideworkshop.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: SliderPuzzleActivity.py:15
+msgid "SliderPuzzle"
+msgstr ""
+
+#: SliderPuzzleUI.py:91
+msgid "Time: "
+msgstr "Tempo: "
+
+#: SliderPuzzleUI.py:264
+msgid "Slider Puzzle Activity"
+msgstr ""
+
+#: SliderPuzzleUI.py:298
+msgid "My Own Picture"
+msgstr "Minha Imagem"
+
+#: SliderPuzzleUI.py:300
+msgid "Solve"
+msgstr "Resolver"
+
+#: SliderPuzzleUI.py:303
+msgid "Jumble"
+msgstr "Baralhar"
+
+#: SliderPuzzleUI.py:369
+msgid "Select Image Category"
+msgstr "Selecciona a Categoria das Imagens"
+
+msgid "jumbler starter pics"
+msgstr "Imagens iniciais do Jumbler" \ No newline at end of file
diff --git a/utils.py b/utils.py
new file mode 100644
index 0000000..7b29315
--- /dev/null
+++ b/utils.py
@@ -0,0 +1,82 @@
+#!/usr/bin/env python
+
+# 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
+#
+
+
+### utils
+### TODO: Describe
+### $Id: $
+###
+### author: Carlos Neves (cn (at) sueste.net)
+### (c) 2007 World Wide Workshop Foundation
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+
+from math import sqrt, pow, ceil
+import sys
+
+DEBUG = True
+
+def debug (what):
+ if DEBUG:
+ print >> sys.stderr, what
+
+def calculate_matrix (pieces):
+ """ Given a number of pieces, calculate the best fit 2 dimensional matrix """
+ rows = int(sqrt(pieces))
+ cols = int(float(pieces) / rows)
+ return rows*cols, rows, cols
+
+def calculate_relative_size (orig_width, orig_height, width, height):
+ """ If any of width or height is -1, the returned width or height will be in the same relative scale as the
+ given part.
+ >>> calculate_relative_size(100, 100, 50, -1)
+ (50, 50)
+ >>> calculate_relative_size(200, 100, -1, 50)
+ (100, 50)
+
+ If both width and height are given, the same values will be returned. If none is given, the orig_* will be returned.
+ >>> calculate_relative_size(200,200,100,150)
+ (100, 150)
+ >>> calculate_relative_size(200,200,-1,-1)
+ (200, 200)
+ """
+ if width < 0:
+ if height >= 0:
+ out_w = int(orig_width * (float(height)/orig_height))
+ out_h = height
+ else:
+ out_w = orig_width
+ out_h = orig_height
+ else:
+ out_w = width
+ if height < 0:
+ out_h = int(orig_height * (float(width)/orig_width))
+ else:
+ out_h = height
+ return out_w, out_h
+
+def load_image (filename, width=-1, height=-1):
+ img = gtk.Image()
+ img.set_from_file(filename)
+ pb = img.get_pixbuf()
+ if pb is None:
+ return None
+ w,h = calculate_relative_size(pb.get_width(), pb.get_height(), width, height)
+ scaled_pb = pb.scale_simple(w,h, gtk.gdk.INTERP_BILINEAR)
+ return scaled_pb