diff options
author | C Neves <cn@goat.(none)> | 2007-07-13 00:40:26 (GMT) |
---|---|---|
committer | C Neves <cn@goat.(none)> | 2007-07-13 00:40:26 (GMT) |
commit | bdfca800f9a5154fdf9fd47c4e1fc2558fc48e38 (patch) | |
tree | 7bcc66cf796e6125d61b87a08656c034b3db1fcc /SliderPuzzleUI.py | |
parent | 23d005892b67a57f8fe634c819e96c48800875b4 (diff) |
Too much stuff changed to document here...
Diffstat (limited to 'SliderPuzzleUI.py')
-rw-r--r-- | SliderPuzzleUI.py | 440 |
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) |