#!/usr/bin/env python # Basic animation template by Chuck Liang. Updated 9/09 import pygtk import gtk import gobject import time import threading from random import randint width,height = 900,700 delaytime = 70 # 100ms delay between animation frames window = gtk.Window(gtk.WINDOW_TOPLEVEL) window.set_title("Simplified Drawing Example") window.connect("destroy", lambda w: gtk.main_quit()) area = gtk.DrawingArea() area.set_size_request(width,height) window.resize(width,height) window.add(area) window.show_all() window.move(0,0) gc0 = area.window.new_gc() cmap = gc0.get_colormap() # common colors green = cmap.alloc_color(red=0,green=65535,blue=0) blue = cmap.alloc_color(red=0,green=0,blue=65535) red = cmap.alloc_color(red=65535,green=0,blue=0) white = cmap.alloc_color("white") black = cmap.alloc_color("black") gray = cmap.alloc_color("gray") yellow = cmap.alloc_color("yellow") purple = cmap.alloc_color("purple") gc0.set_foreground(green) gc0.set_background(blue) gc0.line_width = 1 # double buffering setup dbuf = gtk.gdk.Pixmap(area.window,width,height,-1) gc1 = dbuf.new_gc() gc1.set_colormap(cmap) ### Thread control syn = threading.Event() # throttles mainloop syn2 = threading.Event() # throttles user thread syn.clear() syn2.clear() stopall = False # for cleanup # Thread permits a while loop inside mydraw class MyThread ( threading.Thread ): def __init__(self,brush,gc): self.win = brush self.dgc = gc threading.Thread.__init__(self) def run ( self ): global mydraw mydraw(self.win,self.dgc) def area_expose_cb(area, event): global mainloop, eehandler; my = MyThread(dbuf,gc1) my.start() # start student thread, which calls mydraw area.handler_block(eehandler) # prevent restart when window moved. mainloop(area.window) # sxxtart main animation refresh cycle return True # get ready for expose event eehandler = area.connect("expose_event", area_expose_cb) # animation refresh control loop: def mainloop(brush): if not stopall: syn.wait() # wait for permission to refresh screen syn.clear() # reset for next round brush.draw_drawable(gc0,dbuf,0,0,0,0,width,height) # refresh syn2.set() # informs user thread to goto next iteration eid = gobject.timeout_add(delaytime, mainloop, brush) # reschedule return False # end mainloop def updateDisplay(): syn.set() # release mainloop to refresh screen syn2.wait() # synch with mainloop before looping again syn2.clear() # reset for next round # end updateDisplay def cleanup(): global stopall stopall = True syn.set() syn2.set() # end cleanup ########################################################################## def drawcircle(brush,gc,x,y,radius,fill): brush.draw_arc(gc,fill,x-radius,y-radius,2*radius,2*radius,0,360*64) def drawcircle(brush,x,y,radius,fill): brush.draw_arc(gc1,fill,x-radius,y-radius,2*radius,2*radius,0,360*64) # distance: def dist(x1,y1,x2,y2): dx = x1-x2 dy = y1-y2 return (dx*dx + dy*dy)**0.5 # make sure coordinates stay within width, height: def inbounds(x,y): if (x<15): x = width-15 if (x>(width-15)): x = 15 if (y<15): y = height-15 if (y>height-15): y = 15 return (x,y) # return the tuple x,y # end inbounds # main animation procedure MUST be called mydraw #################### YOUR CODE GOES HERE ###################### def mydraw(brush,gc): x = 80 # center coordinates y = 200 scale = 100 # size while x<=width: gc.set_foreground(white) # sets drawing color brush.draw_rectangle(gc,True,0,0,width,height) # clear background gc.set_foreground(blue) brush.draw_line(gc,x,y-scale,x-scale,y) # upper left brush.draw_line(gc,x-scale,y,x,y+scale) # lower left brush.draw_line(gc,x,y+scale,x+scale,y) # lower right brush.draw_line(gc,x+scale,y,x,y-scale) # upper right x = x+10 scale = scale-10 updateDisplay() # show animation frame (call at end of while loop) #end animation loop cleanup() # should be called after end of all animation # end mydraw ########################################################################## # The following line must be the last line in the program gtk.main()