"""
Version: 1.71 August 22, 2005
Developed in-house for an OSCON talk. Demonstrates
suitability of Pygame for coding a programmatically
controlled, scene-based presentation manager (not a
new idea -- a reimplementation of an old idea).
Fixed some typos after the show.
-- Kirby
(c) 2005, 4D Solutions, GNU Public License.
"""
import pygame
pygame.font.init()
pygame.display.init()
pygame.mixer.init()
from pygame.locals import *
import threading
import time
import sys
import random
class Content(object):
"""
Used to pass media content
"""
step = 1,1
milliseconds = 100
fontsize = 20
scrolldirection = 1
scrollwidth = 600
fontcolor = 'black'
font = 'verdana'
def __getattr__(self, prop):
return None
class Resource( object ):
"""
Standard API for all Resource objects. Some don't respond to some keys,
so the default method in every case is to do nothing
"""
def run(self): pass
def stop(self): pass
def pause(self): pass
def unpause(self): pass
def restart(self): pass
def start(self): pass
def next(self): pass
def prev(self): pass
def join(self): pass
def isAlive(self): pass
class Stillimage( Resource ):
"""
Place a still Image at params.topleft or autocenter)
"""
def __init__(self, params, scene):
self.scene = scene
self.screen = scene.screen
self.theimage = pygame.image.load(params.filename).convert()
self.topleft = params.topleft
def start (self):
w,h = self.theimage.get_size()
if self.topleft:
lc = self.topleft
else:
lc = 512 - w//2, 384 - h//2
self.rect = pygame.Rect(lc,(w,h))
self.screen.blit(self.theimage, self.rect)
pygame.display.update()
class Stilltext( Resource ):
"""
Place still text at params.topleft or autocenter)
"""
def __init__(self, params, scene):
self.scene = scene
self.screen = scene.screen
self.filename = params.filename
self.fontsize = params.fontsize
self.font = pygame.font.SysFont('verdana',self.fontsize)
self.topleft = params.topleft
def start (self):
lines = open(self.filename).readlines()
numlines = len(lines)
leading = self.fontsize//4
surfaces = []
for i in range(numlines):
theline = lines[i][:-1]
theline = theline.replace('\t',' ')
surfaces.append ( self.font.render(theline,1,
pygame.color.Color('black')) )
row = self.topleft[0], self.topleft[1] + ((self.fontsize +
leading) * i)
self.screen.fill(pygame.color.Color(self.scene.bg),
pygame.Rect(row,(600,self.fontsize + leading)) )
self.screen.blit(surfaces[i],
pygame.Rect(row,(600,self.fontsize + leading)),
pygame.Rect(0,0,600, self.fontsize + leading) )
pygame.display.update()
class Movingimage( threading.Thread, Resource ):
"""
Image moves around the screen
"""
moving = True
looping = True
def __init__(self, params, scene):
self.scene = scene
self.screen = scene.screen
self.posrect = params.posrect
self.theimage = pygame.image.load(params.filename).convert()
self.step = params.step
threading.Thread.__init__(self)
def run (self):
hstep, vstep = self.step
while self.looping:
if self.moving:
if self.posrect.right>1040 or self.posrect.left<-10:
hstep = -hstep
if self.posrect.bottom>700 or self.posrect.top<60:
vstep = -vstep
self.screen.fill(pygame.color.Color(self.scene.bg), self.posrect)
self.posrect = self.posrect.move(hstep,vstep)
self.screen.blit(self.theimage, self.posrect)
pygame.display.update()
def restart(self):
self.moving = True
def pause (self):
self.moving = False
def stop (self):
self.looping = False
class Flipimage (Resource ):
def __init__ (self, params, scene ):
self.scene = scene
self.screen = scene.screen
self.imagelist = params.imagelist
self.imagenum = 0
self.rect = None
self.topleft = params.topleft
def start(self):
if self.rect:
self.screen.fill(pygame.color.Color(self.scene.bg), self.rect)
self.theimage = pygame.image.load(self.imagelist[self.imagenum]).convert()
w,h = self.theimage.get_size()
if self.topleft:
lc = self.topleft
else:
lc = 512 - w//2, 384 - h//2
self.rect = pygame.Rect(lc,(w,h))
self.screen.blit(self.theimage, self.rect)
pygame.display.update()
def run(self):
self.start()
def next(self):
self.imagenum += 1
if self.imagenum == len(self.imagelist):
self.imagenum = 0
self.start()
def prev(self):
self.imagenum -= 1
if self.imagenum == -1:
self.imagenum = len(self.imagelist)-1
self.start()
class Autoflipimage ( threading.Thread, Resource ):
def __init__ (self, params, scene ):
self.scene = scene
self.screen = scene.screen
self.imagelist = params.imagelist
self.usercenter = params.usercenter
self.imagenum = 0
self.rect = None
self.topleft = None
self.milliseconds = params.milliseconds
if not self.milliseconds:
self.milliseconds = 100
self.topleft = params.topleft
self.looping = True
self.flipping = True
threading.Thread.__init__(self)
def run (self):
while self.looping:
if self.flipping:
self.theimage = pygame.image.load(self.imagelist[self.imagenum]).convert()
if self.rect:
self.screen.fill(pygame.color.Color(self.scene.bg), self.rect)
w,h = self.theimage.get_size()
if self.topleft:
lc = self.topleft
elif self.usercenter:
lc = self.usercenter[0] - w//2, self.usercenter[1] - h//2
else:
lc = 512 - w//2, 384 - h//2
self.rect = pygame.Rect(lc,(w,h))
self.screen.blit(self.theimage, self.rect)
pygame.display.update()
self.imagenum += 1
if self.imagenum == len(self.imagelist):
self.imagenum = 0
pygame.time.delay(self.milliseconds)
def restart(self):
self.imagenum = 0
self.flipping = True
def pause (self):
self.flipping = False
def unpause (self):
self.flipping = True
def stop (self):
self.looping = False
class Scrolltextfile ( threading.Thread, Resource ):
def __init__ (self, params, scene ):
self.scene = scene
self.screen = scene.screen
self.filename = params.filename
self.milliseconds = params.milliseconds
self.displaylines = params.displaylines
self.fontsize = params.fontsize
self.rect = None
self.looping = True
self.scrolling = True
self.font = params.font
self.font = pygame.font.SysFont(self.font,self.fontsize)
self.fontcolor = params.fontcolor
self.topleft = params.topleft
self.scrolldirection = params.scrolldirection
self.scrollwidth = params.scrollwidth
if not self.topleft:
self.topleft = 100,100
threading.Thread.__init__(self)
def run (self):
lines = open(self.filename).readlines()
lines.append("--------------------------------------")
lines.append(" ")
self.offset = 0
numlines = len(lines)
leading = self.fontsize//4
if not self.displaylines:
self.displaylines = 600//(self.fontsize + leading)
if self.scrolldirection<>1:
therange = list(reversed(range(self.displaylines)))
else:
therange = range(self.displaylines)
while self.looping:
if self.scrolling:
surfaces = []
for i in therange:
theline = lines[(i+self.offset) % numlines][:-1]
theline = theline.replace('\t',' ')
surfaces.append ( self.font.render(theline,1,
pygame.color.Color(self.fontcolor)) )
for i in therange:
row = self.topleft[0], self.topleft[1]+((self.fontsize + leading) * i)
self.screen.fill(pygame.color.Color(self.scene.bg),
pygame.Rect(row,(self.scrollwidth, self.fontsize + leading)) )
self.screen.blit(surfaces[i],
pygame.Rect(row,(600,self.fontsize + leading)),
pygame.Rect(0,0,self.scrollwidth, self.fontsize + leading) )
self.offset += 1
pygame.display.update()
pygame.time.delay(self.milliseconds)
def restart(self):
self.offset = 0
self.scrolling = True
def pause (self):
self.scrolling = False
def unpause (self):
self.scrolling = True
def stop (self):
self.looping = False
class Movieplayer( threading.Thread, Resource ):
def __init__( self, params, scene):
self.scene = scene
self.screen = scene.screen
self.filename = params.filename
self.topleft = params.topleft
self.themovie = None
threading.Thread.__init__(self)
def run ( self ):
if not self.themovie:
self.themovie = pygame.movie.Movie(self.filename)
w,h = self.themovie.get_size()
if not self.topleft:
self.topleft = 512 - w//2, 384 - h//2
self.themovie.set_display(self.screen, pygame.Rect(self.topleft, (w,h)))
self.themovie.play()
def restart ( self ):
if self.themovie.get_busy():
self.themovie.stop()
self.themovie.rewind()
self.themovie.play()
def stop ( self ):
if self.themovie.get_busy():
self.themovie.stop()
def unpause(self):
if self.themovie.get_busy():
self.themovie.play()
pause = stop
class Coderunner( threading.Thread, Resource ):
"""
Runs a generator with output rendered to a surface
"""
def __init__( self, params, scene):
self.scene = scene
self.screen = scene.screen
self.usercenter = params.usercenter
self.topleft = params.topleft
self.milliseconds = params.milliseconds
self.generator = params.generator
self.fontsize = params.fontsize
self.font = params.font
self.font = pygame.font.SysFont(self.font,self.fontsize)
threading.Thread.__init__(self)
def run ( self ):
self.f = self.generator()
self.looping = True
self.iterating = True
self.rect = None
while self.looping:
if self.iterating == True:
output = self.f.next()
if not type(output)==type(''):
output = str(output)
surface = self.font.render(output,1,pygame.color.Color('black'))
if self.rect:
self.screen.fill(pygame.color.Color(self.scene.bg), self.rect)
w,h = surface.get_size()
if self.topleft:
lc = self.topleft
elif self.usercenter:
lc = self.usercenter[0] - w//2, self.usercenter[1] - h//2
else:
lc = 512 - w//2, 384 - h//2
self.screen.blit(surface, pygame.Rect(lc,(w,h)) )
self.rect = pygame.Rect(lc,(w,h))
pygame.display.update()
pygame.time.delay(self.milliseconds)
def restart ( self ):
self.f = self.generator()
self.iterating = True
def stop ( self ):
self.looping = False
def unpause(self):
self.iterating = True
def pause ( self ):
self.iterating = False
class Scene ( object ):
footerfont = pygame.font.SysFont('verdana',20)
headerfont = pygame.font.SysFont('verdana',40)
def __init__(self, screen, bg, name, num, hfcolor='black', contents=[]):
self.screen = screen
self.bg = bg
self.name = name
self.num = num
self.hfcolor = hfcolor
self.contents = contents
self.resources = []
def display(self):
s = self.screen
s.fill(pygame.color.Color(self.bg))
today = time.ctime().split()
today = "%s, %s %s, %s" % (today[0], today[1], today[2], today[4])
footer0 = self.footerfont.render(today,1,pygame.color.Color(self.hfcolor))
footer1 = self.footerfont.render('OSCON 2005',1,pygame.color.Color(self.hfcolor))
footer2 = self.footerfont.render(str(self.num),1,pygame.color.Color(self.hfcolor))
header = self.headerfont.render(self.name,1,pygame.color.Color(self.hfcolor))
w,h = header.get_size()
s.blit(footer1, (450,730))
s.blit(footer0, (20,730))
s.blit(footer2, (950,730))
s.blit(header, (512 - w//2, 10))
self.resources = []
for o in self.contents:
if o.content_type == 'movie':
self.resources.append(Movieplayer( o, self))
elif o.content_type == 'movingimage':
self.resources.append(Movingimage( o, self))
elif o.content_type == 'flipimage':
self.resources.append(Flipimage( o, self ))
elif o.content_type == 'autoflip':
self.resources.append(Autoflipimage( o, self ))
elif o.content_type == 'scrollfile':
self.resources.append(Scrolltextfile( o, self ))
elif o.content_type == 'stillimage':
self.resources.append(Stillimage( o, self ))
elif o.content_type == 'stilltext':
self.resources.append(Stilltext( o, self ))
elif o.content_type == 'coderunner':
self.resources.append(Coderunner( o, self ))
def run(self):
for r in self.resources:
if hasattr(r,"themovie"):
pygame.mixer.quit()
r.start()
def end(self):
for r in self.resources:
r.stop()
if r.isAlive():
r.join()
if not pygame.mixer.get_init():
pygame.mixer.init()
self.resources = []
fpath = "c:/Documents and Settings/Kirby/My Documents/Projects/oscon2005/"
"""
Each slide or scene is set up inside a function, the purpose of which is
to pass in some slide-level parameters, including a list of resources
called 'contents', a list of surface objects to be displayed. Many of
these surface objects invoke their own threads, so that the outer keyboard
loop remains in effect (keystrokes get passed to internal content, e.g.
to pause a video clip or whatever).
"""
def setscene_welcome(s, num=0):
"""
Scroll this source code with animated graphic
"""
mobj = Content()
mobj.content_type = 'scrollfile'
mobj.fontsize = 14
mobj.filename = fpath + "oscon2005.py"
contents = [mobj]
graphics = []
for pic in ['ch1.gif','ch2.gif','ch3.gif','ch4.gif',
'ch5.gif','ch6.gif','ch7.gif','ch8.gif','ch9.gif','ch10.gif']:
graphics.append(fpath + pic)
mobj = Content()
mobj.content_type = 'autoflip'
mobj.imagelist = graphics
mobj.topleft = 680,450
contents.append(mobj)
mobj = Content()
mobj.content_type = 'stillimage'
mobj.filename = fpath + 'osconbanner.gif'
mobj.topleft = 780,100
contents.append(mobj)
scene = Scene( s, 'white', 'Welcome to OSCON 2005',
num, contents = contents)
return scene
def setscene_thankyou(s, num=0):
"""
Your willingness to participate in the free and open source
revolution has given humanity a new vector, towards a more
sustainable and happier career as crew of Spaceship Earth.
"""
contents = []
for r in range(5):
mobj = Content()
mobj.content_type = 'stillimage'
mobj.filename = fpath + 'osconbanner.gif'
mobj.topleft = 150 + r*150,100
contents.append(mobj)
mobj = Content()
mobj.content_type = 'stilltext'
mobj.filename = fpath + "thankyou.txt"
mobj.fontsize = 30
mobj.topleft = (280,400)
contents.append(mobj)
mobj = Content()
mobj.content_type = 'stilltext'
mobj.filename = fpath + "optional.txt"
mobj.fontsize = 30
mobj.topleft = (330,550)
contents.append(mobj)
scene = Scene( s, 'white', 'Thank You!',
num, contents = contents)
return scene
def setscene_rbf(s, num=0):
"""
RBF slide; intro to a series of collaborations
"""
graphics = []
for pic in ['rbfjitter.jpg','vesphere.jpg','domecar.gif',
'dymaxcar.gif','Mtl-biosphere.jpg','eye.gif','bfitm.png',
'bmc1.jpg', 'build.gif','buckyworks.gif','epball1.gif',
'edapple2.jpg','synbook.jpg','buckystampssm.png',
'ohman12192004.jpg','conf_06.gif', 'conf_02.gif',
'conf_03.gif']:
graphics.append(fpath + pic)
mobj = Content()
mobj.content_type = 'flipimage'
mobj.imagelist = graphics
mobj.milliseconds = 500
scene = Scene( s, 'white', 'R. Buckminster Fuller (RBF)',
num, contents = [mobj])
return scene
def setscene_collab(s, num=0):
"""
A scrolling lists of collaborations and contributions that
emerged to define the Fuller School (the list goes on,
and gets longer). I've been in on a few of these, lots of
times I'm just an onlooker from afar.
"""
mobj = Content()
mobj.content_type = 'scrollfile'
mobj.filename = fpath + "collablist.txt"
mobj.fontsize = 20
mobj.milliseconds = 500
mobj.fontcolor = 'yellow'
mobj.font = 'courier'
mobj.scrollwidth = 820
contents = [mobj]
scene = Scene( s, 'black', 'A Web of Collaborations',
num, hfcolor='yellow', contents = [mobj])
return scene
def setscene_rywalt(s, num=0):
"""
Chris unfolds the World Game "game board" creating a
digital library video clip
"""
mobj = Content()
mobj.content_type = 'movie'
mobj.filename = fpath + "dymaxion_2003.animation.mpeg"
mobj.topleft = (110,70)
scene = Scene( s, 'white', 'Chris Rywalt Plays World Game',
num, contents = [mobj])
return scene
def setscene_metoo(s, num=0):
"""
One of my early animations, derived from a POV-Ray tutorial
with some Fuller School twists
"""
mobj = Content()
mobj.content_type = 'movie'
mobj.filename = fpath + "ghostjit.mpeg"
scene = Scene( s, 'black', 'Me Too!',
num, hfcolor = "orange", contents = [mobj])
return scene
def setscene_wanderers(s, num=0):
"""
A cultural phenomenon: the Math Wars = a breakdown in agreement over
what and how to teach mathematics. My view is the open source
community has plenty to offer, and would provide a valuable service
by competing in the recruiting of faculty and students to a curriculum
designed to pass on core skills and values.
"""
mobj = Content()
mobj.content_type = 'flipimage'
graphics = []
for i in range(2):
graphics.append(fpath + ('wwwanderers.jpg','demowanderers.jpg')[i])
mobj.imagelist = graphics
mobj.usercenter = (512,400)
scene = Scene( s, 'black', 'Math Through Storytelling',
num, hfcolor = 'yellow', contents = [mobj])
return scene
def setscene_dome(s, num=0):
"""
Rick Bono started the ball rolling with DOME, an free software
offering (GPL) built on Hugh Kenner's 'Geodesic Math and How
to Use It'
"""
mobj = Content()
mobj.content_type = 'scrollfile'
mobj.filename = fpath + "Geodesic.cpp"
mobj.fontcolor = 'black'
mobj.fontsize = 14
contents = [mobj]
mobj = Content()
mobj.content_type = 'movingimage'
mobj.step = 0,1
mobj.filename = fpath + 'rbono.gif'
mobj.posrect = pygame.Rect(800,400,113,121)
contents.append(mobj)
scene = Scene( s, 'white', 'Dome by Rick Bono',
num, hfcolor = 'orange', contents = contents)
return scene
def setscene_bonoballs(s, num=0):
"""
Illustrates the concept of 'frequency'
"""
contents=[]
graphics = []
pix = ['freq1.png','freq2.png','freq3.png','freq4.png',
'freq5.png','freq6.png', 'freq7.png', 'freq8.png', 'freq9.png']
pix.extend( list(reversed(pix[:-1])) )
for i in pix:
graphics.append(fpath + i)
mobj = Content()
mobj.content_type = 'autoflip'
mobj.imagelist = graphics
mobj.milliseconds = 100
contents.append(mobj)
scene = Scene( s, 'white', 'Dome by Rick Bono',
num, contents = contents)
return scene
def setscene_waterman1(s, num=0):
"""
Waterman Polyhedra include the maximum number of CCP vertices at a
given radius or less, such that overall convexity is preserved.
Larger radius polys become ever more spherical in appearance
"""
mobj = Content()
mobj.filename = fpath + "w1000.gif"
mobj.content_type='movingimage'
mobj.posrect = pygame.Rect(200,200,490,467)
scene = Scene( s, 'white', 'Waterman Polyhedra',
num, contents = [mobj] )
return scene
def setscene_waterman2(s, num=0):
"""
Figuring a convex hull has always been the hard part. Qhull was
a godsend. More recently, QuickHull3D by has meant the whole
computation may be done within a single Jython script.
"""
mobj = Content()
mobj = Content()
mobj.content_type = 'stillimage'
mobj.filename = fpath + 'w500.png'
scene = Scene( s, 'black', 'Waterman Polyhedra',
num, hfcolor = 'yellow', contents = [mobj] )
return scene
def setscene_snelson(s, num=0):
"""
Kenneth Snelson is an internationally recognized artist. He has also put
a lot of skill into a visual atomic model. He had a stormy relationship
with Fuller, after a happy start at Black Mountain College, owing to a
tug-o-war for ownership/priority vis-a-vis tensegrity a.k.a. floating
compression. Both took out patents.
"""
graphics = []
for pic in ['Ken_Snelsonsmall.gif','eqtower.jpg','29-AltComplexAtm.jpeg.jpg',
'26-Neon.jpeg.jpg','ForestDevCross.jpg','WoodenXPiece.jpg']:
graphics.append(fpath + pic)
mobj = Content()
mobj.content_type = 'flipimage'
mobj.imagelist = graphics
scene = Scene( s, 'white', 'Kenneth Snelson',
num, contents = [mobj])
return scene
def setscene_eig(s, num=0):
"""
Kenneth Snelson (and Fuller) inspired Gerald de Jong to create
Elastic Interval Geometry (EIG), a simple concept with for exploring
dynamic networks, where the edges resist being pushed or pulled
from some ideal length. In Fluidiom, Gerald let EIG networks
randomly emerge and had his program select those best able to
cover distance, per some supplied algorithm.
Karl Erickson and Russell Chu were adept EIG sculptors i.e.
Struck power users and contributed to the specimens below (Struck
provided animations in the form of a POV-Ray clock loop).
SpringDance and Springie came later in the story (i.e. after
Struck).
"""
contents = []
mobj = Content()
mobj.content_type = 'movie'
mobj.filename = fpath + "Dolphin.mpg"
mobj.topleft = (10,90)
contents.append(mobj)
mobj = Content()
mobj.content_type = 'movie'
mobj.filename = fpath + "Golem.mpg"
mobj.topleft = (355,90)
contents.append(mobj)
mobj = Content()
mobj.content_type = 'movie'
mobj.filename = fpath + "IcosaFlip.mpg"
mobj.topleft = (700,90)
contents.append(mobj)
mobj = Content()
mobj.content_type = 'movie'
mobj.filename = fpath + "Fishy.mpg"
mobj.topleft = (110,400)
contents.append(mobj)
mobj = Content()
mobj.content_type = 'movie'
mobj.filename = fpath + "Bird.mpg"
mobj.topleft = (510,400)
contents.append(mobj)
scene = Scene( s, 'black', 'Elastic Interval Geometry (EIG)',
num, hfcolor = 'yellow', contents = contents)
return scene
def setscene_bellivm(s, num=0):
"""
Alexander Graham Bell pioneer the development of a space frame known as
the octet truss, which has a close relationship with the CCP sphere
packing. Fuller found out about this later.
"""
graphics = []
contents = []
pics = [('belltower.jpg',(150,70)),
('smbellbigkite.jpg',(550,70)),
('truss.gif',(150,450)),
('archforum1.jpg',(550,320))
]
for pic in pics:
mobj = Content()
mobj.content_type = 'stillimage'
mobj.filename = fpath + pic[0]
mobj.topleft = pic[1]
contents.append(mobj)
scene = Scene( s, 'white', 'Octet Truss',
num, contents = contents )
return scene
def setscene_quadrays(s, num=0):
"""
Doing this kind of tetrahedron-focused geometry led David Chako
and others to invent tetrays or quadray geometry, a way of doing
vector arithmetic that gives easy integer coordinates to many
of our concentric hierarchy vertices
Programming around Quadrays is what led me to explore some new
(to me) languages, always reimplementing a similar design. I
went from FoxPro to Java, then to Python. What hooked me about
Python was the interactive shell, plus operator overloading,
which FoxPro didn't support. I continued to use Visual FoxPro
though, in various professional programming jobs. This was also
time when I looked fairly seriously at Haskell, Ocaml, Scheme
and LISP -- and J.
"""
graphics = []
graphics.append(fpath + "quadray.png")
graphics.append(fpath + "rhdodeca.jpg")
graphics.append(fpath + "povlabels.gif")
graphics.append(fpath + "quadraycode.jpg")
graphics.append(fpath + "hoops.gif")
graphics.append(fpath + "javasamp.jpg")
graphics.append(fpath + "fox.gif")
mobj = Content()
mobj.content_type = 'flipimage'
mobj.imagelist = graphics
scene = Scene( s, 'white', 'Quadrays',
num, contents = [mobj] )
return scene
def setscene_cosmichierarchy(s, num=0):
"""
The concentric hierarchy is a way of presenting a sequence of
polyhedra such that their many logical relationships are made
clear and memorable
"""
graphics = []
for i in range(1,11):
pic = 'ch'+str(i)+'.gif'
graphics.append(fpath + pic)
graphics += list(reversed(graphics[:-1]))
mobj = Content()
mobj.content_type = 'autoflip'
mobj.milliseconds = 200
mobj.imagelist = graphics
scene = Scene( s, 'white', 'Concentric Hierarchy',
num, contents = [mobj] )
return scene
def setscene_grunch(s, num=0):
"""
Towards the end of his life, Fuller contemplated the significance
of swift globalization, and posited that corporations were in
a transformative position, both dissolving national boundaries
for selfish ends, and inadvertently creating the conditions for
a new management philosophy based on letting intellectual goods
cooperate to greater synergetic advantage (e.g. the free software
development model, now recognized and embraced in many tech-savvy
board rooms).
"""
graphics = []
for pic in ['obey1.gif','obey2.gif']:
graphics.append(fpath + pic)
mobj = Content()
mobj.content_type = 'autoflip'
mobj.imagelist = graphics
mobj.milliseconds = 444
scene = Scene( s, 'white', 'Grunch of Giants',
num, contents = [mobj])
return scene
def setscene_eja(s, num=0):
"""
Ed was one of Fuller's primary collaborators. Ed's high level
of discipline made it possible for Fuller to make deeper forays
into philosophy and literature, plus Ed gave us the 'Synergetics
Dictionary' (a four-volume compendium of Fuller's "pattern
language").
Ed also worked on the Wichita House Project (a.k.a. the DDU, or
Dymaxion Deployment Unit).
"""
contents = []
pics = [
('cia.png',(600,100)),
('ejarbf2.jpg',(150,150)),
('eja.jpg',(150,450))
]
for pic in pics:
mobj = Content()
mobj.content_type = 'stillimage'
mobj.filename = fpath + pic[0]
mobj.topleft = pic[1]
contents.append(mobj)
mobj = Content()
mobj.content_type = 'autoflip'
mobj.imagelist = fpath + 'eja.gif', fpath + 'june.gif'
mobj.topleft = (400,100)
mobj.milliseconds = 2000
contents.append(mobj)
mobj1 = Content()
mobj1.content_type = 'stilltext'
mobj1.filename = fpath + "edbio.txt"
mobj1.fontsize = 20
mobj1.topleft = 250,450
contents.append(mobj1)
scene = Scene( s, 'white', 'Ed Applewhite (EJA)',
num, contents = contents)
return scene
def setscene_europix(s, num=0):
"""
The intellectual property theme was big at Europython. Coincidentally,
the campus where we met features a mascot based on a Disney character,
similar to University of Oregons's in my neck of the woods:
http://www.goducks.com/
Tintin is another important cartoon character in Europe, part of a
shared heritage. One of the lawyers present used some Tintin images
in his slides, saying he knew the rules well enough to know that
he was operating within them.
"""
mobj = Content()
mobj.content_type = 'flipimage'
graphics = []
for i in range(9):
graphics.append(fpath + 'euro'+str(i) + '.jpg')
graphics.append('prp.jpg')
mobj.imagelist = graphics
mobj.usercenter = (512,400)
scene = Scene( s, 'black', 'Scholarship & IP',
num, hfcolor = 'yellow', contents = [mobj])
return scene
def setscene_gst(s, num=0):
"""
GST might put a different spin on things than Econ, i.e. is
reflective of a newer management philosophy that doesn't begin
from all the same premises
"""
graphics = []
for pic in ['gst2.gif','gst3.gif','gst1.gif']:
graphics.append(fpath + pic)
mobj = Content()
mobj.content_type = 'flipimage'
mobj.imagelist = graphics
scene = Scene( s, 'white', 'General Systems Theory (GST)',
num, contents = [mobj])
return scene
def setscene_eikclip(s, num=0):
"""
Fuller talking about what he's going to be talking about.
"""
mobj0 = Content()
mobj0.content_type = 'movie'
mobj0.filename = fpath + "04003_new.mpg"
mobj0.topleft = 350,200
mobj1 = Content()
mobj1.content_type = 'scrollfile'
mobj1.filename = fpath + "04003_new.txt"
mobj1.fontsize = 20
mobj1.milliseconds = 4000
mobj1.displaylines = 7
mobj1.fontcolor = 'orange'
mobj1.topleft = 325,450
scene = Scene( s, 'black', '2 Minute EIK Archive Clip',
num, hfcolor = 'orange', contents = [mobj0, mobj1])
return scene
def setscene_ccp(s, num=0):
"""
Demonstrates closest packing of spheres. An easy place for
kids to start learning Python, and 21st century math topics,
is with sequences based on figurate and polyhedral numbers.
Generators are good for this, and this slide features an
object that renders generator output to screen.
"""
graphics = []
for i in range(1,12):
filename = "cubanim"+str(i).zfill(2)
graphics.append(fpath + filename + ".png" )
mobj0 = Content()
mobj0.content_type = 'autoflip'
mobj0.topleft = (400,100)
mobj0.imagelist = graphics
mobj0.milliseconds = 100
mobj1 = Content()
mobj1.content_type = 'stilltext'
mobj1.filename = fpath + "ccp.py"
mobj1.fontsize = 20
mobj1.topleft = (60,200)
mobj2 = Content()
mobj2.content_type = 'coderunner'
mobj2.usercenter = (515,350)
def ccp():
shell, accum = 1,1
yield (shell, accum)
f = 1
while True:
shell = 10*f*f + 2
f += 1
accum += shell
yield shell,accum
mobj2.generator = ccp
mobj2.milliseconds = 1000
mobj3 = Content()
mobj3.content_type = 'autoflip'
mobj3.topleft = (350,400)
mobj3.imagelist = [fpath + 'smbellbigkite.jpg', fpath + 'vesphere.jpg',
fpath + 'bellivm.jpg']
mobj3.milliseconds = 1000
mobj4 = Content()
mobj4.content_type = 'stillimage'
mobj4.topleft = (750,200)
mobj4.filename = fpath + 'tetrapack.gif'
scene = Scene( s, 'white', 'Closest Packing of Spheres',
num, contents = [mobj2, mobj0, mobj1, mobj3, mobj4])
return scene
def main(startslide, num=0):
s = pygame.display.set_mode((1024,768), pygame.FULLSCREEN)
pygame.mouse.set_visible(0)
snd = pygame.mixer.Sound(fpath + "whoosh.wav")
soundon = True
thescenes = enumerate([
setscene_welcome,
setscene_rbf,
setscene_collab,
setscene_rywalt,
setscene_metoo,
setscene_wanderers,
setscene_dome,
setscene_bonoballs,
setscene_snelson,
setscene_eig,
setscene_bellivm,
setscene_ccp,
setscene_waterman1,
setscene_waterman2,
setscene_quadrays,
setscene_cosmichierarchy,
setscene_grunch,
setscene_eja,
setscene_europix,
setscene_gst,
setscene_eikclip,
setscene_thankyou
])
scenes = []
for i, f in thescenes:
scenes.append(f(s,i))
snum = int(startslide)
currscene = scenes[snum]
currscene.display()
if currscene.contents:
currscene.run()
pygame.display.update()
newscene = False
pygame.event.set_blocked(KEYUP)
while 1:
nextkey = pygame.event.wait()
if not hasattr(nextkey, "key"):
continue
if nextkey.key == K_ESCAPE or pygame.event.peek(QUIT):
print "Escape!"
currscene.end()
break
if nextkey.key == K_r:
if currscene.contents:
for r in currscene.resources:
r.restart()
if nextkey.key == K_p:
if currscene.contents:
for r in currscene.resources:
r.pause()
if nextkey.key == K_u:
if currscene.contents:
for r in currscene.resources:
r.unpause()
if nextkey.key == K_x:
if currscene.contents:
for r in currscene.resources:
r.next()
if nextkey.key == K_v:
if currscene.contents:
for r in currscene.resources:
r.prev()
if nextkey.key == K_RIGHT:
snum += 1
if snum == len(scenes):
snum = 0
newscene = True
if nextkey.key == K_LEFT:
snum -= 1
if snum == -1:
snum = len(scenes)-1
newscene = True
if newscene:
currscene.end()
if soundon:
if pygame.mixer.get_init():
snd.play()
print snum
currscene = scenes[snum]
currscene.display()
if currscene.contents:
currscene.run()
newscene = False
pygame.display.update()
pygame.quit()
if __name__ == '__main__':
if len(sys.argv)>1:
startslide = sys.argv[1]
else:
startslide = 0
main(startslide)
# code highlighted using py2html.py version 0.8