# -*- coding: utf-8 -*- #Copyright (c) 2007-8, Playful Invention Company. #Copyright (c) 2008-10, Walter Bender #Copyright (c) 2008-10, Raúl Gutiérrez Segalés #Permission is hereby granted, free of charge, to any person obtaining a copy #of this software and associated documentation files (the "Software"), to deal #in the Software without restriction, including without limitation the rights #to use, copy, modify, merge, publish, distribute, sublicense, and/or sell #copies of the Software, and to permit persons to whom the Software is #furnished to do so, subject to the following conditions: #The above copyright notice and this permission notice shall be included in #all copies or substantial portions of the Software. #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, #OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN #THE SOFTWARE. import gtk import gobject from time import clock from math import sqrt from random import uniform from operator import isNumberType import audioop import subprocess from UserDict import UserDict try: from sugar.datastore import datastore except: pass from taconstants import PRIMITIVES, PALETTES, PALETTE_NAMES, STATUS_LAYER,\ TEMPLATES, BOX_STYLE from tagplay import play_audio, play_movie_from_file, stop_media from tajail import myfunc, myfunc_import from tautils import get_pixbuf_from_journal, movie_media_type,\ audio_media_type, round_int from gettext import gettext as _ procstop = False class noKeyError(UserDict): __missing__=lambda x,y: 0 class symbol: def __init__(self, name): self.name = name self.nargs = None self.fcn = None def __str__(self): return self.name def __repr__(self): return '#'+self.name class logoerror(Exception): def __init__(self, value): self.value = value def __str__(self): return repr(self.value) """ Utility functions """ def careful_divide(x,y): try: if y==0: return 0 return x/y except: return 0 def taequal(x,y): try: return float(x)==float(y) except: if type(x) == str or type(x) == unicode: xx = ord(x[0]) else: xx = x if type(y) == str or type(y) == unicode: yy = ord(y[0]) else: yy = y return xx==yy def taless(x, y): try: return float(x)4: # There could be a '(', ')', '[' or ']'. code.append(dock[4]) if blk.primitive is not None: code.append(blk.primitive) if blk.name not in BOX_STYLE: self.blk_index.append(self.tw.block_list.list.index(blk)) elif len(blk.values)>0: # Extract the value from content blocks. if blk.name=='number': try: code.append(float(blk.values[0])) except ValueError: code.append(float(ord(blk.values[0][0]))) elif blk.name=='string' or blk.name=='title': if type(blk.values[0]) == float or type(blk.values[0]) == int: if int(blk.values[0]) == blk.values[0]: blk.values[0] = int(blk.values[0]) code.append('#s'+str(blk.values[0])) else: code.append('#s'+blk.values[0]) elif blk.name=='journal': if blk.values[0] is not None: code.append('#smedia_'+str(blk.values[0])) else: code.append('#smedia_None') elif blk.name=='description': if blk.values[0] is not None: code.append('#sdescr_'+str(blk.values[0])) else: code.append('#sdescr_None') elif blk.name=='audio': if blk.values[0] is not None: code.append('#saudio_'+str(blk.values[0])) else: code.append('#saudio_None') else: print "%s had no primitive." % (blk.name) return ['%nothing%'] else: print "%s had no value." % (blk.name) return ['%nothing%'] for i in range(1, len(blk.connections)): b = blk.connections[i] dock = blk.docks[i] if len(dock)>4: # There could be a '(', ')', '[' or ']'. for c in dock[4]: code.append(c) if b is not None: code.extend(self.blocks_to_code(b)) elif blk.docks[i][0] not in ['flow', 'unavailable']: code.append('%nothing%') return code """ Execute the psuedocode. """ def setup_cmd(self, str): self.tw.active_turtle.hide() # Hide the turtle while we are running. self.procstop = False list = self.readline(str) self.step = self.start_eval(list) """ Convert the pseudocode into a list of commands. """ def readline(self, line): res = [] while line: token = line.pop(0) if isNumberType(token): res.append(token) elif token.isdigit(): res.append(float(token)) elif token[0]=='-' and token[1:].isdigit(): res.append(-float(token[1:])) elif token[0] == '"': res.append(token[1:]) elif token[0:2] == "#s": res.append(token[2:]) elif token == '[': res.append(self.readline(line)) elif token == ']': return res else: res.append(self.intern(token)) return res """ Step through the list. """ def start_eval(self, list): self.icall(self.evline, list) yield True if self.tw.running_sugar: self.tw.activity.stop_button.set_icon("stopitoff") yield False """ Add a function and its arguments to the program stack. """ def icall(self, fcn, *args): self.istack.append(self.step) self.step = fcn(*(args)) """ Evaluate a line of code from the list. """ def evline(self, list): oldiline = self.iline self.iline = list[:] self.arglist = None while self.iline: if self.tw.step_time > 0: b = self.tw.block_list.list[self.blk_index[self.bi]] b.highlight() self.tw.active_turtle.show() endtime = millis()+self.an_int(self.tw.step_time)*100 while millis()>>>>>>>>>>>>>>>>>>>> in the clear" self.highlighter("clear") print "after call to highlight" stop_media(self) self.tw.canvas.clearscreen() print "unhighlighting" self.unhighlight("plus") def prim_fillscreen(self): self.highlighter("clear") self.tw.canvas.fillscreen(x, y) self.unhighlight("clear") def prim_right(self, x): self.highlighter("left/right") self.tw.canvas.right(x) self.unhighlight("left/right") def prim_forward(self, x): self.highlighter("back/forward") self.tw.canvas.forward(x) self.unhighlight("back/forward") def prim_setheading(self, x): self.highlighter("seth") self.tw.canvas.seth(x) self.unhighlight("seth") def prim_arc(self, x, y): self.highlighter("arc") self.tw.canvas.arc(x, y) self.unhighlight("arc") def prim_setxy(self, x, y): self.highlighter("setxy") self.tw.canvas.setxy(x, y) self.unhighlight("setxy") def prim_show(self, x, y): self.highlighter("show") self.show(x, True) self.unhighlight("show") def prim_setpen(self, x): self.highlighter("pendown/up") self.tw.canvas.setpen(x) self.unhighlight("pendown/up") def prim_setpensize(self, x): self.highlighter("setpensize") self.tw.canvas.setpensize(x) self.unhighlight("setpensize") def prim_setcolor(self, x): self.highlighter("setcolor") self.tw.canvas.setcolor(x) self.unhighlight("setcolor") def prim_setshade(self, x): self.highlighter("setcolor") self.tw.canvas.setshade(x) self.unhighlight("setcolor") def prim_start(self): self.highlighter("start") if self.tw.running_sugar: self.tw.activity.recenter() self.unhighlight("start") def prim_wait(self, time): self.highlighter("wait") self.tw.active_turtle.show() endtime = millis()+self.an_int(time*1000) while millis() 0: b = self.tw.block_list.list[self.blk_index[self.bi-1]] b.unhighlight() print "exiting block %s: (%d: %s)" % (name, self.bi, b.name) """ Everything below is related to multimedia commands """ def show_picture(self, media, x, y, w, h): if media == "" or media[6:] == "": pass elif media[6:] is not "None": pixbuf = None if self.tw.running_sugar: try: dsobject = datastore.get(media[6:]) except: print "Couldn't open Journal object %s" % (media[6:]) if movie_media_type(dsobject.file_path[-4:]): play_movie_from_file(self, dsobject.file_path, int(x), int(y), int(w), int(h)) else: pixbuf = get_pixbuf_from_journal(dsobject, int(w), int(h)) dsobject.destroy() else: try: if movie_media_type(media[-4:]): play_movie_from_file(self, media[6:], int(x), int(y), int(w), int(h)) else: pixbuf = gtk.gdk.pixbuf_new_from_file_at_size( media[6:], int(w), int(h)) except: print "Couldn't open media object %s" % (media[6:]) if pixbuf is not None: self.tw.canvas.draw_pixbuf(pixbuf, 0, 0, int(x), int(y), int(w), int(h)) def show_description(self, media, x, y, w, h): if media == "" or media[6:] == "": pass elif media[6:] is not "None": text = None if self.tw.running_sugar: try: dsobject = datastore.get(media[6:]) text = str(dsobject.metadata['description']) dsobject.destroy() except: print "no description in %s" % (media[6:]) else: try: f = open(media[6:], 'r') text = f.read() f.close() except: print "no text in %s?" % (media[6:]) if text is not None: print "text: %s" % (text) self.tw.canvas.draw_text(text, int(x), int(y), self.body_height, int(w)) def draw_title(self, title, x, y): self.tw.canvas.draw_text(title,int(x),int(y),self.title_height, self.tw.canvas.width-x) # title, one image, and description def show_template1x1(self, title, media): print "entering tp1x1 %d" % (self.bi) self.bi += 1 w,h,xo,yo,dx,dy = calc_position(self.tw, 't1x1') x = -(self.tw.canvas.width/2)+xo y = self.tw.canvas.height/2 self.tw.canvas.setxy(x, y) # save the text size so we can restore it later save_text_size = self.tw.textsize # set title text self.tw.canvas.settextsize(self.title_height) self.show(title) # calculate and set scale for media blocks myscale = 45 * (self.tw.canvas.height - self.title_height*2) \ / self.tw.canvas.height self.set_scale(myscale) # set body text size self.tw.canvas.settextsize(self.body_height) # render media object # leave some space below the title y -= int(self.title_height*2*self.tw.lead) self.tw.canvas.setxy(x, y) self.show(media) if self.tw.running_sugar: x = 0 self.tw.canvas.setxy(x, y) self.show(media.replace("media_","descr_")) # restore text size self.tw.canvas.settextsize(save_text_size) # title, two images (horizontal), two descriptions def show_template2x1(self, title, media1, media2): print "entering tp2x1 %d" % (self.bi) self.bi += 1 w,h,xo,yo,dx,dy = calc_position(self.tw, 't2x1') x = -(self.tw.canvas.width/2)+xo y = self.tw.canvas.height/2 self.tw.canvas.setxy(x, y) # save the text size so we can restore it later save_text_size = self.tw.textsize # set title text self.tw.canvas.settextsize(self.title_height) self.show(title) # calculate and set scale for media blocks myscale = 45 * (self.tw.canvas.height - self.title_height*2)/\ self.tw.canvas.height self.set_scale(myscale) # set body text size self.tw.canvas.settextsize(self.body_height) # render four quadrents # leave some space below the title y -= int(self.title_height*2*self.tw.lead) self.tw.canvas.setxy(x, y) self.show(media1) x = 0 self.tw.canvas.setxy(x, y) self.show(media2) y = -self.title_height if self.tw.running_sugar: self.tw.canvas.setxy(x, y) self.show(media2.replace("media_","descr_")) x = -(self.tw.canvas.width/2)+xo self.tw.canvas.setxy(x, y) self.show(media1.replace("media_","descr_")) # restore text size self.tw.canvas.settextsize(save_text_size) # title and varible number of bullets def show_bullets(self, title, sarray): w,h,xo,yo,dx,dy = calc_position(self.tw, 'bullet') x = -(self.tw.canvas.width/2)+xo y = self.tw.canvas.height/2 self.tw.canvas.setxy(x, y) # save the text size so we can restore it later save_text_size = self.tw.textsize # set title text self.tw.canvas.settextsize(self.title_height) self.show(title) # set body text size self.tw.canvas.settextsize(self.bullet_height) # leave some space below the title y -= int(self.title_height*2*self.tw.lead) for s in sarray: self.tw.canvas.setxy(x, y) self.show(s) y -= int(self.bullet_height*2*self.tw.lead) # restore text size self.tw.canvas.settextsize(save_text_size) # title, two images (vertical), two desciptions def show_template1x2(self, title, media1, media2): print "entering tp1x2 %d" % (self.bi) self.bi += 1 w,h,xo,yo,dx,dy = calc_position(self.tw, 't1x2') x = -(self.tw.canvas.width/2)+xo y = self.tw.canvas.height/2 self.tw.canvas.setxy(x, y) # save the text size so we can restore it later save_text_size = self.tw.textsize # set title text self.tw.canvas.settextsize(self.title_height) self.show(title) # calculate and set scale for media blocks myscale = 45 * (self.tw.canvas.height - self.title_height*2)/\ self.tw.canvas.height self.set_scale(myscale) # set body text size self.tw.canvas.settextsize(self.body_height) # render four quadrents # leave some space below the title y -= int(self.title_height*2*self.tw.lead) self.tw.canvas.setxy(x, y) self.show(media1) if self.tw.running_sugar: x = 0 self.tw.canvas.setxy(x, y) self.show(media1.replace("media_","descr_")) y = -self.title_height self.tw.canvas.setxy(x, y) self.show(media2.replace("media_","descr_")) x = -(self.tw.canvas.width/2)+xo self.tw.canvas.setxy(x, y) self.show(media2) # restore text size self.tw.canvas.settextsize(save_text_size) # title and four images def show_template2x2(self, title, media1, media2, media3, media4): print "entering tp2x2 %d" % (self.bi) self.bi += 1 w,h,xo,yo,dx,dy = calc_position(self.tw, 't2x2') x = -(self.tw.canvas.width/2)+xo y = self.tw.canvas.height/2 self.tw.canvas.setxy(x, y) # save the text size so we can restore it later save_text_size = self.tw.textsize # set title text self.tw.canvas.settextsize(self.title_height) self.show(title) # calculate and set scale for media blocks myscale = 45 * (self.tw.canvas.height - self.title_height*2)/\ self.tw.canvas.height self.set_scale(myscale) # set body text size self.tw.canvas.settextsize(self.body_height) # render four quadrents # leave some space below the title y -= int(self.title_height*2*self.tw.lead) self.tw.canvas.setxy(x, y) self.show(media1) x = 0 self.tw.canvas.setxy(x, y) self.show(media2) y = -self.title_height self.tw.canvas.setxy(x, y) self.show(media4) x = -(self.tw.canvas.width/2)+xo self.tw.canvas.setxy(x, y) self.show(media3) # restore text size self.tw.canvas.settextsize(save_text_size) # title, one media object def show_template1x1a(self, title, media1): print "entering tp1x1a %d" % (self.bi) self.bi += 1 w,h,xo,yo,dx,dy = calc_position(self.tw, 't1x1a') x = -(self.tw.canvas.width/2)+xo y = self.tw.canvas.height/2 self.tw.canvas.setxy(x, y) # save the text size so we can restore it later save_text_size = self.tw.textsize # set title text self.tw.canvas.settextsize(self.title_height) self.show(title) # calculate and set scale for media blocks myscale = 90 * (self.tw.canvas.height - self.title_height*2) /\ self.tw.canvas.height self.set_scale(myscale) # set body text size self.tw.canvas.settextsize(self.body_height) # render media object # leave some space below the title y -= int(self.title_height*2*self.tw.lead) self.tw.canvas.setxy(x, y) self.show(media1) # restore text size self.tw.canvas.settextsize(save_text_size) # image only (at current x,y) def insert_image(self, media, center): w = (self.tw.canvas.width * self.scale)/100 h = (self.tw.canvas.height * self.scale)/100 # convert from Turtle coordinates to screen coordinates x = self.tw.canvas.width/2+int(self.tw.canvas.xcor) y = self.tw.canvas.height/2-int(self.tw.canvas.ycor) if center is True: x -= w/2 y -= h/2 if media[0:5] == 'media': self.show_picture(media, x, y, w, h) # description text only (at current x,y) def insert_desc(self, media): w = (self.tw.canvas.width * self.scale)/100 h = (self.tw.canvas.height * self.scale)/100 # convert from Turtle coordinates to screen coordinates x = self.tw.canvas.width/2+int(self.tw.canvas.xcor) y = self.tw.canvas.height/2-int(self.tw.canvas.ycor) if media[0:5] == 'descr': self.show_description(media, x, y, w, h) def set_scale(self, x): self.highlighter("set") self.bi += 1 self.scale = x # need to fix export logo to map show to write def show(self, string, center=False): # convert from Turtle coordinates to screen coordinates x = self.tw.canvas.width/2+int(self.tw.canvas.xcor) y = self.tw.canvas.height/2-int(self.tw.canvas.ycor) if type(string) == str or type(string) == unicode: if string == "media_None": pass elif string[0:6] == 'media_': self.insert_image(string, center) elif string[0:6] == 'descr_': self.insert_desc(string) elif string[0:6] == 'audio_': self.play_sound(string) else: if center is True: y -= self.tw.textsize self.tw.canvas.draw_text(string,x,y,self.tw.textsize, self.tw.canvas.width-x) elif type(string) == float or type(string) == int: string = round_int(string) if center is True: y -= self.tw.textsize self.tw.canvas.draw_text(string, x, y, self.tw.textsize, self.tw.canvas.width-x) def play_sound(self, audio): if audio == "" or audio[6:] == "": raise logoerror("#nomedia") if self.tw.running_sugar: if audio[6:] != "None": try: dsobject = datastore.get(audio[6:]) play_audio(self, dsobject.file_path) except: print "Couldn't open id: " + str(audio[6:]) else: play_audio(self, audio[6:]) def write(self, string, fsize): self.highlighter("write") # convert from Turtle coordinates to screen coordinates x = self.tw.canvas.width/2+int(self.tw.canvas.xcor) y = self.tw.canvas.height/2-int(self.tw.canvas.ycor) self.tw.canvas.draw_text(string,x,y-15,int(fsize),self.tw.canvas.width) self.unhighlight("write")