#************************************************************************#
#	display.py
#Creates a widget which displays 'digital' characters in the style of
#classic LED displays. The display has two parts: the descriptor and the
#value. The descriptor can take up to 11 characters before truncation, and
#the value can take integers in the range [0, 999]. The descriptor also
#supports the characters "=", "-", "_", "[", "]", "*", and " ". To display
#an "initiation" character (with all LED elements lit up), use "?".
#	Initialzation:
#		display_widget = Display(bg_color, off_color, on_color,
#		width, height, num_flashes)
#	Syntax:
#		display_widget.setCharacters("String", 123)
#
#	Jeremy Flores, last updated 09/25/07
#************************************************************************#

import pygtk
pygtk.require('2.0')
import gtk
import cairo
import gobject

gobject.threads_init()		#needed for the display initiation thread

#Define the class
class Display(gtk.DrawingArea):
	#Use a 15-tuple Boolean array to define which LED elements should be lit for each character
	char_a = 		[1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0]
	char_b = 		[1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0]
	char_c = 		[1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0]
	char_d = 		[0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0]
	char_e = 		[1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0]
	char_f = 		[1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0]
	char_g = 		[1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0]
	char_h = 		[1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
	char_i = 		[0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0]
	char_j = 		[0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
	char_k = 		[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0]
	char_l = 		[1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
	char_m = 		[1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]
	char_n = 		[1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
	char_o = 		[1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0]
	char_p = 		[1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0]
	char_q = 		[1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0]
	char_r = 		[1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0]
	char_s = 		[1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0]
	char_t = 		[0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]
	char_u = 		[1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
	char_v = 		[1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
	char_w = 		[1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0]
	char_x = 		[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1]
	char_y = 		[1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0]
	char_z = 		[0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1]
	
	char_0 = 		[1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0]
	char_1 = 		[0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
	char_2 = 		[0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0]
	char_3 = 		[0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0]
	char_4 = 		[1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
	char_5 = 		[1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0]
	char_6 = 		[1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0]
	char_7 = 		[0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
	char_8 = 		[1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0]
	char_9 = 		[1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0]
	
	char_equal =		[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0]	#	"="
	char_minus =		[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]	#	"-"
	char_underscore =	[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]	#	"_"
	char_lbracket =		[1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0]	#	"["
	char_rbracket =		[0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0]	#	"]"
	char_star =		[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0]	#	"*"
	char_space = 		[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]	#	" "
	
	char_init = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]		#	all elements are "lit"
	
	#bg_color is the background color
	#off_color is the color the LED elements should have when they are not "lit"
	#on_color is the color the LED elements should have when they are lit
	#num_flashes is the number of times the Display should flash the "initialization" characters
	def __init__(self, bg_color, off_color, on_color, width=300, height=30, num_flashes = 0):
		gtk.DrawingArea.__init__(self)		#initialize this class as a gtk.DrawingArea
		self.set_size_request(width, height)	#set the dimensions for the DrawingArea
		self._bg_color = bg_color
		self._off_color = off_color
		self._on_color = on_color
		self._width = width
		self._height = height
		self._char_width = 20			#width of each LED character, in pixels
		self._spacing = 2			#spacing between each LED character
		self._digits = 3			#number of digits in the value
		self._num_flashes = 2*num_flashes	#we need two calls to the thread: one to light, and one to unlight
		self._value = None			#initialize the value to None
		self._chars = None			#initialize the characters to None
		self._chars_array = []
		self._value_array = []
		self.connect("expose-event", self._onExpose)
		self.show()
		if self._num_flashes > 0:
			self.playThread()
		
	def _onExpose(self, widget, event):
		context = widget.window.cairo_create()
		context.rectangle(event.area.x, event.area.y, event.area.width, event.area.height)
		context.clip()
		context.set_source_rgb(self._bg_color[0], self._bg_color[1], self._bg_color[2])
		context.rectangle(0, 0, self._width, self._height)
		context.fill()
		
		context.set_source_rgb(self._off_color[0], self._off_color[1], self._off_color[2])
		#context.set_source_rgb(self._on_color[0], self._on_color[1], self._on_color[2])
		context.set_line_width(1)
		for i in range(0, int(self._width/self._char_width)):
			#draw 'unlit' LED elements
			
			#draw vertical LED elements
			context.move_to(i*self._char_width+2, 2)						#char[0]
			context.line_to(i*self._char_width+2, int(self._height/2)-1)
			context.stroke()
			context.move_to(i*self._char_width+2, int(self._height/2)+1)			#char[1]
			context.line_to(i*self._char_width+2, self._height-2)
			context.stroke()
			context.move_to((i+1)*self._char_width-2, 2)					#char[2]
			context.line_to((i+1)*self._char_width-2, int(self._height/2)-1)
			context.stroke()
			context.move_to((i+1)*self._char_width-2, int(self._height/2)+1)			#char[3]
			context.line_to((i+1)*self._char_width-2, self._height-2)
			context.stroke()
			context.move_to(i*self._char_width+int(self._char_width/2), 2)			#char[4]
			context.line_to(i*self._char_width+int(self._char_width/2), int(self._height/2)-1)
			context.stroke()
			context.move_to(i*self._char_width+int(self._char_width/2), int(self._height/2)+1)	#char[5]
			context.line_to(i*self._char_width+int(self._char_width/2), self._height-2)
			context.stroke()
			#draw horizontal LEDs
			context.move_to(i*self._char_width+2, 2)						#char[6]
			context.line_to((i+1)*self._char_width-2, 2)
			context.stroke()
			context.move_to(i*self._char_width+2, int(self._height/2))				#char[7]
			context.line_to((i+1)*self._char_width-2, int(self._height/2))
			context.stroke()
			context.move_to(i*self._char_width+2, self._height-2)				#char[8]
			context.line_to((i+1)*self._char_width-2, self._height-2)
			context.stroke()
			context.move_to(i*self._char_width+2, int(self._height/4))				#char[9]
			context.line_to((i+1)*self._char_width-2, int(self._height/4))
			context.stroke()
			context.move_to(i*self._char_width+2, int(self._height*3/4))			#char[10]
			context.line_to((i+1)*self._char_width-2, int(self._height*3/4))
			context.stroke()
			#draw diagonal LEDs
			context.move_to(i*self._char_width+2, 2)						#char[11]
			context.line_to((i+1)*self._char_width-2, int(self._height/2)-1)
			context.stroke()
			context.move_to((i+1)*self._char_width-2, 2)					#char[12]
			context.line_to(i*self._char_width+2, int(self._height/2)-1)
			context.stroke()
			context.move_to(i*self._char_width+2, int(self._height/2)+1)			#char[13]
			context.line_to((i+1)*self._char_width-2, self._height-2)
			context.stroke()
			context.move_to((i+1)*self._char_width-2, int(self._height/2)+1)			#char[14]
			context.line_to(i*self._char_width+2, self._height-2)
			context.stroke()
			
		#now draw the lit LED elements
		if (self._value != None) or (self._chars != None):
			context.set_line_width(2)
			context.set_source_rgb(self._on_color[0], self._on_color[1], self._on_color[2])
			
			#draw lit LEDs for the descriptor array
			for i in range(0, len(self._chars_array)):
				if (self._chars_array[i][0] == 1):
					context.move_to(i*self._char_width+2, 2)
					context.line_to(i*self._char_width+2, int(self._height/2)-1)
					context.stroke()
				if (self._chars_array[i][1] == 1):
					context.move_to(i*self._char_width+2, int(self._height/2)+1)
					context.line_to(i*self._char_width+2, self._height-2)
					context.stroke()
				if (self._chars_array[i][2] == 1):
					context.move_to((i+1)*self._char_width-2, 2)
					context.line_to((i+1)*self._char_width-2, int(self._height/2)-1)
					context.stroke()
				if (self._chars_array[i][3] == 1):
					context.move_to((i+1)*self._char_width-2, int(self._height/2)+1)
					context.line_to((i+1)*self._char_width-2, self._height-2)
					context.stroke()
				if (self._chars_array[i][4] == 1):
					context.move_to(i*self._char_width+int(self._char_width/2), 2)
					context.line_to(i*self._char_width+int(self._char_width/2), int(self._height/2)-1)
					context.stroke()
				if (self._chars_array[i][5] == 1):
					context.move_to(i*self._char_width+int(self._char_width/2), int(self._height/2)+1)
					context.line_to(i*self._char_width+int(self._char_width/2), self._height-2)
					context.stroke()
				if (self._chars_array[i][6] == 1):
					context.move_to(i*self._char_width+2, 2)
					context.line_to((i+1)*self._char_width-2, 2)
					context.stroke()
				if (self._chars_array[i][7] == 1):
					context.move_to(i*self._char_width+2, int(self._height/2))
					context.line_to((i+1)*self._char_width-2, int(self._height/2))
					context.stroke()
				if (self._chars_array[i][8] == 1):
					context.move_to(i*self._char_width+2, self._height-2)
					context.line_to((i+1)*self._char_width-2, self._height-2)
					context.stroke()
				if (self._chars_array[i][9] == 1):
					context.move_to(i*self._char_width+2, int(self._height/4))
					context.line_to((i+1)*self._char_width-2, int(self._height/4))
					context.stroke()
				if (self._chars_array[i][10] == 1):
					context.move_to(i*self._char_width+2, int(self._height*3/4))
					context.line_to((i+1)*self._char_width-2, int(self._height*3/4))
					context.stroke()
				if (self._chars_array[i][11] == 1):
					context.move_to(i*self._char_width+2, 2)
					context.line_to((i+1)*self._char_width-2, int(self._height/2)-1)
					context.stroke()
				if (self._chars_array[i][12] == 1):
					context.move_to((i+1)*self._char_width-2, 2)
					context.line_to(i*self._char_width+2, int(self._height/2)-1)
					context.stroke()
				if (self._chars_array[i][13] == 1):
					context.move_to(i*self._char_width+2, int(self._height/2)+1)
					context.line_to((i+1)*self._char_width-2, self._height-2)
					context.stroke()
				if (self._chars_array[i][14] == 1):
					context.move_to((i+1)*self._char_width-2, int(self._height/2)+1)
					context.line_to(i*self._char_width+2, self._height-2)
					context.stroke()
					
			#now draw the lit LEDs for the value array
			for i in range(int(self._width/self._char_width)-3, int(self._width/self._char_width)):
				j = -int(self._width/self._char_width) + 3 + i
				if (self._value_array[j][0] == 1):
					context.move_to(i*self._char_width+2, 2)
					context.line_to(i*self._char_width+2, int(self._height/2)-1)
					context.stroke()
				if (self._value_array[j][1] == 1):
					context.move_to(i*self._char_width+2, int(self._height/2)+1)
					context.line_to(i*self._char_width+2, self._height-2)
					context.stroke()
				if (self._value_array[j][2] == 1):
					context.move_to((i+1)*self._char_width-2, 2)
					context.line_to((i+1)*self._char_width-2, int(self._height/2)-1)
					context.stroke()
				if (self._value_array[j][3] == 1):
					context.move_to((i+1)*self._char_width-2, int(self._height/2)+1)
					context.line_to((i+1)*self._char_width-2, self._height-2)
					context.stroke()
				if (self._value_array[j][4] == 1):
					context.move_to(i*self._char_width+int(self._char_width/2), 2)
					context.line_to(i*self._char_width+int(self._char_width/2), int(self._height/2)-1)
					context.stroke()
				if (self._value_array[j][5] == 1):
					context.move_to(i*self._char_width+int(self._char_width/2), int(self._height/2)+1)
					context.line_to(i*self._char_width+int(self._char_width/2), self._height-2)
					context.stroke()
				if (self._value_array[j][6] == 1):
					context.move_to(i*self._char_width+2, 2)
					context.line_to((i+1)*self._char_width-2, 2)
					context.stroke()
				if (self._value_array[j][7] == 1):
					context.move_to(i*self._char_width+2, int(self._height/2))
					context.line_to((i+1)*self._char_width-2, int(self._height/2))
					context.stroke()
				if (self._value_array[j][8] == 1):
					context.move_to(i*self._char_width+2, self._height-2)
					context.line_to((i+1)*self._char_width-2, self._height-2)
					context.stroke()
				if (self._value_array[j][9] == 1):
					context.move_to(i*self._char_width+2, int(self._height/4))
					context.line_to((i+1)*self._char_width-2, int(self._height/4))
					context.stroke()
				if (self._value_array[j][10] == 1):
					context.move_to(i*self._char_width+2, int(self._height*3/4))
					context.line_to((i+1)*self._char_width-2, int(self._height*3/4))
					context.stroke()
				if (self._value_array[j][11] == 1):
					context.move_to(i*self._char_width+2, 2)
					context.line_to((i+1)*self._char_width-2, int(self._height/2)-1)
					context.stroke()
				if (self._value_array[j][12] == 1):
					context.move_to((i+1)*self._char_width-2, 2)
					context.line_to(i*self._char_width+2, int(self._height/2)-1)
					context.stroke()
				if (self._value_array[j][13] == 1):
					context.move_to(i*self._char_width+2, int(self._height/2)+1)
					context.line_to((i+1)*self._char_width-2, self._height-2)
					context.stroke()
				if (self._value_array[j][14] == 1):
					context.move_to((i+1)*self._char_width-2, int(self._height/2)+1)
					context.line_to(i*self._char_width+2, self._height-2)
					context.stroke()
				
			
		'''
		#draw a border around the entire widget
		context.set_source_rgb(self._on_color[0], self._on_color[1], self._on_color[2])
		context.set_line_width(4)
		context.move_to(0, 0)
		context.line_to(self._width, 0)
		context.line_to(self._width, self._height)
		context.line_to(0, self._height)
		context.line_to(0, 0)
		context.stroke()
		'''
	
	#This method is called by the user to display the descriptor and the value.
	#It will convert character strings and integer values to their corresponding LED 15-tuple representations
	def setCharacters(self, chars, value):
		self._chars = chars.lower()	#We need not concern ourselves with case sensitivity
		self._value = value
		self._chars_array = []
		self._value_array = []
		#print int(self._width/self._char_width) - self._digits - 1
		for i in range(0, len(self._chars)):
			if i == int(self._width/self._char_width) - self._digits - 1:
				break
			if self._chars[i] == 'a':		#then append the corresponding 15-tuple to self._chars_array
				self._chars_array.append(self.char_a)
			elif self._chars[i] == 'b':
				self._chars_array.append(self.char_b)
			elif self._chars[i] == 'c':
				self._chars_array.append(self.char_c)
			elif self._chars[i] == 'd':
				self._chars_array.append(self.char_d)
			elif self._chars[i] == 'e':
				self._chars_array.append(self.char_e)
			elif self._chars[i] == 'f':
				self._chars_array.append(self.char_f)
			elif self._chars[i] == 'g':
				self._chars_array.append(self.char_g)
			elif self._chars[i] == 'h':
				self._chars_array.append(self.char_h)
			elif self._chars[i] == 'i':
				self._chars_array.append(self.char_i)
			elif self._chars[i] == 'j':
				self._chars_array.append(self.char_j)
			elif self._chars[i] == 'k':
				self._chars_array.append(self.char_k)
			elif self._chars[i] == 'l':
				self._chars_array.append(self.char_l)
			elif self._chars[i] == 'm':
				self._chars_array.append(self.char_m)
			elif self._chars[i] == 'n':
				self._chars_array.append(self.char_n)
			elif self._chars[i] == 'o':
				self._chars_array.append(self.char_o)
			elif self._chars[i] == 'p':
				self._chars_array.append(self.char_p)
			elif self._chars[i] == 'q':
				self._chars_array.append(self.char_q)
			elif self._chars[i] == 'r':
				self._chars_array.append(self.char_r)
			elif self._chars[i] == 's':
				self._chars_array.append(self.char_s)
			elif self._chars[i] == 't':
				self._chars_array.append(self.char_t)
			elif self._chars[i] == 'u':
				self._chars_array.append(self.char_u)
			elif self._chars[i] == 'v':
				self._chars_array.append(self.char_v)
			elif self._chars[i] == 'w':
				self._chars_array.append(self.char_w)
			elif self._chars[i] == 'x':
				self._chars_array.append(self.char_x)
			elif self._chars[i] == 'y':
				self._chars_array.append(self.char_y)
			elif self._chars[i] == 'z':
				self._chars_array.append(self.char_z)
			
			elif self._chars[i] == '0':
				self._chars_array.append(self.char_0)
			elif self._chars[i] == '1':
				self._chars_array.append(self.char_1)
			elif self._chars[i] == '2':
				self._chars_array.append(self.char_2)
			elif self._chars[i] == '3':
				self._chars_array.append(self.char_3)
			elif self._chars[i] == '4':
				self._chars_array.append(self.char_4)
			elif self._chars[i] == '5':
				self._chars_array.append(self.char_5)
			elif self._chars[i] == '6':
				self._chars_array.append(self.char_6)
			elif self._chars[i] == '7':
				self._chars_array.append(self.char_7)
			elif self._chars[i] == '8':
				self._chars_array.append(self.char_8)
			elif self._chars[i] == '9':
				self._chars_array.append(self.char_9)
			
			elif self._chars[i] == '''=''':
				self._chars_array.append(self.char_equal)
			elif self._chars[i] == '''_''':
				self._chars_array.append(self.char_underscore)
			elif self._chars[i] == '''[''':
				self._chars_array.append(self.char_lbracket)
			elif self._chars[i] == ''']''':
				self._chars_array.append(self.char_rbracket)
			elif self._chars[i] == '''*''':
				self._chars_array.append(self.char_star)
			elif self._chars[i] == ''' ''':
				self._chars_array.append(self.char_space)
			elif self._chars[i] == '''?''':		#initialization character
				self._chars_array.append(self.char_init)
		
		value_str = str(self._value)	#convert the value to a string to be analyzed
		
		if self._value < 0:		#if < 0, the LED should not light up
			self._value_array.append(self.char_space)
			self._value_array.append(self.char_space)
			self._value_array.append(self.char_space)
		
		if self._value < 100:
			self._value_array.append(self.char_0)
			if self._value < 10:
				self._value_array.append(self.char_0)
				if value_str[0] == '0':
					self._value_array.append(self.char_0)
				elif value_str[0] == '1':
					self._value_array.append(self.char_1)
				elif value_str[0] == '2':
					self._value_array.append(self.char_2)
				elif value_str[0] == '3':
					self._value_array.append(self.char_3)
				elif value_str[0] == '4':
					self._value_array.append(self.char_4)
				elif value_str[0] == '5':
					self._value_array.append(self.char_5)
				elif value_str[0] == '6':
					self._value_array.append(self.char_6)
				elif value_str[0] == '7':
					self._value_array.append(self.char_7)
				elif value_str[0] == '8':
					self._value_array.append(self.char_8)
				elif value_str[0] == '9':
					self._value_array.append(self.char_9)
			else:
				for i in range(0, 2):
					if value_str[i] == '0':
						self._value_array.append(self.char_0)
					elif value_str[i] == '1':
						self._value_array.append(self.char_1)
					elif value_str[i] == '2':
						self._value_array.append(self.char_2)
					elif value_str[i] == '3':
						self._value_array.append(self.char_3)
					elif value_str[i] == '4':
						self._value_array.append(self.char_4)
					elif value_str[i] == '5':
						self._value_array.append(self.char_5)
					elif value_str[i] == '6':
						self._value_array.append(self.char_6)
					elif value_str[i] == '7':
						self._value_array.append(self.char_7)
					elif value_str[i] == '8':
						self._value_array.append(self.char_8)
					elif value_str[i] == '9':
						self._value_array.append(self.char_9)
		else:
			for i in range(0, 3):
				if value_str[i] == '0':
					self._value_array.append(self.char_0)
				elif value_str[i] == '1':
					self._value_array.append(self.char_1)
				elif value_str[i] == '2':
					self._value_array.append(self.char_2)
				elif value_str[i] == '3':
					self._value_array.append(self.char_3)
				elif value_str[i] == '4':
					self._value_array.append(self.char_4)
				elif value_str[i] == '5':
					self._value_array.append(self.char_5)
				elif value_str[i] == '6':
					self._value_array.append(self.char_6)
				elif value_str[i] == '7':
					self._value_array.append(self.char_7)
				elif value_str[i] == '8':
					self._value_array.append(self.char_8)
				elif value_str[i] == '9':
					self._value_array.append(self.char_9)
				

		if self._value >= 1000:		#we do not support values >= 1000
			self._value_array.append(self.char_9)
			self._value_array.append(self.char_9)
			self._value_array.append(self.char_9)
		#print len(self._chars_array)
		self.queue_draw_area(0, 0, self._width, self._height)	#Finally, notify PyGTK to redraw this widget
		
	def playThread(self):
		self._flashes = 0
		gobject.timeout_add(300, self._flashInitialization)
		
	def _flashInitialization(self):
		if self._flashes % 2 == 1:
			self.setCharacters("???????????", 888)
		else:
			self.setCharacters("           ", -1)
		if self._flashes < self._num_flashes:
			self._flashes += 1
			return True
		else:
			self._flashes = 0
			return False
		