Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/SliderPuzzleUI.py
diff options
context:
space:
mode:
authorC Neves <cn@goat.(none)>2007-07-13 00:40:26 (GMT)
committer C Neves <cn@goat.(none)>2007-07-13 00:40:26 (GMT)
commitbdfca800f9a5154fdf9fd47c4e1fc2558fc48e38 (patch)
tree7bcc66cf796e6125d61b87a08656c034b3db1fcc /SliderPuzzleUI.py
parent23d005892b67a57f8fe634c819e96c48800875b4 (diff)
Too much stuff changed to document here...
Diffstat (limited to 'SliderPuzzleUI.py')
-rw-r--r--SliderPuzzleUI.py440
1 files changed, 365 insertions, 75 deletions
diff --git a/SliderPuzzleUI.py b/SliderPuzzleUI.py
index 2fc35ea..a1e69ac 100644
--- a/SliderPuzzleUI.py
+++ b/SliderPuzzleUI.py
@@ -27,7 +27,8 @@ import pygtk
pygtk.require('2.0')
import gtk, gobject, pango
-from utils import load_image
+from utils import load_image, GAME_IDLE, GAME_STARTED, GAME_FINISHED, GAME_QUIT
+#from buddy_handler import BuddyPanel
from mamamedia_ui import NotebookReaderWidget, BorderFrame, BORDER_ALL_BUT_BOTTOM, BORDER_ALL_BUT_LEFT
#from toolbar import SliderToolbar
from i18n import LanguageComboBox
@@ -38,7 +39,7 @@ from glob import glob
from SliderPuzzleWidget import SliderPuzzleWidget
from time import time
import os
-
+import md5
try:
from sugar.activity import activity
@@ -51,7 +52,8 @@ except:
SLICE_BTN_WIDTH = 50
THUMB_SIZE = 48
-GAME_SIZE = 520
+IMAGE_SIZE = 200
+GAME_SIZE = 564
MYOWNPIC_FOLDER = os.path.expanduser("~/.sugar/default/org.worldwideworkshop.olpc.SliderPuzzle.MyOwnPictures")
# Colors from Rich's UI design
@@ -92,6 +94,7 @@ def prepare_btn(btn, w=-1, h=-1):
class TimerWidget (gtk.HBox):
+ __gsignals__ = {'timer_toggle' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (bool,)),}
def __init__ (self, bg_color="#DD4040", fg_color="#4444FF", lbl_color="#DD4040"):
gtk.HBox.__init__(self)
#spacer = gtk.Label()
@@ -99,7 +102,7 @@ class TimerWidget (gtk.HBox):
#self.counter = BorderFrame(size=1, bg_color=bg_color, border_color=border_color)
self.counter = gtk.EventBox()
self.counter.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bg_color))
- self.counter.set_size_request(120, -1)
+ self.counter.set_size_request(90, -1)
hb = gtk.HBox()
self.counter.add(hb)
#self.pack_start(spacer, False)
@@ -115,7 +118,7 @@ class TimerWidget (gtk.HBox):
hb.pack_end(self.icon, False, False, 5)
self.pack_start(self.counter, False)
self.connect("button-press-event", self.process_click)
- self.start_time = None
+ self.start_time = 0
self.timer_id = None
self.finished = False
@@ -130,13 +133,12 @@ class TimerWidget (gtk.HBox):
def modify_bg(self, state, color):
self.foreach(lambda x: x is not self.counter and x.modify_bg(state, color))
- def reset (self):
+ def reset (self, auto_start=True):
+ self.set_sensitive(True)
self.finished = False
- if self.timer_id is not None:
- self.start_time = time()
- self.do_tick()
- else:
- self.start_time = None
+ self.stop()
+ self.start_time = 0
+ if auto_start:
self.start()
def start (self):
@@ -150,6 +152,7 @@ class TimerWidget (gtk.HBox):
self.do_tick()
if self.timer_id is None:
self.timer_id = gobject.timeout_add(1000, self.do_tick)
+ self.emit('timer_toggle', True)
def stop (self, finished=False):
self.icon.set_from_pixbuf(self.icons[1])
@@ -161,6 +164,7 @@ class TimerWidget (gtk.HBox):
self.time_label.set_text("--:--")
else:
self.finished = True
+ self.emit('timer_toggle', False)
def process_click (self, btn, event):
if self.timer_id is None:
@@ -168,9 +172,25 @@ class TimerWidget (gtk.HBox):
else:
self.stop()
+ def is_running (self):
+ return self.timer_id is not None
+
+ def ellapsed (self):
+ if self.is_running():
+ return time() - self.start_time
+ else:
+ return self.start_time
+
+ def is_reset (self):
+ return not self.is_running() and self.start_time == 0
+
def do_tick (self):
t = time() - self.start_time
- self.time_label.set_text("%i:%0.2i" % (t/60, t%60))
+ if t > 5999:
+ # wrap timer
+ t = 0
+ self.start_time = time()
+ self.time_label.set_text("%0.2i:%0.2i" % (t/60, t%60))
return True
def _freeze (self):
@@ -213,7 +233,6 @@ class CategoryDirectory (object):
self.images.extend(glob(os.path.join(self.path, "image_*")))
self.images.sort()
-
def set_image_size (self, w, h):
self.width = w
self.height = h
@@ -279,6 +298,7 @@ class ImageSelectorWidget (gtk.Table):
def __init__ (self, width=-1, height=-1, frame_color=None):
gtk.Table.__init__(self, 2,5,False)
+ self._signals = []
self.width = width
self.height = height
self.image = gtk.Image()
@@ -286,42 +306,73 @@ class ImageSelectorWidget (gtk.Table):
img_box = BorderFrame(border_color=frame_color)
img_box.add(self.image)
img_box.set_border_width(5)
- img_box.connect('button_press_event', self.emit_image_pressed)
+ self._signals.append((img_box, img_box.connect('button_press_event', self.emit_image_pressed)))
self.attach(img_box, 0,5,0,1,0,0)
self.attach(gtk.Label(), 0,1,1,2)
- bl = gtk.Button()
+ self.bl = gtk.Button()
il = gtk.Image()
il.set_from_pixbuf(load_image('icons/arrow_left.png'))
- bl.set_image(il)
+ self.bl.set_image(il)
- bl.connect('clicked', self.previous)
- self.attach(prepare_btn(bl), 1,2,1,2,0,0)
+ self.bl.connect('clicked', self.previous)
+ self.attach(prepare_btn(self.bl), 1,2,1,2,0,0)
cteb = gtk.EventBox()
self.cat_thumb = gtk.Image()
self.cat_thumb.set_size_request(THUMB_SIZE, THUMB_SIZE)
cteb.add(self.cat_thumb)
- cteb.connect('button_press_event', self.emit_cat_pressed)
+ self._signals.append((cteb, cteb.connect('button_press_event', self.emit_cat_pressed)))
self.attach(cteb, 2,3,1,2,0,0,xpadding=10)
- br = gtk.Button()
+ self.br = gtk.Button()
ir = gtk.Image()
ir.set_from_pixbuf(load_image('icons/arrow_right.png'))
- br.set_image(ir)
- br.connect('clicked', self.next)
- self.attach(prepare_btn(br), 3,4,1,2,0,0)
+ self.br.set_image(ir)
+ self.br.connect('clicked', self.next)
+ self.attach(prepare_btn(self.br), 3,4,1,2,0,0)
self.attach(gtk.Label(),4,5,1,2)
self.filename = None
self.show_all()
self.image.set_size_request(width, height)
+ def set_readonly (self, ro=True):
+ if ro:
+ self.bl.hide()
+ self.br.hide()
+ for w, s in self._signals:
+ w.handler_block(s)
+
def set_myownpath (self, path):
""" Sets the path to My Own Pictures storage, so we know where to add links to new pictures """
if not os.path.exists(path):
os.mkdir(path)
self.myownpath = path
+ def is_myownpath (self):
+ """ Checks current path against the set custom image path """
+ return self.myownpath == self.category.path
+
+ def gather_myownpath_images(self):
+ """ """
+ rv = []
+ self.images = []
+ links = glob(os.path.join(self.myownpath, "*.lnk"))
+ for link in links:
+ linfo = filter(None, map(lambda x: x.strip(), file(link).readlines()))
+ fpath = linfo[0]
+ if os.path.isfile(fpath) and not (fpath in self.images):
+ self.images.append(fpath)
+ if len(linfo) > 1:
+ digest = linfo[1]
+ else:
+ digest = md5.new(file(fpath, 'rb').read()).hexdigest()
+ rv.append((link, fpath, digest))
+ for fpath in glob(os.path.join(self.myownpath, "image_*")):
+ digest = md5.new(file(fpath, 'rb').read()).hexdigest()
+ rv.append((fpath, fpath, digest))
+ return rv
+
def emit_cat_pressed (self, *args):
self.emit('category_press')
return True
@@ -349,12 +400,22 @@ class ImageSelectorWidget (gtk.Table):
return self.category.path
def set_image_dir (self, directory):
+ if os.path.exists(directory) and not os.path.isdir(directory):
+ filename = directory
+ directory = os.path.dirname(directory)
+ logging.debug("dir=%s, filename=%s" % (directory, filename))
+ else:
+ logging.debug("dir=%s" % (directory))
+ filename = None
self.category = CategoryDirectory(directory, self.width, self.height)
self.cat_thumb.set_from_pixbuf(self.category.thumb)
- if self.category.has_images():
- self.next()
+ if filename:
+ self.image.set_from_pixbuf(self.category.get_image(filename))
+ else:
+ if self.category.has_images():
+ self.next()
- def load_image(self, filename, force_filename=False):
+ def load_image(self, filename):
""" Loads an image from the file """
if self.myownpath is not None and os.path.isdir(self.myownpath):
name = os.path.splitext(os.path.basename(filename))[0]
@@ -362,6 +423,8 @@ class ImageSelectorWidget (gtk.Table):
name = name + '_'
f = file(os.path.join(self.myownpath, '%s.lnk' % name), 'w')
f.write(filename)
+ image_digest = md5.new(file(filename, 'rb').read()).hexdigest()
+ f.write('\n%s' % image_digest)
f.close()
self.category = CategoryDirectory(self.myownpath, self.width, self.height)
self.image.set_from_pixbuf(self.category.get_image(filename))
@@ -436,7 +499,7 @@ class CategorySelector (gtk.ScrolledWindow):
self.thumbs.append(self.get_pb(fullpath))
if os.path.isdir(MYOWNPIC_FOLDER):
count = CategoryDirectory(MYOWNPIC_FOLDER).count_images()
- store.append([MYOWNPIC_FOLDER, _("My Own Pictures") + (" (%i)" % count), len(self.thumbs)])
+ store.append([MYOWNPIC_FOLDER, _("My Pictures") + (" (%i)" % count), len(self.thumbs)])
self.thumbs.append(self.get_pb(MYOWNPIC_FOLDER))
i = store.get_iter_first()
@@ -456,11 +519,81 @@ class CategorySelector (gtk.ScrolledWindow):
tv, it = tree.get_selection().get_selected()
self.emit("selected", tv.get_value(it,0))
+class BuddyPanel (gtk.ScrolledWindow):
+ def __init__ (self):
+ super(BuddyPanel, self).__init__()
+ self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+
+ self.model = gtk.ListStore(str, str, str)
+ self.model.set_sort_column_id(0, gtk.SORT_ASCENDING)
+ self.treeview = gtk.TreeView()
+
+ col = gtk.TreeViewColumn(_("Buddy"))
+ r = gtk.CellRendererText()
+ col.pack_start(r, True)
+ col.set_attributes(r, text=0)
+ self.treeview.append_column(col)
+
+ col = gtk.TreeViewColumn(_("Status"))
+ r = gtk.CellRendererText()
+ col.pack_start(r, True)
+ col.set_attributes(r, text=1)
+ self.treeview.append_column(col)
+
+ col = gtk.TreeViewColumn(_("Play Time"))
+ r = gtk.CellRendererText()
+ col.pack_start(r, True)
+ col.set_attributes(r, text=2)
+ self.treeview.append_column(col)
+ self.treeview.set_model(self.model)
+ self.add(self.treeview)
+ self.show_all()
+
+ self.players = {}
+
+ def add_player (self, buddy):
+ op = buddy.object_path()
+ if self.players.get(op) is not None:
+ return
+
+ nick = buddy.props.nick
+ if not nick:
+ nick = ""
+ self.players[op] = (buddy, self.model.append([nick, _('synchronizing'), '']))
+
+ def update_player (self, buddy, status, clock_running, time_ellapsed):
+ op = buddy.object_path()
+ if self.players.get(op, None) is None:
+ return
+ print self.players[op]
+ if status == GAME_STARTED[1]:
+ stat = clock_running and _("Playing") or _("Paused")
+ elif status == GAME_FINISHED[1]:
+ stat = _("Finished")
+ elif status == GAME_QUIT[1]:
+ stat = _("Gave up")
+ else:
+ stat = _("Unknown")
+ self.model.set_value(self.players[op][1], 1, stat)
+ self.model.set_value(self.players[op][1], 2, _("%i minutes") % (time_ellapsed/60))
+
+ def get_buddy_from_path (self, object_path):
+ logging.debug("op = " + object_path)
+ logging.debug(self.players)
+ return self.players.get(object_path, None)
+
+ def remove_player (self, buddy):
+ pass
+
class SliderPuzzleUI (gtk.Table):
+ __gsignals__ = {'game-state-changed' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (int,))}
+
def __init__(self, parent):
super(SliderPuzzleUI, self).__init__(3,3,False)
+ self.set_name('ui')
+ self._state = GAME_IDLE
# Add our own icons here, needed for the translation flags
theme = gtk.icon_theme_get_default()
theme.append_search_path(os.path.join(os.getcwd(), 'icons'))
@@ -495,13 +628,18 @@ class SliderPuzzleUI (gtk.Table):
controls_area_1 = BorderFrame(border=BORDER_ALL_BUT_BOTTOM,
bg_color=COLOR_BG_CONTROLS,
border_color=COLOR_FRAME_CONTROLS)
- controls_area_1_box = gtk.VBox(False)
- vbox = gtk.VBox()
- controls_vbox.pack_start(controls_area_1)
- vbox.pack_start(controls_area_1_box, padding=5)
- controls_area_1.add(vbox)
+ controls_area_box = gtk.VBox(False)
+ #controls_area_1_box = gtk.VBox(False)
+ controls_area = gtk.VBox()
+ controls_vbox.pack_start(controls_area_1)
+ controls_area_1.add(controls_area)
+ controls_area.pack_start(controls_area_box, padding=5)
+
# Slice buttons
+ spacer = gtk.Label()
+ spacer.set_size_request(-1, 15)
+ controls_area_box.pack_start(spacer, expand=False, fill=False)
cutter = gtk.HBox(False, 8)
cutter.pack_start(gtk.Label(), True)
self.btn_9 = prepare_btn(gtk.ToggleButton("9"),SLICE_BTN_WIDTH)
@@ -515,38 +653,45 @@ class SliderPuzzleUI (gtk.Table):
self.btn_16.connect("clicked", self.set_nr_pieces, 16)
cutter.pack_start(self.btn_16, False, False)
cutter.pack_start(gtk.Label(), True)
- controls_area_1_box.pack_start(cutter, True)
+ controls_area_box.pack_start(cutter, True)
+ spacer = gtk.Label()
+ spacer.set_size_request(-1, 10)
+ controls_area_box.pack_start(spacer, expand=False, fill=False)
# The image selector with thumbnail
- self.thumb = ImageSelectorWidget(180, 180, frame_color=COLOR_FRAME_THUMB)
+ self.thumb = ImageSelectorWidget(IMAGE_SIZE, IMAGE_SIZE, frame_color=COLOR_FRAME_THUMB)
self.thumb.set_image_dir("images")
self.thumb.set_myownpath(MYOWNPIC_FOLDER)
self.thumb.connect("category_press", self.do_select_category)
- self.thumb.connect("image_press", self.set_nr_pieces, None)
- controls_area_1_box.pack_start(self.thumb, False)
+ self.thumb.connect("image_press", self.set_nr_pieces)
+ controls_area_box.pack_start(self.thumb, False)
- sep = gtk.Label()
- sep.set_size_request(3,3)
- controls_area_1_box.pack_start(sep, False)
+ spacer = gtk.Label()
+ spacer.set_size_request(-1, 5)
+ controls_area_box.pack_start(spacer, expand=False, fill=False)
# The game control buttons
btn_box = gtk.Table(3,3,False)
- btn_box.set_row_spacings(3)
+ btn_box.set_row_spacings(2)
btn_box.attach(gtk.Label(), 0,1,0,3)
btn_box.attach(gtk.Label(), 2,3,0,3)
self.btn_solve = prepare_btn(gtk.Button(" "), 200)
- self.labels_to_translate.append((self.btn_solve, _("Solve")))
+ self.labels_to_translate.append([self.btn_solve, _("Solve")])
self.btn_solve.connect("clicked", self.do_solve)
btn_box.attach(self.btn_solve, 1,2,0,1,0,0)
self.btn_shuffle = prepare_btn(gtk.Button(" "), 200)
- self.labels_to_translate.append((self.btn_shuffle, _("Shuffle")))
+ self.labels_to_translate.append([self.btn_shuffle, _("Shuffle")])
self.btn_shuffle.connect("clicked", self.do_shuffle)
btn_box.attach(self.btn_shuffle, 1,2,1,2,0,0)
self.btn_add = prepare_btn(gtk.Button(" "), 200)
- self.labels_to_translate.append((self.btn_add, _("My Own Picture")))
+ self.labels_to_translate.append([self.btn_add, _("My Picture")])
self.btn_add.connect("clicked", self.do_add_image)
btn_box.attach(self.btn_add, 1,2,2,3,0,0)
- controls_area_1_box.pack_start(btn_box, False)
+ controls_area_box.pack_start(btn_box, False)
+
+ spacer = gtk.Label()
+ spacer.set_size_request(-1, 1)
+ controls_area_box.pack_start(spacer, expand=True, fill=True)
# Language Selection dropdown
controls_area_2 = BorderFrame(bg_color=COLOR_BG_CONTROLS, border_color=COLOR_FRAME_CONTROLS)
@@ -565,6 +710,7 @@ class SliderPuzzleUI (gtk.Table):
self.game = SliderPuzzleWidget(9, GAME_SIZE, GAME_SIZE)
self.game.show()
self.game.connect("solved", self.do_solve)
+ self.game.connect("moved", self.slider_move_cb)
self._parent.connect("key_press_event",self.game.process_key)
self._parent.connect("key_press_event",self.process_key)
self.game_box.add(self.game)
@@ -578,6 +724,7 @@ class SliderPuzzleUI (gtk.Table):
self.timer = TimerWidget(bg_color=COLOR_BG_BUTTONS[0][1],
fg_color=COLOR_FG_BUTTONS[0][1],
lbl_color=COLOR_BG_BUTTONS[1][1])
+ self.timer.set_sensitive(False)
#self.timer.modify_bg(gtk.STATE_NORMAL, bgcolor)
self.timer.set_border_width(3)
self.labels_to_translate.append((self.timer, _("Time: ")))
@@ -585,19 +732,27 @@ class SliderPuzzleUI (gtk.Table):
btn_box.pack_start(gtk.Label(), True)
self.btn_lesson = prepare_btn(gtk.Button(" "))
- self.labels_to_translate.append([self.btn_lesson, _("Lesson Plan")])
+ self.labels_to_translate.append([self.btn_lesson, _("Lesson Plans")])
self.btn_lesson.connect("clicked", self.do_lesson_plan)
btn_box.pack_start(self.btn_lesson, False, padding=8)
vbox.pack_start(btn_box, padding=8)
controls_area_3.add(vbox)
inner_table.attach(controls_area_3, 1,2,1,2)
+# buddybox = BuddyPanel(parent)
+# buddybox.show()
# This has the sole purpose of centering the widget on screen
+# self.attach(buddybox, 0,3,0,1)
self.attach(gtk.Label(), 0,3,0,1)
self.attach(outer_box, 1,2,1,2,0,0)
- self.attach(gtk.Label(), 0,3,2,3)
+ self.msg_label = gtk.Label()
+ self.msg_label.show()
+ self.attach(self.msg_label, 0,3,2,3)
- self.do_select_category(self)
+ if not parent._shared_activity:
+ self.do_select_category(self)
+ else:
+ self.set_message(_("Waiting for remote game..."))
# Push the gettext translator into the global namespace
del _
@@ -605,11 +760,94 @@ class SliderPuzzleUI (gtk.Table):
lang_combo.install()
self.do_select_language(lang_combo)
+ self.buddy_panel = BuddyPanel()
+ self.buddy_panel.show()
+ self.timer.connect('timer_toggle', self.timer_toggle_cb)
+
+
+ #self.controls_area.pack_start(self.contest_controls_area_box, padding=5)
+ # Contest mode flags
+ self.set_contest_mode(False)
+
+ def set_message (self, msg):
+ self.msg_label.set_label(msg)
+
+ def is_initiator (self):
+ return self._parent.initiating
+
+ def set_readonly (self, ro=True):
+ self.thumb.set_readonly(ro)
+ for b in (self.btn_9, self.btn_12, self.btn_16):
+ if not b.get_active():
+ b.set_sensitive(False)
+
+ def timer_toggle_cb (self, evt, running):
+ logging.debug("Timer running: %s" % str(running))
+ if self._contest_mode and running:
+ self.set_game_state(GAME_STARTED)
+ self._send_status_update()
+# if self._contest_mode:
+# if running:
+# if self.game.filename and not self.game.get_parent():
+# self.game_box.pop()
+# else:
+# if not self.buddy_panel.get_parent():
+# self.game_box.push(self.buddy_panel)
+
+ def _set_control_area (self, *args):
+ """ The controls area below the logo needs different actions when in contest mode,
+ and also if we are the contest initiators or not. """
+ if self._contest_mode:
+ if self.get_game_state() > GAME_IDLE:
+ self.set_readonly()
+ else:
+ if self.is_initiator():
+ if self.timer.is_reset():
+ self.set_message(_("Select image to share..."))
+ else:
+ self.set_game_state(GAME_STARTED)
+ else:
+ self.set_message(_("Waiting for game image..."))
+ self.set_button_translation(self.btn_add, "Buddies")
+ self.btn_add.get_child().set_label(_("Buddies"))
+
+ def set_game_state (self, state, force=False):
+ if state[0] > self._state[0] or force:
+ self._state = state
+ self.emit('game-state-changed', state[0])
+ self._set_control_area()
+ if state == GAME_STARTED:
+ self.set_message(_("Game Started!"))
+ self.set_button_translation(self.btn_add, "Buddies")
+ self.btn_add.get_child().set_label(_("Buddies"))
+ self._send_status_update()
+
+ def get_game_state (self):
+ return self._state
+
+ def set_button_translation (self, btn, translation):
+ for i in range(len(self.labels_to_translate)):
+ if self.labels_to_translate[i][0] == btn:
+ self.labels_to_translate[i][1] = translation
+ break
+
+ def set_contest_mode (self, mode):
+ if getattr(self, '_contest_mode', None) != mode:
+ self._contest_mode = bool(mode)
+ self._set_control_area()
+ if self._contest_mode:
+ self.set_button_translation(self.btn_solve, "Give Up")
+ self.btn_solve.get_child().set_label(_("Give Up"))
+ self.set_button_translation(self.btn_shuffle, "Start Game")
+ self.btn_shuffle.get_child().set_label(_("Start Game"))
+
+ def is_contest_mode (self):
+ return self._contest_mode and self.game.filename
+
def do_select_language (self, combo, *args):
self.refresh_labels()
def refresh_labels (self, first_time=False):
- logging.debug(str(_))
self._parent.set_title(_("Slider Puzzle Activity"))
for lbl in self.labels_to_translate:
if isinstance(lbl[0], gtk.Button):
@@ -625,38 +863,78 @@ class SliderPuzzleUI (gtk.Table):
m(self)
def set_nr_pieces (self, btn, nr_pieces=None):
+ logging.debug("0")
+ if isinstance(btn, gtk.ToggleButton) and not btn.get_active():
+ return
+ logging.debug("1")
+ if self.is_contest_mode() and isinstance(btn, gtk.ToggleButton) and nr_pieces == self.game.get_nr_pieces():
+ return
+ logging.debug("2")
if isinstance(btn, gtk.ToggleButton):
if not btn.get_active():
if nr_pieces == self.game.get_nr_pieces():
btn.set_active(True)
return
+ logging.debug("3")
if nr_pieces is None:
nr_pieces = self.game.get_nr_pieces()
+ logging.debug("4")
+ if btn is None: #not isinstance(btn, gtk.ToggleButton):
+ self.set_game_state(GAME_STARTED)
+ for n, b in ((9, self.btn_9),(12, self.btn_12),(16, self.btn_16)):
+ if n == nr_pieces and not b.get_active():
+ b.set_sensitive(True)
+ b.set_active(True)
+ return
+ logging.debug("5 - %i" % (nr_pieces,))
if self.thumb.has_image():
if not self.game.get_parent():
self.game_box.pop()
self.game.load_image(self.thumb.get_filename())
self.game.set_nr_pieces(nr_pieces)
- self.timer.reset()
+ self.timer.reset(False)
+ logging.debug("6")
if isinstance(btn, gtk.ToggleButton):
- for b in (self.btn_9, self.btn_12, self.btn_16):
+ for n, b in ((9, self.btn_9),(12, self.btn_12),(16, self.btn_16)):
if b is not btn:
+ logging.debug("a")
b.set_active(False)
+ logging.debug("b")
+ b.set_sensitive(not self._contest_mode)
+ logging.debug("c")
+ logging.debug("Btn %i active: %s, sensitive: %s" % (n, str(b.get_active()), str(b.get_property('sensitive'))))
+ logging.debug("7")
def do_shuffle (self, *args, **kwargs):
- if self.thumb.has_image():
+ if self._contest_mode:
+ if self.get_game_state() > GAME_IDLE:
+ # Restart
+ self.set_game_state(GAME_STARTED, True)
+ self._parent.frozen.thaw()
+ self.timer.reset(True)
+ elif self.game.filename is not None and self.timer.is_reset():
+ # Start
+ self.timer.start()
+ elif self.thumb.has_image():
if not self.game.get_parent():
self.game_box.pop()
self.game.load_image(self.thumb.get_filename())
self.game.randomize()
- self.timer.reset()
+ self.timer.reset(False)
+ def slider_move_cb (self, *args):
+ if not self.timer.is_running():
+ self.timer.start()
+
def do_solve (self, btn):
- if self.thumb.has_image():
+ if self.game.filename is not None:
if not self.game.get_parent():
self.game_box.pop()
self.game.show_image()
self.timer.stop(True)
+ if self._contest_mode and self.get_game_state() == GAME_STARTED:
+ self.set_game_state(btn != self.btn_solve and GAME_FINISHED or GAME_QUIT)
+ self._set_control_area()
def do_select_category(self, owner, *args, **kwargs):
if isinstance(owner, CategorySelector):
@@ -675,20 +953,34 @@ class SliderPuzzleUI (gtk.Table):
self.game_box.pop()
def do_add_image (self, widget, response=None, *args):
+ """ Use to trigger and process the My Own Image selector.
+ Also used for showing the buddies panel on contest mode"""
if response is None:
- imgfilter = gtk.FileFilter()
- imgfilter.set_name(_("Image Files"))
- imgfilter.add_mime_type('image/*')
- fd = gtk.FileChooserDialog(title=_("Select Image File"), parent=self._parent,
- action=gtk.FILE_CHOOSER_ACTION_OPEN,
- buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
-
- fd.set_current_folder(os.path.expanduser("~/"))
- fd.set_modal(True)
- fd.add_filter(imgfilter)
- fd.connect("response", self.do_add_image)
- fd.resize(800,600)
- fd.show()
+ if self._contest_mode and self.get_game_state() >= GAME_STARTED:
+ # Buddy Panel
+ if not self.buddy_panel.get_parent():
+ self.timer.stop()
+ self.game_box.push(self.buddy_panel)
+ else:
+ self.game_box.pop()
+ elif self._contest_mode and not self.is_initiator():
+ # do nothing
+ pass
+ else:
+ # My Own Image selector
+ imgfilter = gtk.FileFilter()
+ imgfilter.set_name(_("Image Files"))
+ imgfilter.add_mime_type('image/*')
+ fd = gtk.FileChooserDialog(title=_("Select Image File"), parent=self._parent,
+ action=gtk.FILE_CHOOSER_ACTION_OPEN,
+ buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
+
+ fd.set_current_folder(os.path.expanduser("~/"))
+ fd.set_modal(True)
+ fd.add_filter(imgfilter)
+ fd.connect("response", self.do_add_image)
+ fd.resize(800,600)
+ fd.show()
else:
if response == gtk.RESPONSE_ACCEPT:
if self.thumb.load_image(widget.get_filename()):
@@ -709,19 +1001,14 @@ class SliderPuzzleUI (gtk.Table):
s.connect('parent-set', self.do_lesson_plan_reparent)
s.show_all()
self.game_box.push(s)
+ self.timer.stop()
def do_lesson_plan_reparent (self, widget, oldparent):
if widget.parent is None:
- for i in range(len(self.labels_to_translate)):
- if self.labels_to_translate[i][0] == self.btn_lesson:
- self.labels_to_translate[i][1] = "Lesson Plan"
- break
- self.btn_lesson.get_child().set_label(_("Lesson Plan"))
+ self.set_button_translation(self.btn_lesson, "Lesson Plans")
+ self.btn_lesson.get_child().set_label(_("Lesson Plans"))
else:
- for i in range(len(self.labels_to_translate)):
- if self.labels_to_translate[i][0] == self.btn_lesson:
- self.labels_to_translate[i][1] = "Close Lesson"
- break
+ self.set_button_translation(self.btn_lesson, "Close Lesson")
self.btn_lesson.get_child().set_label(_("Close Lesson"))
def process_key (self, w, e):
@@ -773,6 +1060,9 @@ class SliderPuzzleUI (gtk.Table):
self.game._thaw(obj[1])
self.timer._thaw(obj[3])
+ def _send_status_update (self):
+ self._parent.game_tube.StatusUpdate(self._state[1], self.timer.is_running(), self.timer.ellapsed())
+
def main():
win = gtk.Window(gtk.WINDOW_TOPLEVEL)
t = SliderPuzzleUI(win)