From d267599aaa92372d0d9a868f1662f3aec60d722d Mon Sep 17 00:00:00 2001 From: Simon Schampijer Date: Wed, 11 Jul 2007 17:07:15 +0000 Subject: Merge branch 'tubes' Conflicts: NEWS --- diff --git a/NEWS b/NEWS index f9acee0..5f009e9 100644 --- a/NEWS +++ b/NEWS @@ -1 +1,5 @@ +<<<<<<< HEAD:NEWS First version of the collaborated memosono. (erikos) +======= +The initial collaborated memosono (erikos). +>>>>>>> tubes:NEWS diff --git a/activity/activity-memorygame.svg b/activity/activity-memosono.svg index 5a5bf83..5a5bf83 100644 --- a/activity/activity-memorygame.svg +++ b/activity/activity-memosono.svg diff --git a/activity/activity.info b/activity/activity.info index 8b954a8..2949e26 100644 --- a/activity/activity.info +++ b/activity/activity.info @@ -1,6 +1,6 @@ [Activity] name = Memosono -service_name = com.erikos.MemosonoActivity +service_name = org.laptop.Memosono class = memosonoactivity.MemosonoActivity -icon = activity-memorygame +icon = activity-memosono activity_version = 11 diff --git a/buddiespanel.py b/buddiespanel.py index 50c85d6..e3361ad 100644 --- a/buddiespanel.py +++ b/buddiespanel.py @@ -1,11 +1,72 @@ import gtk import hippo +import math + from sugar.graphics.canvasicon import CanvasIcon from sugar.graphics.xocolor import XoColor from sugar.graphics import color -from sugar.graphics import font +from sugar.graphics import style +from sugar.graphics import units + + +class BuddyPlayer(hippo.CanvasBox, hippo.CanvasItem): + __gtype_name__ = 'BuddyPlayer' + _BORDER_DEFAULT = units.points_to_pixels(1.0) + + def __init__(self, buddy, **kargs): + hippo.CanvasBox.__init__(self, **kargs) + + self._radius = units.points_to_pixels(5) + self.props.border_color = 0 + self.props.background_color = 0 + self.props.orientation = hippo.ORIENTATION_VERTICAL + self.props.border = self._BORDER_DEFAULT + self.props.border_left = self._radius + self.props.border_right = self._radius + + buddy_color = buddy.props.color + if not buddy_color: + buddy_color = "#000000,#ffffff" + + self.icon = CanvasIcon( + icon_name='theme:stock-buddy', + xo_color=XoColor(buddy_color)) + + nick = buddy.props.nick + if not nick: + nick = "" + self.name = hippo.CanvasText(text=nick, size_mode=hippo.CANVAS_SIZE_WRAP_WORD, color=color.WHITE.get_int()) + + self.append(self.icon) + self.append(self.name) + + + def do_paint_background(self, cr, damaged_box): + [width, height] = self.get_allocation() + + x = self._BORDER_DEFAULT / 2 + y = self._BORDER_DEFAULT / 2 + width -= self._BORDER_DEFAULT + height -= self._BORDER_DEFAULT + + cr.move_to(x + self._radius, y); + cr.arc(x + width - self._radius, y + self._radius, + self._radius, math.pi * 1.5, math.pi * 2); + cr.arc(x + width - self._radius, x + height - self._radius, + self._radius, 0, math.pi * 0.5); + cr.arc(x + self._radius, y + height - self._radius, + self._radius, math.pi * 0.5, math.pi); + cr.arc(x + self._radius, y + self._radius, self._radius, + math.pi, math.pi * 1.5); + + hippo.cairo_set_source_rgba32(cr, self.props.background_color) + cr.fill() + class BuddiesPanel(hippo.CanvasBox): + _COLOR_ACTIVE = 50 + _COLOR_INACTIVE = 0 + def __init__(self): hippo.CanvasBox.__init__(self, spacing=4, padding=5, orientation=hippo.ORIENTATION_VERTICAL) @@ -22,7 +83,8 @@ class BuddiesPanel(hippo.CanvasBox): self.players = {} self.watchers = {} - + self.last_active = None + def _create_buddy_vbox (self, buddy): buddy_color = buddy.props.color if not buddy_color: @@ -38,6 +100,14 @@ class BuddiesPanel(hippo.CanvasBox): name = hippo.CanvasText(text=nick, color=color.WHITE.get_int()) vbox = hippo.CanvasBox(padding=5) + vbox._radius = units.points_to_pixels(5) + vbox.props.border_color = 100 + vbox.props.background_color = 200 + vbox.props.orientation = hippo.ORIENTATION_VERTICAL + vbox.props.border = units.points_to_pixels(1.0) + vbox.props.border_left = vbox._radius + vbox.props.border_right = vbox._radius + vbox.append(icon) vbox.append(name) @@ -70,11 +140,9 @@ class BuddiesPanel(hippo.CanvasBox): hbox = hippo.CanvasBox(spacing=4, padding=5, orientation=hippo.ORIENTATION_HORIZONTAL) + hbox.append(BuddyPlayer(buddy)) - vbox = self._create_buddy_vbox(buddy) - hbox.append(vbox) - - count_font = font.DEFAULT_BOLD.get_pango_desc() + count_font = style.FONT_BOLD.get_pango_desc() count_font.set_size(30000) count = hippo.CanvasText(text="0", color=color.WHITE.get_int(), font_desc=count_font) @@ -83,17 +151,19 @@ class BuddiesPanel(hippo.CanvasBox): self.players_box.append(hbox) self.players[op] = hbox - + def set_is_playing(self, buddy): - op = buddy.object_path() - for player, hbox in self.players.items(): - vbox = hbox.get_children()[0] - icon, name = vbox.get_children() - if player == op: - name.props.font_desc = font.DEFAULT_BOLD.get_pango_desc() - else: - name.props.font_desc = font.DEFAULT.get_pango_desc() - + hbox = self.players.get(buddy.object_path()) + bp = hbox.get_children()[0] + bp.props.background_color = self._COLOR_ACTIVE + bp.emit_paint_needed(0, 0, -1, -1) + if self.last_active is not None: + hbox = self.players.get(self.last_active.object_path()) + lbp = hbox.get_children()[0] + lbp.props.background_color = self._COLOR_INACTIVE + lbp.emit_paint_needed(0, 0, -1, -1) + self.last_active = buddy + def set_count(self, buddy, val): hbox = self.players.get(buddy.object_path()) if hbox is None: diff --git a/controller.py b/controller.py new file mode 100644 index 0000000..4970d87 --- /dev/null +++ b/controller.py @@ -0,0 +1,250 @@ +import logging + +import gobject +import gtk +import os + +from dbus import Interface +from dbus.service import method, signal +from dbus.gobject_service import ExportedGObject + +from model import Model +from csound.csoundserver import CsoundServer + +SERVICE = "org.freedesktop.Telepathy.Tube.Memosono" +IFACE = SERVICE +PATH = "/org/freedesktop/Telepathy/Tube/Memosono" + + +GAME_PATH = os.path.join(os.path.dirname(__file__),'games/drumgit') +IMAGES_PATH = os.path.join(os.path.dirname(__file__),'games/drumgit/images') +SOUNDS_PATH = os.path.join(os.path.dirname(__file__),'games/drumgit/sounds') +MAX_NUM_PLAYERS = 2 + +_logger = logging.getLogger('controller') + + +class Controller(ExportedGObject): + ''' Networked Controller which is the core component of the activity. It + handles the communication with the components (model, view) and with the + other players over the network. + ''' + def __init__(self, tube, playview, is_initiator, buddies_panel, info_panel, + owner, get_buddy, activity): + super(Controller, self).__init__(tube, PATH) + self.tube = tube + self.pv = playview + self.is_initiator = is_initiator + self.entered = False + self.buddies_panel = buddies_panel + self.info_panel = info_panel + self.owner = owner + self._get_buddy = get_buddy + self.activity = activity + self.numplayers = 0 + self.turn = 0 + + self.cs = CsoundServer() + gtk.gdk.threads_init() + self.cs.start() + + if self.is_initiator: + self.init_game() + + for tile in self.pv.tiles: + tile.connect('button-press-event', self._button_press_cb, self.pv.tiles.index(tile)) + + + self.tube.watch_participants(self.participant_change_cb) + + + def participant_change_cb(self, added, removed): + + _logger.debug('adding participants: %r', added) + _logger.debug('removing participants: %r', removed) + + for handle, bus_name in added: + buddy = self._get_buddy(handle) + if buddy is not None: + _logger.debug('buddy %r was added', buddy) + if self.numplayers < MAX_NUM_PLAYERS: + self.buddies_panel.add_player(buddy) + self.numplayers+=1 + if self.is_initiator: + self.buddies_panel.set_is_playing(buddy) + self.model.players[self.tube.participants[handle]] = [buddy.props.nick, 0] + _logger.debug('list of players: %s', self.model.players) + else: + self.info_panel.show('we are already two players') + + for handle in removed: + buddy = self._get_buddy(handle) + if buddy is not None: + _logger.debug('-----> buddy %r was removed', buddy) + self.buddies_panel.remove_player(buddy) + self.numplayers-=1 + if self.is_initiator: + try: + del self.model.players[self.tube.participants[handle]] + except ValueError: + # already absent + pass + + if not self.entered: + self.playerid = self.tube.get_unique_name() + self.tube.add_signal_receiver(self.info_cb, 'Info', IFACE, + path=PATH, sender_keyword='sender') + self.tube.add_signal_receiver(self.turn_cb, 'Turn', IFACE, + path=PATH, sender_keyword='sender') + self.tube.add_signal_receiver(self.flip_cb, 'Flip', IFACE, + path=PATH, sender_keyword='sender') + self.tube.add_signal_receiver(self.play_cb, 'Play', IFACE, + path=PATH, sender_keyword='sender') + self.tube.add_signal_receiver(self.points_cb, 'Points', IFACE, + path=PATH, sender_keyword='sender') + + self.entered = True + + if self.is_initiator: + if len(self.model.players) == 2 and self.model.started == 0: + _logger.debug('start the game') + self.Info('start the game') + self.model.started = 1 + self.change_turn() + + def init_game(self): + _logger.debug('I am the initiator, so making myself the leader of the game.') + self.model = Model(GAME_PATH, os.path.dirname(__file__)) + self.model.read('drumgit.mson') + self.model.def_grid() + self.tube.add_signal_receiver(self.selected_cb, 'Selected', IFACE, + path=PATH, sender_keyword='sender') + + + @signal(dbus_interface=IFACE, signature='n') + def Selected(self, tilenum): + """Signal that a tile has been selected""" + + def selected_cb(self, tilenum, sender=None): + _logger.debug('MA: %s flipped tile %d', sender, tilenum) + if self.model.grid[tilenum][2] == 1: + self.Info('selected already') + else: + pairkey, moch, state = self.model.grid[tilenum] + color = self.model.pairs[pairkey].props.color + + if moch == 0: + if self.model.pairs[pairkey].props.aimg != None: + img = os.path.join(IMAGES_PATH, self.model.pairs[pairkey].props.aimg) + self.Flip(tilenum, img, color) + if self.model.pairs[pairkey].props.asnd != None: + snd = os.path.join(SOUNDS_PATH, self.model.pairs[pairkey].props.asnd) + self.Play(tilenum, snd, color) + elif moch == 1: + if self.model.pairs[pairkey].props.bimg != None: + img = os.path.join(IMAGES_PATH, self.model.pairs[pairkey].props.bimg) + self.Flip(tilenum, img, color) + if self.model.pairs[pairkey].props.bsnd != None: + snd = os.path.join(SOUNDS_PATH, self.model.pairs[pairkey].props.bsnd) + self.Play(tilenum, snd, color) + + self.model.count+=1 + if self.model.count == 1: + self.model.selected = tilenum + self.model.grid[tilenum][2] = 1 + return + if self.model.count == 2: + self.model.count = 0 + # evaluate + if( self.model.same(tilenum, self.model.selected) == 1): + _logger.debug('MA: Tile(%d) and (%d) are the same', tilenum, self.model.selected) + self.model.grid[tilenum][2] = 1 + self.model.grid[self.model.selected][2] = 1 + + self.model.players[sender][1]+=1 + self.Points(sender, self.model.players[sender][1]) + self.Info('found pair, one more try') + else: + self.model.grid[tilenum][2] = 0 + self.model.grid[self.model.selected][2] = 0 + self.change_turn() + self.Info('pair does not match, next player') + gobject.timeout_add(2000, self._turn_back, tilenum, self.model.selected) + _logger.debug('Tile(%d) and (%d) are NOT the same', tilenum, self.model.selected) + + def _turn_back(self, tilenuma, tilenumb): + self.Flip(tilenuma, 'images/black.png', 100) + self.Flip(tilenumb, 'images/black.png', 100) + return False + + def change_turn(self): + if self.model.player_active < (len(self.model.players)-1): + self.model.player_active+=1 + else: + self.model.player_active = 0 + + key = self.model.players.keys()[self.model.player_active] + self.Turn(key, self.model.players[key][0]) + + + @signal(dbus_interface=IFACE, signature='nsn') + def Flip(self, tilenum, obj, color): + """Signal that a tile will be flipped""" + + def flip_cb(self, tilenum, obj, color, sender=None): + handle = self.tube.bus_name_to_handle[sender] + _logger.debug('Flipped tile(%d) from %s. Show image.', tilenum, sender) + self.pv.flip(tilenum, os.path.join(os.path.dirname(__file__), obj), color) + + + @signal(dbus_interface=IFACE, signature='nsn') + def Play(self, tilenum, obj, color): + """Signal that a sound will be played""" + + def play_cb(self, tilenum, obj, color, sender=None): + handle = self.tube.bus_name_to_handle[sender] + _logger.debug('Flipped tile(%d) from %s. Play sound.', tilenum, sender) + _logger.debug(' Sound: %s', obj) + self.cs.perform('i 108 0.0 3.0 "%s" 1 0.7 0.5 0'%(obj)) + + + @signal(dbus_interface=IFACE, signature='ss') + def Turn(self, playerid, name): + """Signal that it is the players turn""" + + def turn_cb(self, playerid, name, sender=None): + if self.playerid == playerid: + self.turn = 1 + else: + self.turn = 0 + + buddy = self._get_buddy(self.tube.bus_name_to_handle[playerid]) + self.buddies_panel.set_is_playing(buddy) + self.info_panel.show('hey %s it is your turn'%name) + + @signal(dbus_interface=IFACE, signature='sn') + def Points(self, player, points): + """Signal to update the points""" + + def points_cb(self, player, points, sender=None): + handle = self.tube.bus_name_to_handle[player] + buddy = self._get_buddy(handle) + self.buddies_panel.set_count(buddy, points) + + + @signal(dbus_interface=IFACE, signature='s') + def Info(self, msg): + """Signal that there is some game information""" + + def info_cb(self, msg, sender=None): + self.info_panel.show(msg) + + + def _button_press_cb(self, tile, event, tilenum=None): + if self.turn == 1: + self.Selected(tilenum) + else: + _logger.debug('Not my turn') + self.info_panel.show('Not my turn') + + diff --git a/csound/csoundserver.py b/csound/csoundserver.py index c384300..6e7c815 100644 --- a/csound/csoundserver.py +++ b/csound/csoundserver.py @@ -1,106 +1,43 @@ #! /usr/bin/env python -import select import os import logging from threading import Thread import csnd -from osc.oscapi import OscApi + +_logger = logging.getLogger('csound') class CsoundServer(Thread): - CSOUND_PORT = 6783 - MAX_PINGS = 3 - TIMEOUT_PING = 10 def __init__(self): Thread.__init__(self) - self.oscapi = OscApi(self.CSOUND_PORT) - self.oscapi.addmethod('/CSOUND/connect', '', self._connect) - self.oscapi.addmethod('/CSOUND/pong', '', self._pong) - self.oscapi.addmethod('/CSOUND/perform', 's', self._perform) - self.oscapi.addmethod('/CSOUND/disconnect', '', self._disconnect) - self.oscapi.addmethod('/CSOUND/quit', '', self._quit) - self.running = 1 - - self.clients = {} - self.start() - - def run(self): - logging.info('start listening...') self.csound = csnd.Csound() - - while self.running: - inputready,outputready,exceptready = select.select([self.oscapi.iosock],[], [], self.TIMEOUT_PING) - for s in inputready: - if s == self.oscapi.iosock: - data, address = s.recvfrom(1024) - self.oscapi.handlemsg(data, address) - if len(inputready) == 0: - self.ping() - - def ping(self): - rm = [] - for client in self.clients: - if self.clients[client] == self.MAX_PINGS: - rm.append(client) - logging.debug('[ping] remove client %s'%str(client)) - else: - self.oscapi.send(client, '/CSOUND/ping', []) - self.clients[client]+=1 - ### print ' [ping] client=%s seq=%s'%(str(client), self.clients[client]) - - for elem in rm: - del self.clients[elem] - if len(self.clients) == 0: - self.perf.Stop() - self.perf.Join() - self.csound.Reset() - logging.debug('[csound] stop csound performance') - - - def _connect(self, *msg): - if msg[1] in self.clients: - logging.debug('[connect_cb] %s already connected'%str(msg[1])) - else: - self.clients[msg[1]]=0 - logging.debug('[connect_cb] %s connected'%str(msg[1])) - if len(self.clients) == 1: - self.perf = csnd.CsoundPerformanceThread(self.csound) - uniorcpath = os.path.join( os.path.dirname(__file__), 'univorc.csd') - if not os.path.exists(uniorcpath): - logging.error('[csound] univorc not found %s'%uniorcpath) - self.csound.Compile(uniorcpath) - self.perf.Play() - logging.debug('[csound] start csound performance %s'%uniorcpath) - - def _disconnect(self, *msg): - if msg[1] not in self.clients: - logging.debug('[disconnect_cb] %s not connected'%str(msg[1])) - else: - del self.clients[msg[1]] - logging.debug('[disconnect_cb] %s disconnected'%str(msg[1])) - if len(self.clients) == 0: - self.perf.Stop() - self.perf.Join() - self.csound.Reset() - logging.debug('[csound] stop csound performance') - - - def _quit(self, *msg): - logging.info('stop listening...') - self.running = 0 + def start(self): + self.perf = csnd.CsoundPerformanceThread(self.csound) + uniorcpath = os.path.join( os.path.dirname(__file__), 'univorc.csd') + if not os.path.exists(uniorcpath): + _logger.error('univorc not found %s'%uniorcpath) + else: + self.csound.Compile(uniorcpath) + self.perf.Play() + _logger.debug('start csound performance %s'%uniorcpath) + + def pause(self): + self.perf.Stop() + self.perf.Join() self.csound.Reset() - self.csound = None - - - def _pong(self, *msg): - self.clients[msg[1]]-=1 - ### print ' [pong_cb] %s'%str(msg) + _logger.debug('stop performance') + def perform(self, msg): + _logger.debug(' [perform_cb] %s'%str(msg)) + self.perf.InputMessage(str(msg)) - def _perform(self, *msg): - logging.debug(' [perform_cb] %s'%str(msg[0][2])) - self.perf.InputMessage(msg[0][2]) + def quit(self): + _logger.info('quit') + self.perf.Stop() + self.perf.Join() + self.csound.Reset() + self.csound = None diff --git a/games/drumgit/drumgit.mson b/games/drumgit/drumgit.mson index d5b4cfc..4498ae5 100644 --- a/games/drumgit/drumgit.mson +++ b/games/drumgit/drumgit.mson @@ -1,11 +1,29 @@ - - - + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/games/guitar/images/drumkit10_b.jpg b/games/guitar/images/drumkit10_b.jpg deleted file mode 100644 index 9288d4c..0000000 --- a/games/guitar/images/drumkit10_b.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/drumkit11_b.jpg b/games/guitar/images/drumkit11_b.jpg deleted file mode 100644 index cd169ce..0000000 --- a/games/guitar/images/drumkit11_b.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/drumkit12_b.jpg b/games/guitar/images/drumkit12_b.jpg deleted file mode 100644 index f10ade8..0000000 --- a/games/guitar/images/drumkit12_b.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/drumkit1_b.jpg b/games/guitar/images/drumkit1_b.jpg deleted file mode 100644 index 98ab27d..0000000 --- a/games/guitar/images/drumkit1_b.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/drumkit2_b.jpg b/games/guitar/images/drumkit2_b.jpg deleted file mode 100644 index e1a7fc7..0000000 --- a/games/guitar/images/drumkit2_b.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/drumkit3_b.jpg b/games/guitar/images/drumkit3_b.jpg deleted file mode 100644 index 3a75f41..0000000 --- a/games/guitar/images/drumkit3_b.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/drumkit4_b.jpg b/games/guitar/images/drumkit4_b.jpg deleted file mode 100644 index a4c5b97..0000000 --- a/games/guitar/images/drumkit4_b.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/drumkit5_b.jpg b/games/guitar/images/drumkit5_b.jpg deleted file mode 100644 index 063ef59..0000000 --- a/games/guitar/images/drumkit5_b.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/drumkit6_b.jpg b/games/guitar/images/drumkit6_b.jpg deleted file mode 100644 index 991edd8..0000000 --- a/games/guitar/images/drumkit6_b.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/drumkit7_b.jpg b/games/guitar/images/drumkit7_b.jpg deleted file mode 100644 index 4f993e7..0000000 --- a/games/guitar/images/drumkit7_b.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/drumkit8_b.jpg b/games/guitar/images/drumkit8_b.jpg deleted file mode 100644 index dfdd67c..0000000 --- a/games/guitar/images/drumkit8_b.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/drumkit9_b.jpg b/games/guitar/images/drumkit9_b.jpg deleted file mode 100644 index 16197e4..0000000 --- a/games/guitar/images/drumkit9_b.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/guitar10_2.jpg b/games/guitar/images/guitar10_2.jpg deleted file mode 100644 index cc1f29b..0000000 --- a/games/guitar/images/guitar10_2.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/guitar11_2.jpg b/games/guitar/images/guitar11_2.jpg deleted file mode 100644 index a738ef2..0000000 --- a/games/guitar/images/guitar11_2.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/guitar12_2.jpg b/games/guitar/images/guitar12_2.jpg deleted file mode 100644 index 2998cfe..0000000 --- a/games/guitar/images/guitar12_2.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/guitar1_2.jpg b/games/guitar/images/guitar1_2.jpg deleted file mode 100644 index 89dbd7c..0000000 --- a/games/guitar/images/guitar1_2.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/guitar2_2.jpg b/games/guitar/images/guitar2_2.jpg deleted file mode 100644 index 6766232..0000000 --- a/games/guitar/images/guitar2_2.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/guitar3_2.jpg b/games/guitar/images/guitar3_2.jpg deleted file mode 100644 index 3cf7431..0000000 --- a/games/guitar/images/guitar3_2.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/guitar4_2.jpg b/games/guitar/images/guitar4_2.jpg deleted file mode 100644 index ea12232..0000000 --- a/games/guitar/images/guitar4_2.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/guitar5_2.jpg b/games/guitar/images/guitar5_2.jpg deleted file mode 100644 index a5cec0d..0000000 --- a/games/guitar/images/guitar5_2.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/guitar6_2.jpg b/games/guitar/images/guitar6_2.jpg deleted file mode 100644 index 6212245..0000000 --- a/games/guitar/images/guitar6_2.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/guitar7_2.jpg b/games/guitar/images/guitar7_2.jpg deleted file mode 100644 index 356a90f..0000000 --- a/games/guitar/images/guitar7_2.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/guitar8_2.jpg b/games/guitar/images/guitar8_2.jpg deleted file mode 100644 index 2b33f99..0000000 --- a/games/guitar/images/guitar8_2.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/guitar9_2.jpg b/games/guitar/images/guitar9_2.jpg deleted file mode 100644 index 691423d..0000000 --- a/games/guitar/images/guitar9_2.jpg +++ /dev/null Binary files differ diff --git a/games/guitar/images/reference b/games/guitar/images/reference deleted file mode 100644 index 79ce4c4..0000000 --- a/games/guitar/images/reference +++ /dev/null @@ -1,18 +0,0 @@ -The guitar pictures are distributed under the Creative Commons Attribution ShareAlike 2.0 Germany License since they derive of the following work: - -guitar: - creator: Martin Moeller - name: Classical_Guitar_two_views - licence: Creative Commons Attribution ShareAlike 2.0 Germany License - (http://creativecommons.org/licenses/by-sa/2.0/de/) - link: http://de.wikipedia.org/wiki/Bild:Classical_Guitar_two_views.jpg - - -The drumkit pictures are distributed under the GNU Free Documentation License since they derive of the following work: - -drumkit: - creator: Clngre - name: Illustration of a drum kit for "drum kit component" - licence: GNU-Lizenz für freie Dokumentation - (http://commons.wikimedia.org/wiki/Commons:GNU_Free_Documentation_License) - found at: http://de.wikipedia.org/wiki/Bild:Drum_kit_illustration_template.png \ No newline at end of file diff --git a/games/guitar/sounds/beat10.aiff b/games/guitar/sounds/beat10.aiff deleted file mode 100644 index 7a86e46..0000000 --- a/games/guitar/sounds/beat10.aiff +++ /dev/null Binary files differ diff --git a/games/guitar/sounds/beat14.aiff b/games/guitar/sounds/beat14.aiff deleted file mode 100644 index ae530e2..0000000 --- a/games/guitar/sounds/beat14.aiff +++ /dev/null Binary files differ diff --git a/games/guitar/sounds/beat16.aiff b/games/guitar/sounds/beat16.aiff deleted file mode 100644 index 9bd9474..0000000 --- a/games/guitar/sounds/beat16.aiff +++ /dev/null Binary files differ diff --git a/games/guitar/sounds/beat17.aiff b/games/guitar/sounds/beat17.aiff deleted file mode 100644 index 92990b4..0000000 --- a/games/guitar/sounds/beat17.aiff +++ /dev/null Binary files differ diff --git a/games/guitar/sounds/beat1_a.aiff b/games/guitar/sounds/beat1_a.aiff deleted file mode 100644 index 654ba5f..0000000 --- a/games/guitar/sounds/beat1_a.aiff +++ /dev/null Binary files differ diff --git a/games/guitar/sounds/beat1_b.aiff b/games/guitar/sounds/beat1_b.aiff deleted file mode 100644 index a8328e9..0000000 --- a/games/guitar/sounds/beat1_b.aiff +++ /dev/null Binary files differ diff --git a/games/guitar/sounds/beat1_c.aiff b/games/guitar/sounds/beat1_c.aiff deleted file mode 100644 index 776bb23..0000000 --- a/games/guitar/sounds/beat1_c.aiff +++ /dev/null Binary files differ diff --git a/games/guitar/sounds/beat2.aiff b/games/guitar/sounds/beat2.aiff deleted file mode 100644 index 33069d4..0000000 --- a/games/guitar/sounds/beat2.aiff +++ /dev/null Binary files differ diff --git a/games/guitar/sounds/beat3.aiff b/games/guitar/sounds/beat3.aiff deleted file mode 100644 index 3c22de6..0000000 --- a/games/guitar/sounds/beat3.aiff +++ /dev/null Binary files differ diff --git a/games/guitar/sounds/beat4.aiff b/games/guitar/sounds/beat4.aiff deleted file mode 100644 index 1c2fe08..0000000 --- a/games/guitar/sounds/beat4.aiff +++ /dev/null Binary files differ diff --git a/games/guitar/sounds/beat6_2.aiff b/games/guitar/sounds/beat6_2.aiff deleted file mode 100644 index 911e630..0000000 --- a/games/guitar/sounds/beat6_2.aiff +++ /dev/null Binary files differ diff --git a/games/guitar/sounds/beat8.aiff b/games/guitar/sounds/beat8.aiff deleted file mode 100644 index fa85017..0000000 --- a/games/guitar/sounds/beat8.aiff +++ /dev/null Binary files differ diff --git a/games/guitar/sounds/bending_a.aiff b/games/guitar/sounds/bending_a.aiff deleted file mode 100644 index 661c67f..0000000 --- a/games/guitar/sounds/bending_a.aiff +++ /dev/null Binary files differ diff --git a/games/guitar/sounds/bending_b.aiff b/games/guitar/sounds/bending_b.aiff deleted file mode 100644 index ddbfb97..0000000 --- a/games/guitar/sounds/bending_b.aiff +++ /dev/null Binary files differ diff --git a/games/guitar/sounds/flashcomp2a.aiff b/games/guitar/sounds/flashcomp2a.aiff deleted file mode 100644 index 3b5f284..0000000 --- a/games/guitar/sounds/flashcomp2a.aiff +++ /dev/null Binary files differ diff --git a/games/guitar/sounds/flashcomp2b.aiff b/games/guitar/sounds/flashcomp2b.aiff deleted file mode 100644 index 0d7d14d..0000000 --- a/games/guitar/sounds/flashcomp2b.aiff +++ /dev/null Binary files differ diff --git a/games/guitar/sounds/flasholet4.aiff b/games/guitar/sounds/flasholet4.aiff deleted file mode 100644 index 0c4d56e..0000000 --- a/games/guitar/sounds/flasholet4.aiff +++ /dev/null Binary files differ diff --git a/games/guitar/sounds/gedaempft.aiff b/games/guitar/sounds/gedaempft.aiff deleted file mode 100644 index 0ede22e..0000000 --- a/games/guitar/sounds/gedaempft.aiff +++ /dev/null Binary files differ diff --git a/games/guitar/sounds/git_hit1.aiff b/games/guitar/sounds/git_hit1.aiff deleted file mode 100644 index ac7a33e..0000000 --- a/games/guitar/sounds/git_hit1.aiff +++ /dev/null Binary files differ diff --git a/games/guitar/sounds/git_hit4.aiff b/games/guitar/sounds/git_hit4.aiff deleted file mode 100644 index 528d843..0000000 --- a/games/guitar/sounds/git_hit4.aiff +++ /dev/null Binary files differ diff --git a/games/guitar/sounds/guitcello.aiff b/games/guitar/sounds/guitcello.aiff deleted file mode 100644 index 0d5c90b..0000000 --- a/games/guitar/sounds/guitcello.aiff +++ /dev/null Binary files differ diff --git a/games/guitar/sounds/jimi1.aiff b/games/guitar/sounds/jimi1.aiff deleted file mode 100644 index 94c50e4..0000000 --- a/games/guitar/sounds/jimi1.aiff +++ /dev/null Binary files differ diff --git a/games/guitar/sounds/jimi4.aiff b/games/guitar/sounds/jimi4.aiff deleted file mode 100644 index a70611a..0000000 --- a/games/guitar/sounds/jimi4.aiff +++ /dev/null Binary files differ diff --git a/games/guitar/sounds/ungedaempft.aiff b/games/guitar/sounds/ungedaempft.aiff deleted file mode 100644 index d9e5d7c..0000000 --- a/games/guitar/sounds/ungedaempft.aiff +++ /dev/null Binary files differ diff --git a/images/black.png b/images/black.png index 987b088..5fdc7f7 100644 --- a/images/black.png +++ b/images/black.png Binary files differ diff --git a/infopanel.py b/infopanel.py new file mode 100644 index 0000000..95defa6 --- /dev/null +++ b/infopanel.py @@ -0,0 +1,20 @@ +import hippo +import pango +from sugar.graphics import color + +class InfoPanel(hippo.CanvasBox): + def __init__(self): + hippo.CanvasBox.__init__(self, spacing=4, padding=5, + orientation=hippo.ORIENTATION_VERTICAL) + self.status_box = hippo.CanvasBox(spacing=4, padding=5, + orientation=hippo.ORIENTATION_VERTICAL) + self.append(self.status_box) + + def show(self, text): + textwidget = hippo.CanvasText(text=text, + font_desc=pango.FontDescription('Sans 16'), + color=color.WHITE.get_int(), + xalign=hippo.ALIGNMENT_CENTER) + self.status_box.remove_all() + self.status_box.append(textwidget) + diff --git a/memosono.dtd b/memosono.dtd index bd46b94..713c779 100644 --- a/memosono.dtd +++ b/memosono.dtd @@ -7,8 +7,9 @@ diff --git a/memosono.py b/memosono.py deleted file mode 100755 index 9912590..0000000 --- a/memosono.py +++ /dev/null @@ -1,610 +0,0 @@ -#! /usr/bin/env python -# -# Copyright (C) 2006 Simon Schampijer -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# - - -import gobject -import gtk, pygtk -import os -import socket -import logging -import random -import copy -import time -import errno -import gc - -from sugar.activity import activity - -from osc.oscapi import OscApi -from csound.csoundserver import CsoundServer - - -class Server: - def __init__(self, _MEMO, port): - - isserver = 0 - while isserver == 0: - self.port = port - self.oscapi = OscApi(self.port) - isserver = self.oscapi.isserver - port+=1 - - logging.debug(" Memosono-Server has port "+str(self.port) ) - gobject.io_add_watch(self.oscapi.iosock, gobject.IO_IN, self._handle_query) - self.oscapi.addmethod('/MEMO/tile', 'is', self._tile) - self.oscapi.addmethod('/MEMO/connect', 'i', self._connect) - self.compkey = '' - self.key = '' - self.tile = 0 - self.comtile = 0 - self.match = 0 - self.addresses = {} - self.addresses['eva'] = [] - self.addresses['simon'] = [] - self.players = ['eva', 'simon'] - self.currentplayer = 0 - self.lastplayer = 0 - self.numplayers = _MEMO['_NUM_PLAYERS'] - self.count = 0 - self.numpairs = _MEMO['_NUM_GRIDPOINTS']/2 - - def _handle_query(self, source, condition): - data, address = source.recvfrom(1024) - self.oscapi.handlemsg(data, address) - return True - -# OSC-METHODS: - def _connect(self, *msg): - self.addresses['eva'] = [msg[1][0], int(msg[1][1])] - self.addresses['simon'] = [msg[1][0], int(msg[1][1])+1] - - def _tile(self, *msg): - self.tile = msg[0][2] - self.key = msg[0][3] - - # send to other machines - for i in self.addresses: - if msg[1][0] == self.addresses[i][0]: - if msg[1][1] != self.addresses[i][1]: - self.oscapi.send((self.addresses[i][0], self.addresses[i][1]), "/MEMO/tile", - [self.tile, self.key]) - else: - ## logging.debug(" Send the stuff ") - self.oscapi.send((self.addresses[i][0], self.addresses[i][1]), "/MEMO/tile", - [self.tile, self.key]) - # match - if self.compkey != '': - if self.compkey == self.key: - ## logging.debug(" Key matches ") - self.match = 1 - self.count += 1 - else: - ## logging.debug(" Key does NOT match ") - self.match = 0 - self.lastplayer = self.currentplayer - if self.match == 0: - if self.currentplayer == self.numplayers-1 : - self.currentplayer = 0 - else: - self.currentplayer+=1 - i = 0 - for i in self.addresses: - self.oscapi.send((self.addresses[i][0], self.addresses[i][1]),"/MEMO/game/next", - [self.players[self.currentplayer], - self.players[self.lastplayer]]) - i = 0 - for i in self.addresses: - self.oscapi.send((self.addresses[i][0], self.addresses[i][1]), "/MEMO/game/match", - [self.match, self.players[self.lastplayer], - self.comtile, self.tile, self.count/self.numpairs]) - self.compkey = '' - self.comptile = 0 - else: - self.compkey = self.key - self.comtile = self.tile - - - -class Controler(gobject.GObject): - __gsignals__ = { - 'fliptile': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT])), - 'game': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])), - 'updatepointsc': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])), - 'nextc': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT])), - 'addplayer': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])), - 'gameinit': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT])), - 'tileflippedc': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT])), - } - def __init__(self, _MEMO, port): - gobject.GObject.__init__(self) - self._MEMO = _MEMO - self.sound = 1 - self.replyaddr = (('127.0.0.1', port)) - self.serveraddr = (('127.0.0.1', port)) - port+=1 - # OSC-communication - isserver = 0 - while isserver == 0: - self.port = port - self.oscapi = OscApi(self.port) - isserver = self.oscapi.isserver - port+=1 - - logging.debug(" Memosono-Client has port "+str(self.port) ) - self.oscapi.send((self.serveraddr[0], self.serveraddr[1]), "/MEMO/connect", [self.port]) - gobject.io_add_watch(self.oscapi.iosock, gobject.IO_IN, self._handle_query) - self.oscapi.addmethod('/MEMO/addplayer', '', self._addplayer) - self.oscapi.addmethod('/MEMO/init', 'sis', self._game_init) - self.oscapi.addmethod('/MEMO/tile', 'i', self._tile) - self.oscapi.addmethod('/MEMO/game/match', 'isiii', self._game_match) - self.oscapi.addmethod('/MEMO/game/next', 'ss', self._game_next) - self.oscapi.addmethod('/CSOUND/ping', '', self._ping) - self.block = 0 - self.count = 0 - - - # CSOUND-communication - self.id = 0 ##FIXME give a significant number - - def csconnect(self): - self.oscapi.send(('127.0.0.1', 6783), "/CSOUND/connect", []) - - def init_game(self, playername, numplayers, gamename): - self.emit('gameinit', playername, numplayers, gamename) - - def _handle_query(self, source, condition): - data, self.replyaddr = source.recvfrom(1024) - self.oscapi.handlemsg(data, self.replyaddr) - return True - -# SLOTS: - def _user_input(self, widget, tile_number): - #if not self.block: - # self.count+=1 - self.emit('fliptile', tile_number, 0, self.block) - #if self.count == 2: - # self.block = 1 - # self.count = 0 - return False - - def _tile_flipped(self, model, tile_number, pic, sound, requesttype, chosen_flag): - if chosen_flag == 1: - self.emit('game', 'Chosen already!') - else: - logging.debug("tile_number: "+str(tile_number)+" pic: "+pic+" sound: "+sound) - logging.debug("count: "+str(self.count)+" self.block: "+str(self.block)) - if not self.block: - if requesttype is not 2: - self.count+=1 - - if sound is not '-1': - self.emit('tileflippedc', tile_number, pic, sound) - if self.sound is 1: - if os.path.exists(os.path.join(self._MEMO['_DIR_GSOUNDS'],sound)): - file = os.path.join(self._MEMO['_DIR_GSOUNDS'],sound) - self.oscapi.send(('127.0.0.1', 6783), '/CSOUND/perform', ['i 108 0.0 3.0 "%s" 1 0.7 0.5 0'%file]) - logging.debug(" Read file: "+os.path.join(self._MEMO['_DIR_GSOUNDS'],sound)) - else: - logging.error(" Can not read file: "+os.path.join(self._MEMO['_DIR_GSOUNDS'],sound)) - - if requesttype == 0: - logging.debug(" send to server ") - self.oscapi.send((self.serveraddr[0], self.serveraddr[1]), "/MEMO/tile", [tile_number, pic]) - if self.count == 2: - self.block = 1 - self.count = 0 - - return False - -# OSC-METHODS: - def _addplayer(self, *msg): - logging.debug(" Addplayer ") - - def _game_init(self, *msg): - self.init_game(msg[0][2], msg[0][3], msg[0][4]) - - def _tile(self, *msg): - self.emit('fliptile', msg[0][2], 1, self.block) - - def _game_next(self, *msg): - logging.debug("next please --- self.block: "+str(self.block)) - gobject.timeout_add(3000, self._game_next_delayed, msg[0][2], msg[0][3]) - - def _game_next_delayed(self, player, lastplayer): - self.block = 0 - logging.debug("next-delayed please --- self.block: "+str(self.block)) - self.emit('nextc', player, lastplayer) - return False - - def _game_match(self, *msg): - # flag_match, playername, tile1, tile2 - logging.debug(msg) - if msg[0][2] == 1: - # update points - self.block = 0 - self.emit('updatepointsc', msg[0][3]) - if msg[0][6] != 1: - self.emit('game', 'Match!') - else: - logging.debug("end") - self.block = 1 - self.emit('game', 'The end') - else: - requesttype = 2 # 0:normal, 1:setback - self.emit('game', 'Pairs do not match!') - self.emit('fliptile', int(msg[0][4]), requesttype, self.block) - self.emit('fliptile', int(msg[0][5]), requesttype, self.block) - - def _ping(self, *msg): - self.oscapi.send(msg[1], '/CSOUND/pong', []) - - -class Model(gobject.GObject): - __gsignals__ = { - 'tileflipped': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, - gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT])), - 'nextm': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, - gobject.TYPE_PYOBJECT])), - 'updatepointsm': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT])), - } - def __init__(self, grid): - gobject.GObject.__init__(self) - # tile - key=id, pic, sound, flag_flipped - self.tileg = [] - i = 0 - for elem in grid: - self.tileg.append(elem) - i+=1 - # player - key=name, picture, tiles_won, scores - self.player = {} - self.player['eva'] = [0, ['player1_0.jpg', 'player1_0b.jpg'],['player1_1.jpg', 'player1_1b.jpg'], - ['player1_2.jpg', 'player1_2b.jpg'],['player2_3.jpg', 'player2_3b.jpg'], - ['player1_4.jpg', 'player1_4b.jpg'],['player1_5.jpg', 'player1_5b.jpg'], - ['player1_6.jpg', 'player1_6b.jpg'],['player1_7.jpg', 'player1_7b.jpg'], - ['player1_8.jpg', 'player1_8b.jpg'],['player1_9.jpg', 'player1_9b.jpg'], - ['player1_10.jpg', 'player1_10b.jpg'],['player1_11.jpg', 'player1_11b.jpg'], - ['player1_12.jpg', 'player1_12b.jpg'],['player1_13.jpg', 'player1_13b.jpg'], - ['player1_14.jpg', 'player1_14b.jpg'],['player1_15.jpg', 'player1_15b.jpg'], - ['player1_16.jpg', 'player1_16b.jpg'],['player1_17.jpg', 'player1_17b.jpg'], - ['player1_18.jpg', 'player1_18b.jpg']] - - self.player['simon'] = [0, ['player2_0.jpg', 'player2_0b.jpg'],['player2_1.jpg', 'player2_1b.jpg'], - ['player2_2.jpg', 'player2_2b.jpg'],['player2_3.jpg', 'player2_3b.jpg'], - ['player2_4.jpg', 'player2_4b.jpg'],['player2_5.jpg', 'player2_5b.jpg'], - ['player2_6.jpg', 'player2_6b.jpg'],['player2_7.jpg', 'player2_7b.jpg'], - ['player2_8.jpg', 'player2_8b.jpg'],['player2_9.jpg', 'player2_9b.jpg'], - ['player2_10.jpg', 'player2_10b.jpg'],['player2_11.jpg', 'player2_11b.jpg'], - ['player2_12.jpg', 'player2_12b.jpg'],['player2_13.jpg', 'player2_13b.jpg'], - ['player2_14.jpg', 'player2_14b.jpg'],['player2_15.jpg', 'player2_15b.jpg'], - ['player2_16.jpg', 'player2_16b.jpg'],['player2_17.jpg', 'player2_17b.jpg'], - ['player2_18.jpg', 'player2_18b.jpg']] - # game - self.numplayers = 2 - -# SLOTS: - def _game_init(self, controler, playername, numplayers, gamename): - ## logging.debug(" gameinit ") - return False - def _add_player(): - ## logging.debug(" addplayer ") - return False - - def _flip_tile(self, controler, tile_number, requesttype, blocked): - if requesttype == 0 or requesttype == 1: - if self.tileg[tile_number][2] == 0: # !!FIX - better switch - if not blocked: - self.tileg[tile_number][2] = 1 - # --->view: number, pic, sound, requesttype, chosen - self.emit('tileflipped', tile_number, self.tileg[tile_number][0], - self.tileg[tile_number][1], requesttype,0) - else: - self.emit('tileflipped', tile_number, self.tileg[tile_number][0], - self.tileg[tile_number][1], requesttype,1) - else: - # set tilestate back - # self.tileg[tile_number][2] = 0 - gobject.timeout_add(3000, self._reset, tile_number, requesttype) - return False - - def _reset(self, tile_number, requesttype): - self.tileg[tile_number][2] = 0 - self.emit('tileflipped', tile_number, '-1', '-1', requesttype, 0) - return False - - def _next(self, controler, player, lastplayer ): - count1 = self.player[player][0] - count2 = self.player[lastplayer][0] - self.emit('nextm', player, self.player[player][count1+1][1], lastplayer,self.player[lastplayer][count2+1][0]) - - def _updatepoints(self, controler, player): - self.player[player][0] += 1 - pic_id = self.player[player][0] - self.emit('updatepointsm', player, self.player[player][pic_id+1][1]) - -class View: - def __init__(self, controler, memosonoactivity, _MEMO): - self._MEMO = _MEMO - self.row1 = gtk.HBox(False, 0) - # create the grid - self.imageObj = [] - self.buttonObj = [] - # create the players - self.p_imageObj = {} - self.p_fixedObj = {} - -# SLOTS: - def _game_init(self, controler, playername, numplayers, gamename): - # Create a table for the grid - self.num_elem_x = 6 - self.num_elem_y = 6 - self.table = gtk.Table(self.num_elem_y, self.num_elem_x, True) - self.row1.pack_start(self.table) - - # scale black - self.scale_x = 120 - self.scale_y = 120 - pixbuf_i = gtk.gdk.pixbuf_new_from_file(os.path.join(self._MEMO['_DIR_IMAGES'],"black80.jpg")) - self.scaledbuf_i = pixbuf_i.scale_simple(self.scale_x, self.scale_y, gtk.gdk.INTERP_BILINEAR) - - ### fix to release the memory allocated by the pixbuf call - del pixbuf_i - gc.collect() - - self.y = 0 - self.x = 0 - i = 0 - while(self.y < self.num_elem_y): - while(self.x < self.num_elem_x): - self.imageObj.append(gtk.Image()) - self.imageObj[i].set_from_pixbuf(self.scaledbuf_i) - self.imageObj[i].show() - self.buttonObj.append(gtk.Button()) - self.buttonObj[i].add(self.imageObj[i]) - self.table.attach(self.buttonObj[i], self.x, self.x+1, self.y, self.y+1) - self.x+=1 - i+=1 - self.x=0 - self.y+=1 - - # Players - self.pscale_x = 200 - self.pscale_y = 200 - self.downbox = gtk.HBox(False, 0) - self.playerbox = gtk.VBox(False, 0) - self.p1 = 'eva' - self.p2 = 'simon' - self.p_imageObj[self.p1] = gtk.Image() - self.p_imageObj[self.p1].set_from_pixbuf(self.pixbuf("player1_0b.jpg",0, self.pscale_x, self.pscale_y)) - self.p_fixedObj[self.p1] = gtk.Fixed() - self.p_fixedObj[self.p1].set_size_request(self.pscale_x, self.pscale_y) - self.p_fixedObj[self.p1].add(self.p_imageObj[self.p1]) - self.playerbox.pack_start(self.p_fixedObj[self.p1]) - - self.p_imageObj[self.p2] = gtk.Image() - self.p_imageObj[self.p2].set_from_pixbuf(self.pixbuf("player2_0.jpg",0, self.pscale_x, self.pscale_y)) - self.p_fixedObj[self.p2] = gtk.Fixed() - self.p_fixedObj[self.p2].set_size_request(self.pscale_x, self.pscale_y) - self.p_fixedObj[self.p2].add(self.p_imageObj[self.p2]) - self.playerbox.pack_start(self.p_fixedObj[self.p2]) - - self.downbox.pack_start(self.playerbox) - self.row1.pack_start(self.downbox) - self.row1.show_all() - return False - - def pixbuf(self, filename, pictype, pscale_x, pscale_y): - if pictype is 1: - ppixbuf_i = gtk.gdk.pixbuf_new_from_file(os.path.join(self._MEMO['_DIR_GIMAGES'],filename)) - if pictype is 0: - ppixbuf_i = gtk.gdk.pixbuf_new_from_file(os.path.join(self._MEMO['_DIR_IMAGES'],filename)) - - pscaledbuf_i = ppixbuf_i.scale_simple(pscale_x, pscale_y, gtk.gdk.INTERP_BILINEAR) - - ### fix to release the memory allocated by the pixbuf call - del ppixbuf_i - gc.collect() - - return pscaledbuf_i - - def _next(self, controler, playername, filename, lastplayer, lastfilename): - self.p_imageObj[playername].set_from_pixbuf(self.pixbuf(filename, 0, self.pscale_x, self.pscale_y)) - self.p_imageObj[lastplayer].set_from_pixbuf(self.pixbuf(lastfilename, 0, self.pscale_x, self.pscale_y)) - return False - - def _updatepoints(self, controler, playername, pic): - self.p_imageObj[playername].set_from_pixbuf(self.pixbuf(pic, 0, self.pscale_x, self.pscale_y)) - return False - - def _tile_flipped(self, model, tile_number, pic, sound): - if pic == "-1": - self.imageObj[tile_number].set_from_pixbuf(self.pixbuf("black80.jpg", 0, self.scale_x, self.scale_y)) - else: - self.imageObj[tile_number].set_from_pixbuf(self.pixbuf(pic, 1, self.scale_x, self.scale_y)) - return False - - def _game(self, controler, string): - return False - - -def read_config(filename, seed, numelems): - temp = [] - grid = [] - # set random seed - random.seed(seed) - filecheck = filename.split('.') - if filecheck[2] != 'mson': - logging.error(' File format of %s'%filename) - ## sys.exit() - else: - fd = open(filename, 'r') - if fd == None: - logging.error(' Reading setup file %s'%filename) - ## sys.exit() - else: - logging.info(' Read setup for memosono from file %s'%filename) - line = fd.readline() - while line: - zw = line.split() - zw.append(0) - if len(zw) is not 0: - temp.append(zw) - line = fd.readline() - fd.close() - # select randomly numelems of the list - grid = random.sample(temp, numelems) - # make a complete deepcopy of the list - # and concatenate it at the end grid.extend() - tm = copy.deepcopy(grid) - grid.extend(tm) - # shuffle th grid elements - random.shuffle(grid) - return grid - - -def pathes(filename): - # read config file - path = [] - gamename = filename - home = os.path.join(os.path.dirname(os.path.abspath(__file__)), "games") - gamepath = os.path.join(home, gamename) - logging.debug(gamepath) - if not os.path.exists(gamepath): - logging.error(" Game path does NOT exist in the home folder ") - else: - logging.debug(" Game path exist in the home folder ") - configpath = os.path.join(gamepath, filename+".mson") - if not os.path.exists(configpath): - logging.error(" Config file does NOT exist: "+configpath) - logging.error(" Did you name it correct, ending with .mson? ") - #sys.exit() ##FIXME - else: - path.append(configpath) - logging.debug(" Config file is placed in the folder ") - imagespath = os.path.join(gamepath, "images") - soundspath = os.path.join(gamepath, "sounds") - if os.path.exists(imagespath): - logging.debug(" Set path for images: "+imagespath) - path.append(imagespath) - else: - logging.error(" Path to images does NOT exist ") - #sys.exit() ##FIXME - if os.path.exists(soundspath): - logging.debug(" Set path for sounds: "+soundspath) - path.append(soundspath) - else: - logging.error(" Path to images does NOT exist ") - #sys.exit() ##FIXME - return path - - -class MemosonoActivity(activity.Activity): - def __init__(self, handle): - activity.Activity.__init__(self, handle) - self.connect('destroy', self._cleanup_cb) - - self.gamename = 'drumgit' - self.set_title("Memosono - "+self.gamename) - logging.debug(" ---------------------Memosono start-----------------------. ") - - # set path - _MEMO = {} - _MEMO['_DIR_CSSERVER'] = os.path.join(os.path.dirname(__file__), "csserver") - _MEMO['_DIR_IMAGES'] = os.path.join(os.path.dirname(__file__), "images") - logging.error( os.path.dirname('.') ) - _MEMO['_DIR_SOUNDS'] = os.path.join(os.path.dirname(__file__), "sounds") - path = pathes(self.gamename) - _MEMO['_DIR_GIMAGES'] = path[1] - _MEMO['_DIR_GSOUNDS'] = path[2] - # read config - seed = random.randint(0, 14567) - _MEMO['_NUM_GRIDPOINTS'] = 36 - _MEMO['_NUM_ELEMS'] = 18 - grid = read_config(path[0], seed, _MEMO['_NUM_ELEMS']) - - _MEMO['_NUM_PLAYERS'] = 2 - name_creator = 'eva' - - self.server = Server(_MEMO, 7000) - self.controler = Controler(_MEMO, self.server.port) - - self.model = Model(grid) - self.view = View(self.controler, self, _MEMO) - self.set_canvas(self.view.row1) - -# SLOTS connections: - self.model.connect('tileflipped', self.controler._tile_flipped) - self.controler.connect('tileflippedc', self.view._tile_flipped) - self.controler.connect('fliptile', self.model._flip_tile) - self.controler.connect('addplayer', self.model._add_player) - self.controler.connect('gameinit', self.model._game_init) - self.controler.connect('gameinit', self.view._game_init) - self.controler.connect('game', self.view._game) - self.controler.connect('nextc', self.model._next) - self.model.connect('nextm', self.view._next) - self.controler.connect('updatepointsc', self.model._updatepoints) - self.model.connect('updatepointsm', self.view._updatepoints) - # connect to the in/out events of the memosono activity - self.connect('focus_in_event', self._focus_in) - self.connect('focus_out_event', self._focus_out) - - - self.controler.init_game(name_creator, _MEMO['_NUM_PLAYERS'], self.gamename) - i = 0 - while(i < _MEMO['_NUM_GRIDPOINTS']): - self.view.buttonObj[i].connect('clicked', self.controler._user_input, i) - i+=1 - - ### start csound server - self.cs = CsoundServer() - gtk.gdk.threads_init() - self.controler.csconnect() - - def _cleanup_cb(self, data=None): - self.controler.oscapi.send(('127.0.0.1', 6783), "/CSOUND/quit", []) - self.controler.oscapi.iosock.close() - self.server.oscapi.iosock.close() - logging.debug(" Closed OSC sockets ") - - def _focus_in(self, event, data=None): - logging.debug(" Memosono is visible: Connect to the Csound-Server. ") - self.controler.oscapi.send(('127.0.0.1', 6783), "/CSOUND/connect", []) - - def _focus_out(self, event, data=None): - logging.debug(" Memosono is invisible: Close the connection to the Csound-Server. ") - self.controler.oscapi.send(('127.0.0.1', 6783), "/CSOUND/disconnect", []) diff --git a/memosonoactivity.py b/memosonoactivity.py index ffb3610..48783c9 100755 --- a/memosonoactivity.py +++ b/memosonoactivity.py @@ -1,6 +1,6 @@ #! /usr/bin/env python # -# Copyright (C) 2006 Simon Schampijer +# Copyright (C) 2006, 2007 Simon Schampijer # # 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 @@ -23,64 +23,90 @@ import gobject import gtk import os import logging -import dbus import telepathy import telepathy.client +import hippo from sugar.activity.activity import Activity from sugar.activity.activity import ActivityToolbox from sugar.presence import presenceservice -from osc.oscapi import OscApi -from csound.csoundserver import CsoundServer -from selectview import SelectView +from tubeconn import TubeConnection from playview import PlayView -from toolbar import PlayToolbar -from model import Game +from buddiespanel import BuddiesPanel +from infopanel import InfoPanel +from controller import Controller +_logger = logging.getLogger('activity') + class MemosonoActivity(Activity): def __init__(self, handle): Activity.__init__(self, handle) - self.set_title ("Memosono") - self.sv = None - self.pv = None + _logger.debug('Starting Memosono activity...') + + self.set_title(_('Memsosono Activity')) + + w = self.get_screen().get_width() + h = self.get_screen().get_height() + ### FIXME: do better grid calculation + if w <= 1024: + self.pv = PlayView(600, 600, 32) + else: + self.pv = PlayView(800, 800, 32) + + self.buddies_panel = BuddiesPanel() + + self.info_panel = InfoPanel() + + vbox = hippo.CanvasBox(spacing=4, + orientation=hippo.ORIENTATION_VERTICAL) + + hbox = hippo.CanvasBox(spacing=4, + orientation=hippo.ORIENTATION_HORIZONTAL) + + hbox.append(self.buddies_panel) + hbox.append(self.pv, hippo.PACK_EXPAND) + + vbox.append(hbox, hippo.PACK_EXPAND) + vbox.append(self.info_panel, hippo.PACK_END) + + canvas = hippo.Canvas() + canvas.set_root(vbox) + self.set_canvas(canvas) + self.show_all() + toolbox = ActivityToolbox(self) self.set_toolbox(toolbox) toolbox.show() - toolbox._notebook.connect('switch-page', self._switch_page) - - self.play_toolbar = PlayToolbar(self) - toolbox.add_toolbar(_('Play'), self.play_toolbar) - self.play_toolbar.show() - - self.games = {} - - os.path.walk(os.path.join(os.path.dirname(__file__), 'games'), self._find_games, None) - - gamelist = self.games.keys() - gamelist.sort() - logging.debug(gamelist) - self.pv = PlayView(None, self.games[gamelist[0]].pairs) - self.pv.show() - self.sv = SelectView(gamelist) - self.sv.connect('entry-selected', self._entry_selected_cb) - self.sv.show() - + self.pservice = presenceservice.get_instance() - self.owner = self.pservice.get_owner() - bus = dbus.Bus() name, path = self.pservice.get_preferred_connection() self.tp_conn_name = name self.tp_conn_path = path self.conn = telepathy.client.Connection(name, path) self.initiating = None - self.game = None + + self.ctrl = None + + toolbox = ActivityToolbox(self) + self.set_toolbox(toolbox) + toolbox.show() + + # connect to the in/out events of the memosono activity + self.connect('focus_in_event', self._focus_in) + self.connect('focus_out_event', self._focus_out) + self.connect('destroy', self._cleanup_cb) + self.info_panel.show('To play, share!') + self.connect('shared', self._shared_cb) + owner = self.pservice.get_owner() + self.owner = owner + if self._shared_activity: # we are joining the activity self.buddies_panel.add_watcher(owner) @@ -92,31 +118,54 @@ class MemosonoActivity(Activity): self._joined_cb() else: # we are creating the activity - self.pv.buddies_panel .add_player(self.owner) + self.buddies_panel.add_player(owner) + + def _get_buddy(self, cs_handle): + """Get a Buddy from a channel specific handle.""" + _logger.debug('Trying to find owner of handle %u...', cs_handle) + group = self.text_chan[telepathy.CHANNEL_INTERFACE_GROUP] + my_csh = group.GetSelfHandle() + _logger.debug('My handle in that group is %u', my_csh) + if my_csh == cs_handle: + handle = self.conn.GetSelfHandle() + _logger.debug('CS handle %u belongs to me, %u', cs_handle, handle) + elif group.GetGroupFlags() & telepathy.CHANNEL_GROUP_FLAG_CHANNEL_SPECIFIC_HANDLES: + handle = group.GetHandleOwners([cs_handle])[0] + _logger.debug('CS handle %u belongs to %u', cs_handle, handle) + else: + handle = cs_handle + _logger.debug('non-CS handle %u belongs to itself', handle) + # XXX: deal with failure to get the handle owner + assert handle != 0 + + # XXX: we're assuming that we have Buddy objects for all contacts - + # this might break when the server becomes scalable. + return self.pservice.get_buddy_by_telepathy_handle(self.tp_conn_name, + self.tp_conn_path, handle) def _shared_cb(self, activity): - logging.debug('My Memosono activity was shared') + _logger.debug('My Memosono activity was shared') self.initiating = True self._setup() for buddy in self._shared_activity.get_joined_buddies(): - self.pv.buddies_panel.add_watcher(buddy) + self.buddies_panel.add_watcher(buddy) self._shared_activity.connect('buddy-joined', self._buddy_joined_cb) self._shared_activity.connect('buddy-left', self._buddy_left_cb) - logging.debug('This is my activity: making a tube...') + _logger.debug('This is my activity: making a tube...') id = self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].OfferTube( telepathy.TUBE_TYPE_DBUS, 'org.fredektop.Telepathy.Tube.Memosono', {}) - logging.debug('Tube address: %s', self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].GetDBusServerAddress(id)) - logging.debug('Waiting for another player to join') + _logger.debug('Tube address: %s', self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].GetDBusServerAddress(id)) + self.info_panel.show('Waiting for another player to join') # FIXME: presence service should be tubes-aware and give us more help # with this def _setup(self): if self._shared_activity is None: - logging.error('Failed to share or join activity') + _logger.error('Failed to share or join activity') return bus_name, conn_path, channel_paths = self._shared_activity.get_channels() @@ -129,27 +178,27 @@ class MemosonoActivity(Activity): channel = telepathy.client.Channel(bus_name, channel_path) htype, handle = channel.GetHandle() if htype == telepathy.HANDLE_TYPE_ROOM: - logging.debug('Found our room: it has handle#%d "%s"', + _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: - logging.debug('Found our Tubes channel at %s', channel_path) + _logger.debug('Found our Tubes channel at %s', channel_path) tubes_chan = channel elif ctype == telepathy.CHANNEL_TYPE_TEXT: - logging.debug('Found our Text channel at %s', channel_path) + _logger.debug('Found our Text channel at %s', channel_path) text_chan = channel if room is None: - logging.error("Presence service didn't create a room") + _logger.error("Presence service didn't create a room") return if text_chan is None: - logging.error("Presence service didn't create a text channel") + _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: - logging.debug("Didn't find our Tubes channel, requesting one...") + _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) @@ -164,34 +213,34 @@ class MemosonoActivity(Activity): self._new_tube_cb(*tube_info) def _list_tubes_error_cb(self, e): - logging.error('ListTubes() failed: %s', e) + _logger.error('ListTubes() failed: %s', e) def _joined_cb(self, activity): - if self.game is not None: + if self.ctrl is not None: return if not self._shared_activity: return for buddy in self._shared_activity.get_joined_buddies(): - self.pv.buddies_panel.add_watcher(buddy) + self.buddies_panel.add_watcher(buddy) - logging.debug('Joined an existing Connect game') - logging.debug('Joined a game. Waiting for my turn...') + _logger.debug('Joined an existing Memosono game') + self.info_panel.show('Joined a game. Waiting for my turn...') self.initiating = False self._setup() - logging.debug('This is not my activity: waiting for a tube...') + _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): - logging.debug('New tube: ID=%d initator=%d type=%d service=%s ' + _logger.debug('New tube: ID=%d initator=%d type=%d service=%s ' 'params=%r state=%d', id, initiator, type, service, params, state) - if (self.game is None and type == telepathy.TUBE_TYPE_DBUS and + if (self.ctrl is None and type == telepathy.TUBE_TYPE_DBUS and service == 'org.fredektop.Telepathy.Tube.Memosono'): if state == telepathy.TUBE_STATE_LOCAL_PENDING: self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].AcceptTube(id) @@ -199,50 +248,43 @@ class MemosonoActivity(Activity): tube_conn = TubeConnection(self.conn, self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES], id, group_iface=self.text_chan[telepathy.CHANNEL_INTERFACE_GROUP]) - self.game = ConnectGame(tube_conn, self.grid, self.initiating, - self.pv.buddies_panel, self.info_panel, self.owner, + self.ctrl = Controller(tube_conn, self.pv, self.initiating, + self.buddies_panel, self.info_panel, self.owner, self._get_buddy, self) - def _buddy_joined_cb (self, activity, buddy): - logging.debug('buddy joined') - self.pv.buddies_panel.add_watcher(buddy) + def _buddy_joined_cb(self, activity, buddy): + _logger.debug('buddy joined') + self.buddies_panel.add_watcher(buddy) + + def _buddy_left_cb(self, activity, buddy): + _logger.debug('buddy left') + self.buddies_panel.remove_watcher(buddy) + + def write_file(self, file_path): + """Store game state in Journal. + + Handling the Journal is provided by Activity - we only need + to define this method. + """ + _logger.debug(" Write game state. ") + f = open(file_path, 'w') + try: + f.write('erikos won the game') + finally: + f.close() - def _buddy_left_cb (self, activity, buddy): - logging.debug('buddy left') - self.pv.buddies_panel.remove_watcher(buddy) - - - def _find_games(self, arg, dirname, names): - for name in names: - if name.endswith('.mson'): - game = Game(dirname, os.path.dirname(__file__)) - game.read(name) - self.games[name.split('.mson')[0]] = game - - def _entry_selected_cb(self, list_view, entry): - self.pv = PlayView(None, self.games[entry.name].pairs) - self.pv.show() - - def _switch_page(self, notebook, page, page_num, user_param1=None): - if page_num == 1: - self.set_canvas(self.pv) - elif page_num == 0: - if self.sv != None: - self.set_canvas(self.sv) - - def _cleanup_cb(self, data=None): - pass - #self.controler.oscapi.send(('127.0.0.1', 6783), "/CSOUND/quit", []) - #self.controler.oscapi.iosock.close() - #self.server.oscapi.iosock.close() - #logging.debug(" Closed OSC sockets ") - def _focus_in(self, event, data=None): - pass - #logging.debug(" Memosono is visible: Connect to the Csound-Server. ") - #self.controler.oscapi.send(('127.0.0.1', 6783), "/CSOUND/connect", []) + if self.ctrl != None: + self.ctrl.cs.start() + _logger.debug(" Memosono is visible: start csound server. ") def _focus_out(self, event, data=None): - pass - #logging.debug(" Memosono is invisible: Close the connection to the Csound-Server. ") - #self.controler.oscapi.send(('127.0.0.1', 6783), "/CSOUND/disconnect", []) + if self.ctrl != None: + self.ctrl.cs.start() + _logger.debug(" Memosono is invisible: pause csound server. ") + + def _cleanup_cb(self, data=None): + if self.ctrl != None: + self.ctrl.cs.quit() + _logger.debug(" Memosono closes: close csound server. ") + diff --git a/model.py b/model.py index 723e27c..bb7870a 100644 --- a/model.py +++ b/model.py @@ -1,22 +1,89 @@ import libxml2 import os import logging +import random +import gobject -class Game(object): +IMAGES_PATH = 'games/drumgit/images' +GAME_PATH = 'games/drumgit' + +_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), + 'bimg' : (str, None, None, None, gobject.PARAM_READWRITE), + 'bsnd' : (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, 'bimg':None, 'bsnd':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 == "bimg": + return self._properties["bimg"] + elif pspec.name == "bsnd": + return self._properties["bsnd"] + 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 == "bimg": + self._properties["bimg"] = value + elif name == "bsnd": + self._properties["bsnd"] = value + elif name == "color": + self._properties["color"] = int(value) + ''' + def do_set_property(self, props, value): + if props.name == 'a_img': + self._properties['a_img'] = value + ''' + +class Model(object): + ''' The model of the activity. Contains methods to read and save + the configuration for a game from xml. Stores the pairs and grid + information. + ''' def __init__(self, gamepath, dtdpath, name='noname'): self.name = name - self.pairs = {} self.gamepath = gamepath self.dtdpath = dtdpath - try: self.dtd = libxml2.parseDTD(None, os.path.join(self.dtdpath, 'memosono.dtd')) except libxml2.parserError, e: - logging.error('No memosono.dtd found ' +str(e)) + _logger.error('No memosono.dtd found ' +str(e)) self.dtd = None self.ctxt = libxml2.newValidCtxt() + + 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 + + def read(self, filename): + ''' reades the configuration from an xml file ''' try: doc = libxml2.parseFile(os.path.join(self.gamepath, filename)) if doc.validateDtd(self.ctxt, self.dtd): @@ -26,64 +93,91 @@ class Game(object): res = xpa.xpathEval("//*") # write their content to the data structure + self.idpair = 0 for elem in res: attributes = elem.get_properties() - pair = [] - idpair = '' + pair = Pair() for attribute in attributes: if(attribute.name == 'text'): pass - if(attribute.name == 'id'): - idpair = attribute.content - if(attribute.name == 'mother'): - pair.append(attribute.content) - if(attribute.name == 'child'): - pair.append(attribute.content) - if(attribute.name == 'color'): - pair.append(int(attribute.content)) - if( elem.name == 'memosono' ): - self.name = attribute.content - if( elem.name != 'memosono' ): - self.pairs[idpair] = pair + else: + pass + pair.set_property(attribute.name, attribute.content) + if( elem.name == 'pair' ): + self.pairs[self.idpair] = pair + self.idpair+=1 + elif( elem.name == 'memosono' ): + self.name = attribute.content + xpa.xpathFreeContext() else: - logging.error('Error in validation of the file') + _logger.error('Error in validation of the file') doc.freeDoc() except libxml2.parserError, e: - logging.error('Error parsing file ' +str(e)) + _logger.error('Error parsing file ' +str(e)) + def save(self, filename): + ''' saves the configuration to an xml file ''' doc = libxml2.newDoc("1.0") root = doc.newChild(None, "memosono", None) root.setProp("name", self.name) for key in self.pairs: elem = root.newChild(None, "pair", None) - elem.setProp("id", key) - elem.setProp("mother", self.pairs[key][0]) - elem.setProp("child", self.pairs[key][1]) - elem.setProp("color", self.pairs[key][2]) + 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.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) + elem.setProp("color", str(self.pairs[key].props.color)) if doc.validateDtd(self.ctxt, self.dtd): doc.saveFormatFile(filename, 1) doc.freeDoc() - -if __name__ == '__main__': - - print "[Read game from file] " - game = Game() - game.read('memosono.xml') - print " name=" + game.name - print " pairs=%s" %game.pairs - - elemkey = '0' - if game.pairs.has_key(elemkey): - del game.pairs[elemkey] - - game.pairs['2'] = ['frettchen.jpg', 'frettchen.wav'] - print "[Write game to file] " - game.save('memosono.xml') + + def def_grid(self): + ''' create the grid for the play from the pairs information + and shuffles the grid so they always appear in a different + place + ''' + _logger.debug(' pairs: %s', self.pairs) + for key in self.pairs.iterkeys(): + self.grid.append([key, 0, 0]) + self.grid.append([key, 1, 0]) + random.shuffle(self.grid) + _logger.debug(' grid: %s', self.grid) + + + def gettile(self, tilenum): + ''' gets the information of an object associated with a tile number ''' + pairkey, moch, state = self.grid[tilenum] + obj = os.path.join(IMAGES_PATH, self.pairs[pairkey][moch]) + color = self.pairs[pairkey][2] + return (obj, color) + + + def same(self, a, b): + ''' checks wether two tiles are matching ''' + pairkeya, moch, state = self.grid[a] + pairkeyb, moch, state = self.grid[b] + return (pairkeya == pairkeyb) + + +if __name__ == '__main__': + model = Model(GAME_PATH, os.path.dirname(__file__)) + model.read('drumgit.mson') + print '%s' %model.pairs[0].props.color + print '%s' %model.pairs[1]._properties + print '%s' %model.pairs[2]._properties + + model.def_grid() + print model.grid + #model.save('/tmp/mod.txt') diff --git a/playpoints.py b/playpoints.py deleted file mode 100644 index 84f1b3b..0000000 --- a/playpoints.py +++ /dev/null @@ -1,73 +0,0 @@ -import gtk -import hippo -import math -import os - -from sugar.graphics import font -from sugar.graphics import units - -class PlayPoints(hippo.CanvasBox, hippo.CanvasItem): - __gtype_name__ = 'PlayPoints' - _BORDER_DEFAULT = units.points_to_pixels(1.0) - - def __init__(self, name, **kargs): - hippo.CanvasBox.__init__(self, **kargs) - - self.image = os.path.join(os.path.dirname(__file__), 'images/black.png') - - self._radius = units.points_to_pixels(5) - self.props.border_color = 3520189183 - self.props.background_color = 3520189183 - self.props.orientation = hippo.ORIENTATION_VERTICAL - self.props.border = self._BORDER_DEFAULT - self.props.border_left = self._radius - self.props.border_right = self._radius - - self.append(self._build_title_box()) - playername = hippo.CanvasText(text=name, - xalign=hippo.ALIGNMENT_START, - font_desc=font.DEFAULT_BOLD.get_pango_desc(), - size_mode=hippo.CANVAS_SIZE_ELLIPSIZE_END) - self.append(playername) - - def do_paint_background(self, cr, damaged_box): - [width, height] = self.get_allocation() - - x = self._BORDER_DEFAULT / 2 - y = self._BORDER_DEFAULT / 2 - width -= self._BORDER_DEFAULT - height -= self._BORDER_DEFAULT - - cr.move_to(x + self._radius, y); - cr.arc(x + width - self._radius, y + self._radius, - self._radius, math.pi * 1.5, math.pi * 2); - cr.arc(x + width - self._radius, x + height - self._radius, - self._radius, 0, math.pi * 0.5); - cr.arc(x + self._radius, y + height - self._radius, - self._radius, math.pi * 0.5, math.pi); - cr.arc(x + self._radius, y + self._radius, self._radius, - math.pi, math.pi * 1.5); - - hippo.cairo_set_source_rgba32(cr, self.props.background_color) - cr.fill() - - def _build_title_box(self): - hbox = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL) - hbox.props.spacing = units.points_to_pixels(5) - hbox.props.padding_top = units.points_to_pixels(5) - hbox.props.padding_bottom = units.points_to_pixels(5) - - self.img_widget = gtk.Image() - img_pixbuf = gtk.gdk.pixbuf_new_from_file(self.image) - self.pixbuf = img_pixbuf.scale_simple(100, 100, gtk.gdk.INTERP_BILINEAR) - self.img_widget.set_from_pixbuf(self.pixbuf) - - canvas_widget = hippo.CanvasWidget() - canvas_widget.props.widget = self.img_widget - self.img_widget.show() - hbox.append(canvas_widget) - - return hbox - - - diff --git a/playtile.py b/playtile.py index fd56e4d..e3c2494 100644 --- a/playtile.py +++ b/playtile.py @@ -3,18 +3,19 @@ import hippo import math import os -from sugar.graphics import font from sugar.graphics import units class PlayTile(hippo.CanvasBox, hippo.CanvasItem): __gtype_name__ = 'PlayTile' _BORDER_DEFAULT = units.points_to_pixels(1.0) - def __init__(self, num, **kargs): + def __init__(self, num, x, y, **kargs): hippo.CanvasBox.__init__(self, **kargs) self.num = num self.image = os.path.join(os.path.dirname(__file__), 'images/black.png') + self.scale_x = x + self.scale_y = y self._radius = units.points_to_pixels(5) self.props.border_color = 100 @@ -53,10 +54,11 @@ class PlayTile(hippo.CanvasBox, hippo.CanvasItem): hbox.props.spacing = units.points_to_pixels(5) hbox.props.padding_top = units.points_to_pixels(5) hbox.props.padding_bottom = units.points_to_pixels(5) - + self.img_widget = gtk.Image() - self.img_pixbuf = gtk.gdk.pixbuf_new_from_file(self.image) - self.img_widget.set_from_pixbuf(self.img_pixbuf) + pixbuf_i = gtk.gdk.pixbuf_new_from_file(self.image) + self.scaledbuf_i = pixbuf_i.scale_simple(self.scale_x, self.scale_y, gtk.gdk.INTERP_BILINEAR) + self.img_widget.set_from_pixbuf(self.scaledbuf_i) canvas_widget = hippo.CanvasWidget() canvas_widget.props.widget = self.img_widget diff --git a/playview.py b/playview.py index ef3cf96..1a9a15d 100644 --- a/playview.py +++ b/playview.py @@ -2,71 +2,41 @@ import hippo import os import cairo import gtk +import math from sugar.graphics import color -from sugar.graphics import font from playtile import PlayTile -from playpoints import PlayPoints -from buddiespanel import BuddiesPanel -class PlayView(hippo.Canvas): - def __init__(self, oscapi, pairs): - hippo.Canvas.__init__(self) +class PlayView(hippo.CanvasBox, hippo.CanvasItem): + def __init__(self, wx, wy, numtiles, **kargs): + hippo.CanvasBox.__init__(self, **kargs) - root = hippo.CanvasBox() - root.props.orientation = hippo.ORIENTATION_HORIZONTAL - - tilebox = hippo.CanvasBox() - tilebox.props.orientation = hippo.ORIENTATION_VERTICAL - root.append(tilebox) - - self.buddies_panel = BuddiesPanel() - root.append(self.buddies_panel) - - ''' - pointsbox = hippo.CanvasBox() - pointsbox.props.orientation = hippo.ORIENTATION_VERTICAL - root.append(pointsbox) - - point = PlayPoints('erwin') - pointsbox.append(point) - point = PlayPoints('richard') - pointsbox.append(point) - ''' - - self.oscapi = oscapi - self.tiles = [] - self.turn = 0 - + self.props.orientation = hippo.ORIENTATION_VERTICAL + self.tiles = [] tile_num = 0 - numtiles = len(pairs)*2 + + numx = math.pow(float(numtiles), 0.5) + if numx%1 != 0: + numx = int(numx)+1 + self.y = self.x = (int(wx/numx)-10) + while tile_num < numtiles: - if tile_num == 0 or ((tile_num)%4) == 0: + if tile_num == 0 or ((tile_num)%numx) == 0: box = hippo.CanvasBox() box.props.orientation = hippo.ORIENTATION_HORIZONTAL - tilebox.append(box) + self.append(box) - tile = PlayTile(tile_num) - tile.connect('button-press-event', self._button_press_cb, tile.num) + tile = PlayTile(tile_num, self.x, self.y) self.tiles.append(tile) box.append(tile) - tile_num+=1 - - self.set_root(root) - self.show() - - def _button_press_cb(self, tile, event, data=None): - if self.turn: - self.oscapi.send(('127.0.0.1', 40000), "/MEMOSONO/tile/chosen", [data]) - else: - print 'it is not your turn' + tile_num+=1 def flip(self, tile_num, obj, color): tile = self.tiles[tile_num] tile.img_pixbuf = gtk.gdk.pixbuf_new_from_file(obj) - tile.img_widget.set_from_pixbuf(tile.img_pixbuf) + tile.img_widget.set_from_pixbuf(tile.img_pixbuf.scale_simple(self.x, self.y, gtk.gdk.INTERP_BILINEAR)) tile.props.background_color = color tile.emit_paint_needed(0, 0, -1, -1) diff --git a/selectentry.py b/selectentry.py deleted file mode 100644 index 475ae82..0000000 --- a/selectentry.py +++ /dev/null @@ -1,34 +0,0 @@ -import logging -from gettext import gettext as _ -import datetime - -import hippo -import pango - -from sugar.graphics.frame import Frame -from sugar.graphics.xocolor import XoColor -from sugar.graphics import font -from sugar.graphics import color -from sugar.graphics import units - - -class SelectEntry(Frame): - _DATE_COL_WIDTH = units.points_to_pixels(150) - _BUDDIES_COL_WIDTH = units.points_to_pixels(60) - - def __init__(self, name): - Frame.__init__(self) - self.name = name - self.props.box_height = units.grid_to_pixels(1) - self.props.spacing = units.points_to_pixels(5) - - self.props.border_color = color.FRAME_BORDER.get_int() - self.props.background_color = color.FRAME_BORDER.get_int() - logging.debug('FRAME_COLOR %s'%color.FRAME_BORDER.get_int()) - - title = hippo.CanvasText(text=self.name, - xalign=hippo.ALIGNMENT_START, - font_desc=font.DEFAULT_BOLD.get_pango_desc(), - size_mode=hippo.CANVAS_SIZE_ELLIPSIZE_END) - self.append(title) - diff --git a/selectview.py b/selectview.py deleted file mode 100644 index 3975363..0000000 --- a/selectview.py +++ /dev/null @@ -1,54 +0,0 @@ -import hippo -import os -import gobject -import gtk - -from sugar.graphics import color - -from selectentry import SelectEntry - -class SelectView(gtk.ScrolledWindow): - __gtype_name__ = 'SelectView' - - __gsignals__ = { - 'entry-selected': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([object])) - } - - _SELECTED = 1000000 - _UNSELECTED = 3520189183 - def __init__(self, names): - gtk.ScrolledWindow.__init__(self) - - root = hippo.CanvasBox() - root.props.orientation = hippo.ORIENTATION_VERTICAL - - canvas = hippo.Canvas() - canvas.set_root(root) - self.add_with_viewport(canvas) - - self.tiles = [] - self.turn = 0 - self.current = 0 - - for name in names: - entry = SelectEntry(name) - entry.connect('button-press-event', self._button_press_cb) - root.append(entry) - if name == names[0]: - self.current = entry - entry.props.background_color = self._SELECTED - entry.emit_paint_needed(0, 0, -1, -1) - - canvas.show() - - def _button_press_cb(self, entry, event, data=None): - entry.props.background_color = self._SELECTED - entry.emit_paint_needed(0, 0, -1, -1) - - self.current.props.background_color = self._UNSELECTED - self.current.emit_paint_needed(0, 0, -1, -1) - self.current = entry - self.emit('entry-selected', entry) - diff --git a/setup.py b/setup.py index 530f97c..98cfe83 100755 --- a/setup.py +++ b/setup.py @@ -18,4 +18,4 @@ from sugar.activity import bundlebuilder -bundlebuilder.start() +bundlebuilder.start('Memosono') diff --git a/toolbar.py b/toolbar.py deleted file mode 100644 index 1e79185..0000000 --- a/toolbar.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright (C) 2007, Simon Schampijer -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -from gettext import gettext as _ -import logging - -import gtk - -from sugar.graphics.combobox import ComboBox -from sugar.graphics.toolbutton import ToolButton - - -class PlayToolbar(gtk.Toolbar): - def __init__(self, activity): - gtk.Toolbar.__init__(self) - - self._activity = activity - - self._image = ToolButton('go-previous') - self._image_id = self._image.connect('clicked', self._back_cb) - self.insert(self._image, -1) - self._image.show() - - separator = gtk.SeparatorToolItem() - separator.set_draw(True) - self.insert(separator, -1) - - self._num_players_combo = ComboBox() - self._num_players = ['1', '2', '3', '4', '5', '6', '7', '8'] - self._num_players_combo.connect('changed', self._num_players_changed_cb) - for i, s in enumerate(self._num_players): - self._num_players_combo.append_item(i, s, None) - if s == '1': - self._num_players_combo.set_active(i) - self._add_widget(self._num_players_combo) - - #self.close = ToolButton('window-close') - #self.close.connect('clicked', self._close_clicked_cb) - #self.insert(self.close, -1) - #self.close.show() - - #def _close_clicked_cb(self, button): - # self._activity.close() - - def _add_widget(self, widget, expand=False): - tool_item = gtk.ToolItem() - tool_item.set_expand(expand) - - tool_item.add(widget) - widget.show() - - self.insert(tool_item, -1) - tool_item.show() - - def _num_players_changed_cb(self, num_players_combo): - logging.debug('num_players=' + self._num_players[self._num_players_combo.get_active()] ) - - def _back_cb(self, button): - pass - diff --git a/tubeconn.py b/tubeconn.py new file mode 100644 index 0000000..d1c1403 --- /dev/null +++ b/tubeconn.py @@ -0,0 +1,107 @@ +# This should eventually land in telepathy-python, so has the same license: + +# Copyright (C) 2007 Collabora Ltd. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +__all__ = ('TubeConnection',) +__docformat__ = 'reStructuredText' + + +import logging + +from dbus.connection import Connection + + +logger = logging.getLogger('telepathy.tubeconn') + + +class TubeConnection(Connection): + + def __new__(cls, conn, tubes_iface, tube_id, address=None, + group_iface=None, mainloop=None): + if address is None: + address = tubes_iface.GetDBusServerAddress(tube_id) + self = super(TubeConnection, cls).__new__(cls, address, + mainloop=mainloop) + + self._tubes_iface = tubes_iface + self.tube_id = tube_id + self.participants = {} + self.bus_name_to_handle = {} + self._mapping_watches = [] + + if group_iface is None: + method = conn.GetSelfHandle + else: + method = group_iface.GetSelfHandle + method(reply_handler=self._on_get_self_handle_reply, + error_handler=self._on_get_self_handle_error) + + return self + + def _on_get_self_handle_reply(self, handle): + self.self_handle = handle + match = self._tubes_iface.connect_to_signal('DBusNamesChanged', + self._on_dbus_names_changed) + self._tubes_iface.GetDBusNames(self.tube_id, + reply_handler=self._on_get_dbus_names_reply, + error_handler=self._on_get_dbus_names_error) + self._dbus_names_changed_match = match + + def _on_get_self_handle_error(self, e): + logging.basicConfig() + logger.error('GetSelfHandle failed: %s', e) + + def close(self): + self._dbus_names_changed_match.remove() + self._on_dbus_names_changed(self.tube_id, (), self.participants.keys()) + super(TubeConnection, self).close() + + def _on_get_dbus_names_reply(self, names): + self._on_dbus_names_changed(self.tube_id, names, ()) + + def _on_get_dbus_names_error(self, e): + logging.basicConfig() + logger.error('GetDBusNames failed: %s', e) + + def _on_dbus_names_changed(self, tube_id, added, removed): + if tube_id == self.tube_id: + for handle, bus_name in added: + if handle == self.self_handle: + # I've just joined - set my unique name + self.set_unique_name(bus_name) + self.participants[handle] = bus_name + self.bus_name_to_handle[bus_name] = handle + + # call the callback while the removed people are still in + # participants, so their bus names are available + for callback in self._mapping_watches: + callback(added, removed) + + for handle in removed: + bus_name = self.participants.pop(handle, None) + self.bus_name_to_handle.pop(bus_name, None) + + def watch_participants(self, callback): + self._mapping_watches.append(callback) + if self.participants: + # GetDBusNames already returned: fake a participant add event + # immediately + added = [] + for k, v in self.participants.iteritems(): + added.append((k, v)) + callback(added, []) -- cgit v0.9.1