Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Schampijer <simon@schampijer.de>2007-07-11 17:07:15 (GMT)
committer Simon Schampijer <simon@schampijer.de>2007-07-11 17:07:15 (GMT)
commitd267599aaa92372d0d9a868f1662f3aec60d722d (patch)
tree27fe5c0c65a78d01b6d91e36eea711288d77e16b
parent4f1c45f839898bd012e5ae1427c840c88044c38c (diff)
parent25c7815ffa8c93508d95314beab1f93dcd8f7b75 (diff)
Merge branch 'tubes'
Conflicts: NEWS
-rw-r--r--NEWS4
-rw-r--r--activity/activity-memosono.svg (renamed from activity/activity-memorygame.svg)0
-rw-r--r--activity/activity.info4
-rw-r--r--buddiespanel.py102
-rw-r--r--controller.py250
-rw-r--r--csound/csoundserver.py113
-rw-r--r--games/drumgit/drumgit.mson24
-rw-r--r--games/guitar/guitar.mson35
-rw-r--r--games/guitar/images/drumkit10_b.jpgbin16416 -> 0 bytes
-rw-r--r--games/guitar/images/drumkit11_b.jpgbin16488 -> 0 bytes
-rw-r--r--games/guitar/images/drumkit12_b.jpgbin16755 -> 0 bytes
-rw-r--r--games/guitar/images/drumkit1_b.jpgbin17279 -> 0 bytes
-rw-r--r--games/guitar/images/drumkit2_b.jpgbin17257 -> 0 bytes
-rw-r--r--games/guitar/images/drumkit3_b.jpgbin17294 -> 0 bytes
-rw-r--r--games/guitar/images/drumkit4_b.jpgbin17157 -> 0 bytes
-rw-r--r--games/guitar/images/drumkit5_b.jpgbin17248 -> 0 bytes
-rw-r--r--games/guitar/images/drumkit6_b.jpgbin17376 -> 0 bytes
-rw-r--r--games/guitar/images/drumkit7_b.jpgbin17223 -> 0 bytes
-rw-r--r--games/guitar/images/drumkit8_b.jpgbin17257 -> 0 bytes
-rw-r--r--games/guitar/images/drumkit9_b.jpgbin16014 -> 0 bytes
-rw-r--r--games/guitar/images/guitar10_2.jpgbin14457 -> 0 bytes
-rw-r--r--games/guitar/images/guitar11_2.jpgbin14497 -> 0 bytes
-rw-r--r--games/guitar/images/guitar12_2.jpgbin14590 -> 0 bytes
-rw-r--r--games/guitar/images/guitar1_2.jpgbin13943 -> 0 bytes
-rw-r--r--games/guitar/images/guitar2_2.jpgbin13949 -> 0 bytes
-rw-r--r--games/guitar/images/guitar3_2.jpgbin13925 -> 0 bytes
-rw-r--r--games/guitar/images/guitar4_2.jpgbin13922 -> 0 bytes
-rw-r--r--games/guitar/images/guitar5_2.jpgbin13943 -> 0 bytes
-rw-r--r--games/guitar/images/guitar6_2.jpgbin14468 -> 0 bytes
-rw-r--r--games/guitar/images/guitar7_2.jpgbin13909 -> 0 bytes
-rw-r--r--games/guitar/images/guitar8_2.jpgbin13930 -> 0 bytes
-rw-r--r--games/guitar/images/guitar9_2.jpgbin14525 -> 0 bytes
-rw-r--r--games/guitar/images/reference18
-rw-r--r--games/guitar/sounds/beat10.aiffbin175948 -> 0 bytes
-rw-r--r--games/guitar/sounds/beat14.aiffbin240880 -> 0 bytes
-rw-r--r--games/guitar/sounds/beat16.aiffbin264554 -> 0 bytes
-rw-r--r--games/guitar/sounds/beat17.aiffbin198606 -> 0 bytes
-rw-r--r--games/guitar/sounds/beat1_a.aiffbin220588 -> 0 bytes
-rw-r--r--games/guitar/sounds/beat1_b.aiffbin220588 -> 0 bytes
-rw-r--r--games/guitar/sounds/beat1_c.aiffbin220588 -> 0 bytes
-rw-r--r--games/guitar/sounds/beat2.aiffbin165126 -> 0 bytes
-rw-r--r--games/guitar/sounds/beat3.aiffbin221942 -> 0 bytes
-rw-r--r--games/guitar/sounds/beat4.aiffbin152274 -> 0 bytes
-rw-r--r--games/guitar/sounds/beat6_2.aiffbin174932 -> 0 bytes
-rw-r--r--games/guitar/sounds/beat8.aiffbin198268 -> 0 bytes
-rw-r--r--games/guitar/sounds/bending_a.aiffbin220588 -> 0 bytes
-rw-r--r--games/guitar/sounds/bending_b.aiffbin220588 -> 0 bytes
-rw-r--r--games/guitar/sounds/flashcomp2a.aiffbin220588 -> 0 bytes
-rw-r--r--games/guitar/sounds/flashcomp2b.aiffbin176624 -> 0 bytes
-rw-r--r--games/guitar/sounds/flasholet4.aiffbin219724 -> 0 bytes
-rw-r--r--games/guitar/sounds/gedaempft.aiffbin94268 -> 0 bytes
-rw-r--r--games/guitar/sounds/git_hit1.aiffbin215250 -> 0 bytes
-rw-r--r--games/guitar/sounds/git_hit4.aiffbin222862 -> 0 bytes
-rw-r--r--games/guitar/sounds/guitcello.aiffbin265230 -> 0 bytes
-rw-r--r--games/guitar/sounds/jimi1.aiffbin66136 -> 0 bytes
-rw-r--r--games/guitar/sounds/jimi4.aiffbin65112 -> 0 bytes
-rw-r--r--games/guitar/sounds/ungedaempft.aiffbin183376 -> 0 bytes
-rw-r--r--images/black.pngbin276 -> 229 bytes
-rw-r--r--infopanel.py20
-rw-r--r--memosono.dtd9
-rwxr-xr-xmemosono.py610
-rwxr-xr-xmemosonoactivity.py230
-rw-r--r--model.py174
-rw-r--r--playpoints.py73
-rw-r--r--playtile.py12
-rw-r--r--playview.py64
-rw-r--r--selectentry.py34
-rw-r--r--selectview.py54
-rwxr-xr-xsetup.py2
-rw-r--r--toolbar.py73
-rw-r--r--tubeconn.py107
71 files changed, 815 insertions, 1197 deletions
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 @@
<?xml version="1.0"?>
<memosono name="drumgit">
- <pair id="1" mother="guitar12_2.jpg" child="guitar12_2.jpg" color="12345" />
- <pair id="2" mother="drumkit2_b.jpg" child="drumkit2_b.jpg" color="234567" />
- <pair id="3" mother="guitar8_2.jpg" child="guitar8_2.jpg" color="23456767" />
+ <pair aimg="drumkit1_b.jpg" asnd="beat1_a.aiff" bimg="drumkit1_b.jpg" bsnd="beat1_a.aiff" color="100" />
+ <pair aimg="drumkit2_b.jpg" asnd="beat1_b.aiff" bimg="drumkit2_b.jpg" bsnd="beat1_b.aiff" color="100" />
+ <pair aimg="drumkit3_b.jpg" asnd="beat1_c.aiff" bimg="drumkit3_b.jpg" bsnd="beat1_c.aiff" color="100" />
+ <pair aimg="drumkit4_b.jpg" asnd="beat8.aiff" bimg="drumkit4_b.jpg" bsnd="beat8.aiff" color="100" />
+
+ <pair aimg="drumkit6_b.jpg" asnd="beat3.aiff" bimg="drumkit6_b.jpg" bsnd="beat3.aiff" color="100" />
+ <pair aimg="drumkit7_b.jpg" asnd="beat4.aiff" bimg="drumkit7_b.jpg" bsnd="beat4.aiff" color="100" />
+ <pair aimg="drumkit8_b.jpg" asnd="beat14.aiff" bimg="drumkit8_b.jpg" bsnd="beat14.aiff" color="100" />
+ <pair aimg="drumkit9_b.jpg" asnd="beat6_2.aiff" bimg="drumkit9_b.jpg" bsnd="beat6_2.aiff" color="100" />
+
+ <pair aimg="guitar1_2.jpg" asnd="bending_a.aiff" bimg="guitar1_2.jpg" bsnd="bending_a.aiff" color="100" />
+ <pair aimg="guitar2_2.jpg" asnd="bending_b.aiff" bimg="guitar2_2.jpg" bsnd="bending_b.aiff" color="100" />
+ <pair aimg="guitar3_2.jpg" asnd="flashcomp2a.aiff" bimg="guitar3_2.jpg" bsnd="flashcomp2a.aiff" color="100" />
+ <pair aimg="guitar4_2.jpg" asnd="flashcomp2b.aiff" bimg="guitar4_2.jpg" bsnd="flashcomp2b.aiff" color="100" />
+
+ <pair aimg="guitar5_2.jpg" asnd="gedaempft.aiff" bimg="guitar5_2.jpg" bsnd="gedaempft.aiff" color="100" />
+ <pair aimg="guitar6_2.jpg" asnd="gedaempft.aiff" bimg="guitar6_2.jpg" bsnd="gedaempft.aiff" color="100" />
+ <pair aimg="guitar7_2.jpg" asnd="ungedaempft.aiff" bimg="guitar7_2.jpg" bsnd="ungedaempft.aiff" color="100" />
+ <pair aimg="guitar8_2.jpg" asnd="jimi4.aiff" bimg="guitar8_2.jpg" bsnd="jimi4.aiff" color="100" />
+
</memosono>
<!--
+ <pair aimg="" asnd="" bimg="" bsnd="" color="100" />
drumkit1_b.jpg beat1_a.aiff
drumkit2_b.jpg beat1_b.aiff
drumkit3_b.jpg beat1_c.aiff
diff --git a/games/guitar/guitar.mson b/games/guitar/guitar.mson
deleted file mode 100644
index 0db5d9b..0000000
--- a/games/guitar/guitar.mson
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0"?>
-<memosono name="guitar">
- <pair id="1" mother="drumkit9_b.jpg" child="drumkit9_b.jpg" color="12345" />
- <pair id="2" mother="drumkit5_b.jpg" child="drumkit5_b.jpg" color="234567" />
- <pair id="3" mother="drumkit8_b.jpg" child="drumkit10_b.jpg" color="23456767" />
- <pair id="4" mother="drumkit1_b.jpg" child="drumkit1_b.jpg" color="23456767" />
- <pair id="5" mother="drumkit2_b.jpg" child="drumkit2_b.jpg" color="23456767" />
-</memosono>
-
-<!--
-drumkit1_b.jpg beat1_a.aiff
-drumkit2_b.jpg beat1_b.aiff
-drumkit3_b.jpg beat1_c.aiff
-drumkit4_b.jpg beat8.aiff
-drumkit5_b.jpg beat2.aiff
-drumkit6_b.jpg beat3.aiff
-drumkit7_b.jpg beat4.aiff
-drumkit8_b.jpg beat14.aiff
-drumkit9_b.jpg beat6_2.aiff
-drumkit10_b.jpg beat16.aiff
-drumkit11_b.jpg beat17.aiff
-drumkit12_b.jpg beat10.aiff
-guitar1_2.jpg bending_a.aiff
-guitar2_2.jpg bending_b.aiff
-guitar3_2.jpg flashcomp2a.aiff
-guitar4_2.jpg flashcomp2b.aiff
-guitar5_2.jpg gedaempft.aiff
-guitar6_2.jpg ungedaempft.aiff
-guitar7_2.jpg jimi4.aiff
-guitar8_2.jpg git_hit1.aiff
-guitar9_2.jpg git_hit4.aiff
-guitar10_2.jpg guitcello.aiff
-guitar11_2.jpg flasholet4.aiff
-guitar12_2.jpg jimi1.aiff
---> \ 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 @@
<!ELEMENT pair (#PCDATA)* >
<!ATTLIST pair
- id CDATA #REQUIRED
- mother CDATA #REQUIRED
- child CDATA #REQUIRED
- color CDATA #REQUIRED
+ aimg CDATA #IMPLIED
+ asnd CDATA #IMPLIED
+ bimg CDATA #IMPLIED
+ bsnd CDATA #IMPLIED
+ color CDATA #IMPLIED
>
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. <http://www.collabora.co.uk/>
+#
+# 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, [])