# An animated bar-graph. # Yes, more comments would be nice. :p import ihEvent,string,ihApp class ihEmbed(ihApp.Application): def __init__(self,**args): apply(ihApp.Application.__init__,(self,),args) # Allocate colors, buffer. self.red = self.MakeColor(.9,.2,.1) self.white = self.MakeColor(1,1,1) self.black = self.MakeColor(0,0,0) self.background = self.BackPen() self.foreground = self.ForePen() x, y, width, height = self.Dimensions() self.buffer = self.MakePixmap(width,height) self.buffer.ForePen(self.background) self.buffer.FillRectangle(0,0,width,height) # Extract bar arguments if( args.has_key('Bars') ): self.bars = eval(args['Bars']) if( type(self.bars) != type(()) ): raise TypeError,'"Bars" parameter must be a tuple' # Extract update arguments if( args.has_key('Steps') ): self.steps = string.atoi(args['Steps']) else: self.steps = 50 if( args.has_key('Rate') ): self.rate = string.atof(args['Rate']) else: self.rate = 0.05 if( args.has_key('Ticks') ): self.ticks = string.atof(args['Ticks']) else: self.ticks = 10 # Find font dimensions fw,fh,asc,desc = self.TextExtent('Wg') self.frame_w = width self.frame_h = height - (fh*2) self.tick_y = height - desc - 2 self.inner_w = self.frame_w - 2 self.inner_h = self.frame_h - 2 # Initialize an array to hold current bar values self.num = len(self.bars) self.current = [] # [ barvalue, currentvalue, topy, width ] self.area_h = self.inner_h / self.num self.bar_h = (self.area_h*2)/3 self.maxval = 0.0 top = (self.area_h-self.bar_h)/2 for i in self.bars: texty = top + (self.bar_h/2) - (fh/2) + asc self.current.append( [i, 0.0, top, 0.0, texty, "%.2f" % i] ) if( self.maxval < i ): self.maxval = i top = top + self.area_h if( self.maxval <= 0 ): self.maxval = 1.0 # Set number of steps, and start self.curstep = 0 self.update(1) def update(self,restart): if( restart ): self.curstep = 0 self.draw_scales() if( self.curstep < self.steps ): self.call = self.FutureCall(self.rate,self.update,(0,)) else: self.call = self.FutureCall(10,self.update,(1,)) cur = self.curstep + 1 self.curstep = cur #print 'Doing step #',cur for i in self.current: i[1] = (i[0]*cur)/self.steps i[3] = (self.inner_w*i[1])/self.maxval #print 'Ready to draw...' self.draw_bars() #print 'Updating display...' self.redraw() def draw_bars(self): for i in self.current: x, y, w, h = 1, i[2], i[3], self.bar_h #print 'Drawing bar: (%s,%s) at (%sx%s)' % (x,y,w,h) self.buffer.ForePen(self.red) self.buffer.FillRectangle(x,y,w,h) if( w > 0 ): self.buffer.ForePen(self.black) self.buffer.DrawLine(x,y+h-1,x+w-1,y+h-1) self.buffer.DrawLine(x+w-1,y,x+w-1,y+h-1) self.buffer.ForePen(self.white) self.buffer.DrawLine(x,y,x+w-1,y) self.buffer.DrawLine(x,y,x,y+h-1) self.buffer.ForePen(self.foreground) self.buffer.DrawText(x+5,i[4],i[5],-1) def draw_scales(self): x, y, width, height = self.Dimensions() self.buffer.ForePen(self.background) self.buffer.FillRectangle(0,0,width,height) # Place the tick marks self.tick_marks = [] for i in range(self.ticks): text = '%.0f' % ((i*self.maxval)/(self.ticks-1)) tw,th,ta,td = self.buffer.TextExtent(text) xpos = (i*self.frame_w)/(self.ticks-1) - 1 val = (i*self.maxval)/(self.ticks-1) tx = xpos - (tw/2) if( tx < 0 ): tx = 0 elif( (tx+tw) > self.frame_w ): tx = self.frame_w - tw - 1 self.tick_marks.append( ( val, xpos, tx, text, ) ) self.buffer.ForePen(self.foreground) for i in self.tick_marks: self.buffer.DrawLine(i[1],0,i[1],self.frame_h-1) self.buffer.DrawText(i[2],self.tick_y,i[3],-1) self.buffer.ForePen(self.black) self.buffer.DrawLine(0,self.frame_h-1,self.frame_w-1,self.frame_h-1) self.buffer.DrawLine(self.frame_w-1,0,self.frame_w-1,self.frame_h-1) self.buffer.ForePen(self.white) self.buffer.DrawLine(0,0,self.frame_w-1,0) self.buffer.DrawLine(0,0,0,self.frame_h-2) def redraw(self): self.Paste(0,0,self.buffer) def OnRedraw(self,ev,x,y,w,h): self.redraw() def OnMouse(self,ev,x,y,state,hit): if( ev.Code == ihEvent.CodeNames['MousePress'] ): if( self.call ): self.call.Stop() self.update(1)
Dianne Kyra Hackborn <hackbod@angryredplanet.com> | Last modified: Wed Aug 14 14:23:04 PDT 1996 |