Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMuriel de Souza Godoi <muriel@laptop.org>2007-10-29 11:06:02 (GMT)
committer Muriel de Souza Godoi <muriel@laptop.org>2007-10-29 11:06:02 (GMT)
commit5778152f01cf35e25f2f94619c1c9d8907503c46 (patch)
tree461738705d870bbf9c1b7f73639566c3d6923cc0
parent84acb4de8ca9fa0663b9de35df150cc99d49062a (diff)
Send game files over tubes do the other players
-rwxr-xr-xactivity.py725
-rw-r--r--cardlist.py552
-rwxr-xr-xcardtable.py72
-rw-r--r--createcardpanel.py566
-rwxr-xr-xcreatetoolbar.py22
-rwxr-xr-xgame.py163
-rwxr-xr-xmemorizetoolbar.py32
-rw-r--r--messenger.py211
-rw-r--r--model.py693
-rwxr-xr-xplayerscoreboard.py26
-rwxr-xr-xscore.py6
-rwxr-xr-xscoreboard.py4
-rwxr-xr-xsvgcard.py480
-rwxr-xr-xsvglabel.py6
14 files changed, 1826 insertions, 1732 deletions
diff --git a/activity.py b/activity.py
index 51b0af2..2d5be77 100755
--- a/activity.py
+++ b/activity.py
@@ -1,25 +1,25 @@
#! /usr/bin/env python
#
-# Copyright (C) 2006, 2007, One Laptop Per Child
+# Copyright (C) 2006, 2007, One Laptop Per Child
#
-# 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 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.
+# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#
import logging
from gettext import gettext as _
-import os
+from os.path import join, dirname
import dbus
import gtk
@@ -45,9 +45,9 @@ import createcardpanel
from sugar.presence.tubeconn import TubeConnection
-SERVICE = "org.laptop.Memorize"
+SERVICE = 'org.laptop.Memorize'
IFACE = SERVICE
-PATH = "/org/laptop/Memorize"
+PATH = '/org/laptop/Memorize'
_TOOLBAR_CREATE = 1
_TOOLBAR_PLAY = 2
@@ -55,347 +55,354 @@ _TOOLBAR_PLAY = 2
_logger = logging.getLogger('memorize-activity')
class MemorizeActivity(Activity):
- def __init__(self, handle):
- Activity.__init__(self, handle)
-
- self.play_load = False
- self.play_mode = False
-
- toolbox = ActivityToolbox(self)
- toolbox.connect('current-toolbar-changed', self.change_mode)
- activity_toolbar = toolbox.get_activity_toolbar()
-
- self._createToolbar = createtoolbar.CreateToolbar(self)
- toolbox.add_toolbar('Create', self._createToolbar)
- self._createToolbar.show()
-
- self._memorizeToolbar = memorizetoolbar.MemorizeToolbar(self)
- toolbox.add_toolbar(_('Play'), self._memorizeToolbar)
- self._memorizeToolbar.show()
-
- self.set_toolbox(toolbox)
- toolbox.show()
-
- self.cardlist = cardlist.CardList()
- self.createcardpanel = createcardpanel.CreateCardPanel()
- self.createcardpanel.connect('add-pair', self.cardlist.add_pair)
- self.createcardpanel.connect('update-pair', self.cardlist.update_selected)
- self.cardlist.connect('pair-selected', self.createcardpanel.load_pair)
- self.cardlist.connect('update-create-toolbar', self._createToolbar.update_create_toolbar)
- self.cardlist.connect('update-create-buttons', self._createToolbar.update_buttons_status)
- self._createToolbar.connect('create_new_game', self.cardlist.clean_list)
- self._createToolbar.connect('create_new_game', self.createcardpanel.clean)
- self._createToolbar.connect('create_load_game', self.cardlist.load_game)
- self._createToolbar.connect('create_save_game', self.cardlist.save_game)
- self._createToolbar.connect('create_equal_pairs', self.createcardpanel.change_equal_pairs)
-
- self.hbox = gtk.HBox(False)
- self.hbox.pack_start(self.createcardpanel)
- self.hbox.pack_start(self.cardlist, False, False)
- self.set_canvas(self.hbox)
-
- # create csound instance to play sound files
- self.sound = 0
- try:
- import csnd
- del csnd
- self.sound = 1
- except:
- self.sound = 0
-
- if self.sound == 1:
- from csound.csoundserver import CsoundServer
- cs = CsoundServer()
- if cs.start() != 0:
- self.sound = 0
- else:
- cs.quit()
-
- # connect to the in/out events of the memorize activity
- self.connect('focus_in_event', self._focus_in)
- self.connect('focus_out_event', self._focus_out)
- self.connect('destroy', self._cleanup_cb)
-
- # start on the game toolbar, might change this to the create toolbar later
- self.toolbox.set_current_toolbar(_TOOLBAR_CREATE)
-
- # Get the Presence Service
- self.pservice = presenceservice.get_instance()
- try:
- name, path = self.pservice.get_preferred_connection()
- self.tp_conn_name = name
- self.tp_conn_path = path
- self.conn = telepathy.client.Connection(name, path)
- except TypeError:
- _logger.debug('Offline')
- self.initiating = None
-
- # Buddy object for you
- owner = self.pservice.get_owner()
- self.owner = owner
- self.current = 0
- # Owner.props.key
- if self._shared_activity:
- # We are joining the activity
- #_logger.debug("Joined activity, add myself to buddy list nick=%s" %self.owner.props.nick)
- #self.game.add_buddy(self.owner)
- self.toolbox.set_current_toolbar(_TOOLBAR_PLAY)
- self.connect('joined', self._joined_cb)
- if self.get_shared():
- # We've already joined
- self._joined_cb()
- else:
- _logger.debug("buddy joined - __init__: %s", self.owner.props.nick)
- #game_file = game_file = os.path.join(os.path.dirname(__file__),'demos','addition.zip')
- #self.game.load_game(game_file, 4)
- _logger.debug('loading conventional')
- #self.game.add_buddy(self.owner)
- self.show_all()
-
- def read_file(self, file_path):
- if self.metadata['mime_type'] == 'plain/text':
- f = open(file_path, 'r')
- try:
- data = pickle.load(f)
- finally:
- f.close()
-
- _logger.debug('reading from datastore')
-
- self.game.load_remote(data[0], data[1])
- self.game.set_wait_list(data[2])
- elif self.metadata['mime_type'] == 'application/memorizegame':
- self.game.change_game(file_path, 4)
-
- def write_file(self, file_path):
- if not self.metadata['mime_type']:
- self.metadata['mime_type'] = 'plain/text'
-
- if self.metadata['mime_type'] == 'plain/text':
-
-
- data=[self.game.get_grid(), self.game.get_data(), self.game.get_players_data()]
-
- _logger.debug('writing to datastore')
- f = open(file_path, 'w')
- try:
- pickle.dump(data, f)
- finally:
- f.close()
-
- def change_mode(self, notebook, index):
- if index != _TOOLBAR_CREATE:
- if not self.play_load:
- # Create play components
- self.table = cardtable.CardTable()
- self.scoreboard = scoreboard.Scoreboard()
- self.game = game.MemorizeGame()
- self.game.set_myself(self.owner)
- self.hbox.remove(self.createcardpanel)
- self.hbox.remove(self.cardlist)
- self.hbox.pack_start(self.scoreboard, False, False)
- self.hbox.pack_start(self.table)
-
- self.table.connect('key-press-event', self.table.key_press_event)
- self.table.connect('card-flipped', self.game.card_flipped)
- self.table.connect('card-highlighted', self.game.card_highlighted)
-
- self.game.connect('reset_scoreboard', self.scoreboard.reset)
- self.game.connect('reset_table', self.table.reset)
- self.game.connect('load_game', self.table.load_game)
- self.game.connect('change_game', self.table.change_game)
- self.game.connect('load_game', self._memorizeToolbar.update_toolbar)
- self.game.connect('change_game', self._memorizeToolbar.update_toolbar)
- self.game.connect('set-border', self.table.set_border)
- self.game.connect('flop-card', self.table.flop_card)
- self.game.connect('flip-card', self.table.flip_card)
- self.game.connect('highlight-card', self.table.highlight_card)
- self.game.connect('add_buddy', self.scoreboard.add_buddy)
- self.game.connect('rem_buddy', self.scoreboard.rem_buddy)
- self.game.connect('increase-score', self.scoreboard.increase_score)
- self.game.connect('wait_mode_buddy', self.scoreboard.set_wait_mode)
- self.game.connect('change-turn', self.scoreboard.set_selected)
- self.connect('shared', self._shared_cb)
- self.play_load = True
- if not self._shared_activity:
- self.game.add_buddy(self.owner)
- #game_file = os.path.join(os.path.dirname(__file__), 'demos', 'addition.zip')
- #self.game.load_game(game_file, 4)
- else:
- self.hbox.remove(self.createcardpanel)
- self.hbox.remove(self.cardlist)
- self.hbox.pack_start(self.scoreboard, False, False)
- self.hbox.pack_start(self.table)
- self.play_mode = True
- else:
- if self.play_mode:
- self.hbox.remove(self.scoreboard)
- self.hbox.remove(self.table)
- self.hbox.pack_start(self.createcardpanel)
- self.hbox.pack_start(self.cardlist, False, False)
- self.play_mode = False
-
- def restart(self, widget):
- self.game.reset()
-
- def change_game(self, game_name, size):
- self.game.change_game(game_name, size)
-
- def _shared_cb(self, activity):
- _logger.debug('My activity was shared')
- self.initiating = True
- self._setup()
-
- for buddy in self._shared_activity.get_joined_buddies():
- pass # Can do stuff with newly acquired buddies here
-
- self._shared_activity.connect('buddy-joined', self._buddy_joined_cb)
- self._shared_activity.connect('buddy-left', self._buddy_left_cb)
-
- _logger.debug('This is my activity: making a tube...')
- id = self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].OfferDBusTube(
- SERVICE, {})
-
- def _setup(self):
- if self._shared_activity is None:
- _logger.error('Failed to share or join activity')
- return
-
- bus_name, conn_path, channel_paths =\
- self._shared_activity.get_channels()
-
- # Work out what our room is called and whether we have Tubes already
- room = None
- tubes_chan = None
- text_chan = None
- for channel_path in channel_paths:
- channel = telepathy.client.Channel(bus_name, channel_path)
- htype, handle = channel.GetHandle()
- if htype == telepathy.HANDLE_TYPE_ROOM:
- _logger.debug('Found our room: it has handle#%d "%s"',
- handle, self.conn.InspectHandles(htype, [handle])[0])
- room = handle
- ctype = channel.GetChannelType()
- if ctype == telepathy.CHANNEL_TYPE_TUBES:
- _logger.debug('Found our Tubes channel at %s', channel_path)
- tubes_chan = channel
- elif ctype == telepathy.CHANNEL_TYPE_TEXT:
- _logger.debug('Found our Text channel at %s', channel_path)
- text_chan = channel
-
- if room is None:
- _logger.error("Presence service didn't create a room")
- return
- if text_chan is None:
- _logger.error("Presence service didn't create a text channel")
- return
-
- # Make sure we have a Tubes channel - PS doesn't yet provide one
- if tubes_chan is None:
- _logger.debug("Didn't find our Tubes channel, requesting one...")
- tubes_chan = self.conn.request_channel(telepathy.CHANNEL_TYPE_TUBES,
- telepathy.HANDLE_TYPE_ROOM, room, True)
-
- self.tubes_chan = tubes_chan
- self.text_chan = text_chan
-
- tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal('NewTube',
- self._new_tube_cb)
-
- def _list_tubes_reply_cb(self, tubes):
- for tube_info in tubes:
- self._new_tube_cb(*tube_info)
-
- def _list_tubes_error_cb(self, e):
- _logger.error('ListTubes() failed: %s', e)
-
- def _joined_cb(self, activity):
- if not self._shared_activity:
- return
-
- _logger.debug('Joined an existing shared activity')
-
- self.found = 0
- for buddy in self._shared_activity.get_joined_buddies():
- _logger.debug("buddy joined - _joined_cb: %s (get buddies of activity and add them to my list)", buddy.props.nick)
- self.game.add_buddy(buddy)
- if buddy == self.owner:
- self.found = 1
-
- if self.found == 0:
- _logger.debug("buddy joined - _joined_cb: Not foud myself in buddy list - will add myself at end of the list.")
- self.game.add_buddy(self.owner)
-
- self.initiating = False
- self._setup()
-
- self._shared_activity.connect('buddy-joined', self._buddy_joined_cb)
- self._shared_activity.connect('buddy-left', self._buddy_left_cb)
-
- _logger.debug('This is not my activity: waiting for a tube...')
- self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].ListTubes(
- reply_handler=self._list_tubes_reply_cb,
- error_handler=self._list_tubes_error_cb)
-
- def _new_tube_cb(self, id, initiator, type, service, params, state):
- _logger.debug('New tube: ID=%d initator=%d type=%d service=%s '
- 'params=%r state=%d', id, initiator, type, service,
- params, state)
-
- if (type == telepathy.TUBE_TYPE_DBUS and
- service == SERVICE):
- if state == telepathy.TUBE_STATE_LOCAL_PENDING:
- self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].AcceptDBusTube(id)
-
- self.tube_conn = TubeConnection(self.conn,
- self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES],
- id, group_iface=self.text_chan[telepathy.CHANNEL_INTERFACE_GROUP])
-
- self.messenger = messenger.Messenger(self.tube_conn, self.initiating, self._get_buddy, self.game)
- self.game.connect('flip-card-signal', self.messenger.flip)
- self.game.connect('change_game_signal', self.messenger.change_game)
-
- def _get_buddy(self, cs_handle):
- """Get a Buddy from a channel specific handle."""
- group = self.text_chan[telepathy.CHANNEL_INTERFACE_GROUP]
- my_csh = group.GetSelfHandle()
- if my_csh == cs_handle:
- handle = self.conn.GetSelfHandle()
- else:
- handle = group.GetHandleOwners([cs_handle])[0]
- assert handle != 0
- return self.pservice.get_buddy_by_telepathy_handle(self.tp_conn_name,
- self.tp_conn_path, handle)
-
- def _buddy_joined_cb (self, activity, buddy):
- if buddy <> self.owner:
- if buddy.props.nick == '':
- _logger.debug("buddy joined - _buddy_joined_cb: buddy name empty nick=%s. Will not add." %(buddy.props.nick))
- else:
- _logger.debug("buddy joined - _buddy_joined_cb: %s", buddy.props.nick)
- self.game.add_buddy(buddy)
-
- def _buddy_left_cb (self, activity, buddy):
- if buddy.props.nick == '':
- _logger.debug("buddy joined - _buddy_left_cb: buddy name empty nick=%s. Will not remove" %(buddy.props.nick))
- else:
- _logger.debug("buddy left - _buddy_left_cb: %s", buddy.props.nick)
- self.game.rem_buddy(buddy)
-
- def _focus_in(self, event, data=None):
- if self.sound == 1:
- pass
- #self.game.cs.start()
- #_logger.debug(" Memorize is visible: start csound server. ")
-
- def _focus_out(self, event, data=None):
- if self.sound == 1:
- pass
- #self.game.cs.pause()
- #_logger.debug(" Memorize is invisible: pause csound server. ")
-
- def _cleanup_cb(self, data=None):
- if self.sound == 1:
- pass
- #self.game.cs.quit()
- #_logger.debug(" Memorize closes: close csound server. ")
+
+ def __init__(self, handle):
+ Activity.__init__(self, handle)
+
+ self.play_load = False
+ self.play_mode = False
+
+ toolbox = ActivityToolbox(self)
+ toolbox.connect('current-toolbar-changed', self.change_mode)
+ activity_toolbar = toolbox.get_activity_toolbar()
+
+ self._createToolbar = createtoolbar.CreateToolbar(self)
+ toolbox.add_toolbar('Create', self._createToolbar)
+ self._createToolbar.show()
+
+ self._memorizeToolbar = memorizetoolbar.MemorizeToolbar(self)
+ toolbox.add_toolbar(_('Play'), self._memorizeToolbar)
+ self._memorizeToolbar.show()
+
+ self.set_toolbox(toolbox)
+ toolbox.show()
+
+ self.cardlist = cardlist.CardList()
+ self.createcardpanel = createcardpanel.CreateCardPanel()
+ self.createcardpanel.connect('add-pair', self.cardlist.add_pair)
+ self.createcardpanel.connect('update-pair', self.cardlist.update_selected)
+ self.cardlist.connect('pair-selected', self.createcardpanel.load_pair)
+ self.cardlist.connect('update-create-toolbar', self._createToolbar.update_create_toolbar)
+ self.cardlist.connect('update-create-buttons', self._createToolbar.update_buttons_status)
+ self._createToolbar.connect('create_new_game', self.cardlist.clean_list)
+ self._createToolbar.connect('create_new_game', self.createcardpanel.clean)
+ self._createToolbar.connect('create_load_game', self.cardlist.load_game)
+ self._createToolbar.connect('create_save_game', self.cardlist.save_game)
+ self._createToolbar.connect('create_equal_pairs', self.createcardpanel.change_equal_pairs)
+
+ self.hbox = gtk.HBox(False)
+ self.hbox.pack_start(self.createcardpanel)
+ self.hbox.pack_start(self.cardlist, False, False)
+ self.set_canvas(self.hbox)
+
+ # create csound instance to play sound files
+ self.sound = 0
+ try:
+ import csnd
+ del csnd
+ self.sound = 1
+ except:
+ self.sound = 0
+
+ if self.sound == 1:
+ from csound.csoundserver import CsoundServer
+ cs = CsoundServer()
+ if cs.start() != 0:
+ self.sound = 0
+ else:
+ cs.quit()
+
+ # connect to the in/out events of the memorize activity
+ self.connect('focus_in_event', self._focus_in)
+ self.connect('focus_out_event', self._focus_out)
+ self.connect('destroy', self._cleanup_cb)
+
+ # start on the game toolbar, might change this to the create toolbar later
+ self.toolbox.set_current_toolbar(_TOOLBAR_CREATE)
+
+ # Get the Presence Service
+ self.pservice = presenceservice.get_instance()
+ try:
+ name, path = self.pservice.get_preferred_connection()
+ self.tp_conn_name = name
+ self.tp_conn_path = path
+ self.conn = telepathy.client.Connection(name, path)
+ except TypeError:
+ _logger.debug('Offline')
+ self.initiating = None
+
+ # Buddy object for you
+ owner = self.pservice.get_owner()
+ self.owner = owner
+ self.current = 0
+ # Owner.props.key
+ if self._shared_activity:
+ # We are joining the activity
+ self.toolbox.set_current_toolbar(_TOOLBAR_PLAY)
+ self.connect('joined', self._joined_cb)
+ if self.get_shared():
+ # We've already joined
+ self._joined_cb()
+ else:
+ _logger.debug('buddy joined - __init__: %s', self.owner.props.nick)
+ #game_file = join(dirname(__file__),'demos','addition.zip')
+ #self.game.load_game(game_file, 4)
+ _logger.debug('loading conventional')
+ #self.game.add_buddy(self.owner)
+ self.show_all()
+
+ def read_file(self, file_path):
+ '''
+ if self.metadata['mime_type'] == 'plain/text':
+ f = open(file_path, 'r')
+ try:
+ data = pickle.load(f)
+ finally:
+ f.close()
+
+ _logger.debug('reading from datastore')
+
+ self.game.load_remote(data[0], data[1])
+ self.game.set_wait_list(data[2])
+ '''
+ if self.metadata['mime_type'] == 'application/memorizegame':
+ self.toolbox.set_current_toolbar(_TOOLBAR_PLAY)
+ self.game.change_game(None, file_path, 4, 'file', self.metadata['title'], self.metadata['icon-color'])
+
+ '''
+ def write_file(self, file_path):
+ if not self.metadata['mime_type']:
+ self.metadata['mime_type'] = 'plain/text'
+
+ if self.metadata['mime_type'] == 'plain/text':
+
+
+ data=[self.game.get_grid(), self.game.get_data(), self.game.get_players_data()]
+
+ _logger.debug('writing to datastore')
+ f = open(file_path, 'w')
+ try:
+ pickle.dump(data, f)
+ finally:
+ f.close()
+ '''
+ def change_mode(self, notebook, index):
+ if index != _TOOLBAR_CREATE:
+ if not self.play_load:
+ # Create play components
+ self.table = cardtable.CardTable()
+ self.scoreboard = scoreboard.Scoreboard()
+ self.game = game.MemorizeGame()
+ self.game.set_myself(self.owner)
+ self.hbox.remove(self.createcardpanel)
+ self.hbox.remove(self.cardlist)
+ self.hbox.pack_start(self.scoreboard, False, False)
+ self.hbox.pack_start(self.table)
+
+ self.table.connect('key-press-event', self.table.key_press_event)
+ self.table.connect('card-flipped', self.game.card_flipped)
+ self.table.connect('card-highlighted', self.game.card_highlighted)
+
+ self.game.connect('msg_buddy', self.scoreboard.set_buddy_message)
+ self.game.connect('reset_scoreboard', self.scoreboard.reset)
+ self.game.connect('reset_table', self.table.reset)
+ self.game.connect('load_game', self.table.load_game)
+ self.game.connect('load_mode', self.table.load_msg)
+ self.game.connect('change_game', self.table.change_game)
+ #self.game.connect('load_game', self._memorizeToolbar.update_toolbar)
+ #self.game.connect('change_game', self._memorizeToolbar.update_toolbar)
+ self.game.connect('set-border', self.table.set_border)
+ self.game.connect('flop-card', self.table.flop_card)
+ self.game.connect('flip-card', self.table.flip_card)
+ self.game.connect('highlight-card', self.table.highlight_card)
+ self.game.connect('add_buddy', self.scoreboard.add_buddy)
+ self.game.connect('rem_buddy', self.scoreboard.rem_buddy)
+ self.game.connect('increase-score', self.scoreboard.increase_score)
+ self.game.connect('wait_mode_buddy', self.scoreboard.set_wait_mode)
+ self.game.connect('change-turn', self.scoreboard.set_selected)
+
+ self._memorizeToolbar.connect('game_changed', self.game.change_game)
+ self.connect('shared', self._shared_cb)
+ self.play_load = True
+ if not self._shared_activity:
+ self.game.add_buddy(self.owner)
+ #game_file = join(dirname(__file__), 'demos', 'addition.zip')
+ #self.game.load_game(game_file, 4)
+ else:
+ self.hbox.remove(self.createcardpanel)
+ self.hbox.remove(self.cardlist)
+ self.hbox.pack_start(self.scoreboard, False, False)
+ self.hbox.pack_start(self.table)
+ self.play_mode = True
+ else:
+ if self.play_mode:
+ self.hbox.remove(self.scoreboard)
+ self.hbox.remove(self.table)
+ self.hbox.pack_start(self.createcardpanel)
+ self.hbox.pack_start(self.cardlist, False, False)
+ self.play_mode = False
+
+ def restart(self, widget):
+ self.game.reset()
+
+ def change_game(self, game_name, size, title=None, color=None):
+ self.game.change_game(game_name, size, title, color)
+
+ def _shared_cb(self, activity):
+ _logger.debug('My activity was shared')
+ self.initiating = True
+ self._setup()
+
+ for buddy in self._shared_activity.get_joined_buddies():
+ pass # Can do stuff with newly acquired buddies here
+
+ self._shared_activity.connect('buddy-joined', self._buddy_joined_cb)
+ self._shared_activity.connect('buddy-left', self._buddy_left_cb)
+
+ _logger.debug('This is my activity: making a tube...')
+ id = self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].OfferDBusTube(
+ SERVICE, {})
+
+ def _setup(self):
+ if self._shared_activity is None:
+ _logger.error('Failed to share or join activity')
+ return
+
+ bus_name, conn_path, channel_paths =\
+ self._shared_activity.get_channels()
+
+ # Work out what our room is called and whether we have Tubes already
+ room = None
+ tubes_chan = None
+ text_chan = None
+ for channel_path in channel_paths:
+ channel = telepathy.client.Channel(bus_name, channel_path)
+ htype, handle = channel.GetHandle()
+ if htype == telepathy.HANDLE_TYPE_ROOM:
+ _logger.debug('Found our room: it has handle#%d "%s"',
+ handle, self.conn.InspectHandles(htype, [handle])[0])
+ room = handle
+ ctype = channel.GetChannelType()
+ if ctype == telepathy.CHANNEL_TYPE_TUBES:
+ _logger.debug('Found our Tubes channel at %s', channel_path)
+ tubes_chan = channel
+ elif ctype == telepathy.CHANNEL_TYPE_TEXT:
+ _logger.debug('Found our Text channel at %s', channel_path)
+ text_chan = channel
+
+ if room is None:
+ _logger.error("Presence service didn't create a room")
+ return
+ if text_chan is None:
+ _logger.error("Presence service didn't create a text channel")
+ return
+
+ # Make sure we have a Tubes channel - PS doesn't yet provide one
+ if tubes_chan is None:
+ _logger.debug("Didn't find our Tubes channel, requesting one...")
+ tubes_chan = self.conn.request_channel(telepathy.CHANNEL_TYPE_TUBES,
+ telepathy.HANDLE_TYPE_ROOM, room, True)
+
+ self.tubes_chan = tubes_chan
+ self.text_chan = text_chan
+
+ tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal('NewTube',
+ self._new_tube_cb)
+
+ def _list_tubes_reply_cb(self, tubes):
+ for tube_info in tubes:
+ self._new_tube_cb(*tube_info)
+
+ def _list_tubes_error_cb(self, e):
+ _logger.error('ListTubes() failed: %s', e)
+
+ def _joined_cb(self, activity):
+ if not self._shared_activity:
+ return
+
+ _logger.debug('Joined an existing shared activity')
+
+ self.found = 0
+ for buddy in self._shared_activity.get_joined_buddies():
+ _logger.debug("buddy joined - _joined_cb: %s (get buddies of activity and add them to my list)", buddy.props.nick)
+ self.game.add_buddy(buddy)
+ if buddy == self.owner:
+ self.found = 1
+
+ if self.found == 0:
+ _logger.debug("buddy joined - _joined_cb: Not foud myself in buddy list - will add myself at end of the list.")
+ self.game.add_buddy(self.owner)
+
+ self.initiating = False
+ self._setup()
+
+ self._shared_activity.connect('buddy-joined', self._buddy_joined_cb)
+ self._shared_activity.connect('buddy-left', self._buddy_left_cb)
+
+ _logger.debug('This is not my activity: waiting for a tube...')
+ self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].ListTubes(
+ reply_handler=self._list_tubes_reply_cb,
+ error_handler=self._list_tubes_error_cb)
+
+ def _new_tube_cb(self, id, initiator, type, service, params, state):
+ _logger.debug('New tube: ID=%d initator=%d type=%d service=%s '
+ 'params=%r state=%d', id, initiator, type, service,
+ params, state)
+
+ if (type == telepathy.TUBE_TYPE_DBUS and
+ service == SERVICE):
+ if state == telepathy.TUBE_STATE_LOCAL_PENDING:
+ self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].AcceptDBusTube(id)
+
+ self.tube_conn = TubeConnection(self.conn,
+ self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES],
+ id, group_iface=self.text_chan[telepathy.CHANNEL_INTERFACE_GROUP])
+
+ self.messenger = messenger.Messenger(self.tube_conn, self.initiating, self._get_buddy, self.game)
+ self.game.connect('flip-card-signal', self.messenger.flip_sender)
+ self.game.connect('change_game_signal', self.messenger.change_game)
+
+ def _get_buddy(self, cs_handle):
+ """Get a Buddy from a channel specific handle."""
+ group = self.text_chan[telepathy.CHANNEL_INTERFACE_GROUP]
+ my_csh = group.GetSelfHandle()
+ if my_csh == cs_handle:
+ handle = self.conn.GetSelfHandle()
+ else:
+ handle = group.GetHandleOwners([cs_handle])[0]
+ assert handle != 0
+ return self.pservice.get_buddy_by_telepathy_handle(self.tp_conn_name,
+ self.tp_conn_path, handle)
+
+ def _buddy_joined_cb (self, activity, buddy):
+ if buddy <> self.owner:
+ if buddy.props.nick == '':
+ _logger.debug("buddy joined - _buddy_joined_cb: buddy name empty nick=%s. Will not add." %(buddy.props.nick))
+ else:
+ _logger.debug("buddy joined - _buddy_joined_cb: %s", buddy.props.nick)
+ self.game.add_buddy(buddy)
+
+ def _buddy_left_cb (self, activity, buddy):
+ if buddy.props.nick == '':
+ _logger.debug("buddy joined - _buddy_left_cb: buddy name empty nick=%s. Will not remove" %(buddy.props.nick))
+ else:
+ _logger.debug("buddy left - _buddy_left_cb: %s", buddy.props.nick)
+ self.game.rem_buddy(buddy)
+
+ def _focus_in(self, event, data=None):
+ if self.sound == 1:
+ pass
+ #self.game.cs.start()
+ #_logger.debug(" Memorize is visible: start csound server. ")
+
+ def _focus_out(self, event, data=None):
+ if self.sound == 1:
+ pass
+ #self.game.cs.pause()
+ #_logger.debug(" Memorize is invisible: pause csound server. ")
+
+ def _cleanup_cb(self, data=None):
+ if self.sound == 1:
+ pass
+ #self.game.cs.quit()
+ #_logger.debug(" Memorize closes: close csound server. ")
diff --git a/cardlist.py b/cardlist.py
index 237d05d..35df613 100644
--- a/cardlist.py
+++ b/cardlist.py
@@ -1,25 +1,24 @@
#! /usr/bin/env python
#
-# Copyright (C) 2006, 2007, One Laptop Per Child
+# Copyright (C) 2006, 2007, One Laptop Per Child
#
-# 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 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.
+# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#
import gtk
import svgcard
-import gobject
import logging
from os.path import join
import os
@@ -27,278 +26,287 @@ import model
import zipfile
import tempfile
import random
+from gobject import SIGNAL_RUN_FIRST, TYPE_PYOBJECT
+
from sugar import profile
from sugar.datastore import datastore
_logger = logging.getLogger('memorize-activity')
class CardList(gtk.EventBox):
-
- __gsignals__ = {
- 'pair-selected': (gobject.SIGNAL_RUN_FIRST, None, [gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT,gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT]),
- 'update-create-toolbar': (gobject.SIGNAL_RUN_FIRST, None, [gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT]),
- 'update-create-buttons': (gobject.SIGNAL_RUN_FIRST, None, [gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT]),
- }
-
- def __init__(self):
- gtk.EventBox.__init__(self)
- self.model = model.Model(os.path.dirname(__file__))
- self.pairs = []
- self.current_pair = None
-
- self.set_size_request(450, 150)
- self.vbox = gtk.VBox(False)
-
- fill_box = gtk.Label()
- fill_box.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#000000'))
- fill_box.show()
- self.vbox.pack_end(fill_box, True, True)
-
- scroll = gtk.ScrolledWindow()
- scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS)
- scroll.add_with_viewport(self.vbox)
- scroll.set_border_width(0)
- scroll.get_child().modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#000000'))
- self.add(scroll)
- self.show_all()
-
- def load_game(self, widget, game_name):
- self.model.read(game_name)
- self.current_game_key = self.model.data['game_file']
- self.emit('update-create-toolbar', self.model.data['name'], self.model.data.get('equal_pairs', 'False'), self.model.data.get('divided', '0'))
- game_pairs = self.model.pairs
- game_data = self.model.data
- self.clean_list()
- for key in game_pairs:
- if game_pairs[key].props.aimg != None:
- aimg = gtk.gdk.pixbuf_new_from_file(os.path.join(self.model.data['pathimg'], game_pairs[key].props.aimg))
- else:
- aimg = None
-
- if game_pairs[key].props.bimg != None:
- bimg = gtk.gdk.pixbuf_new_from_file(os.path.join(self.model.data['pathimg'], game_pairs[key].props.bimg))
- else:
- bimg = None
-
- asnd = os.path.join(self.data['pathsnd'],game_pairs[key].props.asnd)
- bsnd = os.path.join(self.data['pathsnd'],game_pairs[key].props.bsnd)
-
- self.add_pair(None, game_pairs[key].props.achar, game_pairs[key].props.bchar, aimg, bimg, asnd, bsnd, False)
-
- def save_game(self, widget, game_name, equal_pairs, grouped):
-
- temp_folder = tempfile.mkdtemp()
- temp_img_folder = join(temp_folder, 'images')
- temp_snd_folder = join(temp_folder, 'sounds')
+
+ __gsignals__ = {
+ 'pair-selected': (SIGNAL_RUN_FIRST, None, 6 * [TYPE_PYOBJECT]),
+ 'update-create-toolbar': (SIGNAL_RUN_FIRST, None, 3 * [TYPE_PYOBJECT]),
+ 'update-create-buttons': (SIGNAL_RUN_FIRST, None, 2 * [TYPE_PYOBJECT]),
+ }
+
+ def __init__(self):
+ gtk.EventBox.__init__(self)
+ self.model = model.Model(os.path.dirname(__file__))
+ self.pairs = []
+ self.current_pair = None
+
+ self.set_size_request(450, 150)
+ self.vbox = gtk.VBox(False)
+
+ fill_box = gtk.Label()
+ fill_box.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#000000'))
+ fill_box.show()
+ self.vbox.pack_end(fill_box, True, True)
+
+ scroll = gtk.ScrolledWindow()
+ scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS)
+ scroll.add_with_viewport(self.vbox)
+ scroll.set_border_width(0)
+ scroll.get_child().modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#000000'))
+ self.add(scroll)
+ self.show_all()
+
+ def load_game(self, widget, game_name):
+ self.model.read(game_name)
+ self.current_game_key = self.model.data['game_file']
+ self.emit('update-create-toolbar', self.model.data['name'], self.model.data.get('equal_pairs', 'False'), self.model.data.get('divided', '0'))
+ game_pairs = self.model.pairs
+ game_data = self.model.data
+ self.clean_list()
+ for key in game_pairs:
+ if game_pairs[key].props.aimg != None:
+ aimg = gtk.gdk.pixbuf_new_from_file(os.path.join(self.model.data['pathimg'], game_pairs[key].props.aimg))
+ else:
+ aimg = None
+
+ if game_pairs[key].props.bimg != None:
+ bimg = gtk.gdk.pixbuf_new_from_file(os.path.join(self.model.data['pathimg'], game_pairs[key].props.bimg))
+ else:
+ bimg = None
+
+ if game_pairs[key].props.asnd != None:
+ asnd = os.path.join(self.model.data['pathsnd'], game_pairs[key].props.asnd)
+ else:
+ asnd = None
+
+ if game_pairs[key].props.bsnd != None:
+ bsnd = os.path.join(self.model.data['pathsnd'], game_pairs[key].props.bsnd)
+ else:
+ bsnd = None
+
+ self.add_pair(None, game_pairs[key].props.achar, game_pairs[key].props.bchar, aimg, bimg, asnd, bsnd, False)
+
+ def save_game(self, widget, game_name, equal_pairs, grouped):
+
+ temp_folder = tempfile.mkdtemp()
+ temp_img_folder = join(temp_folder, 'images')
+ temp_snd_folder = join(temp_folder, 'sounds')
- os.makedirs(temp_img_folder)
- os.makedirs(temp_snd_folder)
-
- zip = zipfile.ZipFile(join(temp_folder, 'game.zip'), 'w')
-
- game_model = model.Model(temp_folder)
- game_model.data['name'] = game_name
- for pair in range(len(self.pairs)):
- pair_card = model.Pair()
-
- # achar
- achar = self.pairs[pair].get_text(1)
- if achar != '':
- pair_card.set_property('achar', achar)
-
- # bchar
- bchar = self.pairs[pair].get_text(2)
- if bchar != '':
- pair_card.set_property('bchar', bchar)
+ os.makedirs(temp_img_folder)
+ os.makedirs(temp_snd_folder)
+
+ zip = zipfile.ZipFile(join(temp_folder, 'game.zip'), 'w')
+
+ game_model = model.Model(temp_folder)
+ game_model.data['name'] = game_name
+ for pair in range(len(self.pairs)):
+ pair_card = model.Pair()
+
+ # achar
+ achar = self.pairs[pair].get_text(1)
+ if achar != '':
+ pair_card.set_property('achar', achar)
+
+ # bchar
+ bchar = self.pairs[pair].get_text(2)
+ if bchar != '':
+ pair_card.set_property('bchar', bchar)
- # aimg
- aimg = self.pairs[pair].get_pixbuf(1)
- if aimg != None:
-
- if equal_pairs:
- aimgfile = 'img'+str(pair)+'.jpg'
- else:
- aimgfile = 'aimg'+str(pair)+'.jpg'
- aimg.save(join(temp_img_folder, aimgfile), 'jpeg', {'quality':'85'})
- zip.write(join(temp_img_folder, aimgfile), join('images', aimgfile))
- pair_card.set_property('aimg', aimgfile)
+ # aimg
+ aimg = self.pairs[pair].get_pixbuf(1)
+ if aimg != None:
+
+ if equal_pairs:
+ aimgfile = 'img'+str(pair)+'.jpg'
+ else:
+ aimgfile = 'aimg'+str(pair)+'.jpg'
+ aimg.save(join(temp_img_folder, aimgfile), 'jpeg', {'quality':'85'})
+ zip.write(join(temp_img_folder, aimgfile), join('images', aimgfile))
+ pair_card.set_property('aimg', aimgfile)
- # bimg
- bimg = self.pairs[pair].get_pixbuf(2)
- if bimg != None:
- if equal_pairs:
- bimgfile = 'img'+str(pair)+'.jpg'
- else:
- bimgfile = 'bimg'+str(pair)+'.jpg'
- bimg.save(join(temp_img_folder, bimgfile), 'jpeg', {'quality':'85'})
- zip.write(join(temp_img_folder, bimgfile), join('images', bimgfile))
- pair_card.set_property('bimg', bimgfile)
- # asnd
- asnd = self.pairs[pair].get_sound(1)
- if asnd != None:
- if equal_pairs:
- asndfile = 'snd'+str(pair)+'.wav'
- else:
- asndfile = 'asnd'+str(pair)+'.wav'
- _logger.error(asndfile+': '+ asnd)
- zip.write(asnd, join('sounds', asndfile))
- pair_card.set_property('asnd', asndfile)
+ # bimg
+ bimg = self.pairs[pair].get_pixbuf(2)
+ if bimg != None:
+ if equal_pairs:
+ bimgfile = 'img'+str(pair)+'.jpg'
+ else:
+ bimgfile = 'bimg'+str(pair)+'.jpg'
+ bimg.save(join(temp_img_folder, bimgfile), 'jpeg', {'quality':'85'})
+ zip.write(join(temp_img_folder, bimgfile), join('images', bimgfile))
+ pair_card.set_property('bimg', bimgfile)
+ # asnd
+ asnd = self.pairs[pair].get_sound(1)
+ if asnd != None:
+ if equal_pairs:
+ asndfile = 'snd'+str(pair)+'.wav'
+ else:
+ asndfile = 'asnd'+str(pair)+'.wav'
+ _logger.error(asndfile+': '+ asnd)
+ zip.write(asnd, join('sounds', asndfile))
+ pair_card.set_property('asnd', asndfile)
- # bsnd
- bsnd = self.pairs[pair].get_sound(2)
- if bsnd != None:
- if equal_pairs:
- bsndfile = 'snd'+str(pair)+'.wav'
- else:
- bsndfile = 'bsnd'+str(pair)+'.wav'
- zip.write(bsnd, join('sounds', bsndfile))
- _logger.error(bsndfile+': '+ bsnd)
- pair_card.set_property('bsnd', bsndfile)
-
- game_model.pairs[pair] = pair_card
- game_model.write(equal_pairs, grouped)
- zip.write(join(temp_folder, 'game.xml'), 'game.xml')
- zip.close()
-
- # Saves the zip in datastore
- gameObject = datastore.create()
- gameObject.metadata['title'] = game_name
- gameObject.metadata['mime_type'] = 'application/memorizegame'
- gameObject.metadata['icon-color'] = profile.get_color().to_string()
- gameObject.file_path = join(temp_folder, 'game.zip')
- datastore.write(gameObject)
-
- def clean_list(self, button = None):
- if button != None:
- self.current_game_key = None
- map(lambda x: self.vbox.remove(x), self.pairs)
- del self.pairs
- self.pairs = []
-
- def clean_tmp_folder(self, path):
- for root, dirs, files in os.walk(path, topdown=False):
- for name in files:
- os.remove(join(root, name))
- for name in dirs:
- os.rmdir(join(root, name))
- os.rmdir(path)
-
- def add_pair(self, widget, achar, bchar, aimg, bimg, asnd, bsnd, show = True):
- pair = Pair(achar, bchar, aimg, bimg, asnd, bsnd)
- self.vbox.pack_end(pair, False, True)
- self.pairs.append(pair)
- pair.connect('pair-selected', self.set_selected)
- pair.connect('pair-closed', self.rem_pair)
- self.emit('update-create-buttons', True, True)
- if show:
- self.show_all()
-
- def rem_pair(self, widget, event):
- self.vbox.remove(widget)
- self.pairs.remove(widget)
- del widget
- self.emit('update-create-buttons', True, True)
-
- def set_selected(self, widget, event):
- if self.current_pair <> None:
- self.old = self.current_pair
- self.old.set_selected(False)
- self.current_pair = widget
- widget.set_selected(True)
- self.emit('pair-selected', self.current_pair.get_text(1), self.current_pair.get_text(2), self.current_pair.get_pixbuf(1), self.current_pair.get_pixbuf(2), self.current_pair.get_sound(1),self.current_pair.get_sound(2))
-
- def update_selected(self, widget, newtext1, newtext2, aimg, bimg, asnd, bsnd):
- self.current_pair.change_text(newtext1, newtext2)
- self.current_pair.change_pixbuf(aimg, bimg)
- self.current_pair.change_sound(asnd,bsnd)
-
- self.emit('update-create-buttons', True, True)
-
+ # bsnd
+ bsnd = self.pairs[pair].get_sound(2)
+ if bsnd != None:
+ if equal_pairs:
+ bsndfile = 'snd'+str(pair)+'.wav'
+ else:
+ bsndfile = 'bsnd'+str(pair)+'.wav'
+ zip.write(bsnd, join('sounds', bsndfile))
+ _logger.error(bsndfile+': '+ bsnd)
+ pair_card.set_property('bsnd', bsndfile)
+
+ game_model.pairs[pair] = pair_card
+ game_model.write(equal_pairs, grouped)
+ zip.write(join(temp_folder, 'game.xml'), 'game.xml')
+ zip.close()
+
+ # Saves the zip in datastore
+ gameObject = datastore.create()
+ gameObject.metadata['title'] = game_name
+ gameObject.metadata['mime_type'] = 'application/memorizegame'
+ gameObject.metadata['icon-color'] = profile.get_color().to_string()
+ gameObject.file_path = join(temp_folder, 'game.zip')
+ datastore.write(gameObject)
+
+ def clean_list(self, button = None):
+ if button != None:
+ self.current_game_key = None
+ map(lambda x: self.vbox.remove(x), self.pairs)
+ del self.pairs
+ self.pairs = []
+
+ def clean_tmp_folder(self, path):
+ for root, dirs, files in os.walk(path, topdown=False):
+ for name in files:
+ os.remove(join(root, name))
+ for name in dirs:
+ os.rmdir(join(root, name))
+ os.rmdir(path)
+
+ def add_pair(self, widget, achar, bchar, aimg, bimg, asnd, bsnd, show = True):
+ pair = Pair(achar, bchar, aimg, bimg, asnd, bsnd)
+ self.vbox.pack_end(pair, False, True)
+ self.pairs.append(pair)
+ pair.connect('pair-selected', self.set_selected)
+ pair.connect('pair-closed', self.rem_pair)
+ self.emit('update-create-buttons', True, True)
+ if show:
+ self.show_all()
+
+ def rem_pair(self, widget, event):
+ self.vbox.remove(widget)
+ self.pairs.remove(widget)
+ del widget
+ self.emit('update-create-buttons', True, True)
+
+ def set_selected(self, widget, event):
+ if self.current_pair <> None:
+ self.old = self.current_pair
+ self.old.set_selected(False)
+ self.current_pair = widget
+ widget.set_selected(True)
+ self.emit('pair-selected', self.current_pair.get_text(1), self.current_pair.get_text(2), self.current_pair.get_pixbuf(1), self.current_pair.get_pixbuf(2), self.current_pair.get_sound(1), self.current_pair.get_sound(2))
+
+ def update_selected(self, widget, newtext1, newtext2, aimg, bimg, asnd, bsnd):
+ self.current_pair.change_text(newtext1, newtext2)
+ self.current_pair.change_pixbuf(aimg, bimg)
+ self.current_pair.change_sound(asnd, bsnd)
+
+ self.emit('update-create-buttons', True, True)
+
class Pair(gtk.EventBox):
-
- __gsignals__ = {
- 'pair-selected': (gobject.SIGNAL_RUN_FIRST, None, [gobject.TYPE_PYOBJECT]),
- 'pair-closed': (gobject.SIGNAL_RUN_FIRST, None, [gobject.TYPE_PYOBJECT]),
- }
-
- def __init__(self, text1, text2 = None, aimg = None, bimg = None, asnd = None, bsnd = None):
- gtk.EventBox.__init__(self)
- self.bg_color = '#000000'
- if text2 == None:
- self.text2 = text1
- else:
- self.text2 = text2
- self.text1 = text1
-
- self.asnd = asnd
- self.bsnd = bsnd
-
- self.current_game_key = None
-
- close_button = gtk.Button('X')
- close_button.connect('button-press-event', self.emit_close)
- table = gtk.Table()
- table.connect('button-press-event', self.emit_selected)
- table.set_col_spacings(0)
- table.set_border_width(10)
- self.bcard1 = svgcard.SvgCard(-1, {'front_text':{'card_text':text1, 'text_color':'#ffffff'}, 'front':{'fill_color':'#4c4d4f', 'stroke_color':'#ffffff', 'opacity':'1'}}, None, 184, 1, self.bg_color)
- self.bcard2 = svgcard.SvgCard(-1, {'front_text':{'card_text':text2, 'text_color':'#ffffff'}, 'front':{'fill_color':'#4c4d4f', 'stroke_color':'#ffffff', 'opacity':'1'}}, None, 184, 1, self.bg_color)
+
+ __gsignals__ = {
+ 'pair-selected': (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT]),
+ 'pair-closed': (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT]),
+ }
+
+ def __init__(self, text1, text2 = None, aimg = None, bimg = None, asnd = None, bsnd = None):
+ gtk.EventBox.__init__(self)
+ self.bg_color = '#000000'
+ if text2 == None:
+ self.text2 = text1
+ else:
+ self.text2 = text2
+ self.text1 = text1
+
+ self.asnd = asnd
+ self.bsnd = bsnd
+
+ self.current_game_key = None
+
+ close_button = gtk.Button('X')
+ close_button.connect('button-press-event', self.emit_close)
+ table = gtk.Table()
+ table.connect('button-press-event', self.emit_selected)
+ table.set_col_spacings(0)
+ table.set_border_width(10)
+ self.bcard1 = svgcard.SvgCard(-1, {'front_text':{'card_text':text1, 'text_color':'#ffffff'}, 'front':{'fill_color':'#4c4d4f', 'stroke_color':'#ffffff', 'opacity':'1'}}, None, 184, 1, self.bg_color)
+ self.bcard2 = svgcard.SvgCard(-1, {'front_text':{'card_text':text2, 'text_color':'#ffffff'}, 'front':{'fill_color':'#4c4d4f', 'stroke_color':'#ffffff', 'opacity':'1'}}, None, 184, 1, self.bg_color)
- self.bcard1.flip()
- self.bcard2.flip()
- self.bcard1.set_pixbuf(aimg)
- self.bcard2.set_pixbuf(bimg)
-
- table.attach(self.bcard1, 0, 1, 0, 8)
- table.attach(self.bcard2, 1, 2, 0, 8)
- table.attach(close_button, 2, 3, 0, 1, gtk.FILL, gtk.FILL)
-
- self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.bg_color))
- self.add(table)
- self.show_all()
+ self.bcard1.flip()
+ self.bcard2.flip()
+ self.bcard1.set_pixbuf(aimg)
+ self.bcard2.set_pixbuf(bimg)
+
+ table.attach(self.bcard1, 0, 1, 0, 8)
+ table.attach(self.bcard2, 1, 2, 0, 8)
+ table.attach(close_button, 2, 3, 0, 1, gtk.FILL, gtk.FILL)
+
+ self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.bg_color))
+ self.add(table)
+ self.show_all()
- def emit_selected(self, widget, event):
- self.emit('pair-selected', self)
+ def emit_selected(self, widget, event):
+ self.emit('pair-selected', self)
- def emit_close(self, widget, event):
- self.emit('pair-closed', self)
+ def emit_close(self, widget, event):
+ self.emit('pair-closed', self)
- def set_selected(self, status):
- if not status:
- self.bg_color = '#000000'
- else:
- self.bg_color = '#b2b3b7'
-
- self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.bg_color))
- self.bcard1.set_background(self.bg_color)
- self.bcard2.set_background(self.bg_color)
-
- def change_pixbuf(self, aimg, bimg):
- self.bcard1.set_pixbuf(aimg)
- self.bcard2.set_pixbuf(bimg)
-
- def change_text(self, text1, text2):
- self.bcard1.change_text(text1)
- self.bcard2.change_text(text2)
+ def set_selected(self, status):
+ if not status:
+ self.bg_color = '#000000'
+ else:
+ self.bg_color = '#b2b3b7'
+
+ self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.bg_color))
+ self.bcard1.set_background(self.bg_color)
+ self.bcard2.set_background(self.bg_color)
+
+ def change_pixbuf(self, aimg, bimg):
+ self.bcard1.set_pixbuf(aimg)
+ self.bcard2.set_pixbuf(bimg)
+
+ def change_text(self, text1, text2):
+ self.bcard1.change_text(text1)
+ self.bcard2.change_text(text2)
- def change_sound(self, asnd, bsnd):
- self.asnd = asnd
- self.bsnd = bsnd
-
- def get_text(self, card):
- if card == 1:
- return self.bcard1.get_text()
- else:
- return self.bcard2.get_text()
-
- def get_pixbuf(self, card):
- if card == 1:
- return self.bcard1.get_pixbuf()
- else:
- return self.bcard2.get_pixbuf()
-
- def get_sound(self, card):
- if card == 1:
- return self.asnd
- else:
- return self.bsnd \ No newline at end of file
+ def change_sound(self, asnd, bsnd):
+ self.asnd = asnd
+ self.bsnd = bsnd
+
+ def get_text(self, card):
+ if card == 1:
+ return self.bcard1.get_text()
+ else:
+ return self.bcard2.get_text()
+
+ def get_pixbuf(self, card):
+ if card == 1:
+ return self.bcard1.get_pixbuf()
+ else:
+ return self.bcard2.get_pixbuf()
+
+ def get_sound(self, card):
+ if card == 1:
+ return self.asnd
+ else:
+ return self.bsnd \ No newline at end of file
diff --git a/cardtable.py b/cardtable.py
index a612647..28a2a4d 100755
--- a/cardtable.py
+++ b/cardtable.py
@@ -17,19 +17,21 @@
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
-import gtk, pygtk
+import gtk
+import pygtk
+import pango
import svgcard
import os
import time
-import gobject
import math
import gc
+from gobject import SIGNAL_RUN_FIRST, TYPE_PYOBJECT
class CardTable(gtk.EventBox):
__gsignals__ = {
- 'card-flipped': (gobject.SIGNAL_RUN_FIRST, None, [int, gobject.TYPE_PYOBJECT]),
- 'card-highlighted': (gobject.SIGNAL_RUN_FIRST, None, [int, gobject.TYPE_PYOBJECT]),
+ 'card-flipped': (SIGNAL_RUN_FIRST, None, [int, TYPE_PYOBJECT]),
+ 'card-highlighted': (SIGNAL_RUN_FIRST, None, [int, TYPE_PYOBJECT]),
}
def __init__(self):
@@ -46,7 +48,13 @@ class CardTable(gtk.EventBox):
self.table.set_border_width(11)
self.table.set_resize_mode(gtk.RESIZE_IMMEDIATE)
self.set_property('child', self.table)
- self.fist_load = True
+ self.load_message = gtk.Label('Loading Game')
+ self.load_message.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#ffffff'))
+ self.load_message.modify_font(pango.FontDescription("10"))
+ self.load_message.show()
+ self.first_load = True
+ self.load_mode = False
+ self.dict = None
self.show_all()
def load_game(self, widget, data, grid):
@@ -67,11 +75,11 @@ class CardTable(gtk.EventBox):
# Build the table
if data['divided']=='1':
- text1 = str(self.data.get('face1',''))
- text2 = str(self.data.get('face2',''))
+ text1 = str(self.data.get('face1', ''))
+ text2 = str(self.data.get('face2', ''))
else:
- text1 = str(self.data.get('face',''))
- text2 = str(self.data.get('face',''))
+ text1 = str(self.data.get('face', ''))
+ text2 = str(self.data.get('face', ''))
x = 0
y = 0
@@ -79,7 +87,7 @@ class CardTable(gtk.EventBox):
for card in self.cards_data:
if card.get('img', None):
- jpg = os.path.join(os.path.dirname(__file__), card['img'])
+ jpg = os.path.join(self.data['pathimg'], card['img'])
else:
jpg = None
props = {}
@@ -90,7 +98,8 @@ class CardTable(gtk.EventBox):
elif card['ab']== 'b':
props['back_text']= {'card_text':text2}
- card = svgcard.SvgCard(id, props, jpg, self.card_size,self.data.get('align','1'))
+ align = self.data.get('align', '1')
+ card = svgcard.SvgCard(id, props, jpg, self.card_size, align)
card.connect('enter-notify-event', self.mouse_event, [x, y])
card.connect("button-press-event", self.flip_card_mouse, id)
self.table_positions[(x, y)]=1
@@ -105,17 +114,19 @@ class CardTable(gtk.EventBox):
x = 0
y +=1
id += 1
- self.fist_load = False
+ self.first_load = False
+ if self.load_mode:
+ self._set_load_mode(False)
+ self.show_all()
gc.collect()
def change_game(self, widget, data, grid):
- if not self.fist_load:
+ if not self.first_load:
for card in self.cards.values():
self.table.remove(card)
del card
gc.collect()
self.load_game(None, data, grid)
-
def get_card_size(self, size_table):
x = (780 - (11*size_table))/size_table
@@ -133,31 +144,31 @@ class CardTable(gtk.EventBox):
x= self.selected_card[0]
y= self.selected_card[1]
- if event.keyval in (gtk.keysyms.Left, gtk.keysyms.KP_Left,gtk.keysyms.a):
+ if event.keyval in (gtk.keysyms.Left, gtk.keysyms.KP_Left):
if self.table_positions.has_key((x-1, y)):
card = self.cards[x-1, y]
id = self.cd2id.get(card)
self.emit('card-highlighted', id, False)
- elif event.keyval in (gtk.keysyms.Right, gtk.keysyms.KP_Right,gtk.keysyms.d):
+ elif event.keyval in (gtk.keysyms.Right, gtk.keysyms.KP_Right):
if self.table_positions.has_key((x+1, y)):
card = self.cards[x+1, y]
id = self.cd2id.get(card)
self.emit('card-highlighted', id, False)
- elif event.keyval in (gtk.keysyms.Up, gtk.keysyms.KP_Up,gtk.keysyms.w):
+ elif event.keyval in (gtk.keysyms.Up, gtk.keysyms.KP_Up):
if self.table_positions.has_key((x, y-1)):
card = self.cards[x, y-1]
id = self.cd2id.get(card)
self.emit('card-highlighted', id, False)
- elif event.keyval in (gtk.keysyms.Down, gtk.keysyms.KP_Down,gtk.keysyms.s):
+ elif event.keyval in (gtk.keysyms.Down, gtk.keysyms.KP_Down):
if self.table_positions.has_key((x, y+1)):
card = self.cards[x, y+1]
id = self.cd2id.get(card)
self.emit('card-highlighted', id, False)
- elif event.keyval in (gtk.keysyms.space,gtk.keysyms.KP_Page_Down):
+ elif event.keyval in (gtk.keysyms.space, gtk.keysyms.KP_Page_Down):
card = self.cards[x, y]
self.card_flipped(card)
@@ -181,9 +192,28 @@ class CardTable(gtk.EventBox):
self.id2cd.get(id).flip()
def highlight_card(self, widget, id, status):
- self.selected_card = self.dict.get(id)
- self.id2cd.get(id).set_highlight(status)
+ if self.dict != None:
+ self.selected_card = self.dict.get(id)
+ self.id2cd.get(id).set_highlight(status)
def reset(self, widget):
for id in self.id2cd.keys():
self.id2cd[id].reset()
+
+ def _set_load_mode(self,mode):
+ if mode:
+ self.remove(self.table)
+ self.set_property('child', self.load_message)
+ else:
+ self.remove(self.load_message)
+ self.set_property('child', self.table)
+ self.load_mode = mode
+ self.queue_draw()
+ while gtk.events_pending():
+ gtk.main_iteration()
+
+ def load_msg(self, widget, msg):
+ if not self.load_mode:
+ self._set_load_mode(True)
+ self.load_message.set_text(msg)
+ self.queue_draw() \ No newline at end of file
diff --git a/createcardpanel.py b/createcardpanel.py
index 5812d99..5f869e6 100644
--- a/createcardpanel.py
+++ b/createcardpanel.py
@@ -1,20 +1,20 @@
#! /usr/bin/env python
#
-# Copyright (C) 2006, 2007, One Laptop Per Child
+# Copyright (C) 2006, 2007, One Laptop Per Child
#
-# 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 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.
+# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#
import gtk
@@ -24,286 +24,286 @@ import tempfile
from gettext import gettext as _
import svgcard
import logging
-import gobject
+from gobject import SIGNAL_RUN_FIRST, TYPE_PYOBJECT
from xml.dom.minidom import parse
from sugar.graphics.objectchooser import ObjectChooser
_logger = logging.getLogger('memorize-activity')
class CreateCardPanel(gtk.EventBox):
-
- __gsignals__ = {
- 'add-pair': (gobject.SIGNAL_RUN_FIRST, None, [gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT]),
- 'update-pair': (gobject.SIGNAL_RUN_FIRST, None, [gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT]),
- }
-
- def __init__(self):
- gtk.EventBox.__init__(self)
- self.set_size_request(650, 320)
-
- self.equal_pairs = False
-
- # Set the add new pair buttom
- add_icon = os.path.join(os.path.dirname(__file__), "images/pair-add.svg")
- add_image = gtk.Image()
- add_image.set_from_file(add_icon)
- self._addbutton = gtk.Button(' ' + _('Add as new pair'))
- self._addbutton.set_image(add_image)
- self._addbutton.connect('button-press-event', self.emit_add_pair)
-
- # Set update selected pair buttom
- update_icon = os.path.join(os.path.dirname(__file__), "images/pair-update.svg")
- update_image = gtk.Image()
- update_image.set_from_file(update_icon)
- self._updatebutton = gtk.Button(' ' + _('Update selected pair'))
- self._updatebutton.set_image(update_image)
- self._updatebutton.connect('button-press-event', self.emit_update_pair)
-
- # Set card editors
- self.cardeditor1 = CardEditor()
- self.cardeditor2 = CardEditor()
- self.clean(None)
- self.cardeditor1.connect('has-text', self.receive_text_signals)
- self.cardeditor2.connect('has-text', self.receive_text_signals)
- self.cardeditor1.connect('has-picture', self.receive_picture_signals)
- self.cardeditor2.connect('has-picture', self.receive_picture_signals)
-
- # Create table and add components to the table
- self.table = gtk.Table()
- self.table.set_homogeneous(False)
- self.table.set_col_spacings(10)
- self.table.set_row_spacings(10)
- self.table.set_border_width(10)
- self.table.attach(self.cardeditor1, 0, 2, 0, 1, gtk.SHRINK|gtk.FILL, gtk.SHRINK, 10, 30)
- self.table.attach(self.cardeditor2, 2, 4, 0, 1, gtk.SHRINK|gtk.FILL, gtk.SHRINK, 10, 30)
- self.table.attach(self._addbutton, 1, 2, 1, 2, gtk.SHRINK|gtk.FILL, gtk.SHRINK)
- self.table.attach(self._updatebutton, 2, 3, 1, 2, gtk.SHRINK|gtk.FILL, gtk.SHRINK)
- self.add(self.table)
- self.show_all()
-
- def emit_add_pair(self, widget, event):
- if self.equal_pairs:
- self.emit('add-pair', self.cardeditor1.get_text(), self.cardeditor1.get_text(), self.cardeditor1.get_pixbuf(), self.cardeditor1.get_pixbuf(), self.cardeditor1.get_snd(), self.cardeditor1.get_snd())
- else:
- self.emit('add-pair', self.cardeditor1.get_text(), self.cardeditor2.get_text(), self.cardeditor1.get_pixbuf(), self.cardeditor2.get_pixbuf(), self.cardeditor1.get_snd(), self.cardeditor2.get_snd())
- self.clean(None)
-
+
+ __gsignals__ = {
+ 'add-pair': (SIGNAL_RUN_FIRST, None, 6 * [TYPE_PYOBJECT]),
+ 'update-pair': (SIGNAL_RUN_FIRST, None, 6 * [TYPE_PYOBJECT]),
+ }
+
+ def __init__(self):
+ gtk.EventBox.__init__(self)
+ self.set_size_request(650, 320)
+
+ self.equal_pairs = False
+
+ # Set the add new pair buttom
+ add_icon = os.path.join(os.path.dirname(__file__), "images/pair-add.svg")
+ add_image = gtk.Image()
+ add_image.set_from_file(add_icon)
+ self._addbutton = gtk.Button(' ' + _('Add as new pair'))
+ self._addbutton.set_image(add_image)
+ self._addbutton.connect('button-press-event', self.emit_add_pair)
+
+ # Set update selected pair buttom
+ update_icon = os.path.join(os.path.dirname(__file__), "images/pair-update.svg")
+ update_image = gtk.Image()
+ update_image.set_from_file(update_icon)
+ self._updatebutton = gtk.Button(' ' + _('Update selected pair'))
+ self._updatebutton.set_image(update_image)
+ self._updatebutton.connect('button-press-event', self.emit_update_pair)
+
+ # Set card editors
+ self.cardeditor1 = CardEditor()
+ self.cardeditor2 = CardEditor()
+ self.clean(None)
+ self.cardeditor1.connect('has-text', self.receive_text_signals)
+ self.cardeditor2.connect('has-text', self.receive_text_signals)
+ self.cardeditor1.connect('has-picture', self.receive_picture_signals)
+ self.cardeditor2.connect('has-picture', self.receive_picture_signals)
+
+ # Create table and add components to the table
+ self.table = gtk.Table()
+ self.table.set_homogeneous(False)
+ self.table.set_col_spacings(10)
+ self.table.set_row_spacings(10)
+ self.table.set_border_width(10)
+ self.table.attach(self.cardeditor1, 0, 2, 0, 1, gtk.SHRINK|gtk.FILL, gtk.SHRINK, 10, 30)
+ self.table.attach(self.cardeditor2, 2, 4, 0, 1, gtk.SHRINK|gtk.FILL, gtk.SHRINK, 10, 30)
+ self.table.attach(self._addbutton, 1, 2, 1, 2, gtk.SHRINK|gtk.FILL, gtk.SHRINK)
+ self.table.attach(self._updatebutton, 2, 3, 1, 2, gtk.SHRINK|gtk.FILL, gtk.SHRINK)
+ self.add(self.table)
+ self.show_all()
+
+ def emit_add_pair(self, widget, event):
+ if self.equal_pairs:
+ self.emit('add-pair', self.cardeditor1.get_text(), self.cardeditor1.get_text(), self.cardeditor1.get_pixbuf(), self.cardeditor1.get_pixbuf(), self.cardeditor1.get_snd(), self.cardeditor1.get_snd())
+ else:
+ self.emit('add-pair', self.cardeditor1.get_text(), self.cardeditor2.get_text(), self.cardeditor1.get_pixbuf(), self.cardeditor2.get_pixbuf(), self.cardeditor1.get_snd(), self.cardeditor2.get_snd())
+ self.clean(None)
+
- def emit_update_pair(self, widget, event):
- if self.equal_pairs:
- self.emit('update-pair', self.cardeditor1.get_text(), self.cardeditor1.get_text(), self.cardeditor1.get_pixbuf(), self.cardeditor1.get_pixbuf(), self.cardeditor1.get_snd(), self.cardeditor1.get_snd())
- else:
- self.emit('update-pair', self.cardeditor1.get_text(), self.cardeditor2.get_text(), self.cardeditor1.get_pixbuf(), self.cardeditor2.get_pixbuf(), self.cardeditor1.get_snd(), self.cardeditor2.get_snd())
- self.clean(None)
-
- def load_pair(self, widget, newtext1, newtext2, aimg, bimg, asnd, bsnd):
- self.cardeditor1.set_text(newtext1)
- self.cardeditor2.set_text(newtext2)
- self.cardeditor1.set_pixbuf(aimg)
- self.cardeditor2.set_pixbuf(bimg)
- self.cardeditor1.set_snd(asnd)
- self.cardeditor2.set_snd(bsnd)
- self._addbutton.set_sensitive(True)
- self._updatebutton.set_sensitive(True)
+ def emit_update_pair(self, widget, event):
+ if self.equal_pairs:
+ self.emit('update-pair', self.cardeditor1.get_text(), self.cardeditor1.get_text(), self.cardeditor1.get_pixbuf(), self.cardeditor1.get_pixbuf(), self.cardeditor1.get_snd(), self.cardeditor1.get_snd())
+ else:
+ self.emit('update-pair', self.cardeditor1.get_text(), self.cardeditor2.get_text(), self.cardeditor1.get_pixbuf(), self.cardeditor2.get_pixbuf(), self.cardeditor1.get_snd(), self.cardeditor2.get_snd())
+ self.clean(None)
+
+ def load_pair(self, widget, newtext1, newtext2, aimg, bimg, asnd, bsnd):
+ self.cardeditor1.set_text(newtext1)
+ self.cardeditor2.set_text(newtext2)
+ self.cardeditor1.set_pixbuf(aimg)
+ self.cardeditor2.set_pixbuf(bimg)
+ self.cardeditor1.set_snd(asnd)
+ self.cardeditor2.set_snd(bsnd)
+ self._addbutton.set_sensitive(True)
+ self._updatebutton.set_sensitive(True)
- def change_equal_pairs(self, widget, state):
- self.equal_pairs = state
- self.clean(None)
- if self.equal_pairs:
- self.table.remove(self.cardeditor1)
- self.table.remove(self.cardeditor2)
- self.table.attach(self.cardeditor1, 0, 4, 0, 1, gtk.SHRINK|gtk.FILL, gtk.SHRINK, 200, 30)
- else:
- self.table.remove(self.cardeditor1)
- self.table.attach(self.cardeditor1, 0, 2, 0, 1, gtk.SHRINK|gtk.FILL, gtk.SHRINK, 10, 30)
- self.table.attach(self.cardeditor2, 2, 4, 0, 1, gtk.SHRINK|gtk.FILL, gtk.SHRINK, 10, 30)
-
- def clean(self, widget):
- self.cardeditor1.clean()
- self.cardeditor2.clean()
- self._addbutton.set_sensitive(False)
- self._updatebutton.set_sensitive(False)
- self._card1_has_text = False
- self._card2_has_text = False
- self._card1_has_picture = False
- self._card2_has_picture = False
-
- def receive_text_signals(self, widget, has_text):
- if widget == self.cardeditor1:
- self._card1_has_text = has_text
- if widget == self.cardeditor2:
- self._card2_has_text = has_text
- self._update_buttom_status()
-
- def receive_picture_signals(self, widget, has_picture):
- if widget == self.cardeditor1:
- self._card1_has_picture = has_picture
- if widget == self.cardeditor2:
- self._card2_has_picture = has_picture
- self._update_buttom_status()
-
- def _update_buttom_status(self):
- if not self.equal_pairs:
- if (self._card1_has_text or self._card1_has_picture) and (self._card2_has_text or self._card2_has_picture):
- self._addbutton.set_sensitive(True)
- self._updatebutton.set_sensitive(True)
- else:
- self._addbutton.set_sensitive(False)
- self._updatebutton.set_sensitive(False)
- else:
- if self._card1_has_text or self._card1_has_picture:
- self._addbutton.set_sensitive(True)
- self._updatebutton.set_sensitive(True)
- else:
- self._addbutton.set_sensitive(False)
- self._updatebutton.set_sensitive(False)
-
+ def change_equal_pairs(self, widget, state):
+ self.equal_pairs = state
+ self.clean(None)
+ if self.equal_pairs:
+ self.table.remove(self.cardeditor1)
+ self.table.remove(self.cardeditor2)
+ self.table.attach(self.cardeditor1, 0, 4, 0, 1, gtk.SHRINK|gtk.FILL, gtk.SHRINK, 200, 30)
+ else:
+ self.table.remove(self.cardeditor1)
+ self.table.attach(self.cardeditor1, 0, 2, 0, 1, gtk.SHRINK|gtk.FILL, gtk.SHRINK, 10, 30)
+ self.table.attach(self.cardeditor2, 2, 4, 0, 1, gtk.SHRINK|gtk.FILL, gtk.SHRINK, 10, 30)
+
+ def clean(self, widget):
+ self.cardeditor1.clean()
+ self.cardeditor2.clean()
+ self._addbutton.set_sensitive(False)
+ self._updatebutton.set_sensitive(False)
+ self._card1_has_text = False
+ self._card2_has_text = False
+ self._card1_has_picture = False
+ self._card2_has_picture = False
+
+ def receive_text_signals(self, widget, has_text):
+ if widget == self.cardeditor1:
+ self._card1_has_text = has_text
+ if widget == self.cardeditor2:
+ self._card2_has_text = has_text
+ self._update_buttom_status()
+
+ def receive_picture_signals(self, widget, has_picture):
+ if widget == self.cardeditor1:
+ self._card1_has_picture = has_picture
+ if widget == self.cardeditor2:
+ self._card2_has_picture = has_picture
+ self._update_buttom_status()
+
+ def _update_buttom_status(self):
+ if not self.equal_pairs:
+ if (self._card1_has_text or self._card1_has_picture) and (self._card2_has_text or self._card2_has_picture):
+ self._addbutton.set_sensitive(True)
+ self._updatebutton.set_sensitive(True)
+ else:
+ self._addbutton.set_sensitive(False)
+ self._updatebutton.set_sensitive(False)
+ else:
+ if self._card1_has_text or self._card1_has_picture:
+ self._addbutton.set_sensitive(True)
+ self._updatebutton.set_sensitive(True)
+ else:
+ self._addbutton.set_sensitive(False)
+ self._updatebutton.set_sensitive(False)
+
class CardEditor(gtk.EventBox):
-
- __gsignals__ = {
- 'has-text': (gobject.SIGNAL_RUN_FIRST, None, [gobject.TYPE_PYOBJECT]),
- 'has-picture': (gobject.SIGNAL_RUN_FIRST, None, [gobject.TYPE_PYOBJECT]),
- }
-
- def __init__(self):
- gtk.EventBox.__init__(self)
- self.set_size_request(310, 320)
+
+ __gsignals__ = {
+ 'has-text': (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT]),
+ 'has-picture': (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT]),
+ }
+
+ def __init__(self):
+ gtk.EventBox.__init__(self)
+ self.set_size_request(310, 320)
- self.temp_folder = tempfile.mkdtemp()
-
- table = gtk.Table()
- self.previewlabel = gtk.Label(_('Preview:'))
- self.previewlabel.set_alignment(1, 0.5)
- self.textlabel = gtk.Label(_('Text:'))
- self.textlabel.set_alignment(1, 0.5)
-
- picture_icon = os.path.join(os.path.dirname(__file__), 'images/import_picture.svg')
- picture_image = gtk.Image()
- picture_image.set_from_file(picture_icon)
- self.browsepicture = gtk.Button()
- self.browsepicture.set_image(picture_image)
- self.browsepicture.connect('button-press-event', self._import_image)
-
- sound_icon = os.path.join(os.path.dirname(__file__), 'images/import_sound.svg')
- sound_image = gtk.Image()
- sound_image.set_from_file(sound_icon)
- self.browsesound = gtk.Button()
- self.browsesound.set_image(sound_image)
- self.browsesound.connect('button-press-event', self._import_audio)
- self.snd = None
- self.textentry = gtk.Entry()
- self.textentry.connect('changed', self.update_text)
-
- table.set_homogeneous(False)
- table.set_col_spacings(10)
- table.set_row_spacings(10)
- table.set_border_width(10)
- self.card = svgcard.SvgCard(-1, {'front_text':{'card_text':'', 'text_color':'#ffffff'}, 'front_border':{'fill_color':'#4c4d4f', 'stroke_color':'#ffffff', 'opacity':'1'}}, None, 184, 1, '#c0c0c0')
- self.card.flip()
-
- table.attach(self.previewlabel, 0, 1, 1, 2, gtk.EXPAND, gtk.EXPAND)
- table.attach(self.card, 1, 3, 1, 2, gtk.EXPAND, gtk.EXPAND, 10)
- #Text label and entry
- table.attach(self.textlabel, 0, 1, 2, 3, gtk.EXPAND|gtk.FILL, gtk.EXPAND)
- table.attach(self.textentry, 1, 3, 2, 3, gtk.EXPAND|gtk.FILL, gtk.EXPAND)
- #Picture label and entry
- table.attach(self.browsepicture, 1, 2, 3, 4, gtk.EXPAND|gtk.FILL, gtk.EXPAND)
- #Sound label and entry
- table.attach(self.browsesound, 2, 3, 3, 4, gtk.EXPAND|gtk.FILL, gtk.EXPAND)
-
- self.add(table)
-
- def update_text(self, entry):
- self.card.change_text(entry.get_text())
- if len(entry.get_text()) == 0:
- self.emit('has-text', False)
- else:
- self.emit('has-text', True)
-
- def get_text(self):
- return self.textentry.get_text()
+ self.temp_folder = tempfile.mkdtemp()
+
+ table = gtk.Table()
+ self.previewlabel = gtk.Label(_('Preview:'))
+ self.previewlabel.set_alignment(1, 0.5)
+ self.textlabel = gtk.Label(_('Text:'))
+ self.textlabel.set_alignment(1, 0.5)
+
+ picture_icon = os.path.join(os.path.dirname(__file__), 'images/import_picture.svg')
+ picture_image = gtk.Image()
+ picture_image.set_from_file(picture_icon)
+ self.browsepicture = gtk.Button()
+ self.browsepicture.set_image(picture_image)
+ self.browsepicture.connect('button-press-event', self._import_image)
+
+ sound_icon = os.path.join(os.path.dirname(__file__), 'images/import_sound.svg')
+ sound_image = gtk.Image()
+ sound_image.set_from_file(sound_icon)
+ self.browsesound = gtk.Button()
+ self.browsesound.set_image(sound_image)
+ self.browsesound.connect('button-press-event', self._import_audio)
+ self.snd = None
+ self.textentry = gtk.Entry()
+ self.textentry.connect('changed', self.update_text)
+
+ table.set_homogeneous(False)
+ table.set_col_spacings(10)
+ table.set_row_spacings(10)
+ table.set_border_width(10)
+ self.card = svgcard.SvgCard(-1, {'front_text':{'card_text':'', 'text_color':'#ffffff'}, 'front_border':{'fill_color':'#4c4d4f', 'stroke_color':'#ffffff', 'opacity':'1'}}, None, 184, 1, '#c0c0c0')
+ self.card.flip()
+
+ table.attach(self.previewlabel, 0, 1, 1, 2, gtk.EXPAND, gtk.EXPAND)
+ table.attach(self.card, 1, 3, 1, 2, gtk.EXPAND, gtk.EXPAND, 10)
+ #Text label and entry
+ table.attach(self.textlabel, 0, 1, 2, 3, gtk.EXPAND|gtk.FILL, gtk.EXPAND)
+ table.attach(self.textentry, 1, 3, 2, 3, gtk.EXPAND|gtk.FILL, gtk.EXPAND)
+ #Picture label and entry
+ table.attach(self.browsepicture, 1, 2, 3, 4, gtk.EXPAND|gtk.FILL, gtk.EXPAND)
+ #Sound label and entry
+ table.attach(self.browsesound, 2, 3, 3, 4, gtk.EXPAND|gtk.FILL, gtk.EXPAND)
+
+ self.add(table)
+
+ def update_text(self, entry):
+ self.card.change_text(entry.get_text())
+ if len(entry.get_text()) == 0:
+ self.emit('has-text', False)
+ else:
+ self.emit('has-text', True)
+
+ def get_text(self):
+ return self.textentry.get_text()
- def set_text(self, newtext):
- if newtext == None:
- newtext = ''
- self.textentry.set_text(newtext)
-
- def get_pixbuf(self):
- return self.card.get_pixbuf()
-
- def set_pixbuf(self, pixbuf):
- self.card.set_pixbuf(pixbuf)
-
- def _import_image(self, widget, event):
- chooser = ObjectChooser(_('Choose image'), None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
- try:
- result = chooser.run()
- if result == gtk.RESPONSE_ACCEPT:
- _logger.debug('ObjectChooser: %r' % chooser.get_selected_object())
- jobject = chooser.get_selected_object()
- if jobject and jobject.file_path:
- self._load_image(jobject.file_path)
- finally:
- chooser.destroy()
- del chooser
-
- def _load_image(self, index):
- pixbuf_t = gtk.gdk.pixbuf_new_from_file(index)
- self.card.set_pixbuf(self.to_card_pixbuf(pixbuf_t))
- _logger.error('Picture Loaded: '+index)
- self.emit('has-picture', True)
- del pixbuf_t
-
- def _import_audio(self, widget, event):
- chooser = ObjectChooser(_('Choose audio'), None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
- jobject = ''
- try:
- result = chooser.run()
- if result == gtk.RESPONSE_ACCEPT:
- _logger.debug('ObjectChooser: %r' % chooser.get_selected_object())
- jobject = chooser.get_selected_object()
- if not jobject or not jobject.file_path:
- return
- finally:
- chooser.destroy()
- del chooser
-
- if jobject and jobject.file_path:
- self._load_audio(jobject.file_path)
-
- def _load_audio(self, index):
- dst = os.path.join(self.temp_folder, os.path.basename(index))
- shutil.copy(index, dst)
- self.set_snd(dst)
- _logger.error('Audio Loaded: '+dst)
-
- def set_snd(self, snd):
- self.snd = snd
-
- def get_snd(self):
- return self.snd
+ def set_text(self, newtext):
+ if newtext == None:
+ newtext = ''
+ self.textentry.set_text(newtext)
+
+ def get_pixbuf(self):
+ return self.card.get_pixbuf()
+
+ def set_pixbuf(self, pixbuf):
+ self.card.set_pixbuf(pixbuf)
+
+ def _import_image(self, widget, event):
+ chooser = ObjectChooser(_('Choose image'), None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
+ try:
+ result = chooser.run()
+ if result == gtk.RESPONSE_ACCEPT:
+ _logger.debug('ObjectChooser: %r' % chooser.get_selected_object())
+ jobject = chooser.get_selected_object()
+ if jobject and jobject.file_path:
+ self._load_image(jobject.file_path)
+ finally:
+ chooser.destroy()
+ del chooser
+
+ def _load_image(self, index):
+ pixbuf_t = gtk.gdk.pixbuf_new_from_file(index)
+ self.card.set_pixbuf(self.to_card_pixbuf(pixbuf_t))
+ _logger.error('Picture Loaded: '+index)
+ self.emit('has-picture', True)
+ del pixbuf_t
+
+ def _import_audio(self, widget, event):
+ chooser = ObjectChooser(_('Choose audio'), None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
+ jobject = ''
+ try:
+ result = chooser.run()
+ if result == gtk.RESPONSE_ACCEPT:
+ _logger.debug('ObjectChooser: %r' % chooser.get_selected_object())
+ jobject = chooser.get_selected_object()
+ if not jobject or not jobject.file_path:
+ return
+ finally:
+ chooser.destroy()
+ del chooser
+
+ if jobject and jobject.file_path:
+ self._load_audio(jobject.file_path)
+
+ def _load_audio(self, index):
+ dst = os.path.join(self.temp_folder, os.path.basename(index))
+ shutil.copy(index, dst)
+ self.set_snd(dst)
+ _logger.error('Audio Loaded: '+dst)
+
+ def set_snd(self, snd):
+ self.snd = snd
+
+ def get_snd(self):
+ return self.snd
- def clean(self):
- self.textentry.set_text('')
- self.card.set_pixbuf(None)
- self.emit('has-text', False)
- self.emit('has-picture', False)
-
- def to_card_pixbuf(self, pixbuf):
- if pixbuf.get_width() == pixbuf.get_height():
- new = pixbuf_t.scale_simple(162, 162, gtk.gdk.INTERP_BILINEAR)
- elif pixbuf.get_width() > pixbuf.get_height():
- new = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, 162, 162)
- aspect = float(pixbuf.get_width()) / float(pixbuf.get_height())
- pixbuf_t = pixbuf.scale_simple(int(float(162)*aspect) , 162, gtk.gdk.INTERP_BILINEAR)
- diff = pixbuf_t.get_width() - pixbuf_t.get_height()
- pixbuf_t.scale(new, 0, 0, 162, 162, -(diff/2), 0, 1, 1, gtk.gdk.INTERP_BILINEAR)
- del pixbuf_t
- elif pixbuf.get_width() < pixbuf.get_height():
- new = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, 162, 162)
- aspect = float(pixbuf.get_height()) / float(pixbuf.get_width())
- pixbuf_t = pixbuf.scale_simple(162 , int(float(162)*aspect), gtk.gdk.INTERP_BILINEAR)
- diff = pixbuf_t.get_height() - pixbuf_t.get_width()
- pixbuf_t.scale(new, 0, 0, 162, 162, 0, -(diff/2), 1, 1, gtk.gdk.INTERP_BILINEAR)
- del pixbuf_t
- return new \ No newline at end of file
+ def clean(self):
+ self.textentry.set_text('')
+ self.card.set_pixbuf(None)
+ self.emit('has-text', False)
+ self.emit('has-picture', False)
+
+ def to_card_pixbuf(self, pixbuf):
+ if pixbuf.get_width() == pixbuf.get_height():
+ new = pixbuf_t.scale_simple(162, 162, gtk.gdk.INTERP_BILINEAR)
+ elif pixbuf.get_width() > pixbuf.get_height():
+ new = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, 162, 162)
+ aspect = float(pixbuf.get_width()) / float(pixbuf.get_height())
+ pixbuf_t = pixbuf.scale_simple(int(float(162)*aspect) , 162, gtk.gdk.INTERP_BILINEAR)
+ diff = pixbuf_t.get_width() - pixbuf_t.get_height()
+ pixbuf_t.scale(new, 0, 0, 162, 162, -(diff/2), 0, 1, 1, gtk.gdk.INTERP_BILINEAR)
+ del pixbuf_t
+ elif pixbuf.get_width() < pixbuf.get_height():
+ new = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, 162, 162)
+ aspect = float(pixbuf.get_height()) / float(pixbuf.get_width())
+ pixbuf_t = pixbuf.scale_simple(162 , int(float(162)*aspect), gtk.gdk.INTERP_BILINEAR)
+ diff = pixbuf_t.get_height() - pixbuf_t.get_width()
+ pixbuf_t.scale(new, 0, 0, 162, 162, 0, -(diff/2), 1, 1, gtk.gdk.INTERP_BILINEAR)
+ del pixbuf_t
+ return new \ No newline at end of file
diff --git a/createtoolbar.py b/createtoolbar.py
index 385dc99..4d64989 100755
--- a/createtoolbar.py
+++ b/createtoolbar.py
@@ -22,7 +22,7 @@ from gettext import gettext as _
import gtk
import os
-import gobject
+from gobject import SIGNAL_RUN_FIRST, TYPE_PYOBJECT
from sugar.graphics.toolbutton import ToolButton
from sugar.graphics.toggletoolbutton import ToggleToolButton
@@ -33,10 +33,10 @@ class CreateToolbar(gtk.Toolbar):
__gtype_name__ = 'CreateToolbar'
__gsignals__ = {
- 'create_new_game': (gobject.SIGNAL_RUN_FIRST, None, []),
- 'create_load_game': (gobject.SIGNAL_RUN_FIRST, None, [gobject.TYPE_PYOBJECT]),
- 'create_save_game': (gobject.SIGNAL_RUN_FIRST, None, [gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT]),
- 'create_equal_pairs': (gobject.SIGNAL_RUN_FIRST, None, [gobject.TYPE_PYOBJECT]),
+ 'create_new_game': (SIGNAL_RUN_FIRST, None, []),
+ 'create_load_game': (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT]),
+ 'create_save_game': (SIGNAL_RUN_FIRST, None, 3 * [TYPE_PYOBJECT]),
+ 'create_equal_pairs': (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT]),
}
def __init__(self, activity):
@@ -110,7 +110,7 @@ class CreateToolbar(gtk.Toolbar):
def _game_changed_cb(self, combobox, game_name):
self.game_name_entry.set_text(game_name)
- self.emit('create_load_game',game_name)
+ self.emit('create_load_game', game_name)
def _load_game(self, button):
chooser = ObjectChooser(_('Choose memorize game'), None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
@@ -127,7 +127,7 @@ class CreateToolbar(gtk.Toolbar):
del chooser
if jobject and jobject.file_path:
- self.emit('create_load_game',jobject.file_path)
+ self.emit('create_load_game', jobject.file_path)
self._save_button.set_sensitive(False)
def _new_game_bt(self, button):
@@ -139,14 +139,14 @@ class CreateToolbar(gtk.Toolbar):
self._save_button.set_sensitive(False)
def _save_game_bt(self, button):
- self.emit('create_save_game',self.game_name_entry.get_text(), self._equal_pairs.get_active(), self._grouped.get_active())
+ self.emit('create_save_game', self.game_name_entry.get_text(), self._equal_pairs.get_active(), self._grouped.get_active())
self._save_button.set_sensitive(False)
- def _emit_equal_pairs(self,checkbutton):
- self.emit('create_equal_pairs',checkbutton.get_active())
+ def _emit_equal_pairs(self, checkbutton):
+ self.emit('create_equal_pairs', checkbutton.get_active())
self._save_button.set_sensitive(True)
- def _grouped_cb(self,widget):
+ def _grouped_cb(self, widget):
self._save_button.set_sensitive(True)
if self._grouped.get_active():
self._grouped.set_icon_widget(self._grouped_image2)
diff --git a/game.py b/game.py
index 1f0357d..0a867fb 100755
--- a/game.py
+++ b/game.py
@@ -17,43 +17,44 @@
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
-import os
import logging
import gobject
+from os.path import join, dirname
from sugar import profile
from dbus.service import method, signal
from dbus.gobject_service import ExportedGObject
-
-import gobject
+from gobject import SIGNAL_RUN_FIRST, TYPE_PYOBJECT, GObject, timeout_add
from model import Model
_logger = logging.getLogger('memorize-activity')
-SERVICE = "org.laptop.Memorize"
+SERVICE = 'org.laptop.Memorize'
IFACE = SERVICE
-PATH = "/org/laptop/Memorize"
+PATH = '/org/laptop/Memorize'
-class MemorizeGame(gobject.GObject):
+class MemorizeGame(GObject):
__gsignals__ = {
- 'reset_scoreboard': (gobject.SIGNAL_RUN_FIRST, None, []),
- 'reset_table': (gobject.SIGNAL_RUN_FIRST, None, []),
- 'load_game': (gobject.SIGNAL_RUN_FIRST, None, [gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT]),
- 'change_game': (gobject.SIGNAL_RUN_FIRST, None, [gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT]),
- 'change_game_signal': (gobject.SIGNAL_RUN_FIRST, None, [gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT]),
- 'set-border': (gobject.SIGNAL_RUN_FIRST, None, [int, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT]),
- 'flip-card': (gobject.SIGNAL_RUN_FIRST, None, [int]),
- 'flip-card-signal': (gobject.SIGNAL_RUN_FIRST, None, [int]),
- 'flop-card': (gobject.SIGNAL_RUN_FIRST, None, [int]),
- 'highlight-card': (gobject.SIGNAL_RUN_FIRST, None, [int, gobject.TYPE_PYOBJECT]),
- 'add_buddy': (gobject.SIGNAL_RUN_FIRST, None, [gobject.TYPE_PYOBJECT, int]),
- 'rem_buddy': (gobject.SIGNAL_RUN_FIRST, None, [gobject.TYPE_PYOBJECT]),
- 'increase-score': (gobject.SIGNAL_RUN_FIRST, None, [gobject.TYPE_PYOBJECT]),
- 'wait_mode_buddy': (gobject.SIGNAL_RUN_FIRST, None, [gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT]),
- 'change-turn': (gobject.SIGNAL_RUN_FIRST, None, [gobject.TYPE_PYOBJECT]),
+ 'reset_scoreboard': (SIGNAL_RUN_FIRST, None, []),
+ 'reset_table': (SIGNAL_RUN_FIRST, None, []),
+ 'load_mode': (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT]),
+ 'load_game': (SIGNAL_RUN_FIRST, None, 2 * [TYPE_PYOBJECT]),
+ 'change_game': (SIGNAL_RUN_FIRST, None, 2 * [TYPE_PYOBJECT]),
+ 'change_game_signal': (SIGNAL_RUN_FIRST, None, 5 * [TYPE_PYOBJECT]),
+ 'set-border': (SIGNAL_RUN_FIRST, None, 3 * [TYPE_PYOBJECT]),
+ 'flip-card': (SIGNAL_RUN_FIRST, None, [int]),
+ 'flip-card-signal': (SIGNAL_RUN_FIRST, None, [int]),
+ 'flop-card': (SIGNAL_RUN_FIRST, None, [int]),
+ 'highlight-card': (SIGNAL_RUN_FIRST, None, 2 * [TYPE_PYOBJECT]),
+ 'add_buddy': (SIGNAL_RUN_FIRST, None, 2 * [TYPE_PYOBJECT]),
+ 'rem_buddy': (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT]),
+ 'increase-score': (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT]),
+ 'wait_mode_buddy': (SIGNAL_RUN_FIRST, None, 2 * [TYPE_PYOBJECT]),
+ 'msg_buddy': (SIGNAL_RUN_FIRST, None, 2 * [TYPE_PYOBJECT]),
+ 'change-turn': (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT]),
}
def __init__(self):
@@ -65,10 +66,10 @@ class MemorizeGame(gobject.GObject):
self.current_player = None
self.last_flipped = -1
self.last_highlight = 1
- self.game_dir = os.path.join(os.path.dirname(__file__), 'games')
+ self.game_dir = join(dirname(__file__), 'games')
self.messenger = None
self.sentitive = True
- self.model = Model(os.path.dirname(__file__))
+ self.model = Model(dirname(__file__))
self.flip_block = False
# create csound instance to play sound files
@@ -87,17 +88,40 @@ class MemorizeGame(gobject.GObject):
if self.cs.start() != 0:
_logger.error(' Error starting csound performance.')
self.sound = 0
-
- def load_game(self, game_name, size):
-
+ def load_game(self, game_name, size):
+ self.set_load_mode('Loading game')
if self.model.read(game_name) == 0:
self.model.def_grid(size)
self.model.data['running'] = 'False'
- logging.debug(' Read setup file %s: %s '%(game_name, self.model.grid))
+ logging.debug(' Read setup file %s: %s '%(game_name, self.model.grid))
self.emit('load_game', self.model.data, self.model.grid)
else:
logging.error(' Reading setup file %s'%game_name)
+
+ def load_remote(self, grid, data, mode, signal = False):
+ self.set_load_mode('Loading game...')
+ self.model.grid = grid
+ self.model.data = data
+ self.emit('reset_scoreboard')
+ if not signal:
+ self.emit('change_game_signal', mode, self.get_grid(), self.get_data(), self.waiting_players, self.model.data['game_file'])
+ self.emit('change_game', self.get_data(), self.get_grid())
+ for buddy in self.players:
+ self.players_score[buddy] = 0
+ self.current_player = None
+ self.last_flipped = -1
+ self.last_highlight = 1
+ self.change_turn()
+ self.model.data['running'] = 'False'
+ for card in self.model.grid:
+ if card['state'] == '1':
+ self.emit('flip-card', self.model.grid.index(card))
+ self.last_flipped = self.model.grid.index(card)
+ elif card['state'] != '0':
+ stroke_color, fill_color = card['state'].split(',')
+ self.emit('flip-card', self.model.grid.index(card))
+ self.emit('set-border', self.model.grid.index(card), stroke_color, fill_color)
def add_buddy(self, buddy, score = 0):
_logger.debug('Buddy %r was added to game', buddy.props.nick)
@@ -112,16 +136,19 @@ class MemorizeGame(gobject.GObject):
def rem_buddy(self, buddy):
_logger.debug('Buddy %r was removed from game', buddy.props.nick)
- index = self.players.index(buddy)
+ if self.current_player == buddy and len(self.players) >= 2:
+ self.change_turn()
+ index = self.players.index(buddy)
del self.players[index]
del (self.players_score[buddy])
- if self.current_player == buddy and len(self.players) >= 2: ### fix from <> 0
- self.change_turn()
self.emit('rem_buddy', buddy)
+
+ def buddy_message(self, buddy, text):
+ self.emit('msg_buddy', buddy, text)
def change_turn(self):
- if len(self.players) == 0:
- return
+ if len(self.players) <= 1:
+ self.current_player = self.players[0]
if self.current_player == None:
self.current_player = self.players[0]
elif self.current_player == self.players[-1]:
@@ -152,12 +179,13 @@ class MemorizeGame(gobject.GObject):
if self.sound == 1:
snd = self.model.grid[id].get('snd', None)
if snd != None:
+ sound_file = join(self.model.data.get('pathsnd'),snd)
if len(snd.split('.')) > 1:
if snd.split('.')[1] in ['wav', 'aif', 'aiff']:
- self.cs.perform('i 102 0.0 3.0 "%s" 1 0.9 0'%(os.path.join(os.path.dirname(__file__), snd)))
- else:
- self.cs.perform('i 100 0.0 3.0 "%s" 1 0.9 0'%(os.path.join(os.path.dirname(__file__), snd)))
- _logger.debug('Audio: play sound=%s'%snd)
+ self.cs.perform('i 102 0.0 3.0 "%s" 1 0.9 0'%(sound_file))
+ else:
+ self.cs.perform('i 100 0.0 3.0 "%s" 1 0.9 0'%(sound_file))
+ _logger.debug('Audio: play sound=%s'%sound_file)
# First card case
if self.last_flipped == -1:
@@ -190,7 +218,7 @@ class MemorizeGame(gobject.GObject):
if not signal:
self.emit('flip-card-signal', id)
self.model.grid[id]['state'] = '1'
- gobject.timeout_add(2000, self.flop_card, id, widget)
+ timeout_add(2000, self.flop_card, id, widget)
def flop_card(self, id, widget):
self.emit('flop-card', id)
@@ -235,12 +263,21 @@ class MemorizeGame(gobject.GObject):
def get_data(self):
return self.model.data
- def change_game(self, game_name, size):
- if self.model.read(game_name) == 0:
- self.model.def_grid(size)
- self.load_remote(self.model.grid, self.model.data, False)
- else:
- logging.error(' Reading setup file %s'%game_name)
+ def change_game(self, widget, game_name, size, mode, title = None, color= None):
+ if mode in ['file','demo']:
+ if self.model.read(game_name) != 0:
+ logging.error(' Reading setup file %s'%game_name)
+ return
+ #elif mode in ['reset','size']:
+ if size == None:
+ size = int(self.model.data['size'])
+ self.model.def_grid(size)
+
+ if title != None:
+ self.model.data['title'] = title
+ if color != None:
+ self.model.data['color'] = color
+ self.load_remote(self.model.grid, self.model.data, mode, False)
def reset_game(self, size = None):
if size == None:
@@ -248,29 +285,9 @@ class MemorizeGame(gobject.GObject):
self.model.def_grid(size)
self.load_remote(self.model.grid, self.model.data, False)
- def load_remote(self, grid, data, signal = False):
- self.model.grid = grid
- self.model.data = data
- self.emit('reset_scoreboard')
- self.emit('change_game', self.get_data(), self.get_grid())
- if not signal:
- self.emit('change_game_signal', self.get_grid(), self.get_data(), self.waiting_players)
- for buddy in self.players:
- self.players_score[buddy] = 0
- self.current_player = None
- self.last_flipped = -1
- self.last_highlight = 1
- self.change_turn()
- self.model.data['running'] = 'False'
- for card in self.model.grid:
- if card['state'] == '1':
- self.emit('flip-card', self.model.grid.index(card))
- self.last_flipped = self.model.grid.index(card)
- elif card['state'] != '0':
- stroke_color, fill_color = card['state'].split(',')
- self.emit('flip-card', self.model.grid.index(card))
- self.emit('set-border',self.model.grid.index(card), stroke_color, fill_color)
-
+ def set_load_mode(self, msg):
+ self.emit('load_mode', msg)
+
def set_messenger(self, messenger):
self.messenger = messenger
@@ -288,8 +305,8 @@ class MemorizeGame(gobject.GObject):
def get_players_data(self):
data = []
- for player,score in self.players_score.items():
- data.append([player.props.key,player.props.nick,player.props.color,score])
+ for player, score in self.players_score.items():
+ data.append([player.props.key, player.props.nick, player.props.color, score])
return data
def set_wait_list(self, list):
@@ -304,17 +321,17 @@ class MemorizeGame(gobject.GObject):
def set_myself(self, buddy):
self.myself = buddy
- def add_to_waiting_list(self,buddy):
+ def add_to_waiting_list(self, buddy):
self.players.remove(buddy)
self.waiting_players.append(buddy)
- self.emit('wait_mode_buddy',buddy,True)
+ self.emit('wait_mode_buddy', buddy, True)
- def rem_to_waiting_list(self,buddy):
+ def rem_to_waiting_list(self, buddy):
self.waiting_players.remove(buddy)
self.players.append(buddy)
- self.emit('wait_mode_buddy',buddy,False)
+ self.emit('wait_mode_buddy', buddy, False)
- def load_waiting_list(self,list):
+ def load_waiting_list(self, list):
for buddy in list:
self.add_to_waiting_list(buddy)
diff --git a/memorizetoolbar.py b/memorizetoolbar.py
index 68b7d1c..015ac47 100755
--- a/memorizetoolbar.py
+++ b/memorizetoolbar.py
@@ -18,13 +18,14 @@
#
import gtk
-import os
+from os.path import join, dirname
from gettext import gettext as _
from sugar.graphics.toolbutton import ToolButton
from sugar.graphics.toolcombobox import ToolComboBox
from sugar.graphics.objectchooser import ObjectChooser
import logging
+from gobject import SIGNAL_RUN_FIRST, TYPE_PYOBJECT
_logger = logging.getLogger('memorize-activity')
@@ -34,14 +35,18 @@ class MemorizeToolbar(gtk.Toolbar):
standard_game_names = ['Load demo games', 'addition', 'capitals', 'drumgit', 'letters', 'numbers', 'phonemes']
translated_game_names = [_('Load demo games'), _('addition'), _('capitals'), _('drumgit'), _('letters'), _('numbers'), _('phonemes')]
+ __gsignals__ = {
+ 'game_changed': (SIGNAL_RUN_FIRST, None, 5 * [TYPE_PYOBJECT])
+ }
+
def __init__(self, activity):
gtk.Toolbar.__init__(self)
self.activity = activity
self._lock = True
-
+ self.jobject = None
# Reset Button
- restart_icon = os.path.join(os.path.dirname(__file__), "images/game-restart.svg")
+ restart_icon = join(dirname(__file__), 'images', 'game-restart.svg')
restart_image = gtk.Image()
restart_image.set_from_file(restart_icon)
self._restart_button = ToolButton()
@@ -52,7 +57,7 @@ class MemorizeToolbar(gtk.Toolbar):
self._restart_button.show()
# Load Button
- load_icon = os.path.join(os.path.dirname(__file__), "images/game-load.svg")
+ load_icon = join(dirname(__file__), 'images', 'game-load.svg')
load_image = gtk.Image()
load_image.set_from_file(load_icon)
self._load_button = ToolButton()
@@ -97,7 +102,7 @@ class MemorizeToolbar(gtk.Toolbar):
tool_item.show()
def _game_reset_cb(self, widget):
- self.activity.game.reset_game()
+ self.emit('game_changed', None, None, 'reset', None, None)
def _load_game(self, button):
chooser = ObjectChooser(_('Choose memorize game'), None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
@@ -113,23 +118,30 @@ class MemorizeToolbar(gtk.Toolbar):
chooser.destroy()
del chooser
- if jobject and jobject.file_path:
- self.activity.change_game(jobject.file_path, 4)
+ if jobject and jobject.file_path:
+ title = jobject.metadata['title']
+ color = jobject.metadata['icon-color']
+ self.emit('game_changed', jobject.file_path, 4, 'file', title, color)
+
+ if self.jobject != None:
+ self.jobject.destroy()
+ self.jobject = jobject
def _game_size_cb(self, widget):
game_size = int(self._sizes[self._size_combo.combo.get_active()][0])
- self.activity.game.reset_game(game_size)
+ self.emit('game_changed', None, game_size, 'size', None, None)
def _game_changed_cb(self, combobox):
if combobox.get_active() == 0: return
if not self._lock:
game_name = self.standard_game_names[self._game_combo.combo.get_active()]
- game_file = os.path.join(os.path.dirname(__file__),'demos',game_name+'.zip')
+ game_file = join(dirname(__file__), 'demos', game_name+'.zip')
game_size = int(self._sizes[self._size_combo.combo.get_active()][0])
if game_name in self.translated_game_names:
index = self.translated_game_names.index(game_name)
game_name = self.standard_game_names[index]
- self.activity.change_game(game_file, game_size)
+ self.emit('game_changed', game_file, game_size, 'demo', None, None)
+ #self.activity.change_game(game_file, game_size)
self._game_combo.combo.set_active(0)
def update_toolbar(self, widget, data, grid):
diff --git a/messenger.py b/messenger.py
index f23dcf9..e66e115 100644
--- a/messenger.py
+++ b/messenger.py
@@ -18,14 +18,17 @@
#
import logging
-import dbus
+_logger = logging.getLogger('memorize-activity')
+
+import tempfile
+from os.path import join, getsize, isfile, dirname, basename
+from dbus.service import method, signal
from dbus.gobject_service import ExportedGObject
+from sugar.datastore import datastore
-SERVICE = "org.laptop.Memorize"
+SERVICE = 'org.laptop.Memorize'
IFACE = SERVICE
-PATH = "/org/laptop/Memorize"
-
-_logger = logging.getLogger('memorize-activity')
+PATH = '/org/laptop/Memorize'
class Messenger(ExportedGObject):
@@ -38,81 +41,171 @@ class Messenger(ExportedGObject):
self.ordered_bus_names = []
self.entered = False
self._tube.watch_participants(self.participant_change_cb)
+ self.files = {}
def participant_change_cb(self, added, removed):
- _logger.debug('Participants change add=%s rem=%s' %(added, removed))
-
if not self.entered:
- self._tube.add_signal_receiver(self._flip_receiver, '_flip_signal', IFACE, path=PATH, sender_keyword='sender')
- self._tube.add_signal_receiver(self._change_game_receiver, '_change_game_signal', IFACE, path=PATH, sender_keyword='sender')
+ self._flip_handler()
+ self._change_game_handler()
+ self._file_part_handler()
if self.is_initiator:
- _logger.debug('Initialising a new game, I am %s .', self._tube.get_unique_name())
self.player_id = self._tube.get_unique_name()
self.ordered_bus_names = [self.player_id]
- self._tube.add_signal_receiver(self._hello_receiver, '_hello_signal', IFACE, path=PATH, sender_keyword='sender')
+ self._hello_handler()
else:
self._hello_signal()
self.entered = True
-
- @dbus.service.signal(IFACE, signature='')
+
+ # hello methods
+
+ @signal(IFACE, signature='')
def _hello_signal(self):
- ''' Notify current players that you joined '''
- _logger.debug('Sending hello to all')
+ pass
+
+ def _hello_handler(self):
+ self._tube.add_signal_receiver(self._hello_receiver,
+ '_hello_signal',
+ IFACE,
+ path=PATH,
+ sender_keyword='sender')
def _hello_receiver(self, sender=None):
- ''' Someone joined the game, so sync the new player '''
- _logger.debug('The new player %s has joined', sender)
self.ordered_bus_names.append(sender)
- _logger.debug('The grid to send: %s', self.game.get_grid())
- _logger.debug('The data to send: %s', self.game.get_data())
- self._tube.get_object(sender, PATH).load_game(self.ordered_bus_names, self.game.get_grid(), self.game.get_data(), self.game.players.index(self.game.current_player), self.game.waiting_players, dbus_interface=IFACE)
- _logger.debug('Sent the game state')
+ data = self.game.model.data
+ path = data['game_file']
+ title = data.get('title', 'Received game')
+ color = data.get('color', '#ff00ff,#00ff00')
+ self.file_sender(path, title, color)
+
+ remote_object = self._tube.get_object(sender, PATH)
+ remote_object.load_game(self.ordered_bus_names,
+ self.game.get_grid(),
+ self.game.get_data(),
+ self.game.players.index(self.game.current_player),
+ #self.game.waiting_players,
+ path)
- @dbus.service.method(dbus_interface=IFACE, in_signature='asaa{ss}a{ss}nav', out_signature='')
- def load_game(self, bus_names, grid, data, current_player, list):
- ''' Sync the game with with players '''
- _logger.debug('Data received to sync game data')
- _logger.debug('grid %s '%grid)
+ @method(dbus_interface=IFACE, in_signature='asaa{ss}a{ss}ns', out_signature='', byte_arrays=True)
+ def load_game(self, bus_names, grid, data, current_player, path):
self.ordered_bus_names = bus_names
self.player_id = bus_names.index(self._tube.get_unique_name())
- self.game.load_remote(grid, data, True)
- self.game.load_waiting_list(list)
- _logger.debug('Current player id=%d' %current_player)
+ #self.game.load_waiting_list(list)
self.game.current_player = self.game.players[current_player]
+ self._change_game_receiver('file', grid, data, path)
+
+ # Change game method
+
+ def change_game(self, sender, mode, grid, data, waiting_list, zip):
+ path = self.game.model.data['game_file']
+ title = data.get('title', 'Received game')
+ color = data.get('color', '')
+ if mode == 'file':
+ self.file_sender(path, title, color)
+ self._change_game_signal(mode, grid, data, path)
+
+ def _change_game_handler(self):
+ self._tube.add_signal_receiver(self._change_game_receiver,
+ '_change_game_signal',
+ IFACE, path=PATH,
+ sender_keyword='sender',
+ byte_arrays=True)
+
+ @signal(IFACE, signature='saa{ss}a{ss}s')
+ def _change_game_signal(self, mode, grid, data, path):
+ pass
+
+ def _change_game_receiver(self, mode, grid, data, path, sender=None):
+ # ignore my own signal
+ if sender == self._tube.get_unique_name():
+ return
+ if mode == 'demo':
+ game_name = self.game.model.data['key']
+ game_file = join(dirname(__file__), 'demos', game_name+'.zip')
+ self.game.model.read(game_file)
+ if mode == 'file':
+ self.game.model.read(self.files[path])
+ data['path'] = self.game.model.data['path']
+ data['pathimg'] = self.game.model.data['pathimg']
+ data['pathsnd'] = self.game.model.data['pathsnd']
+ if mode == 'demo':
+ self.game.load_remote(grid, data, mode, True)
+ else:
+ self.game.load_remote(grid, data, mode, True)
+
+ # File transfer methods
+
+ def file_sender(self, filename, title, color):
+ size = getsize(filename)
+ f = open(filename, 'r+b')
+ part_size = 4096
+ num_parts = (size / part_size) +1
+ for part in range(num_parts):
+ bytes = f.read(part_size)
+ self._file_part_signal(filename, part+1, num_parts, bytes, title, color)
+ f.close()
+
+ @signal(dbus_interface=IFACE, signature='suuayss')
+ def _file_part_signal(self, filename, part, numparts, bytes, title, color):
+ pass
+
+ def _file_part_handler(self):
+ self._tube.add_signal_receiver(self._file_part_receiver,
+ '_file_part_signal',
+ IFACE,
+ path=PATH,
+ sender_keyword='sender',
+ byte_arrays=True)
+
+ def _file_part_receiver(self, filename, part, numparts, bytes, title=None, color=None, sender=None):
+ # ignore my own signal
+ if sender == self._tube.get_unique_name():
+ return
- def flip(self, widget, id):
- ''' Notify other players that you flipped a card '''
- _logger.debug('Sending flip message: '+str(id))
+ # first chunk
+ if part == 1:
+ temp_dir = tempfile.mkdtemp()
+ self.temp_file = join(temp_dir, 'game.zip')
+ self.files[filename] = self.temp_file
+ self.f = open(self.temp_file, 'a+b')
+
+ self.f.write(bytes)
+
+ percentage = int(float(part) / float(numparts) * 100.0)
+ self.game.set_load_mode('Receiving game: '+str(percentage)+'% done.')
+
+ # last chunk
+ if part == numparts:
+ self.f.close()
+ #file = self.files[filename]
+ # Saves the zip in datastore
+ gameObject = datastore.create()
+ gameObject.metadata['title'] = title
+ gameObject.metadata['mime_type'] = 'application/memorizegame'
+ gameObject.metadata['icon-color'] = color
+ gameObject.file_path = self.temp_file
+ datastore.write(gameObject)
+ #gameObject.destroy()
+
+
+ # flip card methods
+
+ def flip_sender(self, widget, id):
self._flip_signal(id)
- @dbus.service.signal(IFACE, signature='n')
+ def _flip_handler(self):
+ self._tube.add_signal_receiver(self._flip_receiver,
+ '_flip_signal',
+ IFACE,
+ path=PATH,
+ sender_keyword='sender')
+
+ @signal(IFACE, signature='n')
def _flip_signal(self, card_number):
- _logger.debug('Notifing other players that you flipped: %s', str(card_number))
- ''' Notify current players that you flipped a card '''
+ pass
def _flip_receiver(self, card_number, sender=None):
- ''' Someone flipped a card '''
- handle = self._tube.bus_name_to_handle[sender]
-
- if self._tube.self_handle <> handle:
- _logger.debug('Other player flipped: %s ', str(card_number))
- self.game.card_flipped(None, card_number, True)
-
- def change_game(self, sender, grid, data, waiting_list):
- ''' Notify other players that you changed the game '''
- _logger.debug('Sending changed game message')
- self._change_game_signal(grid, data)
-
- @dbus.service.signal(IFACE, signature='aa{ss}a{ss}')
- def _change_game_signal(self, grid, data):
- _logger.debug('Notifing other players that you changed the game')
- ''' Notify current players that you changed the game '''
-
- def _change_game_receiver(self, grid, data, sender=None):
- ''' Game changed by other player '''
- handle = self._tube.bus_name_to_handle[sender]
-
- if self._tube.self_handle <> handle:
- _logger.debug('Game changed by other player')
- self.game.load_remote(grid, data, True)
+ # ignore my own signal
+ if sender == self._tube.get_unique_name():
+ return
+ self.game.card_flipped(None, card_number, True)
\ No newline at end of file
diff --git a/model.py b/model.py
index 857d7ee..0751d57 100644
--- a/model.py
+++ b/model.py
@@ -1,417 +1,340 @@
#! /usr/bin/env python
#
-# Copyright (C) 2006, 2007, One Laptop Per Child
+# Copyright (C) 2006, 2007, One Laptop Per Child
#
-# 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 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.
+# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#
import libxml2
import os
+from os.path import join, basename
import logging
import random
import gobject
import zipfile
import tempfile
+from sugar import profile
+from sugar.datastore import datastore
_logger = logging.getLogger('model')
-class Pair(gobject.GObject):
- __gproperties__ = {
- 'aimg' : (str, None, None, None, gobject.PARAM_READWRITE),
- 'asnd' : (str, None, None, None, gobject.PARAM_READWRITE),
- 'achar' : (str, None, None, None, gobject.PARAM_READWRITE),
- 'bimg' : (str, None, None, None, gobject.PARAM_READWRITE),
- 'bsnd' : (str, None, None, None, gobject.PARAM_READWRITE),
- 'bchar' : (str, None, None, None, gobject.PARAM_READWRITE),
- 'color': (gobject.TYPE_INT, 'Base', 'Base', 0, 10, 0, gobject.PARAM_READWRITE)
- }
-
- def __init__(self):
- gobject.GObject.__init__(self)
- self._properties = {'aimg':None, 'asnd':None, 'achar':None, 'bimg':None,
- 'bsnd':None, 'bchar':None, 'color':100}
-
- def do_get_property(self, pspec):
- """Retrieve a particular property from our property dictionary
- """
- if pspec.name == "aimg":
- return self._properties["aimg"]
- elif pspec.name == "asnd":
- return self._properties["asnd"]
- elif pspec.name == "achar":
- return self._properties["achar"]
- elif pspec.name == "bimg":
- return self._properties["bimg"]
- elif pspec.name == "bsnd":
- return self._properties["bsnd"]
- elif pspec.name == "bchar":
- return self._properties["bchar"]
- elif pspec.name == "color":
- return self._properties["color"]
+class Pair(gobject.GObject):
+ __gproperties__ = {
+ 'aimg' : (str, None, None, None, gobject.PARAM_READWRITE),
+ 'asnd' : (str, None, None, None, gobject.PARAM_READWRITE),
+ 'achar' : (str, None, None, None, gobject.PARAM_READWRITE),
+ 'bimg' : (str, None, None, None, gobject.PARAM_READWRITE),
+ 'bsnd' : (str, None, None, None, gobject.PARAM_READWRITE),
+ 'bchar' : (str, None, None, None, gobject.PARAM_READWRITE),
+ 'color': (gobject.TYPE_INT, 'Base', 'Base', 0, 10, 0, gobject.PARAM_READWRITE)
+ }
+
+ def __init__(self):
+ gobject.GObject.__init__(self)
+ self._properties = {'aimg':None, 'asnd':None, 'achar':None, 'bimg':None,
+ 'bsnd':None, 'bchar':None, 'color':100}
+
+ def do_get_property(self, pspec):
+ """Retrieve a particular property from our property dictionary
+ """
+ if pspec.name == "aimg":
+ return self._properties["aimg"]
+ elif pspec.name == "asnd":
+ return self._properties["asnd"]
+ elif pspec.name == "achar":
+ return self._properties["achar"]
+ elif pspec.name == "bimg":
+ return self._properties["bimg"]
+ elif pspec.name == "bsnd":
+ return self._properties["bsnd"]
+ elif pspec.name == "bchar":
+ return self._properties["bchar"]
+ elif pspec.name == "color":
+ return self._properties["color"]
- def set_property(self, name, value):
- if name == 'aimg':
- self._properties['aimg'] = value
- elif name == "asnd":
- self._properties["asnd"] = value
- elif name == "achar":
- self._properties["achar"] = value
- elif name == "bimg":
- self._properties["bimg"] = value
- elif name == "bsnd":
- self._properties["bsnd"] = value
- elif name == "bchar":
- self._properties["bchar"] = value
- elif name == "color":
- self._properties["color"] = value
+ def set_property(self, name, value):
+ if name == 'aimg':
+ self._properties['aimg'] = value
+ elif name == "asnd":
+ self._properties["asnd"] = value
+ elif name == "achar":
+ self._properties["achar"] = value
+ elif name == "bimg":
+ self._properties["bimg"] = value
+ elif name == "bsnd":
+ self._properties["bsnd"] = value
+ elif name == "bchar":
+ self._properties["bchar"] = value
+ elif name == "color":
+ self._properties["color"] = value
class Model(object):
- ''' The model of the activity. Contains methods to read and write
- the configuration for a game from xml. Stores the pairs and grid
- information.
- '''
-
- def __init__(self, game_path, dtd_path = None):
- self.data = {}
- if dtd_path == None:
- self.dtd_path = os.path.dirname(__file__)
- else:
- self.dtd_path = dtd_path
-
- if os.path.isdir(game_path):
- self.game_path = game_path
- else:
- _logger.error('Game_path not found ' +str(e))
- return
-
- self.data['face'] = ''
- self.data['align'] = '1'
-
- try:
- self.dtd = libxml2.parseDTD(None, os.path.join(self.dtd_path, 'memorize.dtd'))
- except libxml2.parserError, e:
- _logger.error('Init: no memorize.dtd found ' +str(e))
- self.dtd = None
- self.ctxt = libxml2.newValidCtxt()
+ ''' The model of the activity. Contains methods to read and write
+ the configuration for a game from xml. Stores the pairs and grid
+ information.
+ '''
+
+ def __init__(self, game_path, dtd_path = None):
+ self.data = {}
+ if dtd_path == None:
+ self.dtd_path = os.path.dirname(__file__)
+ else:
+ self.dtd_path = dtd_path
+
+ if os.path.isdir(game_path):
+ self.game_path = game_path
+ else:
+ _logger.error('Game_path not found ' +str(e))
+ return
+
+ self.data['face'] = ''
+ self.data['align'] = '1'
+
+ try:
+ self.dtd = libxml2.parseDTD(None, os.path.join(self.dtd_path, 'memorize.dtd'))
+ except libxml2.parserError, e:
+ _logger.error('Init: no memorize.dtd found ' +str(e))
+ self.dtd = None
+ self.ctxt = libxml2.newValidCtxt()
- self.pairs = {}
- self.grid = []
+ self.pairs = {}
+ self.grid = []
- # used by the leader of the game to keep track of the game state
- self.players = {}
- self.player_active = 0
- self.selected = 0
- self.turn = 0
- self.started = 0
- self.count = 0
+ # used by the leader of the game to keep track of the game state
+ self.players = {}
+ self.player_active = 0
+ self.selected = 0
+ self.turn = 0
+ self.started = 0
+ self.count = 0
- def read(self, game_file):
- if game_file in ["addition", "capitals", "drumgit", "letters", "numbers", "phonemes"]:
- game_file = os.path.join(os.path.dirname(__file__), 'games', game_file+'.zip')
- game_name = os.path.basename(game_file)[:-4]
-
- temp_folder = tempfile.mkdtemp()
- self.data['key'] = os.path.basename(game_file)
- self.data['game_file'] = game_file
- self.data['path'] = temp_folder
- self.data['pathimg'] = os.path.join(self.data['path'], 'images')
- self.data['pathsnd'] = os.path.join(self.data['path'], 'sounds')
-
- ''' extracts files in the zip file '''
- game_name = os.path.basename(game_file)[:-4]
- zipFile = zipfile.ZipFile(game_file, "r")
- for each in zipFile.namelist():
- if not each.endswith('/'):
- root, name = os.path.split(each)
- directory = os.path.normpath(os.path.join(self.data['path'], root))
- if not os.path.isdir(directory):
- os.makedirs(directory)
- file(os.path.join(directory, name), 'wb').write(zipFile.read(each))
+ def read(self, game_file):
+ if game_file in ["addition", "capitals", "drumgit", "letters", "numbers", "phonemes"]:
+ game_file = os.path.join(os.path.dirname(__file__), 'games', game_file+'.zip')
+ game_name = os.path.basename(game_file)[:-4]
+
+ temp_folder = tempfile.mkdtemp()
+ self.data['key'] = os.path.basename(game_file)
+ self.data['game_file'] = game_file
+ self.data['path'] = temp_folder
+ self.data['pathimg'] = os.path.join(self.data['path'], 'images')
+ self.data['pathsnd'] = os.path.join(self.data['path'], 'sounds')
+
+ ''' extracts files in the zip file '''
+ game_name = os.path.basename(game_file)[:-4]
+ zipFile = zipfile.ZipFile(game_file, "r")
+ for each in zipFile.namelist():
+ if not each.endswith('/'):
+ root, name = os.path.split(each)
+ directory = os.path.normpath(os.path.join(self.data['path'], root))
+ if not os.path.isdir(directory):
+ os.makedirs(directory)
+ file(os.path.join(directory, name), 'wb').write(zipFile.read(each))
- self.pairs = {}
-
- ''' reads the configuration from an xml file '''
- try:
- doc = libxml2.parseFile(os.path.join(os.path.dirname(__file__), os.path.join(self.data['path'], 'game.xml')))
- if doc.validateDtd(self.ctxt, self.dtd):
-
- # get the requested nodes
- xpa = doc.xpathNewContext()
- res = xpa.xpathEval("//*")
+ self.pairs = {}
+
+ ''' reads the configuration from an xml file '''
+ try:
+ doc = libxml2.parseFile(os.path.join(os.path.dirname(__file__), os.path.join(self.data['path'], 'game.xml')))
+ if doc.validateDtd(self.ctxt, self.dtd):
+
+ # get the requested nodes
+ xpa = doc.xpathNewContext()
+ res = xpa.xpathEval("//*")
- # write their content to the data structure
- self.idpair = 0
- for elem in res:
- attributes = elem.get_properties()
- pair = Pair()
- if(elem.name == 'pair'):
- for attribute in attributes:
- if(attribute.name == 'text'):
- pass
- else:
- pair.set_property(attribute.name, attribute.content)
- self.pairs[str(self.idpair)] = pair
- self.idpair+=1
- elif(elem.name == 'memorize'):
- for attribute in attributes:
- if(attribute.name == 'text'):
- pass
- elif(attribute.name == 'name'):
- self.data['name'] = attribute.content
- elif(attribute.name == 'scoresnd'):
- self.data['scoresnd'] = attribute.content
- elif(attribute.name == 'winsnd'):
- self.data['winsnd'] = attribute.content
- elif(attribute.name == 'divided'):
- self.data['divided'] = attribute.content
- elif(attribute.name == 'face'):
- self.data['face'] = attribute.content
- elif(attribute.name == 'face1'):
- self.data['face1'] = attribute.content
- elif(attribute.name == 'face2'):
- self.data['face2'] = attribute.content
- elif(attribute.name == 'align'):
- self.data['align'] = attribute.content
- elif(attribute.name == 'equal_pairs'):
- self.data['equal_pairs'] = attribute.content
- xpa.xpathFreeContext()
- else:
- _logger.error('Read: Error in validation of the file')
- doc.freeDoc()
- return 1
- doc.freeDoc()
- return 0
- except libxml2.parserError, e:
- _logger.error('Read: Error parsing file ' +str(e))
- return 2
-
- def write(self, equal_pairs, divided):
- ''' writes the configuration to an xml file '''
- doc = libxml2.newDoc("1.0")
- root = doc.newChild(None, "memorize", None)
-
- if(self.data.get('name', None) != None):
- root.setProp("name", self.data['name'])
-
- if divided:
- root.setProp('divided', '1')
- root.setProp('face1', '1')
- root.setProp('face2', '2')
- else:
- root.setProp('divided', '0')
-
- if equal_pairs:
- root.setProp('equal_pairs', str(equal_pairs))
-
- if(self.data.get('scoresnd', None) != None):
- root.setProp("scoresnd", self.data['scoresnd'])
- if(self.data.get('winsnd', None) != None):
- root.setProp("winsnd", self.data['winsnd'])
- if(self.data.get('divided', None) != None):
- root.setProp("divided", self.data['divided'])
- if(self.data.get('face', None) != None):
- root.setProp("face", self.data['face'])
- if(self.data.get('face1', None) != None):
- root.setProp("face1", self.data['face1'])
- if(self.data.get('face2', None) != None):
- root.setProp("face2", self.data['face2'])
- if(self.data.get('align', None) != None):
- root.setProp("align", self.data['align'])
+ # write their content to the data structure
+ self.idpair = 0
+ for elem in res:
+ attributes = elem.get_properties()
+ pair = Pair()
+ if(elem.name == 'pair'):
+ for attribute in attributes:
+ if(attribute.name == 'text'):
+ pass
+ else:
+ pair.set_property(attribute.name, attribute.content)
+ self.pairs[str(self.idpair)] = pair
+ self.idpair+=1
+ elif(elem.name == 'memorize'):
+ for attribute in attributes:
+ if(attribute.name == 'text'):
+ pass
+ elif(attribute.name == 'name'):
+ self.data['name'] = attribute.content
+ elif(attribute.name == 'scoresnd'):
+ self.data['scoresnd'] = attribute.content
+ elif(attribute.name == 'winsnd'):
+ self.data['winsnd'] = attribute.content
+ elif(attribute.name == 'divided'):
+ self.data['divided'] = attribute.content
+ elif(attribute.name == 'face'):
+ self.data['face'] = attribute.content
+ elif(attribute.name == 'face1'):
+ self.data['face1'] = attribute.content
+ elif(attribute.name == 'face2'):
+ self.data['face2'] = attribute.content
+ elif(attribute.name == 'align'):
+ self.data['align'] = attribute.content
+ elif(attribute.name == 'equal_pairs'):
+ self.data['equal_pairs'] = attribute.content
+ xpa.xpathFreeContext()
+ else:
+ _logger.error('Read: Error in validation of the file')
+ doc.freeDoc()
+ return 1
+ doc.freeDoc()
+ return 0
+ except libxml2.parserError, e:
+ _logger.error('Read: Error parsing file ' +str(e))
+ return 2
+
+ def write(self, equal_pairs, divided):
+ ''' writes the configuration to an xml file '''
+ doc = libxml2.newDoc("1.0")
+ root = doc.newChild(None, "memorize", None)
+
+ if(self.data.get('name', None) != None):
+ root.setProp("name", self.data['name'])
+
+ if divided:
+ root.setProp('divided', '1')
+ root.setProp('face1', '1')
+ root.setProp('face2', '2')
+ else:
+ root.setProp('divided', '0')
+
+ if equal_pairs:
+ root.setProp('equal_pairs', str(equal_pairs))
+
+ if(self.data.get('scoresnd', None) != None):
+ root.setProp("scoresnd", self.data['scoresnd'])
+ if(self.data.get('winsnd', None) != None):
+ root.setProp("winsnd", self.data['winsnd'])
+ if(self.data.get('divided', None) != None):
+ root.setProp("divided", self.data['divided'])
+ if(self.data.get('face', None) != None):
+ root.setProp("face", self.data['face'])
+ if(self.data.get('face1', None) != None):
+ root.setProp("face1", self.data['face1'])
+ if(self.data.get('face2', None) != None):
+ root.setProp("face2", self.data['face2'])
+ if(self.data.get('align', None) != None):
+ root.setProp("align", self.data['align'])
- for key in self.pairs:
- elem = root.newChild(None, "pair", None)
- if self.pairs[key].props.aimg != None:
- elem.setProp("aimg", self.pairs[key].props.aimg)
- if self.pairs[key].props.asnd != None:
- elem.setProp("asnd", self.pairs[key].props.asnd)
- if self.pairs[key].props.achar != None:
- elem.setProp("achar", self.pairs[key].props.achar)
- if self.pairs[key].props.bimg != None:
- elem.setProp("bimg", self.pairs[key].props.bimg)
- if self.pairs[key].props.bsnd != None:
- elem.setProp("bsnd", self.pairs[key].props.bsnd)
- if self.pairs[key].props.bchar != None:
- elem.setProp("bchar", self.pairs[key].props.bchar)
- # elem.setProp("color", str(self.pairs[key].props.color))
-
- if doc.validateDtd(self.ctxt, self.dtd):
- doc.saveFormatFile(os.path.join(self.game_path, 'game.xml'), 1)
- else:
- _logger.error('Write: Error in validation of the file')
- doc.freeDoc()
- return 2
- doc.freeDoc()
- return 0
-
+ for key in self.pairs:
+ elem = root.newChild(None, "pair", None)
+ if self.pairs[key].props.aimg != None:
+ elem.setProp("aimg", self.pairs[key].props.aimg)
+ if self.pairs[key].props.asnd != None:
+ elem.setProp("asnd", self.pairs[key].props.asnd)
+ if self.pairs[key].props.achar != None:
+ elem.setProp("achar", self.pairs[key].props.achar)
+ if self.pairs[key].props.bimg != None:
+ elem.setProp("bimg", self.pairs[key].props.bimg)
+ if self.pairs[key].props.bsnd != None:
+ elem.setProp("bsnd", self.pairs[key].props.bsnd)
+ if self.pairs[key].props.bchar != None:
+ elem.setProp("bchar", self.pairs[key].props.bchar)
+ # elem.setProp("color", str(self.pairs[key].props.color))
+
+ if doc.validateDtd(self.ctxt, self.dtd):
+ doc.saveFormatFile(os.path.join(self.game_path, 'game.xml'), 1)
+ else:
+ _logger.error('Write: Error in validation of the file')
+ doc.freeDoc()
+ return 2
+ doc.freeDoc()
+ return 0
+
- def def_grid(self, size):
- ''' create the grid for the play from the pairs information
- and shuffles the grid so they always appear in a different
- place
- '''
- psize=(size*size/2)
- _logger.debug('Size requested: %d' %psize)
- self.grid = []
- temp1 = []
- temp2 = []
- i=0
+ def def_grid(self, size):
+ ''' create the grid for the play from the pairs information
+ and shuffles the grid so they always appear in a different
+ place
+ '''
+ psize=(size*size/2)
+ _logger.debug('Size requested: %d' %psize)
+ self.grid = []
+ temp1 = []
+ temp2 = []
+ i=0
- # shuffle the pairs first to avoid only taking the first ones when there are more
- # pairs in the config file then the grid is using
- keys = self.pairs.keys()
- random.shuffle(keys)
+ # shuffle the pairs first to avoid only taking the first ones when there are more
+ # pairs in the config file then the grid is using
+ keys = self.pairs.keys()
+ random.shuffle(keys)
- for key in keys:
- if i < psize:
- elem = {}
- elem['pairkey'] = key
- elem['state'] = '0'
- elem['ab'] = 'a'
- if self.pairs[key].props.aimg != None:
- elem['img'] = os.path.join(self.data['pathimg'], self.pairs[key].props.aimg)
- if self.pairs[key].props.asnd != None:
- elem['snd'] = os.path.join(self.data['pathsnd'], self.pairs[key].props.asnd)
- if self.pairs[key].props.achar != None:
- elem['char'] = self.pairs[key].props.achar
- temp1.append(elem)
-
- elem = {}
- elem['pairkey'] = key
- elem['state'] = '0'
- elem['ab'] = 'b'
- if self.pairs[key].props.bimg != None:
- elem['img'] = os.path.join(self.data['pathimg'], self.pairs[key].props.bimg)
- if self.pairs[key].props.bsnd != None:
- elem['snd'] = os.path.join(self.data['pathsnd'], self.pairs[key].props.bsnd)
- if self.pairs[key].props.bchar != None:
- elem['char'] = self.pairs[key].props.bchar
- temp2.append(elem)
- i+=1
- else:
- break
-
- numpairs = len(self.pairs)
- if numpairs < psize:
- _logger.debug('Defgrid: We did not have enough pairs. requested=%s had=%s' %(psize, numpairs))
- self.data['size'] = str(size)
+ for key in keys:
+ if i < psize:
+ elem = {}
+ elem['pairkey'] = key
+ elem['state'] = '0'
+ elem['ab'] = 'a'
+ if self.pairs[key].props.aimg != None:
+ elem['img'] = self.pairs[key].props.aimg
+ if self.pairs[key].props.asnd != None:
+ elem['snd'] = self.pairs[key].props.asnd
+ if self.pairs[key].props.achar != None:
+ elem['char'] = self.pairs[key].props.achar
+ temp1.append(elem)
+
+ elem = {}
+ elem['pairkey'] = key
+ elem['state'] = '0'
+ elem['ab'] = 'b'
+ if self.pairs[key].props.bimg != None:
+ elem['img'] = self.pairs[key].props.bimg
+ if self.pairs[key].props.bsnd != None:
+ elem['snd'] = self.pairs[key].props.bsnd
+ if self.pairs[key].props.bchar != None:
+ elem['char'] = self.pairs[key].props.bchar
+ temp2.append(elem)
+ i+=1
+ else:
+ break
+
+ numpairs = len(self.pairs)
+ if numpairs < psize:
+ _logger.debug('Defgrid: We did not have enough pairs. requested=%s had=%s' %(psize, numpairs))
+ self.data['size'] = str(size)
- if self.data['divided'] == '1':
- random.shuffle(temp1)
- random.shuffle(temp2)
- temp1.extend(temp2)
- else:
- temp1.extend(temp2)
- random.shuffle(temp1)
- self.grid = temp1
- _logger.debug('Defgrid: grid( size=%s ): %s' %(self.data['size'], self.grid))
+ if self.data['divided'] == '1':
+ random.shuffle(temp1)
+ random.shuffle(temp2)
+ temp1.extend(temp2)
+ else:
+ temp1.extend(temp2)
+ random.shuffle(temp1)
+ self.grid = temp1
+ _logger.debug('Defgrid: grid( size=%s ): %s' %(self.data['size'], self.grid))
- def set_data_grid(self, data, grid):
- self.data = data
- self.grid = grid
-
-if __name__ == '__main__':
- model = Model(os.path.dirname(__file__))
- model.data['name'] = 'hilde'
- pair = Pair()
- id = '0'
- model.pairs[id] = pair
-
- model.pairs[id].set_property('aimg', 'eva.png')
-
- print [model.pairs[key].props.aimg for key in model.pairs]
- if model.write('/tmp/save.mem') != 0:
- print 'error'
-
- '''
- print 'name=%s scoresnd=%s winsnd=%s div=%s' %(model.data['name'], model.data['scoresnd'],
- model.data['winsnd'], model.data['divided'])
-
- model.def_grid(4)
- print 'grid %s'%model.grid #['size']
-
- print 'Test set state of tile 7:'
- tilenum = 7
- model.grid[tilenum]['state'] = '1'
- print ' %s' %model.grid[tilenum]
-
- print 'Test sound:'
- snd = model.grid[tilenum].get('snd', None)
- if snd == None:
- print ' no sound'
- else:
- print ' play sound=%s'%snd
-
- print 'Test the same function: 0 1'
- if model.grid[0]['pairkey'] == model.grid[1]['pairkey']:
- print ' they are the same'
- else:
- print ' they are NOT the same'
-
- for tile in model.grid:
- id = model.grid.index(tile)
- if tile.get('img', None):
- print 'we got an image=%s '%tile['img']
- elif tile.get('char', None):
- print 'we got an char=%s'%tile.get('char')
- else:
- print 'we got no pic so prepare for sound game'
-
- print '\n_______________________________\n'
-
- if model.read('addition') == 0:
- print '%s' %model.pairs[0]._properties
- print 'name=%s' %model.data['name']
- print 'scoresnd=%s' %model.data['scoresnd']
- print 'winsnd=%s' %model.data['winsnd']
- print 'div=%d' %model.data['divided']
-
- model.def_grid(12)
- for tile in model.grid:
- id = model.grid.index(tile)
- if tile.get('img', None):
- print 'we got an image=%s '%tile.get('img')
- elif tile.get('char', None):
- print 'we got an char=%s'%tile.get('char')
- else:
- print 'we got no img so prepare for sound game'
-
- else:
- print 'error during reading of the game'
-
-
- print '\n_______________________________\n'
- if model.read('numbers') == 0:
- print '%s' %model.pairs[0]._properties
- print 'name=%s' %model.data['name']
- print 'scoresnd=%s' %model.data['scoresnd']
- print 'winsnd=%s' %model.data['winsnd']
- print 'div=%d' %model.data['divided']
- print 'face1=%s' %model.data['face1']
- print 'face2=%s' %model.data['face2']
-
- model.def_grid(12)
- for tile in model.grid:
- id = model.grid.index(tile)
- if tile.get('img', None):
- print 'we got an image=%s '%tile.get('img')
- elif tile.get('char', None):
- print 'we got an char=%s'%tile.get('char')
- else:
- print 'we got no img so prepare for sound game'
-
- else:
- print 'error during reading of the game'
- '''
+ def set_data_grid(self, data, grid):
+ self.data = data
+ self.grid = grid
+
+ def save_byte_array(self, path, title= None, color= None):
+ if color == None:
+ color = profile.get_color().to_string()
+ _logger.debug('Save new game in datastore')
+
+ # Saves the zip in datastore
+ gameObject = datastore.create()
+ gameObject.metadata['title'] = title
+ gameObject.metadata['mime_type'] = 'application/memorizegame'
+ gameObject.metadata['icon-color'] = color
+ gameObject.file_path = path
+ datastore.write(gameObject)
+ \ No newline at end of file
diff --git a/playerscoreboard.py b/playerscoreboard.py
index e7f2835..b0c0a88 100755
--- a/playerscoreboard.py
+++ b/playerscoreboard.py
@@ -22,14 +22,14 @@ import gtk, pygtk
import pango
import svglabel
import logging
-import os
+from os.path import join, dirname
from score import Score
_logger = logging.getLogger('memorize-activity')
class PlayerScoreboard(gtk.EventBox):
- def __init__(self, nick, fill_color, stroke_color,score = 0):
+ def __init__(self, nick, fill_color, stroke_color, score = 0):
gtk.EventBox.__init__(self)
self.default_color = '#4c4d4f'
@@ -53,7 +53,7 @@ class PlayerScoreboard(gtk.EventBox):
status = False
# Set buddy icon
- self.xo_buddy = os.path.join(os.path.dirname(__file__), "images/stock-buddy.svg")
+ self.xo_buddy = join(dirname(__file__), 'images', 'stock-buddy.svg')
self.icon = svglabel.SvgLabel(self.xo_buddy, fill_color, stroke_color, False, self.current_color, 45, 55)
# Set waiting buddy icon
@@ -61,15 +61,15 @@ class PlayerScoreboard(gtk.EventBox):
# Set nick label
self.nick = gtk.Label(nick)
- self.nick.modify_font(pango.FontDescription("12"))
+ self.nick.modify_font(pango.FontDescription('12'))
self.nick.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#ffffff'))
self.nick.set_alignment(0, 0.5)
# Set message label
- #self.msg = gtk.Label('Waiting for next game...')
- #self.msg.modify_font(pango.FontDescription("12"))
- #self.msg.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#ffffff'))
- #self.msg.set_alignment(0, 0.5)
+ self.msg = gtk.Label('Waiting for next game...')
+ self.msg.modify_font(pango.FontDescription('12'))
+ self.msg.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#ffffff'))
+ self.msg.set_alignment(0, 0.5)
self.add(self.table)
self.table.attach(self.icon, 0, 1, 0, 1)
@@ -78,16 +78,15 @@ class PlayerScoreboard(gtk.EventBox):
if score <> 0:
for i in range(score):
self.increase_score()
-
+
def increase_score(self):
- _logger.debug('Increase to: '+self.nick.get_text())
if len(self.scores) == 0:
# Cache the score icon
score_label = Score(self.fill_color, self.stroke_color)
self.score_pixbuf_unsel = score_label.get_pixbuf()
self.score_pixbuf_sel = score_label.get_pixbuf_sel()
- new_score = Score(self.fill_color, self.stroke_color, self.score_pixbuf_sel, self.score_pixbuf_unsel,self.status)
+ new_score = Score(self.fill_color, self.stroke_color, self.score_pixbuf_sel, self.score_pixbuf_unsel, self.status)
self.scores.append(new_score)
new_score.show()
self.table.attach(new_score, self.current_x , self.current_x+1, self.current_y, self.current_y+1)
@@ -118,7 +117,7 @@ class PlayerScoreboard(gtk.EventBox):
self.scores = []
self.queue_draw()
- def set_wait_mode(self,status):
+ def set_wait_mode(self, status):
if status:
self.table.remove(self.icon)
self.table.attach(self.waiting_icon, 0, 1, 0, 1)
@@ -132,3 +131,6 @@ class PlayerScoreboard(gtk.EventBox):
self.table.remove(self.msg)
self.queue_draw()
+ def set_message(self, msg):
+ self.msg.set_text(msg)
+
diff --git a/score.py b/score.py
index 1ee1028..74e68b6 100755
--- a/score.py
+++ b/score.py
@@ -30,7 +30,7 @@ class Score(svglabel.SvgLabel):
default_color = "#4c4d4f"
status = False
- def __init__(self, fill_color, stroke_color, pixbuf= None, pixbuf_sel = None,status= False):
+ def __init__(self, fill_color, stroke_color, pixbuf= None, pixbuf_sel = None, status= False):
filename = os.path.join(os.path.dirname(__file__), "images/score.svg")
self.pixbuf_un = pixbuf
self.pixbuf_sel = pixbuf_sel
@@ -51,10 +51,10 @@ class Score(svglabel.SvgLabel):
self.status = status
if status:
self.pixbuf = self.pixbuf_sel
- self.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(self.selected_color))
+ self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.selected_color))
else:
self.pixbuf = self.pixbuf_un
- self.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(self.default_color))
+ self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.default_color))
self.queue_draw()
def get_pixbuf_un(self):
diff --git a/scoreboard.py b/scoreboard.py
index 847c38d..f370f75 100755
--- a/scoreboard.py
+++ b/scoreboard.py
@@ -70,9 +70,11 @@ class Scoreboard(gtk.EventBox):
self.current_buddy = buddy
player = self.players[buddy]
player.set_selected(True)
+
+ def set_buddy_message(self, widget, buddy, msg):
+ self.players[buddy].set_message(msg)
def increase_score(self, widget, buddy):
- _logger.debug('Increase to: '+buddy.props.nick)
self.players[buddy].increase_score()
def reset(self, widget):
diff --git a/svgcard.py b/svgcard.py
index 7423b38..dec2d46 100755
--- a/svgcard.py
+++ b/svgcard.py
@@ -1,25 +1,25 @@
#! /usr/bin/env python
#
-# Copyright (C) 2007, One Laptop Per Child
+# Copyright (C) 2007, One Laptop Per Child
#
-# Muriel de Souza Godoi - muriel@laptop.org
+# Muriel de Souza Godoi - muriel@laptop.org
#
-# 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 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.
+# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#
-import os
+from os.path import join, dirname
import gc
import rsvg
import re
@@ -30,238 +30,238 @@ import logging
_logger = logging.getLogger('memorize-activity')
class SvgCard(gtk.DrawingArea):
-
- border_svg = os.path.join(os.path.dirname(__file__), "images/card.svg")
+
+ border_svg = join(dirname(__file__), 'images', 'card.svg')
- # Default properties
- default_props = {}
- default_props['back'] = {'fill_color':'#b2b3b7', 'stroke_color':'#b2b3b7', 'opacity':'1'}
- default_props['back_h'] = {'fill_color':'#b2b3b7', 'stroke_color':'#ffffff', 'opacity':'1'}
- default_props['back_text'] = {'text_color':'#c7c8cc'}
- default_props['front'] = {'fill_color':'#4c4d4f', 'stroke_color':'#ffffff', 'opacity':'1'}
- default_props['front_h'] = {'fill_color':'#555555', 'stroke_color':'#888888', 'opacity':'1'}
- default_props['front_text'] = {'text_color':'#ffffff'}
-
- cache = {}
-
- def __init__(self, id, pprops, jpeg, size, align, bg_color='#000000'):
- gtk.DrawingArea.__init__(self)
- self.set_size_request(size, size)
- self.bg_color = bg_color
- self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.bg_color))
- self.flipped = False
- self.flipped_once = False
- self.id = id
- self.jpeg = jpeg
- self.show_jpeg = False
- self.show_text = False
- self.size = size
- self.align = align
-
- # Views properties
- views = ['back', 'back_h', 'back_text', 'front', 'front_h', 'front_text']
- self.pprops = pprops
- self.props = {}
- for view in views:
- self.props[view] = {}
- self.props[view].update(self.default_props[view])
- self.props[view].update(pprops.get(view, {}))
-
- if len(self.props['back_text'].get('card_text', '')) > 0:
- self.back_layout = self.get_text_layout(self.props['back_text']['card_text'], self.size-12)
- self.back_layout_position = (self.size -(self.back_layout.get_size()[1]/1000))/2
- self.current_layout = self.back_layout
- self.current_layout_position = self.back_layout_position
- self.current_text_color = self.props['back_text']['text_color']
- self.show_text = True
- self.current_face = 'back'
-
- # Set events and listeners
- self.connect('expose-event', self._expose_cb)
- self.set_events(gtk.gdk.ALL_EVENTS_MASK)
- gc.collect()
- self.show()
+ # Default properties
+ default_props = {}
+ default_props['back'] = {'fill_color':'#b2b3b7', 'stroke_color':'#b2b3b7', 'opacity':'1'}
+ default_props['back_h'] = {'fill_color':'#b2b3b7', 'stroke_color':'#ffffff', 'opacity':'1'}
+ default_props['back_text'] = {'text_color':'#c7c8cc'}
+ default_props['front'] = {'fill_color':'#4c4d4f', 'stroke_color':'#ffffff', 'opacity':'1'}
+ default_props['front_h'] = {'fill_color':'#555555', 'stroke_color':'#888888', 'opacity':'1'}
+ default_props['front_text'] = {'text_color':'#ffffff'}
+
+ cache = {}
+
+ def __init__(self, id, pprops, jpeg, size, align, bg_color='#000000'):
+ gtk.DrawingArea.__init__(self)
+ self.set_size_request(size, size)
+ self.bg_color = bg_color
+ self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.bg_color))
+ self.flipped = False
+ self.flipped_once = False
+ self.id = id
+ self.jpeg = jpeg
+ self.show_jpeg = False
+ self.show_text = False
+ self.size = size
+ self.align = align
+
+ # Views properties
+ views = ['back', 'back_h', 'back_text', 'front', 'front_h', 'front_text']
+ self.pprops = pprops
+ self.props = {}
+ for view in views:
+ self.props[view] = {}
+ self.props[view].update(self.default_props[view])
+ self.props[view].update(pprops.get(view, {}))
+
+ if len(self.props['back_text'].get('card_text', '')) > 0:
+ self.back_layout = self.get_text_layout(self.props['back_text']['card_text'], self.size-12)
+ self.back_layout_position = (self.size -(self.back_layout.get_size()[1]/1000))/2
+ self.current_layout = self.back_layout
+ self.current_layout_position = self.back_layout_position
+ self.current_text_color = self.props['back_text']['text_color']
+ self.show_text = True
+ self.current_face = 'back'
+
+ # Set events and listeners
+ self.connect('expose-event', self._expose_cb)
+ self.set_events(gtk.gdk.ALL_EVENTS_MASK)
+ gc.collect()
+ self.show()
- def _expose_cb(self, widget, event):
- gc = self.window.new_gc()
- pixbuf = self._read_icon_data(self.current_face)
- self.window.draw_pixbuf(None, pixbuf, 0, 0, 0, 0)
- if self.show_jpeg:
- self.window.draw_pixbuf(None, self.jpeg, 0, 0, 11, 11)
- if self.show_text:
- widget.window.draw_layout(gc, x=6, y=self.current_layout_position, layout=self.current_layout, foreground=gtk.gdk.color_parse(self.current_text_color))
- return False
+ def _expose_cb(self, widget, event):
+ gc = self.window.new_gc()
+ pixbuf = self._read_icon_data(self.current_face)
+ self.window.draw_pixbuf(None, pixbuf, 0, 0, 0, 0)
+ if self.show_jpeg:
+ self.window.draw_pixbuf(None, self.jpeg, 0, 0, 11, 11)
+ if self.show_text:
+ widget.window.draw_layout(gc, x=6, y=self.current_layout_position, layout=self.current_layout, foreground=gtk.gdk.color_parse(self.current_text_color))
+ return False
- def _read_icon_data(self, view):
- dict = self.props[view]
- set = str(self.size)+dict.get('fill_color')+dict.get('stroke_color')
- if self.cache.has_key(set):
- return self.cache[set]
-
- icon_file = open(self.border_svg, 'r')
- data = icon_file.read()
- icon_file.close()
+ def _read_icon_data(self, view):
+ dict = self.props[view]
+ set = str(self.size)+dict.get('fill_color')+dict.get('stroke_color')
+ if self.cache.has_key(set):
+ return self.cache[set]
+
+ icon_file = open(self.border_svg, 'r')
+ data = icon_file.read()
+ icon_file.close()
- # Replace borders parameters
- entity = '<!ENTITY fill_color "%s">' % dict.get('fill_color', '')
- data = re.sub('<!ENTITY fill_color .*>', entity, data)
+ # Replace borders parameters
+ entity = '<!ENTITY fill_color "%s">' % dict.get('fill_color', '')
+ data = re.sub('<!ENTITY fill_color .*>', entity, data)
- entity = '<!ENTITY stroke_color "%s">' % dict.get('stroke_color', '')
- data = re.sub('<!ENTITY stroke_color .*>', entity, data)
-
- entity = '<!ENTITY opacity "%s">' % dict.get('opacity', '')
- data = re.sub('<!ENTITY opacity .*>', entity, data)
-
- data = re.sub('size_card1', str(self.size), data)
- data = re.sub('size_card2', str(self.size-6), data)
- data = re.sub('size_card3', str(self.size-17), data)
- pixbuf = rsvg.Handle(data=data).get_pixbuf()
- self.cache[set] = pixbuf
- return pixbuf
-
- def set_border(self, stroke_color, fill_color):
- self.props['front'].update({'fill_color':fill_color, 'stroke_color':stroke_color})
- self.queue_draw()
- while gtk.events_pending():
- gtk.main_iteration()
-
- def set_pixbuf(self, pixbuf):
- if pixbuf == None:
- self.jpeg = None
- self.show_jpeg = False
- else:
- if self.jpeg != None:
- del self.jpeg
-
- self.jpeg = pixbuf
- del pixbuf
- self.show_jpeg = True
-
- self.queue_draw()
- while gtk.events_pending():
- gtk.main_iteration()
-
- def get_pixbuf(self):
- return self.jpeg
-
- def set_highlight(self, status, mouse = False):
- if self.flipped:
- if mouse:
- return
- if status:
- self.current_face = 'front_h'
- else:
- self.current_face = 'front'
- else:
- if status:
- self.current_face = 'back_h'
- else:
- self.current_face = 'back'
- self.queue_draw()
-
- def flip(self):
- if not self.flipped:
- if not self.flipped_once:
- if self.jpeg <> None:
- pixbuf_t = gtk.gdk.pixbuf_new_from_file(self.jpeg)
- if pixbuf_t.get_width() != self.size-22 or pixbuf_t.get_height() != self.size-22:
- self.jpeg = pixbuf_t.scale_simple(self.size-22, self.size-22, gtk.gdk.INTERP_BILINEAR)
- del pixbuf_t
- else:
- self.jpeg = pixbuf_t
- text = self.props.get('front_text', {}).get('card_text', '')
- if text != None and len(text) > 0:
- self.front_layout = self.get_text_layout(self.props['front_text']['card_text'], self.size-12)
- self.front_layout_position = (self.size -(self.front_layout.get_size()[1]/1000))/2
- self.flipped_once = True
-
- if self.jpeg <> None:
- self.show_jpeg = True
- text = self.props.get('front_text', {}).get('card_text', '')
- if text != None and len(text) > 0:
- self.current_layout = self.front_layout
- self.current_layout_position = self.front_layout_position
- self.current_text_color = self.props['front_text']['text_color']
- self.show_text = True
- else:
- self.show_text = False
+ entity = '<!ENTITY stroke_color "%s">' % dict.get('stroke_color', '')
+ data = re.sub('<!ENTITY stroke_color .*>', entity, data)
+
+ entity = '<!ENTITY opacity "%s">' % dict.get('opacity', '')
+ data = re.sub('<!ENTITY opacity .*>', entity, data)
+
+ data = re.sub('size_card1', str(self.size), data)
+ data = re.sub('size_card2', str(self.size-6), data)
+ data = re.sub('size_card3', str(self.size-17), data)
+ pixbuf = rsvg.Handle(data=data).get_pixbuf()
+ self.cache[set] = pixbuf
+ return pixbuf
+
+ def set_border(self, stroke_color, fill_color):
+ self.props['front'].update({'fill_color':fill_color, 'stroke_color':stroke_color})
+ self.queue_draw()
+ while gtk.events_pending():
+ gtk.main_iteration()
+
+ def set_pixbuf(self, pixbuf):
+ if pixbuf == None:
+ self.jpeg = None
+ self.show_jpeg = False
+ else:
+ if self.jpeg != None:
+ del self.jpeg
+
+ self.jpeg = pixbuf
+ del pixbuf
+ self.show_jpeg = True
+
+ self.queue_draw()
+ while gtk.events_pending():
+ gtk.main_iteration()
+
+ def get_pixbuf(self):
+ return self.jpeg
+
+ def set_highlight(self, status, mouse = False):
+ if self.flipped:
+ if mouse:
+ return
+ if status:
+ self.current_face = 'front_h'
+ else:
+ self.current_face = 'front'
+ else:
+ if status:
+ self.current_face = 'back_h'
+ else:
+ self.current_face = 'back'
+ self.queue_draw()
+
+ def flip(self):
+ if not self.flipped:
+ if not self.flipped_once:
+ if self.jpeg <> None:
+ pixbuf_t = gtk.gdk.pixbuf_new_from_file(self.jpeg)
+ if pixbuf_t.get_width() != self.size-22 or pixbuf_t.get_height() != self.size-22:
+ self.jpeg = pixbuf_t.scale_simple(self.size-22, self.size-22, gtk.gdk.INTERP_BILINEAR)
+ del pixbuf_t
+ else:
+ self.jpeg = pixbuf_t
+ text = self.props.get('front_text', {}).get('card_text', '')
+ if text != None and len(text) > 0:
+ self.front_layout = self.get_text_layout(self.props['front_text']['card_text'], self.size-12)
+ self.front_layout_position = (self.size -(self.front_layout.get_size()[1]/1000))/2
+ self.flipped_once = True
+
+ if self.jpeg <> None:
+ self.show_jpeg = True
+ text = self.props.get('front_text', {}).get('card_text', '')
+ if text != None and len(text) > 0:
+ self.current_layout = self.front_layout
+ self.current_layout_position = self.front_layout_position
+ self.current_text_color = self.props['front_text']['text_color']
+ self.show_text = True
+ else:
+ self.show_text = False
- self.current_face = 'front'
+ self.current_face = 'front'
- self.flipped = True
- self.queue_draw()
-
- while gtk.events_pending():
- gtk.main_iteration()
- gc.collect()
-
- def flop(self):
- self.current_face = 'back'
- if len(self.props['back_text'].get('card_text', '')) > 0:
- self.current_layout = self.back_layout
- self.current_layout_position = self.back_layout_position
- self.current_text_color = self.props['back_text']['text_color']
- self.show_text = True
- else:
- self.show_text = False
- self.flipped = False
- self.show_jpeg = False
- self.queue_draw()
-
- def is_flipped(self):
- return self.flipped
-
- def get_id(self):
- return self.id
-
- def reset(self):
- if self.flipped:
- fill_color = self.default_props.get('front_border').get('fill_color')
- stroke_color = self.default_propsfront_text.get('front_border').get('stroke_color')
- self.set_border(fill_color, stroke_color)
- self.flop()
-
- def get_text_layout(self, text, size):
- if self.size == 119:
- font_sizes = [30, 24, 16, 13, 10, 8, 8, 8]
- elif self.size == 145:
- font_sizes = [45, 28, 20, 16, 13, 11, 9, 8]
- else:
- font_sizes = [50, 40, 26, 20, 17, 13, 11, 8]
- # Set font size considering string length
- if len(text) <= 8:
- font_size = font_sizes[len(text)-1]
- else:
- font_size = 8
+ self.flipped = True
+ self.queue_draw()
+
+ while gtk.events_pending():
+ gtk.main_iteration()
+ gc.collect()
+
+ def flop(self):
+ self.current_face = 'back'
+ if len(self.props['back_text'].get('card_text', '')) > 0:
+ self.current_layout = self.back_layout
+ self.current_layout_position = self.back_layout_position
+ self.current_text_color = self.props['back_text']['text_color']
+ self.show_text = True
+ else:
+ self.show_text = False
+ self.flipped = False
+ self.show_jpeg = False
+ self.queue_draw()
+
+ def is_flipped(self):
+ return self.flipped
+
+ def get_id(self):
+ return self.id
+
+ def reset(self):
+ if self.flipped:
+ fill_color = self.default_props.get('front_border').get('fill_color')
+ stroke_color = self.default_propsfront_text.get('front_border').get('stroke_color')
+ self.set_border(fill_color, stroke_color)
+ self.flop()
+
+ def get_text_layout(self, text, size):
+ if self.size == 119:
+ font_sizes = [30, 24, 16, 13, 10, 8, 8, 8]
+ elif self.size == 145:
+ font_sizes = [45, 28, 20, 16, 13, 11, 9, 8]
+ else:
+ font_sizes = [50, 40, 26, 20, 17, 13, 11, 8]
+ # Set font size considering string length
+ if len(text) <= 8:
+ font_size = font_sizes[len(text)-1]
+ else:
+ font_size = 8
- # Set Pango context and Pango layout
- context = self.create_pango_context()
- layout = self.create_pango_layout(text)
- desc = pango.FontDescription('Deja Vu Sans bold '+str(font_size))
- layout.set_font_description(desc)
- layout.set_alignment(pango.ALIGN_CENTER)
- layout.set_width(size*1000)
- return layout
+ # Set Pango context and Pango layout
+ context = self.create_pango_context()
+ layout = self.create_pango_layout(text)
+ desc = pango.FontDescription('Deja Vu Sans bold '+str(font_size))
+ layout.set_font_description(desc)
+ layout.set_alignment(pango.ALIGN_CENTER)
+ layout.set_width(size*1000)
+ return layout
- def set_background(self, color):
- self.bg_color = color
- self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.bg_color))
-
- def change_text(self, newtext):
- self.props['front_text']['card_text'] = newtext
- self.front_layout = self.get_text_layout(self.props['front_text'].get('card_text', ''), self.size-11)
- if self.align == '2': # top
- self.front_layout_position = 6
- elif self.align == '3': # bottom
- self.front_layout_position = self.size -(self.front_layout.get_size()[1]/1000)
- else: # center and none
- self.front_layout_position = (self.size -(self.front_layout.get_size()[1]/1000))/2
-
- self.current_layout = self.front_layout
- self.current_layout_position = self.front_layout_position
- self.current_text_color = self.props['front_text']['text_color']
- if len(newtext) > 0:
- self.show_text = True
- self.queue_draw()
- def get_text(self):
- return self.props['front_text'].get('card_text', '')
+ def set_background(self, color):
+ self.bg_color = color
+ self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.bg_color))
+
+ def change_text(self, newtext):
+ self.props['front_text']['card_text'] = newtext
+ self.front_layout = self.get_text_layout(self.props['front_text'].get('card_text', ''), self.size-11)
+ if self.align == '2': # top
+ self.front_layout_position = 6
+ elif self.align == '3': # bottom
+ self.front_layout_position = self.size -(self.front_layout.get_size()[1]/1000)
+ else: # center and none
+ self.front_layout_position = (self.size -(self.front_layout.get_size()[1]/1000))/2
+
+ self.current_layout = self.front_layout
+ self.current_layout_position = self.front_layout_position
+ self.current_text_color = self.props['front_text']['text_color']
+ if len(newtext) > 0:
+ self.show_text = True
+ self.queue_draw()
+ def get_text(self):
+ return self.props['front_text'].get('card_text', '')
diff --git a/svglabel.py b/svglabel.py
index d30883e..9f98640 100755
--- a/svglabel.py
+++ b/svglabel.py
@@ -37,7 +37,7 @@ class SvgLabel(gtk.DrawingArea):
self.background_color = background_color
self.fill_color = fill_color
self.stroke_color = stroke_color
- self.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(background_color))
+ self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(background_color))
if pixbuf:
self.pixbuf = pixbuf
else:
@@ -46,7 +46,7 @@ class SvgLabel(gtk.DrawingArea):
self.connect('expose-event', self._expose_cb)
def _expose_cb(self, widget, event):
- widget.window.draw_pixbuf(None,self.pixbuf, 0, 0, 0, 0)
+ widget.window.draw_pixbuf(None, self.pixbuf, 0, 0, 0, 0)
return False
def _read_icon_data(self, filename, fill_color, stroke_color):
@@ -96,6 +96,6 @@ class SvgLabel(gtk.DrawingArea):
def set_background(self, background_color):
self.background_color = background_color
- self.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(self.background_color))
+ self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.background_color))
self.queue_draw()