diff options
Diffstat (limited to 'flipsticks.py')
-rw-r--r-- | flipsticks.py | 1882 |
1 files changed, 1882 insertions, 0 deletions
diff --git a/flipsticks.py b/flipsticks.py new file mode 100644 index 0000000..05b9290 --- /dev/null +++ b/flipsticks.py @@ -0,0 +1,1882 @@ +#!/usr/bin/env python + +# 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 +# + + +### flipsticks +### +### author: Ed Stoner (ed@whsd.net) +### (c) 2007 World Wide Workshop Foundation + +import time +import pygtk +pygtk.require('2.0') +import gtk +import gobject +import os +import math +import textwrap +import pickle + +SERVICE = 'org.freedesktop.Telepathy.Tube.Connect' +IFACE = SERVICE +PATH = '/org/freedesktop/Telepathy/Tube/Connect' +GRAY = "#B7B7B7" # gray +PINK = "#FF0099" # pink +YELLOW = "#FFFF00" # yellow +WHITE = "#FFFFFF" +BLACK = "#000000" +BACKGROUND = "#66CC00" # light green +BUTTON_FOREGROUND = "#CCFB99" # very light green +BUTTON_BACKGROUND = "#027F01" # dark green +COLOR_FG_BUTTONS = ( + (gtk.STATE_NORMAL,"#CCFF99"), + (gtk.STATE_ACTIVE,"#CCFF99"), + (gtk.STATE_PRELIGHT,"#CCFF99"), + (gtk.STATE_SELECTED,"#CCFF99"), + (gtk.STATE_INSENSITIVE,"#CCFF99"), + ) # very light green +COLOR_BG_BUTTONS = ( + (gtk.STATE_NORMAL,"#027F01"), + (gtk.STATE_ACTIVE,"#CCFF99"), + (gtk.STATE_PRELIGHT,"#016D01"), + (gtk.STATE_SELECTED,"#CCFF99"), + (gtk.STATE_INSENSITIVE,"#027F01"), + ) +OLD_COLOR_BG_BUTTONS = ( + (gtk.STATE_NORMAL,"#027F01"), + (gtk.STATE_ACTIVE,"#014D01"), + (gtk.STATE_PRELIGHT,"#016D01"), + (gtk.STATE_SELECTED,"#027F01"), + (gtk.STATE_INSENSITIVE,"#027F01"), + ) + +SPANISH = u'Espa\xf1ol' +LANG = {'English':{'size':'Size', + 'angle':'Angle', + 'lessonplan':'Lesson Plans', + 'lpdir':'lp-en', + 'export':'Export Frame One', + 'HEAD':'Head', + 'NECK':'Neck', + 'RIGHT SHOULDER':'Right Shoulder', + 'UPPER RIGHT ARM':'Upper Right Arm', + 'LOWER RIGHT ARM':'Lower Right Arm', + 'RIGHT HAND':'Right Hand', + 'LEFT SHOULDER':'Left Shoulder', + 'UPPER LEFT ARM':'Upper Left Arm', + 'LOWER LEFT ARM':'Lower Left Arm', + 'LEFT HAND':'Left Hand', + 'TORSO':'Torso', + 'RIGHT HIP':'Right Hip', + 'UPPER RIGHT LEG':'Upper Right Leg', + 'LOWER RIGHT LEG':'Lower Right Leg', + 'RIGHT FOOT':'Right Foot', + 'LEFT HIP':'Left Hip', + 'UPPER LEFT LEG':'Upper Left Leg', + 'LOWER LEFT LEG':'Lower Left Leg', + 'LEFT FOOT':'Left Foot'}, + SPANISH:{'size':u'Tama\xf1o', + 'angle':u'\xe1ngulo', + 'lessonplan':u'Planes de la lecci\xf3n', + 'lpdir':'lp-en', + 'export':'Un marco de la exportacion', + 'HEAD':'Cabeza', + 'NECK':'Cuello', + 'RIGHT SHOULDER':'Hombro derecho', + 'UPPER RIGHT ARM':'Brazo derecho superior', + 'LOWER RIGHT ARM':'Bajar el brazo derecho', + 'RIGHT HAND':'Mano derecha', + 'LEFT SHOULDER':'Hombro izquierdo', + 'UPPER LEFT ARM':'Brazo izquierdo superior', + 'LOWER LEFT ARM':u'Un brazo izquierdo m\xe1s bajo', + 'LEFT HAND':'Mano izquierda', + 'TORSO':'Torso', + 'RIGHT HIP':'Cadera derecha', + 'UPPER RIGHT LEG':'Pierna derecha superior', + 'LOWER RIGHT LEG':'Bajar la pierna derecha', + 'RIGHT FOOT':'Pie derecho', + 'LEFT HIP':'Cadera izquierda', + 'UPPER LEFT LEG':'Pierna izquierda superior', + 'LOWER LEFT LEG':u'Una pierna izquierda m\xe1s baja', + 'LEFT FOOT':'Pie izquierdo'}} + +DRAWWIDTH = 750 +DRAWHEIGHT = 500 +FPWIDTH = 150 +FPHEIGHT = 100 +#DRAWHEIGHT = 300 for my laptop +KEYFRAMEWIDTH = 675 +KEYFRAMEHEIGHT = 80 + +KEYFRAMES = [50,190,337,487,625] +TOTALFRAMES = 30 + +STICKS = {'HEAD':(0,15), + 'NECK':(90,15), + 'RIGHT SHOULDER':(185,25), + 'UPPER RIGHT ARM':(60,35), + 'LOWER RIGHT ARM':(35,35), + 'LEFT SHOULDER':(355,25), + 'UPPER LEFT ARM':(300,35), + 'LOWER LEFT ARM':(325,35), + 'TORSO':(270,60), + 'RIGHT HIP':(80,20), + 'UPPER RIGHT LEG':(300,50), + 'LOWER RIGHT LEG':(340,40), + 'RIGHT FOOT':(85,15), + 'LEFT HIP':(280,20), + 'UPPER LEFT LEG':(65,50), + 'LOWER LEFT LEG':(15,40), + 'LEFT FOOT':(275,15)} + +PARTS = {'RIGHT HAND':14, + 'LEFT HAND':14} + + +STICKLIST = ['NECK','HEAD','RIGHT SHOULDER','UPPER RIGHT ARM','LOWER RIGHT ARM', + 'LEFT SHOULDER','UPPER LEFT ARM','LOWER LEFT ARM','TORSO', + 'RIGHT HIP','UPPER RIGHT LEG','LOWER RIGHT LEG','RIGHT FOOT', + 'LEFT HIP','UPPER LEFT LEG','LOWER LEFT LEG','LEFT FOOT'] + +LABELLIST = ['HEAD','NECK','RIGHT SHOULDER','UPPER RIGHT ARM','LOWER RIGHT ARM', + 'RIGHT HAND','LEFT SHOULDER','UPPER LEFT ARM','LOWER LEFT ARM','LEFT HAND', + 'TORSO','RIGHT HIP','UPPER RIGHT LEG','LOWER RIGHT LEG','RIGHT FOOT', + 'LEFT HIP','UPPER LEFT LEG','LOWER LEFT LEG','LEFT FOOT'] + +# The joint is the circle at the end of the stick + +JOINTS = {'HEAD':'head', + 'NECK':'neck', + 'RIGHT SHOULDER':'rightshoulder', + 'UPPER RIGHT ARM':'rightelbow', + 'LOWER RIGHT ARM':'righthand', + 'LEFT SHOULDER':'leftshoulder', + 'UPPER LEFT ARM':'leftelbow', + 'LOWER LEFT ARM':'lefthand', + 'TORSO':'groin', + 'RIGHT HIP':'righthip', + 'UPPER RIGHT LEG':'rightknee', + 'LOWER RIGHT LEG':'rightheel', + 'RIGHT FOOT':'righttoe', + 'LEFT HIP':'lefthip', + 'UPPER LEFT LEG':'leftknee', + 'LOWER LEFT LEG':'leftheel', + 'LEFT FOOT':'lefttoe'} + +JOINTTOSTICK = {} +for jname in JOINTS: + JOINTTOSTICK[JOINTS[jname]] = jname + +PARTS = {'HEAD':40, + 'RIGHT HAND':14, + 'LEFT HAND':14} + +TESTSTICKS = {'RIGHT SHOULDER':(37,20), + 'UPPER RIGHT ARM':(6,15), + 'LOWER RIGHT ARM':(10,15)} + +def getwrappedfile(filepath,linelength): + text = [] + f = file(filepath) + for line in f: + if line == '\n': + text.append(line) + else: + for wline in textwrap.wrap(line.strip()): + text.append('%s\n' % wline) + return ''.join(text) + +def capwords(s): + x = s.split() + n = [] + for word in x: + n.append(word.capitalize()) + return ' '.join(n) + +def prepare_btn(btn, w=-1, h=-1): + for state, color in COLOR_BG_BUTTONS: + btn.modify_bg(state, gtk.gdk.color_parse(color)) + c = btn.get_child() + if c is not None: + for state, color in COLOR_FG_BUTTONS: + c.modify_fg(state, gtk.gdk.color_parse(color)) + else: + for state, color in COLOR_FG_BUTTONS: + btn.modify_fg(state, gtk.gdk.color_parse(color)) + if w>0 or h>0: + btn.set_size_request(w, h) + return btn + +def inarea(x,y,awidth,aheight): + if x+5 > awidth: + return False + if y+5 > aheight: + return False + if y < 5: + return False + if x < 5: + return False + return True + +def interpolate(x,x0,y0,x1,y1): + if x1-x0 == 0: + return y0 + m = float(y1-y0)/float(x1-x0) + y = y0 + ((x-x0)*m) + return y + +def getpoints(x,y,angle,len): + nx = int(round(x + (len * math.cos(math.radians(angle))))) + ny = int(round(y - (len * math.sin(math.radians(angle))))) + return (nx,ny) + +def scalesticks(stickdict,i): + for key in stickdict: + (angle,len) = stickdict[key] + newlen = int(len * i) + stickdict[key] = (angle,newlen) + +class flipsticks: + def delete_event(self, widget, event, data=None): + return False + + def destroy(self, widget, data=None): + gtk.main_quit() + + def expose_event(self, widget, event): + x , y, width, height = event.area + widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], + self.pixmap, x, y, x, y, width, height) + return False + + def kf_expose_event(self, widget, event): + x , y, width, height = event.area + widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], + self.kfpixmap, x, y, x, y, width, height) + return False + + def fp_expose_event(self, widget, event): + x , y, width, height = event.area + widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], + self.fppixmap, x, y, x, y, width, height) + return False + + def configure_event(self, widget, event): + x, y, width, height = self.mfdraw.get_allocation() + self.pixmap = gtk.gdk.Pixmap(self.mfdraw.window, width, height) + self.drawmainframe() + return True + + def kf_configure_event(self, widget, event): + self.drawkeyframe() + return True + + def fp_configure_event(self, widget, event): + self.drawfp() + return True + + def motion_notify_event(self, widget, event): + if event.is_hint: + x, y, state = event.window.get_pointer() + else: + x = event.x + y = event.y + state = event.state + if state & gtk.gdk.BUTTON1_MASK and self.pixmap != None: + if self.jointpressed: + if inarea(x,y,DRAWWIDTH,DRAWHEIGHT): + #self.joints[self.jointpressed] = (x,y) # old hack way + # first find the parents x,y + (px,py) = self.getparentjoint(self.jointpressed,self.joints, + self.middle) + if x-px == 0: + #computeangle = 0 + b = 1 + else: + b = float(px-x) + a = float(y-py) + computeangle = int(math.degrees(math.atan(a/b))) + stickname = JOINTTOSTICK[self.jointpressed] + # add sum of parent angles to new angle + parents = self.getparentsticks(stickname) + panglesum = 0 + for parentname in parents: + (pangle,plen) = self.sticks[parentname] + panglesum += pangle + (angle, len) = self.sticks[stickname] + #print 'X:%s,Y:%s,PX:%s,PY:%s,ANGLE:%s,NEWANGLE:%s' % (x,y,px,py,angle,newangle) + newangle = computeangle-panglesum + if (x < px) or (b == 1): + newangle = newangle + 180 + if newangle < 0: + newangle = 360 + newangle + self.sticks[stickname] = (newangle,len) + self.setjoints() # this is overkill + self.drawmainframe() + self.updateentrybox() + elif self.middlepressed: + if inarea(x,y,DRAWWIDTH,DRAWHEIGHT): + xdiff = x-self.middle[0] + ydiff = y-self.middle[1] + self.shiftjoints(xdiff,ydiff) + self.middle = (x,y) + self.drawmainframe() + elif self.rotatepressed: + if inarea(x,y,DRAWWIDTH,DRAWHEIGHT): + (px,py) = self.middle + if x-px == 0: + #computeangle = 0 + b = 1 + else: + b = float(px-x) + a = float(y-py) + computeangle = int(math.degrees(math.atan(a/b))) + stickname = 'TORSO' + (angle, len) = self.sticks[stickname] + newangle = computeangle + if (x < px) or (b == 1): + newangle = newangle + 180 + if newangle < 0: + newangle = 360 + newangle + anglediff = newangle-angle + self.sticks[stickname] = (newangle,len) + # now rotate the other sticks off of the middle + for stickname in ['NECK','RIGHT SHOULDER','LEFT SHOULDER']: + (sangle,slen) = self.sticks[stickname] + newsangle = sangle+anglediff + if newsangle < 0: + newsangle = 360 + newsangle + if newsangle > 360: + newsangle = newsangle - 360 + self.sticks[stickname] = (newsangle,slen) + self.setjoints() + self.drawmainframe() + self.updateentrybox() + + return True + + def kf_motion_notify_event(self, widget, event): + if event.is_hint: + x, y, state = event.window.get_pointer() + else: + x = event.x + y = event.y + state = event.state + if state & gtk.gdk.BUTTON1_MASK and self.pixmap != None: + if self.kfpressed >= 0: + if inarea(x,y,KEYFRAMEWIDTH,KEYFRAMEHEIGHT): + xdiff = x-self.keyframes[self.kfpressed] + self.shiftjoints(xdiff,0,self.kfsjoints[self.kfpressed]) + self.keyframes[self.kfpressed] = x + self.drawkeyframe() + return True + + def button_press_event(self, widget, event): + if event.button == 1 and self.pixmap != None: + joint = self.injoint(event.x, event.y) + if joint: + self.jointpressed = joint + self.drawmainframe() + elif self.inmiddle(event.x, event.y): + self.middlepressed = True + self.drawmainframe() + elif self.inrotate(event.x, event.y): + self.rotatepressed = True + self.drawmainframe() + return True + + def syncmaintokf(self): + # set the main window to the keyframe + if self.kfsticks[self.kfselected]: + self.sticks = self.kfsticks[self.kfselected].copy() + self.parts = self.kfparts[self.kfselected].copy() + self.middle = self.kfmiddles[self.kfselected] + self.setjoints() + self.drawmainframe() + + def kf_button_press_event(self, widget, event): + if event.button == 1 and self.pixmap != None: + kfnum = self.inkeyframe(event.x, event.y) + if kfnum >= 0: + self.kfpressed = kfnum + self.kfselected = kfnum + self.drawkeyframe() + self.syncmaintokf() + self.updateentrybox() + return True + + def button_release_event(self, widget, event): + self.jointpressed = None + self.middlepressed = False + self.rotatepressed = False + self.drawmainframe() + return True + + def kf_button_release_event(self, widget, event): + self.kfpressed = -1 + self.drawkeyframe() + return True + + def setplayspeed(self,adj): + #self.waittime = int((6-adj.value)*150) + self.waittime = int((6-adj.value)*75) + if self.playing: + gobject.source_remove(self.playing) + self.playing = gobject.timeout_add(self.waittime, self.playframe) + + def playframe(self): + if not self.playing: + return False + else: + if self.playframenum == -1: + return True + joints = self.frames[self.playframenum] + parts = self.fparts[self.playframenum] + # draw on the main drawing area + area = self.toplevel.window + drawgc = area.new_gc() + drawgc.line_width = 3 + cm = drawgc.get_colormap() + white = cm.alloc_color('white') + black = cm.alloc_color('black') + drawgc.fill = gtk.gdk.SOLID + x, y, width, height = self.mfdraw.get_allocation() + #self.pixmap = gtk.gdk.Pixmap(self.mfdraw.window, width, height) + # clear area + drawgc.set_foreground(white) + self.pixmap.draw_rectangle(drawgc,True,0,0,width,height) + + drawgc.set_foreground(black) + #hsize = self.sticks['HEAD'][1] # really half of head size + hsize = self.fhsize[self.playframenum] + middle = self.fmiddles[self.playframenum] + rhsize = parts['RIGHT HAND'] + lhsize = parts['LEFT HAND'] + self.drawstickman(drawgc,self.pixmap,middle,joints,hsize,rhsize,lhsize) + # draw circle for middle + #green = cm.alloc_color('green') + #drawgc.set_foreground(green) + #x,y = middle + #self.pixmap.draw_arc(drawgc,True,x-5,y-5,10,10,0,360*64) + self.mfdraw.queue_draw() + + fsecs = self.frames.keys() + fsecs.sort() + if self.playingbackwards: + # decrement playframenum + if self.playframenum == fsecs[0]: + self.playframenum = fsecs[-1] + else: + i = fsecs.index(self.playframenum) + self.playframenum = fsecs[i-1] + else: + # increment playframenum + if self.playframenum == fsecs[-1]: + self.playframenum = fsecs[0] + else: + i = fsecs.index(self.playframenum) + self.playframenum = fsecs[i+1] + if self.playing: + return True + else: + return False + + def enterangle_callback(self, widget, entry): + stickname = self.stickselected + if stickname in self.sticks: + newangle = int(entry.get_text()) + (angle, len) = self.sticks[stickname] + self.sticks[stickname] = (newangle,len) + else: + # part not stick + self.angleentry.set_text('-') + self.setjoints() + self.drawmainframe() + + def updateentrybox(self): + if self.stickselected in self.sticks: + (angle, len) = self.sticks[self.stickselected] + self.angleentry.set_text(str(angle)) + else: + # part not stick + len = self.parts[self.stickselected] + self.sizeentry.set_text(str(len)) + + def enterlen_callback(self, widget, entry): + stickname = self.stickselected + newlen = int(entry.get_text()) + if stickname in self.sticks: + if stickname == 'HEAD': + newlen = int(newlen/2.0) + (angle, len) = self.sticks[stickname] + self.sticks[stickname] = (angle,newlen) + else: + # part not stick + self.parts[stickname] = newlen + self.setjoints() + self.drawmainframe() + + def reset(self, widget, data=None): + xmiddle = int(DRAWWIDTH/2.0) + ymiddle = int(DRAWHEIGHT/2.0) + self.middle = (xmiddle,ymiddle) + self.sticks = STICKS.copy() + self.parts = PARTS.copy() + self.selectstickebox() + self.setjoints() + self.drawmainframe() + + def setframe(self, widget, data=None): + self.kfmiddles[self.kfselected] = self.middle + self.kfparts[self.kfselected] = self.parts.copy() + self.kfsticks[self.kfselected] = self.sticks.copy() + self.kfssticks[self.kfselected] = self.sticks.copy() + scalesticks(self.kfssticks[self.kfselected],.2) + self.kfjoints[self.kfselected] = self.joints.copy() + self.kfsjoints[self.kfselected] = self.initjoints() + #x, y, width, height = self.kfdraw.get_allocation() + #y = int(height/2.0) + #y = int(KEYFRAMEHEIGHT/2.0)-5 + y = int(KEYFRAMEHEIGHT/2.0) + x = self.keyframes[self.kfselected] + kfmiddle = (x,y) + self.setjoints(self.kfsjoints[self.kfselected],self.kfssticks[self.kfselected],kfmiddle) + self.drawkeyframe() + + def clearframe(self, widget, data=None): + self.kfsticks[self.kfselected] = None + self.kfssticks[self.kfselected] = None + self.kfjoints[self.kfselected] = None + self.kfsjoints[self.kfselected] = None + self.kfparts[self.kfselected] = None + self.drawkeyframe() + + def intjoints(self,sjoints,ejoints,count,numpoints): + # numpoints: number of points between start and end + # count: point were getting now + ijoints = {} + for jname in sjoints: + (x0,y0) = sjoints[jname] + (x1,y1) = ejoints[jname] + #print 'x0:%s,y0:%s' % (x0,y0) + #print 'x1:%s,y1:%s' % (x1,y1) + x = x0 + (count * ((x1-x0)/float(numpoints))) + y = interpolate(x,x0,y0,x1,y1) + ijoints[jname] = (int(x),int(y)) + return ijoints + + def intparts(self,sparts,eparts,count,numpoints): + iparts = {} + for pname in sparts: + x0 = sparts[pname] + x1 = eparts[pname] + if x0 == x1: + iparts[pname] = x0 + continue + x = x0 + (count * ((x1-x0)/float(numpoints))) + iparts[pname] = int(x) + return iparts + + def inthsize(self,shsize,ehsize,count,numpoints): + x0 = shsize + x1 = ehsize + if x0 == x1: + return x0 + x = x0 + (count * ((x1-x0)/float(numpoints))) + return int(x) + + def intmiddle(self,smiddle,emiddle,count,numpoints): + (x0,y0) = smiddle + (x1,y1) = emiddle + x = x0 + (count * ((x1-x0)/float(numpoints))) + y = interpolate(x,x0,y0,x1,y1) + return (int(x),int(y)) + + def makeframes(self): + endsecs = KEYFRAMEWIDTH + fint = int(endsecs/float(TOTALFRAMES)) # frame interval + self.frames = {} + self.fparts = {} + self.fmiddles = {} + self.fhsize = {} + kf = {} # point to keyframes by x-middle (which represents a time, like seconds) + for i in range(len(self.keyframes)): + secs = self.keyframes[i] + #kf[secs] = i + # use self.kfjoints[kf[secs]] and self.kfparts[kf[secs]] + if self.kfjoints[i]: + self.frames[secs] = self.kfjoints[i].copy() + self.fparts[secs] = self.kfparts[i].copy() + self.fmiddles[secs] = self.kfmiddles[i] + #print '%s:KFMIDDLE:%s = (%s,%s)' % (i,secs,self.fmiddles[secs][0],self.fmiddles[secs][1]) + self.fhsize[secs] = self.kfsticks[i]['HEAD'][1] + fsecs = self.frames.keys() + fsecs.sort() + if not fsecs: + return + # ADD frame at 0 + self.frames[0] = self.frames[fsecs[0]].copy() + self.fparts[0] = self.fparts[fsecs[0]].copy() + self.fmiddles[0] = self.fmiddles[fsecs[0]] + self.fhsize[0] = self.fhsize[fsecs[0]] + # ADD frame at end + self.frames[endsecs] = self.frames[fsecs[-1]].copy() + self.fparts[endsecs] = self.fparts[fsecs[-1]].copy() + self.fmiddles[endsecs] = self.fmiddles[fsecs[-1]] + self.fhsize[endsecs] = self.fhsize[fsecs[-1]] + # now fill in frames between + fsecs = self.frames.keys() + fsecs.sort() + for i in range(len(fsecs)): + if i == len(fsecs)-1: + continue # nothing after end + startsecs = fsecs[i] + endsecs = fsecs[i+1] + numframes = int((endsecs-startsecs)/float(fint))-1 + #print 'NUMFRAMES(%s):%s' % (i,numframes) + for j in range(numframes-1): # MAYBE SHOULD BE numframes + secs = startsecs + ((j+1)*fint) + self.frames[secs] = self.intjoints(self.frames[startsecs],self.frames[endsecs], + j+1,numframes) + self.fparts[secs] = self.intparts(self.fparts[startsecs],self.fparts[endsecs], + j+1,numframes) + self.fmiddles[secs] = self.intmiddle(self.fmiddles[startsecs],self.fmiddles[endsecs], + j+1,numframes) + self.fhsize[secs] = self.inthsize(self.fhsize[startsecs],self.fhsize[endsecs], + j+1,numframes) + #print '%s,%s(%s secs):(%s,%s) START(%s,%s) - END(%s,%s) startsecs:%s endsecs:%s numframes:%s' % (i,j,secs,self.fmiddles[secs][0],self.fmiddles[secs][1],self.fmiddles[startsecs][0],self.fmiddles[startsecs][1],self.fmiddles[endsecs][0],self.fmiddles[endsecs][1],startsecs,endsecs,numframes) + #print self.frames.keys() + + def shiftjoints(self,xdiff,ydiff,joints=None): + if not joints: + joints = self.joints + for jname in joints: + #if isinstance(self.joints[jname],tuple): + (jx,jy) = joints[jname] + njx = jx + xdiff + njy = jy + ydiff + joints[jname] = (njx,njy) + + def initjoints(self): + joints = {} + for stickname in JOINTS: + jname = JOINTS[stickname] + joints[jname] = (0,0) + return joints + + def getparentsticks(self, stickname): + if stickname in ['RIGHT SHOULDER','LEFT SHOULDER','NECK','TORSO']: + return [] + if stickname in ['HEAD']: + return ['NECK'] + if stickname == 'UPPER RIGHT ARM': + return ['RIGHT SHOULDER'] + if stickname == 'LOWER RIGHT ARM': + return ['UPPER RIGHT ARM','RIGHT SHOULDER'] + if stickname == 'UPPER LEFT ARM': + return ['LEFT SHOULDER'] + if stickname == 'LOWER LEFT ARM': + return ['UPPER LEFT ARM','LEFT SHOULDER'] + if stickname == 'RIGHT HIP': + return ['TORSO'] + if stickname == 'UPPER RIGHT LEG': + return ['RIGHT HIP','TORSO'] + if stickname == 'LOWER RIGHT LEG': + return ['UPPER RIGHT LEG','RIGHT HIP','TORSO'] + if stickname == 'RIGHT FOOT': + return ['LOWER RIGHT LEG','UPPER RIGHT LEG','RIGHT HIP','TORSO'] + if stickname == 'LEFT HIP': + return ['TORSO'] + if stickname == 'UPPER LEFT LEG': + return ['LEFT HIP','TORSO'] + if stickname == 'LOWER LEFT LEG': + return ['UPPER LEFT LEG','LEFT HIP','TORSO'] + if stickname == 'LEFT FOOT': + return ['LOWER LEFT LEG','UPPER LEFT LEG','LEFT HIP','TORSO'] + + def getparentjoint(self,jname,joints,middle): + if jname in ['rightshoulder','leftshoulder','groin','neck']: + return middle + parentjoints = {'rightelbow':'rightshoulder', + 'righthand':'rightelbow', + 'leftelbow':'leftshoulder', + 'lefthand':'leftelbow', + 'righthip':'groin', + 'rightknee':'righthip', + 'rightheel':'rightknee', + 'righttoe':'rightheel', + 'lefthip':'groin', + 'leftknee':'lefthip', + 'leftheel':'leftknee', + 'lefttoe':'leftheel', + 'head':'neck'} + return joints[parentjoints[jname]] + + def setjoints(self,joints=None,sticks=None,middle=None): + if not joints: + joints = self.joints + if not sticks: + sticks = self.sticks + if not middle: + middle = self.middle + # have to traverse in order because + # parent joints must be set right + for stickname in self.sticklist: + (angle,len) = sticks[stickname] + jname = JOINTS[stickname] + (x,y) = self.getparentjoint(jname,joints,middle) + parents = self.getparentsticks(stickname) + panglesum = 0 + for parentname in parents: + (pangle,plen) = sticks[parentname] + panglesum += pangle + (nx,ny) = getpoints(x,y,angle+panglesum,len) + joints[jname] = (nx,ny) + + def drawmainframe(self): + area = self.toplevel.window + drawgc = area.new_gc() + drawgc.line_width = 3 + cm = drawgc.get_colormap() + red = cm.alloc_color('red') + yellow = cm.alloc_color('yellow') + white = cm.alloc_color('white') + black = cm.alloc_color('black') + blue = cm.alloc_color('blue') + green = cm.alloc_color('green') + drawgc.fill = gtk.gdk.SOLID + x, y, width, height = self.mfdraw.get_allocation() + #self.pixmap = gtk.gdk.Pixmap(self.mfdraw.window, width, height) + # clear area + drawgc.set_foreground(white) + self.pixmap.draw_rectangle(drawgc,True,0,0,width,height) + + drawgc.set_foreground(black) + hsize = self.sticks['HEAD'][1] # really half of head size + rhsize = self.parts['RIGHT HAND'] + lhsize = self.parts['LEFT HAND'] + self.drawstickman(drawgc,self.pixmap,self.middle,self.joints,hsize,rhsize,lhsize) + # draw circle for middle + drawgc.set_foreground(green) + if self.middlepressed: + drawgc.set_foreground(blue) + x,y = self.middle + self.pixmap.draw_arc(drawgc,True,x-5,y-5,10,10,0,360*64) + # draw circle for rotate (should be halfway between middle and groin + (rx,ry) = self.getrotatepoint() + drawgc.set_foreground(yellow) + if self.rotatepressed: + drawgc.set_foreground(blue) + self.pixmap.draw_arc(drawgc,True,rx-5,ry-5,10,10,0,360*64) + # draw circles for joints + drawgc.set_foreground(black) + for jname in self.joints: + if jname == 'head': + continue + x,y = self.joints[jname] + if self.jointpressed == jname: + drawgc.set_foreground(blue) + self.pixmap.draw_arc(drawgc,True,x-5,y-5,10,10,0,360*64) + drawgc.set_foreground(black) + else: + drawgc.set_foreground(red) + self.pixmap.draw_arc(drawgc,True,x-5,y-5,10,10,0,360*64) + drawgc.set_foreground(black) + self.mfdraw.queue_draw() + + def drawstickman(self,drawgc,pixmap,middle,joints,hsize,rhsize,lhsize): + leftarm = [middle, joints['leftshoulder'],joints['leftelbow'],joints['lefthand']] + rightarm = [middle, joints['rightshoulder'],joints['rightelbow'],joints['righthand']] + torso = [joints['neck'],middle,joints['groin']] + leftleg = [joints['groin'],joints['lefthip'],joints['leftknee'], + joints['leftheel'],joints['lefttoe']] + rightleg = [joints['groin'],joints['righthip'],joints['rightknee'], + joints['rightheel'],joints['righttoe']] + # draw lines + pixmap.draw_lines(drawgc, leftarm) + pixmap.draw_lines(drawgc, rightarm) + pixmap.draw_lines(drawgc, torso) + pixmap.draw_lines(drawgc, leftleg) + pixmap.draw_lines(drawgc, rightleg) + # draw head + x,y = joints['head'] + pixmap.draw_arc(drawgc,True,x-hsize,y-hsize,hsize*2,hsize*2,0,360*64) + # draw circles for hands + x,y = joints['righthand'] + pixmap.draw_arc(drawgc,True,x-int(rhsize/2.0),y-int(rhsize/2.0),rhsize,rhsize,0,360*64) + x,y = joints['lefthand'] + pixmap.draw_arc(drawgc,True,x-int(lhsize/2.0),y-int(lhsize/2.0),lhsize,lhsize,0,360*64) + + def drawkeyframe(self): + area = self.toplevel.window + drawgc = area.new_gc() + drawgc.line_width = 2 + cm = drawgc.get_colormap() + red = cm.alloc_color('red') + white = cm.alloc_color('white') + black = cm.alloc_color('black') + blue = cm.alloc_color('blue') + green = cm.alloc_color('green') + pink = cm.alloc_color(PINK) + bgcolor = cm.alloc_color(BACKGROUND) + darkgreen = cm.alloc_color(BUTTON_BACKGROUND) + drawgc.fill = gtk.gdk.SOLID + x, y, width, height = self.kfdraw.get_allocation() + self.kfpixmap = gtk.gdk.Pixmap(self.kfdraw.window, width, height) + # clear area + drawgc.set_foreground(bgcolor) + self.kfpixmap.draw_rectangle(drawgc,True,0,0,width,height) + # draw line in middle + drawgc.set_foreground(darkgreen) + self.kfpixmap.draw_rectangle(drawgc,True,10,int(height/2.0)-5,width-20,10) + x = 10 + y = int(height/2.0) + self.kfpixmap.draw_arc(drawgc,True,x-5,y-5,10,10,0,360*64) + x = width-10 + self.kfpixmap.draw_arc(drawgc,True,x-5,y-5,10,10,0,360*64) + # draw the keyframe circles + for i in range(len(self.keyframes)): + # first the outer circle + x = self.keyframes[i] + if i == self.kfselected: + drawgc.set_foreground(pink) + else: + drawgc.set_foreground(darkgreen) + self.kfpixmap.draw_arc(drawgc,True,x-40,y-40,80,80,0,360*64) + # then the inner circle + drawgc.set_foreground(white) + self.kfpixmap.draw_arc(drawgc,True,x-35,y-35,70,70,0,360*64) + if self.kfssticks[i]: + # draw a man in the circle + drawgc.set_foreground(black) + hsize = self.kfssticks[i]['HEAD'][1] + rhsize = int(self.kfparts[i]['RIGHT HAND']*0.2) + lhsize = int(self.kfparts[i]['LEFT HAND']*0.2) + self.drawstickman(drawgc,self.kfpixmap,(x,y),self.kfsjoints[i],hsize,rhsize,lhsize) + #self.kfpixmap.draw_arc(drawgc,True,x-5,y-5,10,10,0,360*64) + self.kfdraw.queue_draw() + + def drawfp(self): + area = self.toplevel.window + drawgc = area.new_gc() + drawgc.line_width = 1 + cm = drawgc.get_colormap() + red = cm.alloc_color('red') + white = cm.alloc_color('white') + black = cm.alloc_color('black') + blue = cm.alloc_color('blue') + green = cm.alloc_color('green') + pink = cm.alloc_color(PINK) + bgcolor = cm.alloc_color(BACKGROUND) + darkgreen = cm.alloc_color(BUTTON_BACKGROUND) + drawgc.fill = gtk.gdk.SOLID + x, y, width, height = self.fpdraw.get_allocation() + self.fppixmap = gtk.gdk.Pixmap(self.fpdraw.window, width, height) + # clear area + drawgc.set_foreground(white) + self.fppixmap.draw_rectangle(drawgc,True,0,0,width,height) + self.fpdraw.queue_draw() + + def inkeyframe(self, x, y): + for i in range(len(self.keyframes)): + kx = self.keyframes[i] + if (abs(kx-x) <= 20): + return i + return -1 + + def injoint(self, x, y): + for jname in self.joints: + jx, jy = self.joints[jname] + if (abs(jx-x) <= 5) and (abs(jy-y) <= 5): + return jname + + def inmiddle(self, x, y): + mx, my = self.middle + if (abs(mx-x) <= 5) and (abs(my-y) <= 5): + return True + + def inrotate(self, x, y): + rx, ry = self.getrotatepoint() + if (abs(rx-x) <= 5) and (abs(ry-y) <= 5): + return True + + def getrotatepoint(self): + (angle,len) = self.sticks['TORSO'] + x,y = self.middle + (rx,ry) = getpoints(x,y,angle,int(len/2.0)) + return (rx,ry) + + def selectstick(self, widget, event, data=None): + if data: + if self.stickselected: + ebox = self.stickbuttons[self.stickselected] + ebox.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(BUTTON_BACKGROUND)) + label = ebox.get_child() + label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BUTTON_FOREGROUND)) + self.stickselected = data + self.selectstickebox() + + def selectstickebox(self): + ebox = self.stickbuttons[self.stickselected] + ebox.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(BUTTON_FOREGROUND)) + label = ebox.get_child() + label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BUTTON_BACKGROUND)) + if self.stickselected in self.sticks: + if self.stickselected == 'HEAD': + self.sizeentry.set_text(str(self.sticks[self.stickselected][1]*2)) + else: + self.sizeentry.set_text(str(self.sticks[self.stickselected][1])) + + self.angleentry.set_text(str(self.sticks[self.stickselected][0])) + else: + # its a part not a stick + self.angleentry.set_text('-') + self.sizeentry.set_text(str(self.parts[self.stickselected])) + + def showlessonplans(self, widget, data=None): + dia = gtk.Dialog(title='Lesson Plans', + parent=None, + flags=0, + buttons=None) + dia.set_default_size(500,500) + dia.show() + + #dia.vbox.pack_start(scrolled_window, True, True, 0) + notebook = gtk.Notebook() + # uncomment below to highlight tabs + notebook.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(WHITE)) + notebook.set_tab_pos(gtk.POS_TOP) + #notebook.set_default_size(400,400) + notebook.show() + lessonplans = {} + lpdir = os.path.join(self.mdirpath,LANG[self.language]['lpdir']) + lpentries = os.listdir(lpdir) + for entry in lpentries: + fpath = os.path.join(lpdir,entry) + lessonplans[entry] = getwrappedfile(fpath,95) + lpkeys = lessonplans.keys() + lpkeys.sort() + for lpkey in lpkeys: + lpname = lpkey.replace('_',' ').replace('0','')[:-4] + label = gtk.Label(lessonplans[lpkey]) + #if self.insugar: + # label.modify_fg(gtk.STATE_NORMAL,gtk.gdk.color_parse(WHITE)) + eb = gtk.EventBox() + eb.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(WHITE)) + #label.set_line_wrap(True) + label.show() + eb.add(label) + eb.show() + #tlabel = gtk.Label('Lesson Plan %s' % str(i+1)) + tlabel = gtk.Label(lpname) + tlabel.show() + scrolled_window = gtk.ScrolledWindow() + scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) + scrolled_window.show() + scrolled_window.add_with_viewport(eb) + notebook.append_page(scrolled_window, tlabel) + #dia.action_area.pack_start(notebook, True, True, 0) + dia.vbox.pack_start(notebook, True, True, 0) + result = dia.run() + dia.destroy() + + def loadfile(self, widget, data=None): + pass + + def savefile(self, widget, data=None): + pass + + def exportanim(self, widget, data=None): + if self.insugar: + self.exporttojournal() + else: + self.exportfile() + + def exportfile(self): + self.makeframes() + fsecs = self.frames.keys() + tmpdir = '/tmp' + pngpaths = [] + for i in fsecs: + joints = self.frames[i] + parts = self.fparts[i] + # draw on the main drawing area + area = self.toplevel.window + drawgc = area.new_gc() + drawgc.line_width = 3 + cm = drawgc.get_colormap() + white = cm.alloc_color('white') + black = cm.alloc_color('black') + drawgc.fill = gtk.gdk.SOLID + x, y, width, height = self.mfdraw.get_allocation() + pixmap = gtk.gdk.Pixmap(self.mfdraw.window, width, height) + # clear area + drawgc.set_foreground(white) + pixmap.draw_rectangle(drawgc,True,0,0,width,height) + + drawgc.set_foreground(black) + #hsize = self.sticks['HEAD'][1] # really half of head size + hsize = self.fhsize[i] + middle = self.fmiddles[i] + rhsize = parts['RIGHT HAND'] + lhsize = parts['LEFT HAND'] + self.drawstickman(drawgc,pixmap,middle,joints,hsize,rhsize,lhsize) + pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, width, height) + gtk.gdk.Pixbuf.get_from_drawable(pixbuf,pixmap,pixmap.get_colormap(),0,0,0,0,width,height) + filename = 'fp%03d.png' % i + filepath = os.path.join(tmpdir,filename) + pixbuf.save(filepath,'png') + pngpaths.append(filepath) + # now convert all of the pngs to gif and then make a gif animation + convertpath = 'convert' + tmpdir = '/tmp' + entires = os.listdir(tmpdir) + gifpaths = [] + for pngfilepath in pngpaths: + giffilepath = pngfilepath[:-4]+'.gif' + gifpaths.append(giffilepath) + os.system('%s %s %s' % (convertpath,pngfilepath,giffilepath)) + #os.remove(pngfilepath) + agifpath = os.path.join(self.mdirpath,'animatefp.gif') + os.system('%s -delay 20 -loop 0 %s/fp*.gif %s' % (convertpath,tmpdir,agifpath)) + for giffilepath in gifpaths: + os.remove(giffilepath) + + def exporttojournal(self): + self.makeframes() + fsecs = self.frames.keys() + tmpdir = '/tmp' + pngpaths = [] + firstpixindex = fsecs[0] + for i in [fsecs[0]]: + joints = self.frames[i] + parts = self.fparts[i] + # draw on the main drawing area + area = self.toplevel.window + drawgc = area.new_gc() + drawgc.line_width = 3 + cm = drawgc.get_colormap() + white = cm.alloc_color('white') + black = cm.alloc_color('black') + drawgc.fill = gtk.gdk.SOLID + x, y, width, height = self.mfdraw.get_allocation() + pixmap = gtk.gdk.Pixmap(self.mfdraw.window, width, height) + # clear area + drawgc.set_foreground(white) + pixmap.draw_rectangle(drawgc,True,0,0,width,height) + + drawgc.set_foreground(black) + #hsize = self.sticks['HEAD'][1] # really half of head size + hsize = self.fhsize[i] + middle = self.fmiddles[i] + rhsize = parts['RIGHT HAND'] + lhsize = parts['LEFT HAND'] + self.drawstickman(drawgc,pixmap,middle,joints,hsize,rhsize,lhsize) + pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, width, height) + if i == firstpixindex: + firstpixbuf = pixbuf + gtk.gdk.Pixbuf.get_from_drawable(pixbuf,pixmap,pixmap.get_colormap(),0,0,0,0,width,height) + filename = 'fp%03d.png' % i + filepath = os.path.join(tmpdir,filename) + pixbuf.save(filepath,'png') + pngpaths.append(filepath) + from sugar.datastore import datastore + mediaObject = datastore.create() + mediaObject.metadata['title'] = 'FlipSticks PNG' + thumbData = self._get_base64_pixbuf_data(firstpixbuf) + mediaObject.metadata['preview'] = thumbData + #medaiObject.metadata['icon-color'] = '' + mediaObject.metadata['mime_type'] = 'image/png' + mediaObject.file_path = pngpaths[0] + datastore.write(mediaObject) + + def _get_base64_pixbuf_data(self, pixbuf): + data = [""] + pixbuf.save_to_callback(self._save_data_to_buffer_cb, "png", {}, data) + import base64 + return base64.b64encode(str(data[0])) + + def _save_data_to_buffer_cb(self, buf, data): + data[0] += buf + return True + + def playbackwards(self, widget, data=None): + if self.playing: + playimg = gtk.Image() + playimg.set_from_file(os.path.join(self.iconsdir,'big_left_arrow.png')) + playimg.show() + widget.set_image(playimg) + self.playing = False + # set the main window to the keyframe + if self.kfsticks[self.kfselected]: + self.sticks = self.kfsticks[self.kfselected].copy() + self.parts = self.kfparts[self.kfselected].copy() + self.middle = self.kfmiddles[self.kfselected] + self.setjoints() + self.drawmainframe() + self.updateentrybox() + else: + stopimg = gtk.Image() + stopimg.set_from_file(os.path.join(self.iconsdir,'big_pause.png')) + stopimg.show() + widget.set_image(stopimg) + self.makeframes() + fsecs = self.frames.keys() + fsecs.sort() + if fsecs: + self.playframenum = fsecs[-1] + else: + self.playframenum = -1 + self.playingbackwards = True + self.playing = gobject.timeout_add(self.waittime, self.playframe) + + def playforwards(self, widget, data=None): + if self.playing: + playimg = gtk.Image() + playimg.set_from_file(os.path.join(self.iconsdir,'big_right_arrow.png')) + playimg.show() + widget.set_image(playimg) + self.playing = False + # set the main window to the keyframe + if self.kfsticks[self.kfselected]: + self.sticks = self.kfsticks[self.kfselected].copy() + self.parts = self.kfparts[self.kfselected].copy() + self.middle = self.kfmiddles[self.kfselected] + self.setjoints() + self.drawmainframe() + self.updateentrybox() + else: + stopimg = gtk.Image() + stopimg.set_from_file(os.path.join(self.iconsdir,'big_pause.png')) + stopimg.show() + widget.set_image(stopimg) + self.makeframes() + #mkeys = self.fmiddles.keys() + #mkeys.sort() + #for mkey in mkeys: + # print '%s:(%s,%s)' % (mkey,self.fmiddles[mkey][0],self.fmiddles[mkey][1]) + fsecs = self.frames.keys() + fsecs.sort() + if fsecs: + self.playframenum = fsecs[0] + else: + self.playframenum = -1 + self.playingbackwards = False + self.playing = gobject.timeout_add(self.waittime, self.playframe) + + def changed_cb(self, combobox): + model = combobox.get_model() + index = combobox.get_active() + if index: + lang = model[index][0] + if lang == 'Espa\xc3\xb1ol': + lang = SPANISH + if lang in LANG: + self.lessonplans.set_label(LANG[lang]['lessonplan']) + self.anglelabel.set_label(LANG[lang]['angle']+':') + self.sizelabel.set_label(LANG[lang]['size']+':') + self.export.set_label(LANG[lang]['export']) + for stickpartname in self.labellist: + label = self.sticklabels[stickpartname] + label.set_label(LANG[lang][stickpartname]) + prepare_btn(self.lessonplans) + prepare_btn(self.export) + return + + def setlastlanguage(self, widget, data=None): + li = LANGLIST.index(self.language) + if li == 0: + self.language = LANGLIST[len(LANGLIST)-1] + else: + self.language = LANGLIST[li-1] + self.changebuttonlang() + + def setnextlanguage(self, widget, data=None): + li = LANGLIST.index(self.language) + if li == (len(LANGLIST)-1): + self.language = LANGLIST[0] + else: + self.language = LANGLIST[li+1] + self.changebuttonlang() + + def getdefaultlang(self): + return 'English' + + def getsdata(self): + self.makeframes() + sdd = {} # save data dictionary + sdd['kfmiddles'] = self.kfmiddles + sdd['kfparts'] = self.kfparts + sdd['kfsticks'] = self.kfsticks + sdd['kfssticks'] = self.kfssticks + sdd['kfjoints'] = self.kfjoints + sdd['kfsjoints'] = self.kfsjoints + sdd['keyframes'] = self.keyframes + sdd['kfselected'] = self.kfselected + return pickle.dumps(sdd) + + def restore(self, sdata): + sdd = pickle.loads(sdata) + self.kfmiddles = sdd['kfmiddles'] + self.kfparts = sdd['kfparts'] + self.kfsticks = sdd['kfsticks'] + self.kfssticks = sdd['kfssticks'] + self.kfjoints = sdd['kfjoints'] + self.kfsjoints = sdd['kfsjoints'] + self.keyframes = sdd['keyframes'] + self.kfselected = sdd['kfselected'] + self.drawkeyframe() + self.syncmaintokf() + self.updateentrybox() + + def __init__(self, toplevel_window, mdirpath): + self.insugar = False + self.playing = False + self.playingbackwards = False + self.waittime = 3*150 + self.keyframe = 0 + self.toplevel = toplevel_window + self.mdirpath = mdirpath + xmiddle = int(DRAWWIDTH/2.0) + ymiddle = int(DRAWHEIGHT/2.0) + self.middle = (xmiddle,ymiddle) + self.sticks = STICKS.copy() + self.parts = PARTS.copy() + self.sticklist = STICKLIST + self.labellist = LABELLIST + self.stickselected = 'RIGHT SHOULDER' + self.laststickselected = None + self.keyframes = KEYFRAMES + self.kfsticks = [None,None,None,None,None] + self.kfssticks = [None,None,None,None,None] + self.kfjoints = [None,None,None,None,None] + self.kfsjoints = [None,None,None,None,None] + self.kfmiddles = [None,None,None,None,None] + self.kfparts = [None,None,None,None,None] + self.kfselected = 0 + self.joints = self.initjoints() + self.setjoints() + self.jointpressed = None + self.kfpressed = -1 + self.middlepressed = False + self.rotatepressed = False + self.iconsdir = os.path.join(self.mdirpath,'icons') + self.language = self.getdefaultlang() + + self.mpbox = gtk.VBox() + self.main = gtk.EventBox() + self.main.show() + self.main.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(YELLOW)) + self.mainbox = gtk.EventBox() + self.mainbox.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(BACKGROUND)) + self.mainbox.set_border_width(5) + self.mainbox.show() + self.main.add(self.mainbox) + self.mpbox.show() + self.hbox = gtk.HBox() + self.hbox.show() + self.vbox = gtk.VBox() + self.vbox.show() + self.hbox.pack_start(self.vbox,False,False,0) + self.mainbox.add(self.mpbox) + self.mpbox.pack_start(self.hbox,True,True,0) + + self.logobox = gtk.HBox(False,0) + self.logobox.show() + self.logo = gtk.Image() + self.logo.show() + self.logo.set_from_file(os.path.join(self.iconsdir,'logo.png')) + self.logobox.pack_start(self.logo,False,False,0) + self.lessonplans = gtk.Button('Lesson Plans') + self.lessonplans.connect('clicked',self.showlessonplans, None) + prepare_btn(self.lessonplans) + self.lessonplans.show() + self.lpvbox = gtk.VBox() + self.lpvbox.show() + self.lpvbox.pack_start(self.lessonplans,True,False,0) + self.lpoframe = gtk.EventBox() + self.lpoframe.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(YELLOW)) + self.lpoframe.show() + self.lpframe = gtk.EventBox() + self.lpframe.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(BACKGROUND)) + self.lpframe.show() + self.lpalign = gtk.Alignment(1.0,1.0,1.0,1.0) + self.lpalign.add(self.lpframe) + self.lpalign.set_padding(0,5,5,0) + self.lpalign.show() + self.lpoframe.add(self.lpalign) + self.lphbox = gtk.HBox() + self.lphbox.show() + self.lphbox.pack_start(self.lpvbox,True,False,0) + self.lpframe.add(self.lphbox) + self.logobox.pack_start(self.lpoframe,True,True,0) + #vvvvv LANGUAGE BUTTONS vvvvv + #self.lastlang = gtk.Button() + #self.lastlang.connect('clicked', self.setlastlanguage, None) + #llla = gtk.Image() + #llla.set_from_file(os.path.join(self.iconsdir,'left_arrow.png')) + #llla.show() + #self.lastlang.add(llla) + #prepare_btn(self.lastlang) + #self.lastlang.show() + #self.llvbox = gtk.VBox() + #self.llvbox.show() + #self.llvbox.pack_start(self.lastlang,True,False,0) + #self.lang = gtk.Button(self.language) + #prepare_btn(self.lang) + #self.lang.show() + #self.nextlang = gtk.Button() + #self.nextlang.connect('clicked', self.setnextlanguage, None) + #nlra = gtk.Image() + #nlra.set_from_file(os.path.join(self.iconsdir,'right_arrow.png')) + #nlra.show() + #self.nextlang.add(nlra) + #prepare_btn(self.nextlang) + #self.nextlang.show() + #self.nlvbox = gtk.VBox() + #self.nlvbox.show() + #self.nlvbox.pack_start(self.nextlang,True,False,0) + #self.langvbox = gtk.VBox() + #self.langvbox.show() + #self.langvbox.pack_start(self.lang,True,False,0) + #^^^^^ LANGUAGE BUTTONS ^^^^^ + #vvvvv LANGUAGE DROPDOWN vvvvv + self.langdd = gtk.combo_box_new_text() + self.langdd.append_text('Language') + self.langdd.append_text('English') + self.langdd.append_text(SPANISH) + self.langdd.connect('changed', self.changed_cb) + self.langdd.set_active(0) + self.langdd.show() + self.langddvbox = gtk.VBox() + self.langddvbox.show() + self.langddvbox.pack_start(self.langdd,True,False,0) + #^^^^^ LANGUAGE DROPDOWN ^^^^^ + self.langoframe = gtk.EventBox() + self.langoframe.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(YELLOW)) + self.langoframe.show() + self.langframe = gtk.EventBox() + self.langframe.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(BACKGROUND)) + self.langframe.show() + self.langalign = gtk.Alignment(1.0,1.0,1.0,1.0) + self.langalign.add(self.langframe) + self.langalign.set_padding(0,5,5,5) + self.langalign.show() + self.langoframe.add(self.langalign) + self.langhbox = gtk.HBox() + self.langhbox.show() + #self.langhbox.pack_start(self.llvbox,True,False,0) + #self.langhbox.pack_start(self.langvbox,True,False,0) + #self.langhbox.pack_start(self.nlvbox,True,False,0) + self.langhbox.pack_start(self.langddvbox,True,False,0) + self.langframe.add(self.langhbox) + self.logobox.pack_start(self.langoframe,True,True,0) + + self.vbox.pack_start(self.logobox,False,False,0) + + #self.drawhbox = gtk.HBox() + #self.drawhbox.show() + self.mfdraw = gtk.DrawingArea() + self.mfdraw.set_size_request(DRAWWIDTH,DRAWHEIGHT) + self.mfdraw.show() + self.mfdraw.connect('expose_event', self.expose_event) + self.mfdraw.connect('configure_event', self.configure_event) + self.mfdraw.connect('motion_notify_event', self.motion_notify_event) + self.mfdraw.connect('button_press_event', self.button_press_event) + self.mfdraw.connect('button_release_event', self.button_release_event) + self.mfdraw.set_events(gtk.gdk.EXPOSURE_MASK + | gtk.gdk.LEAVE_NOTIFY_MASK + | gtk.gdk.BUTTON_PRESS_MASK + | gtk.gdk.BUTTON_RELEASE_MASK + | gtk.gdk.POINTER_MOTION_MASK + | gtk.gdk.POINTER_MOTION_HINT_MASK) + self.drawborder = gtk.EventBox() + self.drawborder.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(PINK)) + self.drawborder.set_border_width(10) + self.drawborder.show() + self.drawframe = gtk.EventBox() + self.drawframe.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(BACKGROUND)) + self.drawframe.set_border_width(5) + self.drawframe.show() + self.drawborder.add(self.drawframe) + self.drawframe.add(self.mfdraw) + #self.drawhbox.pack_start(self.drawborder, False, False, 10) + + #self.vbox.pack_start(self.drawhbox,False,False,0) + self.vbox.pack_start(self.drawborder,False,False,0) + + self.keyframehbox = gtk.HBox() + self.keyframehbox.show() + + self.playback = gtk.Button() + self.playback.connect('clicked', self.playbackwards, None) + playbackla = gtk.Image() + playbackla.set_from_file(os.path.join(self.iconsdir,'big_left_arrow.png')) + playbackla.show() + self.playback.add(playbackla) + prepare_btn(self.playback) + self.playback.show() + self.playbackvbox = gtk.VBox() + self.playbackvbox.show() + self.playbackvbox.pack_start(self.playback,True,False,0) + self.keyframehbox.pack_start(self.playbackvbox,True,False,0) + # vvvvvvvvvvKEYFRAME DRAWING AREA HEREvvvvvvvvvvvv + self.kfdraw = gtk.DrawingArea() + self.kfdraw.set_size_request(KEYFRAMEWIDTH,KEYFRAMEHEIGHT) + self.kfdraw.show() + self.kfdraw.connect('expose_event', self.kf_expose_event) + self.kfdraw.connect('configure_event', self.kf_configure_event) + self.kfdraw.connect('motion_notify_event', self.kf_motion_notify_event) + self.kfdraw.connect('button_press_event', self.kf_button_press_event) + self.kfdraw.connect('button_release_event', self.kf_button_release_event) + self.kfdraw.set_events(gtk.gdk.EXPOSURE_MASK + | gtk.gdk.LEAVE_NOTIFY_MASK + | gtk.gdk.BUTTON_PRESS_MASK + | gtk.gdk.BUTTON_RELEASE_MASK + | gtk.gdk.POINTER_MOTION_MASK + | gtk.gdk.POINTER_MOTION_HINT_MASK) + #self.drawborder = gtk.EventBox() + #self.drawborder.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(PINK)) + #self.drawborder.show() + #self.drawframe = gtk.EventBox() + #self.drawframe.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(BACKGROUND)) + #self.drawframe.set_border_width(5) + #self.drawframe.show() + #self.drawborder.add(self.drawframe) + #self.drawframe.add(self.mfdraw) + self.keyframehbox.pack_start(self.kfdraw,False,False,0) + + # ^^^^^^^^^^KEYFRAME DRAWING AREA HERE^^^^^^^^^^^^ + self.playforward = gtk.Button() + self.playforward.connect('clicked', self.playforwards, None) + playforwardla = gtk.Image() + playforwardla.set_from_file(os.path.join(self.iconsdir,'big_right_arrow.png')) + playforwardla.show() + self.playforward.add(playforwardla) + prepare_btn(self.playforward) + self.playforward.show() + self.playforwardvbox = gtk.VBox() + self.playforwardvbox.show() + self.playforwardvbox.pack_start(self.playforward,True,False,0) + self.keyframehbox.pack_start(self.playforwardvbox,True,False,0) + + self.vbox.pack_start(self.keyframehbox,False,False,10) + + self.bottomcontrolshbox = gtk.HBox() + self.bottomcontrolshbox.show() + self.resetbutton = gtk.Button() + resetimg = gtk.Image() + resetimg.set_from_file(os.path.join(self.iconsdir,'reset.png')) + resetimg.show() + self.resetbutton.add(resetimg) + self.resetbutton.connect('clicked', self.reset, None) + prepare_btn(self.resetbutton) + self.resetbutton.show() + self.bottomcontrolshbox.pack_start(self.resetbutton, True, False, 0) + + self.setframebutton = gtk.Button() + cameraimg = gtk.Image() + cameraimg.set_from_file(os.path.join(self.iconsdir,'camera.png')) + cameraimg.show() + self.setframebutton.add(cameraimg) + self.setframebutton.connect('clicked', self.setframe, None) + prepare_btn(self.setframebutton) + self.setframebutton.show() + self.bottomcontrolshbox.pack_start(self.setframebutton, True, False, 0) + + self.clearframebutton = gtk.Button() + clearimg = gtk.Image() + clearimg.set_from_file(os.path.join(self.iconsdir,'clear.png')) + clearimg.show() + self.clearframebutton.add(clearimg) + self.clearframebutton.connect('clicked', self.clearframe, None) + prepare_btn(self.clearframebutton) + self.clearframebutton.show() + self.bottomcontrolshbox.pack_start(self.clearframebutton, True, False, 0) + + adj = gtk.Adjustment(2.5,1,5,.5,1) + adj.connect('value_changed',self.setplayspeed) + self.playspeed = gtk.HScale(adj) + self.playspeed.set_draw_value(False) + for state, color in COLOR_BG_BUTTONS: + self.playspeed.modify_bg(state, gtk.gdk.color_parse(color)) + self.playspeed.show() + self.bottomcontrolshbox.pack_start(self.playspeed, True, True, 5) + self.vbox.pack_start(self.bottomcontrolshbox,False,False,10) + + # NOW THE RIGHT SIDE + self.rightvbox = gtk.VBox() + self.rightvbox.show() + # vvvvv FILE PICKER THING vvvvv + #self.filechooserhbox = gtk.HBox() + #self.filechooserhbox.show() + #self.lastfile = gtk.Button() + #lfla = gtk.Image() + #lfla.set_from_file(os.path.join(self.iconsdir,'left_arrow.png')) + #lfla.show() + #self.lastfile.add(lfla) + #prepare_btn(self.lastfile) + #self.lastfile.show() + #self.lfvbox = gtk.VBox() + #self.lfvbox.show() + #self.lfvbox.pack_start(self.lastfile,True,False,0) + #self.filechooserhbox.pack_start(self.lfvbox,True,False,5) + ## vvvvv FILE PICKER DRAWING AREA vvvvv + #self.fpdraw = gtk.DrawingArea() + #self.fpdraw.set_size_request(FPWIDTH,FPHEIGHT) + #self.fpdraw.show() + #self.fpdraw.connect('expose_event', self.fp_expose_event) + #self.fpdraw.connect('configure_event', self.fp_configure_event) + #self.fpdrawborder = gtk.EventBox() + #self.fpdrawborder.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(PINK)) + #self.fpdrawborder.show() + #self.fpdrawframe = gtk.EventBox() + #self.fpdrawframe.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(BACKGROUND)) + #self.fpdrawframe.set_border_width(5) + #self.fpdrawframe.show() + #self.fpdrawborder.add(self.fpdrawframe) + #self.fpdrawframe.add(self.fpdraw) + #self.filechooserhbox.pack_start(self.fpdrawborder,False,False,0) + ## ^^^^^ FILE PICKER DRAWING AREA ^^^^^ + #self.nextfile = gtk.Button() + #nfla = gtk.Image() + #nfla.set_from_file(os.path.join(self.iconsdir,'right_arrow.png')) + #nfla.show() + #self.nextfile.add(nfla) + #prepare_btn(self.nextfile) + #self.nextfile.show() + #self.nfvbox = gtk.VBox() + #self.nfvbox.show() + #self.nfvbox.pack_start(self.nextfile,True,False,0) + #self.filechooserhbox.pack_start(self.nfvbox,True,False,5) + #self.rightvbox.pack_start(self.filechooserhbox,False,False,5) + # ADD FILENAME LABEL HERE + # ^^^^^ FILE PICKER THING ^^^^^ + # START OF STICK CONTROLS + self.stickcontrols = gtk.VBox() + self.stickcontrols.show() + self.stickcontrolsborder = gtk.EventBox() + self.stickcontrolsborder.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(PINK)) + self.stickcontrolsborder.set_border_width(5) + self.stickcontrolsborder.show() + self.stickcontrolsframe = gtk.EventBox() + self.stickcontrolsframe.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(BUTTON_BACKGROUND)) + self.stickcontrolsframe.set_border_width(5) + self.stickcontrolsframe.show() + self.stickcontrolsborder.add(self.stickcontrolsframe) + self.stickcontrolsframe.add(self.stickcontrols) + self.anglesizehbox = gtk.HBox() + self.anglesizehbox.show() + #label = gtk.Label('Angle:') + self.anglelabel = gtk.Label(LANG[self.language]['angle']+':') + self.anglelabel.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BUTTON_BACKGROUND)) + self.anglelabel.show() + self.anglesizehbox.pack_start(self.anglelabel,False,False,5) + self.angleentry = gtk.Entry() + self.angleentry.set_max_length(3) + self.angleentry.set_width_chars(3) + self.angleentry.connect('activate', self.enterangle_callback, self.angleentry) + self.angleentry.show() + self.anglesizehbox.pack_start(self.angleentry,False,False,0) + #label = gtk.Label('Size:') + self.sizelabel = gtk.Label(LANG[self.language]['size']+':') + self.sizelabel.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BUTTON_BACKGROUND)) + self.sizelabel.show() + self.anglesizehbox.pack_start(self.sizelabel,False,False,5) + self.sizeentry = gtk.Entry() + self.sizeentry.set_max_length(3) + self.sizeentry.set_width_chars(3) + self.sizeentry.connect('activate', self.enterlen_callback, self.sizeentry) + self.sizeentry.show() + self.anglesizehbox.pack_start(self.sizeentry,False,False,0) + self.asbox = gtk.EventBox() + self.asbox.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(BUTTON_FOREGROUND)) + self.asbox.show() + self.asbox.add(self.anglesizehbox) + self.stickcontrols.pack_start(self.asbox,False,False,0) + self.stickbuttons = {} + self.sticklabels = {} + for stickpartname in self.labellist: + #label = gtk.Label(capwords(stickpartname)) + label = gtk.Label(LANG[self.language][stickpartname]) + label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BUTTON_FOREGROUND)) + label.show() + self.sticklabels[stickpartname] = label + ebox = gtk.EventBox() + ebox.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(BUTTON_BACKGROUND)) + ebox.show() + ebox.set_events(gtk.gdk.BUTTON_PRESS_MASK) + ebox.connect('button_press_event',self.selectstick,stickpartname) + ebox.add(label) + self.stickbuttons[stickpartname] = ebox + self.stickcontrols.pack_start(ebox,False,False,0) + # highlight the currently selected stick and update the entry boxes + self.selectstickebox() + # END OF STICK CONTROLS + stickalign = gtk.Alignment(1.0,1.0,1.0,1.0) + stickalign.add(self.stickcontrolsborder) + stickalign.set_padding(80,5,5,5) # top,bottom,left,right + stickalign.show() + self.rightvbox.pack_start(stickalign,False,False, 0) + #self.rightvbox.pack_start(self.stickcontrolsborder,False,False, 0) + #self.filesave = gtk.Button() + #self.filesave.set_label('SAVE') + #prepare_btn(self.filesave) + #self.filesave.connect('clicked',self.savefile,None) + #self.filesave.show() + #self.fshbox = gtk.HBox() + #self.fshbox.show() + #self.fshbox.pack_start(self.filesave,True,False,0) + #self.rightvbox.pack_start(self.fshbox,True,False,0) + self.export = gtk.Button() + #self.export.set_label('EXPORT') + self.export.set_label(LANG[self.language]['export']) + prepare_btn(self.export) + self.export.connect('clicked',self.exportanim,None) + self.export.show() + self.exporthbox = gtk.HBox() + self.exporthbox.show() + self.exporthbox.pack_start(self.export,True,False,0) + self.rightvbox.pack_start(self.exporthbox,True,False,0) + + self.hbox.pack_start(self.rightvbox,False,False,0) + +try: + from sugar.activity import activity + from sugar.presence import presenceservice + from sugar.presence.tubeconn import TubeConnection + import telepathy + import telepathy.client + from dbus import Interface + from dbus.service import method, signal + from dbus.gobject_service import ExportedGObject + + class flipsticksActivity(activity.Activity): + def __init__(self, handle): + activity.Activity.__init__(self,handle) + self.connect("destroy",self.destroy_cb) + bundle_path = activity.get_bundle_path() + os.chdir(bundle_path) + self.set_title('FlipSticks') + toolbox = activity.ActivityToolbox(self) + self.set_toolbox(toolbox) + toolbox.show() + if hasattr(self, '_jobject'): + self._jobject.metadata['title'] = 'FlipSticks' + title_widget = toolbox._activity_toolbar.title + title_widget.set_size_request(title_widget.get_layout().get_pixel_size()[0] + 20, -1) + self.app = flipsticks(self, bundle_path) + self.app.insugar = True + outerframe = gtk.EventBox() + outerframe.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(BUTTON_BACKGROUND)) + outerframe.show() + innerframe = gtk.EventBox() + innerframe.show() + ifalign = gtk.Alignment(1.0,1.0,1.0,1.0) + ifalign.add(innerframe) + ifalign.set_padding(20,20,50,50) # top,bottom,left,right + ifalign.show() + #innerframe.set_border_width(150) + outerframe.add(ifalign) + innerframe.add(self.app.main) + self.set_canvas(outerframe) + + + # mesh stuff + self.pservice = presenceservice.get_instance() + owner = self.pservice.get_owner() + self.owner = owner + try: + name, path = self.pservice.get_preferred_connection() + self.tp_conn_name = name + self.tp_conn_path = path + self.conn = telepathy.client.Connection(name, path) + except TypeError: + pass + self.initiating = None + + #sharing stuff + self.game = None + self.connect('shared', self._shared_cb) + if self._shared_activity: + # we are joining the activity + self.connect('joined', self._joined_cb) + if self.get_shared(): + # oh, OK, we've already joined + self._joined_cb() + else: + # we are creating the activity + pass + + def destroy_cb(self, data=None): + return True + + def read_file(self, filepath): + f = file(filepath) + sdata = f.read() + f.close() + self.app.restore(sdata) + + def write_file(self, filepath): + sdata = self.app.getsdata() + f = open(filepath,'w') + f.write(sdata) + f.close() + + def _shared_cb(self,activity): + self.initiating = True + self._setup() + id = self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].OfferDBusTube( + SERVICE, {}) + #self.app.export.set_label('Shared Me') + + def _joined_cb(self,activity): + if self.game is not None: + return + + if not self._shared_activity: + return + + #for buddy in self._shared_activity.get_joined_buddies(): + # self.buddies_panel.add_watcher(buddy) + + #logger.debug('Joined an existing Connect game') + #self.app.export.set_label('Joined You') + self.initiating = False + self._setup() + + #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 _setup(self): + if self._shared_activity is None: + return + + bus_name, conn_path, channel_paths = self._shared_activity.get_channels() + + # Work out what our room is called and whether we have Tubes already + room = None + tubes_chan = None + text_chan = None + for channel_path in channel_paths: + channel = telepathy.client.Channel(bus_name, channel_path) + htype, handle = channel.GetHandle() + if htype == telepathy.HANDLE_TYPE_ROOM: + #logger.debug('Found our room: it has handle#%d "%s"', + # handle, self.conn.InspectHandles(htype, [handle])[0]) + room = handle + ctype = channel.GetChannelType() + if ctype == telepathy.CHANNEL_TYPE_TUBES: + #logger.debug('Found our Tubes channel at %s', channel_path) + tubes_chan = channel + elif ctype == telepathy.CHANNEL_TYPE_TEXT: + #logger.debug('Found our Text channel at %s', channel_path) + text_chan = channel + + if room is None: + #logger.error("Presence service didn't create a room") + return + if text_chan is None: + #logger.error("Presence service didn't create a text channel") + return + + # Make sure we have a Tubes channel - PS doesn't yet provide one + if tubes_chan is None: + #logger.debug("Didn't find our Tubes channel, requesting one...") + tubes_chan = self.conn.request_channel(telepathy.CHANNEL_TYPE_TUBES, + telepathy.HANDLE_TYPE_ROOM, room, True) + + self.tubes_chan = tubes_chan + self.text_chan = text_chan + + tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal('NewTube', + self._new_tube_cb) + + def _list_tubes_reply_cb(self, tubes): + for tube_info in tubes: + self._new_tube_cb(*tube_info) + + def _list_tubes_error_cb(self, e): + #logger.error('ListTubes() failed: %s', e) + pass + + def _new_tube_cb(self, id, initiator, type, service, params, state): + #logger.debug('New tube: ID=%d initator=%d type=%d service=%s ' + # 'params=%r state=%d', id, initiator, type, service, + # params, state) + + if (self.game is None and type == telepathy.TUBE_TYPE_DBUS and + service == SERVICE): + if state == telepathy.TUBE_STATE_LOCAL_PENDING: + self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].AcceptDBusTube(id) + + 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.initiating, self) + + class ConnectGame(ExportedGObject): + def __init__(self,tube, is_initiator, activity): + super(ConnectGame,self).__init__(tube,PATH) + self.tube = tube + self.is_initiator = is_initiator + self.entered = False + self.activity = activity + + self.ordered_bus_names=[] + self.tube.watch_participants(self.participant_change_cb) + + def participant_change_cb(self, added, removed): + if not self.entered: + if self.is_initiator: + self.add_hello_handler() + else: + self.Hello() + self.entered = True + + @signal(dbus_interface=IFACE,signature='') + def Hello(self): + """Request that this player's Welcome method is called to bring it + up to date with the game state. + """ + + @method(dbus_interface=IFACE, in_signature='s', out_signature='') + def Welcome(self, sdata): + self.activity.app.restore(str(sdata)) + + def add_hello_handler(self): + self.tube.add_signal_receiver(self.hello_cb, 'Hello', IFACE, + path=PATH, sender_keyword='sender') + + def hello_cb(self, sender=None): + self.tube.get_object(sender, PATH).Welcome(self.activity.app.getsdata(),dbus_interface=IFACE) + +except ImportError: + pass + +if __name__ == '__main__': + toplevel_window = gtk.Window(gtk.WINDOW_TOPLEVEL) + mdirpath = os.path.abspath(os.curdir) + app = flipsticks(toplevel_window,mdirpath) + toplevel_window.add(app.main) + toplevel_window.set_title('FlipSticks') + toplevel_window.connect('delete_event', app.delete_event) + toplevel_window.connect('destroy', app.destroy) + toplevel_window.show() + gtk.main() |