Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWalter Bender <walter@walter-laptop.(none)>2009-03-29 15:52:58 (GMT)
committer Walter Bender <walter@walter-laptop.(none)>2009-03-29 15:52:58 (GMT)
commit7791cf357149e29b279090251ab0769fda9a3fe1 (patch)
treee42e826d36642237a1bd933b6dd305fd093fdd62
parenta80d14a4f1c96c3f91bb1ee666b3ce132637bb54 (diff)
rcenter on start block
-rw-r--r--TurtleArtActivity.py2
-rw-r--r--tagplay.py220
-rw-r--r--talogo.py16
-rw-r--r--taproject.py29
-rw-r--r--tasetup.py2
-rw-r--r--tasprites.py8
-rw-r--r--taturtle.py11
-rw-r--r--tawindow.py2
8 files changed, 157 insertions, 133 deletions
diff --git a/TurtleArtActivity.py b/TurtleArtActivity.py
index 3b4ee42..9f76e4d 100644
--- a/TurtleArtActivity.py
+++ b/TurtleArtActivity.py
@@ -733,7 +733,6 @@ class ProjectToolbar(gtk.Toolbar):
def do_run(self, button):
self.runproject.set_icon("run-faston")
self.stop.set_icon("stopiton")
- self.activity.recenter()
tawindow.runbutton(self.activity.tw, 0)
gobject.timeout_add(1000,self.runproject.set_icon,"run-fastoff")
gobject.timeout_add(1000,self.stepproject.set_icon,"run-slowoff")
@@ -741,7 +740,6 @@ class ProjectToolbar(gtk.Toolbar):
def do_step(self, button):
self.stepproject.set_icon("run-slowon")
self.stop.set_icon("stopiton")
- self.activity.recenter()
tawindow.runbutton(self.activity.tw, 3)
gobject.timeout_add(1000,self.stepproject.set_icon,"run-slowoff")
gobject.timeout_add(1000,self.runproject.set_icon,"run-fastoff")
diff --git a/tagplay.py b/tagplay.py
index 9caaea4..3d7bb59 100644
--- a/tagplay.py
+++ b/tagplay.py
@@ -1,7 +1,32 @@
+#Copyright (c) 2009, Walter Bender (on behalf of Sugar Labs)
+
+#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.
+
+"""
+Video and audio playback
+
+Based on code snippets from
+http://wiki.sugarlabs.org/go/Development_Team/Almanac/GStreamer
+"""
import gtk
import pygtk
pygtk.require('2.0')
-# import sys
import pygst
pygst.require('0.10')
import gst
@@ -15,105 +40,99 @@ from talogo import *
class Gplay:
- def __init__(self):
- self.window = None
- self.playing = False
-
- self.player = gst.element_factory_make("playbin", "playbin")
- xis = gst.element_factory_make("xvimagesink", "xvimagesink")
- self.player.set_property("video-sink", xis)
- bus = self.player.get_bus()
- bus.enable_sync_message_emission()
- bus.add_signal_watch()
- self.SYNC_ID = bus.connect('sync-message::element', self._onSyncMessageCb)
-
-
- def _onSyncMessageCb(self, bus, message):
- if message.structure is None:
- return True
- if message.structure.get_name() == 'prepare-xwindow-id':
- self.window.set_sink(message.src)
- message.src.set_property('force-aspect-ratio', True)
- return True
-
-
- def setFile(self, path):
- uri = "file://" + str( path )
- if (self.player.get_property('uri') == uri):
- self.seek(gst.SECOND*0)
- return
-
- self.player.set_state(gst.STATE_READY)
- self.player.set_property('uri', uri)
- ext = uri[len(uri)-3:]
- if (ext == "jpg"):
- self.pause()
- else:
- self.play()
-
-
- def queryPosition(self):
- #"Returns a (position, duration) tuple"
- try:
- position, format = self.player.query_position(gst.FORMAT_TIME)
- except:
- position = gst.CLOCK_TIME_NONE
-
- try:
- duration, format = self.player.query_duration(gst.FORMAT_TIME)
- except:
- duration = gst.CLOCK_TIME_NONE
-
- return (position, duration)
-
-
- def seek(self, time):
- event = gst.event_new_seek(1.0, gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH | \
- gst.SEEK_FLAG_ACCURATE, gst.SEEK_TYPE_SET, time, gst.SEEK_TYPE_NONE, 0)
- res = self.player.send_event(event)
- if res:
- self.player.set_new_stream_time(0L)
-
-
- def pause(self):
- self.playing = False
- self.player.set_state(gst.STATE_PAUSED)
-
-
- def play(self):
- self.playing = True
- self.player.set_state(gst.STATE_PLAYING)
-
-
- def stop(self):
- self.playing = False
- self.player.set_state(gst.STATE_NULL)
- # self.nextMovie()
-
-
- def get_state(self, timeout=1):
- return self.player.get_state(timeout=timeout)
-
-
- def is_playing(self):
- return self.playing
+ def __init__(self):
+ self.window = None
+ self.playing = False
+
+ self.player = gst.element_factory_make("playbin", "playbin")
+ xis = gst.element_factory_make("xvimagesink", "xvimagesink")
+ self.player.set_property("video-sink", xis)
+ bus = self.player.get_bus()
+ bus.enable_sync_message_emission()
+ bus.add_signal_watch()
+ self.SYNC_ID = bus.connect('sync-message::element', \
+ self._onSyncMessageCb)
+
+ def _onSyncMessageCb(self, bus, message):
+ if message.structure is None:
+ return True
+ if message.structure.get_name() == 'prepare-xwindow-id':
+ self.window.set_sink(message.src)
+ message.src.set_property('force-aspect-ratio', True)
+ return True
+
+ def setFile(self, path):
+ uri = "file://" + str( path )
+ if (self.player.get_property('uri') == uri):
+ self.seek(gst.SECOND*0)
+ return
+
+ self.player.set_state(gst.STATE_READY)
+ self.player.set_property('uri', uri)
+ ext = uri[len(uri)-3:]
+ if (ext == "jpg"):
+ self.pause()
+ else:
+ self.play()
+
+ def queryPosition(self):
+ #"Returns a (position, duration) tuple"
+ try:
+ position, format = self.player.query_position(gst.FORMAT_TIME)
+ except:
+ position = gst.CLOCK_TIME_NONE
+ try:
+ duration, format = self.player.query_duration(gst.FORMAT_TIME)
+ except:
+ duration = gst.CLOCK_TIME_NONE
+ return (position, duration)
+
+ def seek(self, time):
+ event = gst.event_new_seek(1.0,\
+ gst.FORMAT_TIME,\
+ gst.SEEK_FLAG_FLUSH|gst.SEEK_FLAG_ACCURATE,\
+ gst.SEEK_TYPE_SET,\
+ time,\
+ gst.SEEK_TYPE_NONE, 0)
+ res = self.player.send_event(event)
+ if res:
+ self.player.set_new_stream_time(0L)
+
+ def pause(self):
+ self.playing = False
+ self.player.set_state(gst.STATE_PAUSED)
+
+ def play(self):
+ self.playing = True
+ self.player.set_state(gst.STATE_PLAYING)
+
+ def stop(self):
+ self.playing = False
+ self.player.set_state(gst.STATE_NULL)
+ # self.nextMovie()
+
+ def get_state(self, timeout=1):
+ return self.player.get_state(timeout=timeout)
+
+ def is_playing(self):
+ return self.playing
class PlayVideoWindow(gtk.Window):
- def __init__(self):
- gtk.Window.__init__(self)
- self.imagesink = None
- self.unset_flags(gtk.DOUBLE_BUFFERED)
- self.set_flags(gtk.APP_PAINTABLE)
+ def __init__(self):
+ gtk.Window.__init__(self)
+ self.imagesink = None
+ self.unset_flags(gtk.DOUBLE_BUFFERED)
+ self.set_flags(gtk.APP_PAINTABLE)
- def set_sink(self, sink):
- if (self.imagesink != None):
- assert self.window.xid
- self.imagesink = None
- del self.imagesink
+ def set_sink(self, sink):
+ if (self.imagesink != None):
+ assert self.window.xid
+ self.imagesink = None
+ del self.imagesink
- self.imagesink = sink
- self.imagesink.set_xwindow_id(self.window.xid)
+ self.imagesink = sink
+ self.imagesink.set_xwindow_id(self.window.xid)
def play_audio(lc, audio):
print "loading audio id: " + str(audio)
@@ -161,11 +180,10 @@ def stop_media(lc):
return
lc.gplay.stop()
if lc.gplay.window != None:
- # need to figure out how to destroy the video window
-# lc.gplay.window.destroy()
-# lc.gplay == None
- # but meanwhile, just shrink it
+ # We need to figure out how to destroy the video window
+ #lc.gplay.window.destroy()
+ #lc.gplay == None
+
+ # But meanwhile, just shrink it
lc.gplay.window.move( 0, 0 )
lc.gplay.window.resize( 1, 1 )
-
-
diff --git a/talogo.py b/talogo.py
index d5dce93..65a96b8 100644
--- a/talogo.py
+++ b/talogo.py
@@ -1,4 +1,4 @@
-#Copyright (c) 2007, Playful Invention Company.
+#Copyright (c) 2007-8, Playful Invention Company.
#Copyright (c) 2008-9, Walter Bender
#Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -376,6 +376,11 @@ def tasqrt(x):
def identity(x):
return(x)
+# recenter the canvas when the start block is clicked
+def start_stack(lc):
+ if hasattr(lc.tw,'activity'):
+ lc.tw.activity.recenter()
+
def lcNew(tw):
lc = taLogo()
lc.tw = tw
@@ -462,7 +467,7 @@ def lcNew(tw):
defprim(lc,'nop1', 0, lambda lc: None)
defprim(lc,'nop2', 0, lambda lc: None)
defprim(lc,'nop3', 1, lambda lc,x: None)
- defprim(lc,'start', 0, lambda: None)
+ defprim(lc,'start', 0, lambda lc: start_stack(lc))
defprim(lc,'tp1', 2, lambda lc,x,y: show_template1(lc, x, y))
defprim(lc,'tp8', 2, lambda lc,x,y: show_template8(lc, x, y))
@@ -549,7 +554,8 @@ def show_picture(lc, media, x, y, w, h):
def get_pixbuf_from_journal(dsobject,w,h):
try:
- pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(dsobject.file_path,int(w),int(h))
+ pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(dsobject.file_path, \
+ int(w),int(h))
except:
try:
# print "Trying preview..."
@@ -573,8 +579,8 @@ def show_description(lc, media, x, y, w, h):
try:
dsobject = datastore.get(media[6:])
draw_text(lc.tw.turtle, \
- dsobject.metadata['description'],int(x),int(y), \
- lc.body_height, int(w))
+ dsobject.metadata['description'],int(x),int(y), \
+ lc.body_height, int(w))
dsobject.destroy()
except:
print "no description?"
diff --git a/taproject.py b/taproject.py
index b7ff1a2..71550cb 100644
--- a/taproject.py
+++ b/taproject.py
@@ -1,4 +1,5 @@
-#Copyright (c) 2007-9, Playful Invention Company.
+#Copyright (c) 2007-8, Playful Invention Company.
+#Copyright (c) 2008-9, Walter Bender
#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
@@ -22,7 +23,6 @@ import pygtk
pygtk.require('2.0')
import gtk
import pickle
-#import cjson
try:
import json
json.dumps
@@ -57,19 +57,20 @@ def load_files(tw,ta_file, png_file=''):
# print "reading saved json data"
f.seek(0) # rewind necessary because of pickle.load
text = f.read()
-# listdata = cjson.decode(text)
listdata = json.decode(text)
data = tuplify(listdata) # json converts tuples to lists
f.close()
new_project(tw)
read_data(tw,data)
# don't load the png_file -- we run the program instead
- # if png_file != '':
- # try:
- # load_pict(tw,png_file)
- # except:
- # pass
- # inval(tw.turtle.canvas)
+ """
+ if png_file != '':
+ try:
+ load_pict(tw,png_file)
+ except:
+ pass
+ inval(tw.turtle.canvas)
+ """
def get_load_name(tw):
dialog = gtk.FileChooserDialog("Load...", None, \
@@ -80,7 +81,6 @@ def get_load_name(tw):
# unpack serialized data sent across a share
def load_string(tw,text):
-# listdata = cjson.decode(text)
listdata = json.decode(text)
data = tuplify(listdata) # json converts tuples to lists
new_project(tw)
@@ -107,10 +107,8 @@ def read_data(tw,data):
def load_spr(tw,b):
media = None
btype, label = b[1],None
-# print btype
if type(btype)==type((1,2)):
btype, label = btype
-# print "found a label: " + label
if btype == 'title': # for backward compatibility
btype = 'string'
if btype == 'journal' or btype == 'audiooff':
@@ -176,7 +174,6 @@ def get_save_name(tw):
def save_data(tw,fname):
f = file(fname, "w")
data = assemble_data_to_save(tw)
-# text = cjson.encode(data)
text = json.encode(data)
f.write(text)
f.close()
@@ -184,8 +181,6 @@ def save_data(tw,fname):
# used to send data across a shared session
def save_string(tw):
data = assemble_data_to_save(tw)
- # encode it for sending across the network
-# text = cjson.encode(data)
text = json.encode(data)
return text
@@ -215,9 +210,9 @@ def assemble_data_to_save(tw):
def save_pict(tw,fname):
tc = tw.turtle.canvas
pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, tc.width, \
- tc.height)
+ tc.height)
pixbuf.get_from_drawable(tc.image, tc.image.get_colormap(), 0, 0, 0, 0, \
- tc.width, tc.height)
+ tc.width, tc.height)
pixbuf.save(fname, 'png')
def get_id(x):
diff --git a/tasetup.py b/tasetup.py
index b9d42b6..9fdf55d 100644
--- a/tasetup.py
+++ b/tasetup.py
@@ -114,7 +114,7 @@ selectors = (
('vspace','nop','vspace'),
('lock','nop','lock'))),
('myblocks', 55,
- (('start','nop','start'),
+ (('start','start','start'),
('hat1','nop1','start'),
('stack1','stack1','noarg'),
('hat2','nop2','start'),
diff --git a/tasprites.py b/tasprites.py
index 4db1e4d..4f3eff7 100644
--- a/tasprites.py
+++ b/tasprites.py
@@ -1,4 +1,5 @@
#Copyright (c) 2007-8, Playful Invention Company.
+#Copyright (c) 2008-9, Walter Bender
#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
@@ -71,7 +72,10 @@ def setlayer(spr, layer):
if spr in sprites: sprites.remove(spr)
spr.layer = layer
for i in range(len(sprites)):
- if layer < sprites[i].layer: sprites.insert(i, spr); inval(spr); return
+ if layer < sprites[i].layer:
+ sprites.insert(i, spr)
+ inval(spr)
+ return
sprites.append(spr)
inval(spr)
@@ -86,7 +90,7 @@ def setlabel(spr,label):
def inval(spr):
spr.tw.area.invalidate_rect(gtk.gdk.Rectangle(spr.x,spr.y,spr.width, \
- spr.height), False)
+ spr.height), False)
def draw(spr):
if isinstance(spr.image,gtk.gdk.Pixbuf):
diff --git a/taturtle.py b/taturtle.py
index cf228b3..0c35211 100644
--- a/taturtle.py
+++ b/taturtle.py
@@ -1,4 +1,5 @@
#Copyright (c) 2007-8, Playful Invention Company.
+#Copyright (c) 2008-9, Walter Bender
#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
@@ -129,7 +130,7 @@ def rarc(t,a,r):
x,y,w,h=t.width/2+int(cx-r),t.height/2-int(cy+r),int(2*r),int(2*r)
if t.pendown:
t.canvas.image.draw_arc(t.gc,False,x,y,w,h, \
- int(180-t.heading-a)*64,int(a)*64)
+ int(180-t.heading-a)*64,int(a)*64)
invalt(t,x-t.pensize/2-3,y-t.pensize/2-3,w+t.pensize+6,h+t.pensize+6)
right(t,a)
t.xcor=cx-r*cos(t.heading*DEGTOR)
@@ -142,7 +143,7 @@ def larc(t,a,r):
x,y,w,h=t.width/2+int(cx-r),t.height/2-int(cy+r),int(2*r),int(2*r)
if t.pendown:
t.canvas.image.draw_arc(t.gc,False,x,y,w,h,int(360-t.heading)*64, \
- int(a)*64)
+ int(a)*64)
invalt(t,x-t.pensize/2-3,y-t.pensize/2-3,w+t.pensize+6,h+t.pensize+6)
right(t,-a)
t.xcor=cx+r*cos(t.heading*DEGTOR)
@@ -163,7 +164,7 @@ def setpensize(t,ps):
except:
pass
t.gc.set_line_attributes(int(t.pensize),gtk.gdk.LINE_SOLID, \
- gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_MITER)
+ gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_MITER)
return None
def setcolor(t,c):
@@ -260,7 +261,7 @@ def draw_line(t,x1,y1,x2,y2):
w,h=maxx-minx,maxy-miny
t.canvas.image.draw_line(t.gc,x1,y1,x2,y2)
invalt(t,minx-t.pensize/2-3,miny-t.pensize/2-3,w+t.pensize+6, \
- h+t.pensize+6)
+ h+t.pensize+6)
def turn_turtle(t):
setshape(t.spr, t.shapelist[(int(t.heading+5)%360)/10])
@@ -272,7 +273,7 @@ def move_turtle(t):
def invalt(t,x,y,w,h):
rect = gtk.gdk.Rectangle(int(x+t.canvas.x),int(y+t.canvas.y), \
- int(w),int(h))
+ int(w),int(h))
t.tw.area.invalidate_rect(rect, False)
diff --git a/tawindow.py b/tawindow.py
index 325eeb2..80240ba 100644
--- a/tawindow.py
+++ b/tawindow.py
@@ -657,6 +657,8 @@ def runbutton(tw, time):
for b in blocks(tw):
if find_start_stack(tw, b):
tw.step_time = time
+ if hasattr(tw,'activity'):
+ tw.activity.recenter()
run_stack(tw, b)
return
# no start block, so run a stack that isn't a hat