# 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 |