#!/usr/bin/env python

# This application is released under the GNU General Public License 
# v3 (or, at your option, any later version). You can find the full 
# text of the license under http://www.gnu.org/licenses/gpl.txt. 
# By using, editing and/or distributing this software you agree to 
# the terms and conditions of this license. 
# Thank you for using free software!
#
#(c) Whise 2008,2009 <helderfraga@gmail.com>
#
# GnoMenu widgets
# Part of the GnoMenu

import pygtk
pygtk.require("2.0")
import gtk
import cairo
import gobject
from gtk import gdk
import pango
from Menu_Items import XDGMenu
import os
import commands
import Globals
import IconFactory
import cairo_drawing
#import gc
#import time


try:
	INSTALL_PREFIX = open("/etc/gnomenu/prefix").read()[:-1] 
except:
	INSTALL_PREFIX = '/usr'

import gettext

gettext.textdomain('gnomenu')
gettext.install('gnomenu', INSTALL_PREFIX +  '/share/locale')
gettext.bindtextdomain('gnomenu', INSTALL_PREFIX +  '/share/locale')

def _(s):
	return gettext.gettext(s)


class MenuButton:
	def __init__(self,i,base,backimage):
		# base > EventBox > Fixed > All the rest
		self.i = i
		self.backimagearea = None
		self.Button = gtk.EventBox()
		self.Frame = gtk.Fixed()
		if not self.Button.is_composited():
	 
			self.supports_alpha = False
		else:
			self.supports_alpha = True
		self.Button.connect("composited-changed", self.composite_changed)
		self.Frame.connect("expose_event", self.expose)
		self.Button.add(self.Frame)
		if Globals.MenuButtonIcon[i]:
			self.Icon = gtk.Image()
			self.SetIcon(Globals.ImageDirectory + Globals.MenuButtonIcon[i])
		self.Image = gtk.Image()
	   	self.Setimage(Globals.ImageDirectory + Globals.MenuButtonImage[i])
		self.w = self.Pic.get_width()
		self.h = self.Pic.get_height()
		if self.backimagearea is None:
			if Globals.flip == False:
				self.backimagearea = backimage.subpixbuf(Globals.MenuButtonX[i],Globals.MenuHeight - Globals.MenuButtonY[i] - self.h,self.w,self.h)
				self.backimagearea = self.backimagearea.flip(Globals.flip)
			else:
				self.backimagearea = backimage.subpixbuf(Globals.MenuButtonX[i],Globals.MenuButtonY[i] ,self.w,self.h)
		# Set the background which is always present
		self.BackgroundImage = gtk.Image()
		if Globals.MenuButtonImageBack[i] != '':
			self.BackgroundImage.set_from_pixbuf(gtk.gdk.pixbuf_new_from_file(Globals.ImageDirectory + Globals.MenuButtonImageBack[i]))
		else:
			self.BackgroundImage.set_from_pixbuf(None)
		self.Image.set_size_request(self.w,self.h)
		self.Frame.set_size_request(self.w,self.h)		
		self.SetBackground(i)

		self.Frame.put(self.BackgroundImage,0,0)
		self.Frame.put(self.Image,0,0)
		if Globals.MenuButtonIcon[i]:
			self.Frame.put(self.Icon,Globals.MenuButtonIconX[i],Globals.MenuButtonIconY[i])
		self.Label = gtk.Label()
		self.txt = Globals.MenuButtonMarkup[i]
		try:
			self.txt = self.txt.replace(Globals.MenuButtonNames[i],_(Globals.MenuButtonNames[i]))

		except:pass
		self.Label.set_markup(self.txt)
		if Globals.MenuButtonNameAlignment[i] == 0:
			self.Label.set_alignment(0, 0)
		elif Globals.MenuButtonNameAlignment[i] == 1:
			self.Label.set_alignment(0.5, 0)
		else:
			self.Label.set_alignment(1, 0)
		self.Label.set_size_request(int(self.w-Globals.MenuButtonNameOffsetX[i]*2)-2,-1)
		self.Label.set_ellipsize(pango.ELLIPSIZE_END)
		self.Frame.put(self.Label,Globals.MenuButtonNameOffsetX[i],Globals.MenuButtonNameOffsetY[i])
		if self.Label.get_text() == '' or Globals.Settings['Show_Tips']:
			self.Frame.set_tooltip_text(_(Globals.MenuButtonNames[i]))
		base.put(self.Button,Globals.MenuButtonX[i],Globals.MenuButtonY[i])
		#gc.collect()

	def composite_changed(self,widget):
		
	 	if not self.Button.is_composited():
	 
			self.supports_alpha = False
		else:
			self.supports_alpha = True

	def expose (self, widget, event):
		self.ctx = widget.window.cairo_create()
		# set a clip region for the expose event
		if self.supports_alpha == False:
			self.ctx.set_source_rgb(1, 1, 1)
		else:
			self.ctx.set_source_rgba(1, 1, 1,0)
		self.ctx.set_operator (cairo.OPERATOR_SOURCE)
		self.ctx.paint()
		cairo_drawing.draw_pixbuf(self.ctx,self.backimagearea)


	  
	def SetIcon(self,filename):
		# If the menu has an icon on top, then add that
		try:
			if Globals.MenuButtonIconSize[self.i] != 0:
				self.ww = Globals.MenuButtonIconSize[self.i]
				self.hh = self.ww
				self.Pic = gtk.gdk.pixbuf_new_from_file_at_size(filename,self.ww,self.hh)
			else:
				self.Pic = gtk.gdk.pixbuf_new_from_file(filename)
				self.ww = self.Pic.get_width()
				self.hh = self.Pic.get_height()
			if Globals.Settings['System_Icons']:
				if Globals.MenuButtonIconSel[self.i] == '':
					ico = IconFactory.GetSystemIcon(Globals.MenuButtonIcon[self.i])
					if not ico:
						ico = filename
					self.Pic = gtk.gdk.pixbuf_new_from_file_at_size(ico,self.ww,self.hh)
			self.Icon.set_from_pixbuf(self.Pic)
		except:print 'error on button seticon'  + filename
				

	def Setimage(self,imagefile):
		# The image is background when it's not displaying the overlay
		self.Pic = gtk.gdk.pixbuf_new_from_file(imagefile)
		self.Image.set_from_pixbuf(self.Pic)

	def SetBackground(self, i):
		self.Pic = gtk.gdk.pixbuf_new_from_file("/usr/share/gnomenu/Themes/Menu/XP/item-background.png")
                if i == 13 or i == 14:
                        self.Pic = gtk.gdk.pixbuf_new_from_file("/usr/share/gnomenu/Themes/Menu/XP/lock-background.png")
                if i == 15:
                        self.Pic = gtk.gdk.pixbuf_new_from_file("/usr/share/gnomenu/Themes/Menu/XP/all-background.png")
		self.Image.set_from_pixbuf(self.Pic)


class MenuImage:
	def __init__(self,i,base,backimage):
		self.backimagearea = None
		self.Frame = gtk.Fixed()
		if not self.Frame.is_composited():
	 
			self.supports_alpha = False
		else:
			self.supports_alpha = True
		self.Frame.connect("composited-changed", self.composite_changed)
		self.Image = gtk.Image()
		self.Pic = gtk.gdk.pixbuf_new_from_file(Globals.ImageDirectory + Globals.MenuImage[i])
		self.w = self.Pic.get_width()
		self.h = self.Pic.get_height()
		if Globals.Settings['System_Icons']:
			ico = IconFactory.GetSystemIcon(Globals.MenuImage[i])
			if not ico:
				ico = Globals.ImageDirectory + Globals.MenuImage[i]
			self.Pic = gtk.gdk.pixbuf_new_from_file_at_size(ico,self.w,self.h)

		if self.backimagearea is None:
			if Globals.flip == False:
				self.backimagearea = backimage.subpixbuf(Globals.MenuImageX[i],Globals.MenuHeight - Globals.MenuImageY[i] - self.h,self.w,self.h)
				self.backimagearea = self.backimagearea.flip(Globals.flip)
			else:
				self.backimagearea = backimage.subpixbuf(Globals.MenuImageX[i],Globals.MenuImageY[i] ,self.w,self.h)
		self.Pic.composite(self.backimagearea, 0, 0, self.w, self.h, 0, 0, 1, 1, gtk.gdk.INTERP_BILINEAR, 255)
		# Set the background which is always present
		self.Image.set_from_pixbuf(self.backimagearea)
		self.Image.set_size_request(self.w,self.h)
		self.Frame.set_size_request(self.w,self.h)
		self.Frame.put(self.Image,0,0)
		base.put(self.Frame,Globals.MenuImageX[i],Globals.MenuImageY[i])
		#gc.collect()

	def composite_changed(self,widget):
		
	 	if not self.Frame.is_composited():
	 
			self.supports_alpha = False
		else:
			self.supports_alpha = True


	def expose (self, widget, event):
		
		self.ctx = widget.window.cairo_create()
		# set a clip region for the expose event
		if self.supports_alpha == False:
			self.ctx.set_source_rgb(1, 1, 1)
		else:
			self.ctx.set_source_rgba(1, 1, 1,0)
		self.ctx.set_operator (cairo.OPERATOR_SOURCE)
		self.ctx.paint()

class MenuTab:
	def __init__(self,i,base,backimage):
		self.i = i
		self.backimagearea = None
		self.Tab = gtk.EventBox()
		self.Frame = gtk.Fixed()
		if not self.Tab.is_composited():
	 
			self.supports_alpha = False
		else:
			self.supports_alpha = True
		self.Tab.connect("composited-changed", self.composite_changed)
		self.Tab.connect("enter_notify_event", self.enter,i)
		self.Tab.connect("leave_notify_event", self.leave,i)
		self.Frame.connect("expose_event", self.expose)
		sel = gtk.gdk.pixbuf_get_file_info(Globals.ImageDirectory +Globals.MenuTabImageSel[self.i])
		self.w = sel[1]
		self.h = sel[2]
		sel = None
		self.Tab.add(self.Frame)
		if Globals.MenuTabIcon[i] != '':
			self.Icon = gtk.Image()
			self.SetIcon(Globals.ImageDirectory + Globals.MenuTabIcon[i])
		# Set the top image
		self.Image = gtk.Image()
	   	self.Setimage(Globals.ImageDirectory + Globals.MenuTabImage[i])
		
		# Clip the background from the back image
		# Grab the background pixels from under the location of the menu Tab

		if self.backimagearea is None:
			if Globals.flip == False:
				self.backimagearea = backimage.subpixbuf(Globals.MenuTabX[i],Globals.MenuHeight - Globals.MenuTabY[i] - self.h,self.w,self.h)
				self.backimagearea = self.backimagearea.flip(Globals.flip)
			else:
				self.backimagearea = backimage.subpixbuf(Globals.MenuTabX[i],Globals.MenuTabY[i] ,self.w,self.h)
		# Set the background which is always present
		self.Image.set_size_request(self.w,self.h)
		self.Frame.set_size_request(self.w,self.h)
		self.SetBackground()
		self.Frame.put(self.Image,0,0)
		if Globals.MenuTabIcon[i]:
			self.Frame.put(self.Icon,Globals.MenuCairoIcontabX[i],Globals.MenuCairoIcontabY[i])
		self.Label = gtk.Label()
		self.txt = Globals.MenuTabMarkup[i]
		try:
			self.txt = self.txt.replace(Globals.MenuTabNames[i],_(Globals.MenuTabNames[i]))
		except:pass
		self.prime_color = self.txt[(self.txt.find("span foreground='") +len("span foreground='")):]
		self.prime_color = self.prime_color[:self.prime_color.find("'")]
		if self.prime_color == '':self.prime_color = Globals.ThemeColorHtml
		self.theme_color = gtk.gdk.color_parse(self.prime_color)
		self.theme_color_r = 65535 - int(self.theme_color.red)
		self.theme_color_g = 65535 - int(self.theme_color.green)
		self.theme_color_b = 65535 - int(self.theme_color.blue)
		self.color = gtk.gdk.Color(self.theme_color_r,self.theme_color_g,self.theme_color_b,0)
		self.second_color = self.color_to_hex(self.color)
		self.Frame.set_tooltip_text(_(Globals.MenuTabNames[i]))
		#self.Label.set_markup(self.txt)
		if Globals.MenuTabNameAlignment[i] == 0:
			self.Label.set_alignment(0, 0)
		elif Globals.MenuTabNameAlignment[i] == 1:
			self.Label.set_alignment(0.5, 0)
		else:
			self.Label.set_alignment(1, 0)
		self.Label.set_size_request(int(self.w-Globals.MenuTabNameOffsetX[i]*2)-2,-1)
		self.Label.set_ellipsize(pango.ELLIPSIZE_END)
		self.Frame.put(self.Label,Globals.MenuTabNameOffsetX[i],Globals.MenuTabNameOffsetY[i])
		base.put(self.Tab,Globals.MenuTabX[i],Globals.MenuTabY[i])
		self.selected_tab = False
		#gc.collect()


	def enter (self, widget, event,i):

		if Globals.Settings['Tab_Efect'] != 0 and Globals.MenuTabIcon[i] != '':
			if Globals.Settings['System_Icons']:
				ico = ico = IconFactory.GetSystemIcon(Globals.MenuTabIcon[i])
				if not ico:
					ico = Globals.ImageDirectory + Globals.MenuTabIcon[i]

			else:
				ico = Globals.ImageDirectory + Globals.MenuTabIcon[i]

			if Globals.Settings['Tab_Efect'] == 1: #grow
				self.Pic = gtk.gdk.pixbuf_new_from_file_at_size(ico,self.ww+4,self.hh+4)


			elif Globals.Settings['Tab_Efect'] == 2:#bw
				self.Pic = gtk.gdk.pixbuf_new_from_file_at_size(ico,self.ww,self.hh)
				self.Pic.saturate_and_pixelate(self.Pic, 0.0, False)

			elif Globals.Settings['Tab_Efect'] == 3:#Blur

				colorpb = gtk.gdk.pixbuf_new_from_file_at_size(ico,self.ww,self.hh)
				alpha = 255#int(int(70) * 2.55 + 0.2)
				tk = 2
				bg = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, self.ww,self.hh)
				bg.fill(0x00000000)
				glow = bg.copy()
				# Prepare the glow that should be put bind the icon
				tk1 = tk - int(tk/2)
				for x, y in ((-tk1,-tk1), (-tk1,tk1), (tk1,-tk1), (tk1,tk1)):
					colorpb.composite(glow, 0, 0, self.ww, self.hh, x, y, 1, 1, gtk.gdk.INTERP_BILINEAR, 170)
				for x, y in ((-tk,-tk), (-tk,tk), (tk,-tk), (tk,tk)):
					colorpb.composite(glow, 0, 0, self.ww, self.hh, x, y, 1, 1, gtk.gdk.INTERP_BILINEAR, 70)
				glow.composite(bg, 0, 0, self.ww, self.hh, 0, 0, 1, 1, gtk.gdk.INTERP_BILINEAR, alpha)
				self.Pic = bg
				

			elif Globals.Settings['Tab_Efect'] == 4:#glow
				if Globals.Has_Numpy:
					r = 255
				        g = 255
					b = 0
					self.Pic = gtk.gdk.pixbuf_new_from_file_at_size(ico,self.ww,self.hh)
					colorpb= self.Pic.copy()
				        for row in colorpb.get_pixels_array():
					        for pix in row:
						        pix[0] = r
					                pix[1] = g
	                				pix[2] = b
	
					alpha = 255#int(int(70) * 2.55 + 0.2)
					tk = 2
				        bg = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, self.ww,self.hh)
				        bg.fill(0x00000000)
				        glow = bg.copy()
				        # Prepare the glow that should be put bind the icon
				        tk1 = tk - int(tk/2)
				        for x, y in ((-tk1,-tk1), (-tk1,tk1), (tk1,-tk1), (tk1,tk1)):
						colorpb.composite(glow, 0, 0, self.ww, self.hh, x, y, 1, 1, gtk.gdk.INTERP_BILINEAR, 170)
					for x, y in ((-tk,-tk), (-tk,tk), (tk,-tk), (tk,tk)):
						colorpb.composite(glow, 0, 0, self.ww, self.hh, x, y, 1, 1, gtk.gdk.INTERP_BILINEAR, 70)
					glow.composite(bg, 0, 0, self.ww, self.hh, 0, 0, 1, 1, gtk.gdk.INTERP_BILINEAR, alpha)
					self.Pic.composite(bg, 0, 0, self.ww, self.hh, 0, 0, 1, 1, gtk.gdk.INTERP_BILINEAR, 255)
				        self.Pic = bg
				else:print 'Error - This efect requires numpy installed'					

			elif Globals.Settings['Tab_Efect'] == 5:#saturate
				self.Pic = gtk.gdk.pixbuf_new_from_file_at_size(ico,self.ww,self.hh)
				self.Pic.saturate_and_pixelate(self.Pic, 6.0, False)
					

			self.Icon.set_from_pixbuf(self.Pic)

			if Globals.Settings['Tab_Efect'] == 1:
				self.Frame.move(self.Icon,Globals.MenuCairoIcontabX[i]-2,Globals.MenuCairoIcontabY[i]-2)
			else:
				self.Frame.move(self.Icon,Globals.MenuCairoIcontabX[i],Globals.MenuCairoIcontabY[i])

	def leave (self, widget, event,i):
		if Globals.Settings['Tab_Efect'] != 0 and Globals.MenuTabIcon[i] != '':		
			if Globals.Settings['System_Icons']:
				ico = IconFactory.GetSystemIcon(Globals.MenuTabIcon[i])
				if not ico : 
					ico = Globals.ImageDirectory + Globals.MenuTabIcon[i]
			else:
				ico = Globals.ImageDirectory + Globals.MenuTabIcon[i]

			self.Pic = gtk.gdk.pixbuf_new_from_file_at_size(ico,self.ww,self.hh)
			self.Frame.move(self.Icon,Globals.MenuCairoIcontabX[i],Globals.MenuCairoIcontabY[i])
			self.Icon.set_from_pixbuf(self.Pic)

	def composite_changed(self,widget):
		
	 	if not self.Tab.is_composited():
	 
			self.supports_alpha = False
		else:
			self.supports_alpha = True

	def expose (self, widget, event):
		self.ctx = widget.window.cairo_create()
		# set a clip region for the expose event
		if self.supports_alpha == False:
			self.ctx.set_source_rgb(1, 1, 1)
		else:
			self.ctx.set_source_rgba(1, 1, 1,0)
		self.ctx.set_operator (cairo.OPERATOR_SOURCE)
		self.ctx.paint()
		cairo_drawing.draw_pixbuf(self.ctx,self.backimagearea)


	  
	def SetIcon(self,filename):
		# If the menu has an icon on top, then add that

		if Globals.Settings['System_Icons']:
			ico = IconFactory.GetSystemIcon(Globals.MenuTabIcon[self.i])
			if not ico:
				ico = Globals.ImageDirectory + Globals.MenuTabIcon[self.i]
		else:
			ico = Globals.ImageDirectory + Globals.MenuTabIcon[self.i]
		self.Pic = gtk.gdk.pixbuf_get_file_info(Globals.ImageDirectory + Globals.MenuTabIcon[self.i])
		self.ww = Globals.MenuCairoIcontabSize[self.i]
		self.hh = self.ww
		if self.ww == 0:self.ww = self.Pic[1]
		if self.hh == 0:self.hh = self.Pic[2]

		self.Pic = gtk.gdk.pixbuf_new_from_file_at_size(ico,self.ww,self.hh)
		self.Icon.set_from_pixbuf(self.Pic)
		#except:print 'Menu Tab error in - ' + filename
				

	def Setimage(self,imagefile):
		# The image is background when it's not displaying the overlay
		try:
			self.Pic = gtk.gdk.pixbuf_new_from_file(imagefile)
			if Globals.Settings['GtkColors'] == 1 and Globals.Has_Numpy:
				
				bgcolor = Globals.GtkColorCode
				r = (bgcolor.red*255)/65535.0
				g = (bgcolor.green*255)/65535.0
				b = (bgcolor.blue*255)/65535.0
				colorpb= self.Pic.copy()
				for row in colorpb.get_pixels_array():
				        for pix in row:
					        pix[0] = r
				                pix[1] = g
		                		pix[2] = b

				self.Pic.composite(colorpb, 0, 0, self.w, self.h, 0, 0, 1, 1, gtk.gdk.INTERP_BILINEAR, 70)
				self.Pic = colorpb

			if Globals.flip == False:
				self.Pic.flip(Globals.flip)
				self.Image.set_from_pixbuf(self.Pic.flip(Globals.flip))
			else:
				self.Image.set_from_pixbuf(self.Pic)
		except:pass


	def SetBackground(self):
		self.Image.set_from_pixbuf(None)

	def SetSelectedTab(self,tab):
		if tab == False:
			if Globals.MenuTabInvertTextColorSel[self.i]:
				self.txt1 = self.txt.replace(self.prime_color,self.second_color)
				self.Label.set_markup(self.txt1)
			else:
				self.Label.set_markup(self.txt)	
			self.selected_tab = False
			self.SetBackground()
			self.Setimage(Globals.ImageDirectory + Globals.MenuTabImage[self.i])

		else:
			self.Label.set_markup(self.txt)	
			self.selected_tab = True
			self.Setimage(Globals.ImageDirectory + Globals.MenuTabImageSel[self.i])

	def GetSelectedTab(self):
		return self.selected_tab

	def color_to_hex(self, color):
	        hexstring = ""
	        for col in 'red','green','blue':
	            hexfrag = hex(getattr(color,col) / (16 * 16)).split("x")[1]
	            if len(hexfrag) < 2: hexfrag = "0" + hexfrag
	            hexstring += hexfrag
	        #print 'returning hexstring: ',hexstring
	        return ('#' + str(hexstring))

class Separator:
	def __init__(self,i,base):
		self.Image = gtk.Image()
		self.Setimage(Globals.ImageDirectory + Globals.MenuButtonImage[i])
		base.put(self.Image,Globals.MenuButtonX[i],Globals.MenuButtonY[i])

	def Setimage(self,imagefile):
		self.Pic = gtk.gdk.pixbuf_new_from_file(imagefile)
		self.Image.set_from_pixbuf(self.Pic)

class MenuLabel:
	def __init__(self,i,base):
		self.Label = gtk.Label()
		self.Label.connect_after('expose-event', self.expose,i)
		self.txt = Globals.MenuLabelMarkup[i]
		self.txt = self.txt.replace(Globals.MenuLabelNames[i],_(Globals.MenuLabelNames[i]))
		if Globals.MenuLabelCommands[i] != "":
			a = commands.getoutput(str(Globals.MenuLabelCommands[i]))
			self.txt = self.txt.replace('[TEXT]',a)
		self.Label.set_markup(self.txt)
		#self.Label.set_max_width_chars(int(self.w/9))
		#self.Label.set_ellipsize(3)
		if Globals.MenuLabelNameAlignment[i] == 0:
			s = 0
		elif Globals.MenuLabelNameAlignment[i] == 1:
			s = int(self.Label.size_request()[0] /2)
		else:
			s = self.Label.size_request()[0]
		if Globals.flip == False:
			base.put(self.Label,Globals.MenuLabelX[i]-s,Globals.MenuLabelY[i]-self.Label.size_request()[1])
		else:
			base.put(self.Label,Globals.MenuLabelX[i]-s,Globals.MenuLabelY[i])
		#gc.collect()

	def expose(self,widget,event,i):
		self.txt = Globals.MenuLabelMarkup[i]

		if Globals.MenuLabelCommands[i] != "":
			a = commands.getoutput(str(Globals.MenuLabelCommands[i]))
			self.txt1 = self.txt.replace('[TEXT]',a)
			if self.txt1 != self.txt and self.txt1 != self.Label.get_label():
				
				self.Label.set_markup(self.txt1)

class ImageFrame:
	def __init__(self,w,h,ix,iy,iw,ih,base,backimage):
		self.backimagearea = None
		self.w = w
		self.h = h
		#print w,h,iw,ih,ix,iy
		self.ix = ix
		self.iy = iy
		self.iw = iw
		self.ih = ih
		self.base = base
		self.timer = None
		self.icons = [None,None,None,None]
		self.iconopacity = [0,0,0,0]
		self.step = [0,0,0,0]
		self.intrans = False 
		self.Pic = None
		self.frame_window = gtk.EventBox()
		if not self.frame_window.is_composited():
	 
			self.supports_alpha = False
		else:
			self.supports_alpha = True
		self.Frame = gtk.Fixed()
		self.Image = gtk.Image()
		self.frame_window.set_tooltip_text(_('About Me'))
		self.frame_window.connect("button-press-event", self.but_click)
		self.frame_window.connect("composited-changed", self.composite_changed)
		self.Frame.connect('expose-event', self.expose)
		self.frame_window.add(self.Frame)
		#self.frame_window.set_size_request(w,h)
		self.frame_window.set_size_request(53,53)
		# Grab the background pixels from under the location of the menu button

		#self.backimagearea = self.backimagearea.add_alpha(True, chr(0xff), chr(0xff), chr(0xff))
		if self.backimagearea is None:
	
			if Globals.flip == False:

				self.backimagearea = backimage.subpixbuf(Globals.UserIconFrameOffsetX,Globals.MenuHeight - Globals.UserIconFrameOffsetY - self.h,self.w,self.h)
				self.backimagearea = self.backimagearea.flip(Globals.flip)
	
			else:
				self.backimagearea = backimage.subpixbuf(Globals.UserIconFrameOffsetX,Globals.UserIconFrameOffsetY,self.w,self.h)
		# Set the background which is always present
		self.Image.set_size_request(self.w,self.h)
		self.Frame.set_size_request(self.w,self.h)		
		self.SetBackground()
		self.Frame.put(self.Image,0,0)
		self.base.put(self.frame_window,self.ix,self.iy)
		self.Pic = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, self.w,self.h)
		self.Pic.fill(0x00000000)
		#gc.collect()


	def expose (self, widget, event):
		self.ctx = widget.window.cairo_create()
		# set a clip region for the expose event
		if self.supports_alpha == False:
			self.ctx.set_source_rgb(1, 1, 1)
		else:
			self.ctx.set_source_rgba(1, 1, 1,0)
		self.ctx.set_operator (cairo.OPERATOR_SOURCE)
		self.ctx.paint()
		cairo_drawing.draw_pixbuf(self.ctx,self.backimagearea)

	def composite_changed(self,widget):
		print self.frame_window.is_composited()

	def screen_changed(self,widget):
		# Screen change event
		screen = widget.get_screen()
		colormap = screen.get_rgba_colormap()
		widget.set_colormap(colormap)

	def Setimage(self):
		# The image is background when it's not displaying the overlay
		self.Image.set_from_pixbuf(None)
		self.Pic = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, self.w,self.h)
		self.Pic.fill(0x00000000)
		bg = self.Pic.copy()
		for i in range(0,len(self.iconopacity)):
			if self.icons[i] != None and self.iconopacity[i] > 0:
				if i ==1:
					self.icons[i].composite(self.Pic, self.ix, self.iy, self.icons[i].get_width(), self.icons[i].get_height(), self.ix, self.iy, 1, 1, gtk.gdk.INTERP_BILINEAR, int(self.iconopacity[i]* 255))
				else:
					self.icons[i].composite(self.Pic, 0, 0, self.icons[i].get_width(), self.icons[i].get_height(), 0, 0, 1, 1, gtk.gdk.INTERP_BILINEAR, int(self.iconopacity[i]* 255))
		
		self.Image.set_from_pixbuf(self.Pic)

	def SetBackground(self):
		self.Image.set_from_pixbuf(None)


	def but_click(self, widget, event):
		os.system(Globals.Settings['User'] + ' &')


	def move(self,x,y):
		# Relocate the window
		self.base.move(self.frame_window,x,y)

	def transition(self,step, speed, rate, termination_event):
		if self.timer:
			gobject.source_remove(self.timer)
			self.intrans = False
			self.Pic = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, self.w,self.h)
			self.Pic.fill(0x00000000)
		
		if step != self.step:
			if self.timer:
				gobject.source_remove(self.timer)
				self.intrans = False
		self.step = step
		if self.intrans == False:
			self.intrans = True
			# Add timer
			self.Pic = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, self.w,self.h)
			self.Pic.fill(0x00000000)
			self.timer = gobject.timeout_add(speed,self.updatefade, termination_event, rate)

	def updatefade(self, termination_event, rate):

		if self.step==[0,0,0,0]:
			self.intrans = False
			if termination_event:
				termination_event()
			return False
		for i in range(0,len(self.iconopacity)):
			self.iconopacity[i] = self.iconopacity[i] + round((rate*self.step[i]),2)
			if self.iconopacity[i] < 0: self.iconopacity[i] = 0
			if self.iconopacity[i] > 1: self.iconopacity[i] = 1
			if (self.iconopacity[i]<=0 or self.iconopacity[i]>=1) and self.step[i]!=0:
				self.step[i]=0
				
				self.iconopacity[i]=int(self.iconopacity[i])
			self.iconopacity[i]=round(self.iconopacity[i],2)
		
		self.Setimage()
		if self.step==[0,0,0,0]:
			self.Pic = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, self.w,self.h)
			self.Pic.fill(0x00000000)
			self.intrans = False
			if termination_event:
				termination_event()
			return False
		return True


	def updateimage(self,index,imagefile):

			# All .face files will load through this routine, even though they may be 'png' format 

		if index==1:

			self.temp = gtk.gdk.pixbuf_new_from_file(imagefile).scale_simple(self.iw,self.ih,gtk.gdk.INTERP_BILINEAR)

		elif index==0:	

			self.temp = gtk.gdk.pixbuf_new_from_file(imagefile)
			self.w = self.temp.get_width()
			self.h = self.temp.get_height()
		else:
			try:
				self.temp = gtk.gdk.pixbuf_new_from_file_at_size(imagefile, self.w, self.h)
			except:
				print 'Warning: icon %s not found in gnomenu icons, trying system icons instead!' % imagefile
				image = IconFactory.GetSystemIcon(imagefile.split('/').pop())
				if not image:
					print 'Warning: icon %s was not found in system icons either!' % imagefile
					image = IconFactory.GetSystemIcon('gtk-missing-image')
				
				self.temp = gtk.gdk.pixbuf_new_from_file_at_size(image, self.w, self.h)
		if index==0:
			#FRAME
			self.icons[0] = self.temp
		if index==1:
			#.FACE
			self.icons[1] = self.temp
		if index==2:
			#1ST ICON
			self.icons[2] = self.temp
		if index==3:
			#2ND ICON
			self.icons[3] = self.temp


class ImageFrame_cairo_surface:#flickers
	def __init__(self,w,h,ix,iy,iw,ih,base,backimage):
		self.backimagearea = None
		# Create the window itself
		self.w = w
		self.h = h
		self.ix = ix
		self.iy = iy
		self.iw = iw
		self.ih = ih
		self.frame_window = gtk.EventBox()
		self.frame_window.set_tooltip_text(_('About Me'))
		base.put(self.frame_window,self.ix,self.iy)
		
		self.frame_window.set_size_request(w,h)
		#Connect redraw-events
		self.frame_window.connect("button-press-event", self.but_click)
		self.frame_window.connect("composited-changed", self.composite_changed)
		self.frame_window.connect_after('expose-event', self.expose)
		self.frame_window.connect('screen-changed', self.screen_changed)
		self.frame_window.connect('destroy', self.destroy)
		self.icons = [None,None,None,None]
		self.timer = None
		self.screen_changed(self.frame_window)
		if self.backimagearea is None:
	
			if Globals.flip == False:

				self.backimagearea = backimage.subpixbuf(Globals.UserIconFrameOffsetX,Globals.MenuHeight - Globals.UserIconFrameOffsetY - self.h,self.w,self.h)
				self.backimagearea = self.backimagearea.flip(Globals.flip)
	
			else:
				self.backimagearea = backimage.subpixbuf(Globals.UserIconFrameOffsetX,Globals.UserIconFrameOffsetY,self.w,self.h)
		self.resizematch(self.w,self.h)		
		self.iconopacity = [0,0,0,0]
		self.step = [0,0,0,0]
		self.intrans = False 
		self.backbuffer = None
		#gc.collect()


		
	def but_click(self, widget, event):
		os.system('%s &' % Globals.Settings['User'])

	def transition(self,step, speed, rate, termination_event):
		self.step = step
		if self.timer is None:
			self.timer = gobject.timeout_add(speed,self.updatefade, termination_event, rate)
	
	def composite_changed(self,widget):
		print self.frame_window.is_composited()

	def updatefade(self, termination_event, rate):

		for i in range(0,len(self.iconopacity)):
			if self.step[i]!=0:
				self.iconopacity[i] = self.iconopacity[i] + (rate*self.step[i])
				if self.iconopacity[i] < rate: self.iconopacity[i] = 0
				if self.iconopacity[i] > 1-rate: self.iconopacity[i] = 1
				if (self.iconopacity[i]<=0 or self.iconopacity[i]>=1):
					self.step[i]=0
	

		self.Redraw()
		if self.step==[0,0,0,0]:
			self.timer = None
			return False
		return True
		
	def screen_changed(self,widget):
		# Screen change event
		screen = widget.get_screen()
		colormap = screen.get_rgba_colormap()
		widget.set_colormap(colormap)
	
	def expose(self,widget,event):
		self.Redraw()
	
	def Redraw(self):
		if self.frame_window.window :
			self.cr = self.frame_window.window.cairo_create()

			if self.frame_window.is_composited() is True:	
				self.cr.save()
				self.cr.set_source_rgba(1, 1, 1, 0)
				self.cr.set_operator (cairo.OPERATOR_SOURCE)
				self.cr.set_source_pixbuf(self.backimagearea, 0, 0)
				self.cr.paint()
				self.cr.restore()
				self.cr.set_operator(cairo.OPERATOR_OVER) #DEST_ATOP
				#self.iconopacity.sort()
				for i in range(0,len(self.iconopacity)):
					if self.icons[i] != None and self.iconopacity[i] > 0:
						if i == 1:
							self.cr.set_source_surface(self.icons[i], self.ix, self.iy)				
						else:
							self.cr.set_source_surface(self.icons[i], 0, 0)
						self.cr.paint_with_alpha(round(self.iconopacity[i],2))

			else:
				self.cr.set_source_rgb(1, 1, 1)
				self.cr.set_operator (cairo.OPERATOR_SOURCE)
				self.cr.paint()
				self.cr.set_operator(cairo.OPERATOR_OVER) #DEST_ATOP
				self.cr.set_source_pixbuf(self.backimagearea, 0, 0)
				self.cr.paint()
				
				for i in range(0,len(self.iconopacity)):
					if self.icons[i] != None and self.iconopacity[i] > 0:
						if i == 1:
							self.cr.set_source_surface(self.icons[i], self.ix, self.iy)				
						else:
							self.cr.set_source_surface(self.icons[i], 0, 0)
						self.cr.paint_with_alpha(round(self.iconopacity[i],2))

	def move(self,x,y):
		# Relocate the window
		self.frame_window.set_uposition(x,y)


	def resize(self,w,h):
		self.frame_window.set_size_request(w,h)

	def resizematch(self,w,h):
		self.frame_window.set_size_request(w,h)
	
	def destroy(self,event):
		# Remove the window
		self.frame_window.destroy()
		gtk.main_quit()

	def update(self):
		# Update the screen profile on request
		self.screen_changed(self.frame_window)
		
	def updateimage(self,index,imagefile):


		if index==0:

			self.temppixbuf = gtk.gdk.pixbuf_new_from_file(imagefile)
			self.w = self.temppixbuf.get_width()
			self.h = self.temppixbuf.get_height()

		elif index==1:

			self.temppixbuf = gtk.gdk.pixbuf_new_from_file(imagefile).scale_simple(self.iw,self.iw,gtk.gdk.INTERP_BILINEAR)

		else:
			self.temppixbuf = gtk.gdk.pixbuf_new_from_file_at_size(imagefile, self.w, self.h)

		self.temp = cairo.ImageSurface(cairo.FORMAT_ARGB32, self.w, self.h)
		self.cr2 = cairo.Context(self.temp)
		self.ct = gtk.gdk.CairoContext(self.cr2)
		self.ct.set_source_pixbuf(self.temppixbuf,0,0)
		self.ct.paint()

		if index==0:
			#FRAME
			self.icons[0] = self.temp
		elif index==1:
			#.FACE
			self.icons[1] = self.temp
		elif index==2:
			#1ST ICON
			self.icons[2] = self.temp
		elif index==3:
			#2ND ICON
			self.icons[3] = self.temp


class ImageFrame_new:
	def __init__(self,w,h,ix,iy,iw,ih,base,backimage):
		self.backimagearea = None
		# Create the window itself
		self.w = w
		self.h = h
		self.ix = ix
		self.iy = iy
		self.iw = iw
		self.ih = ih
		self.frame_window = gtk.EventBox()
		self.frame_window.set_tooltip_text(_('About Me'))
		base.put(self.frame_window,self.ix,self.iy)
		
		self.frame_window.set_size_request(w,h)
		#Connect redraw-events
		self.frame_window.connect("button-press-event", self.but_click)
		self.frame_window.connect("composited-changed", self.composite_changed)
		self.frame_window.connect_after('expose-event', self.expose)
		self.frame_window.connect('screen-changed', self.screen_changed)
		self.frame_window.connect('destroy', self.destroy)
		self.icon1=cairo.ImageSurface
		self.icon2=cairo.ImageSurface
		self.icon3=cairo.ImageSurface
		self.icon4=cairo.ImageSurface
		self.timer = None
		self.screen_changed(self.frame_window)
		if self.backimagearea is None:
	
			if Globals.flip == False:

				self.backimagearea = backimage.subpixbuf(Globals.UserIconFrameOffsetX,Globals.MenuHeight - Globals.UserIconFrameOffsetY - self.h,self.w,self.h)
				self.backimagearea = self.backimagearea.flip(Globals.flip)
	
			else:
				self.backimagearea = backimage.subpixbuf(Globals.UserIconFrameOffsetX,Globals.UserIconFrameOffsetY,self.w,self.h)
		self.resizematch(self.w,self.h)		
		self.iconopacity = [0,0,0,0]
		self.step = [0,0,0,0]
		self.intrans = False 
		#gc.collect()

		
	def but_click(self, widget, event):
		os.system('%s &' % Globals.Settings['User'])

	def transition(self,step, speed, rate, termination_event):
		if self.timer:
			gobject.source_remove(self.timer)
			self.intrans = False
		
		if step != self.step:
			if self.timer:
				gobject.source_remove(self.timer)
				self.intrans = False
		self.step = step
		if self.intrans == False:
			self.intrans = True
			# Add timer
			self.timer = gobject.timeout_add(speed,self.updatefade, termination_event, rate)

	def composite_changed(self,widget):
		print self.frame_window.is_composited()

	def updatefade(self, termination_event, rate):

		for i in range(0,len(self.iconopacity)):

			self.iconopacity[i] = self.iconopacity[i] + (rate*self.step[i])
			if self.iconopacity[i] < 0: self.iconopacity[i] = 0
			if self.iconopacity[i] > 1: self.iconopacity[i] = 1
			if (self.iconopacity[i]<=0 or self.iconopacity[i]>=1):
				self.step[i]=0


		self.Redraw()
		if self.step==[0,0,0,0]:
			self.intrans = False
			if termination_event:
				termination_event()
			return False
		return True
	


		
	def screen_changed(self,widget):
		# Screen change event
		screen = widget.get_screen()
		colormap = screen.get_rgba_colormap()
		widget.set_colormap(colormap)
	
	def expose(self,widget,event):
		self.Redraw()
	
	def Redraw(self):
		if self.frame_window.window :
			self.cr = self.frame_window.window.cairo_create()
			if self.frame_window.is_composited() is True:	
				self.cr.set_source_rgba(1, 1, 1, 0)
				self.cr.set_operator (cairo.OPERATOR_SOURCE)
				pixbuf = self.backimagearea

				self.cr.set_source_pixbuf(pixbuf, 0, 0)
				self.cr.paint()
				#self.cr.set_operator(cairo.OPERATOR_OVER) #DEST_ATOP
				
				if self.iconopacity[0] != 0:
					self.icon1.paint_with_alpha(self.iconopacity[0])
				if self.iconopacity[1] != 0:
					self.icon2.paint_with_alpha(self.iconopacity[1])
				if self.iconopacity[2] != 0:
					self.icon3.paint_with_alpha(self.iconopacity[2])
				if self.iconopacity[3] != 0:
					self.icon4.paint_with_alpha(self.iconopacity[3])
			else:
				self.cr.set_source_rgb(1, 1, 1)
				self.cr.set_operator (cairo.OPERATOR_SOURCE)
				self.cr.paint()
				self.cr.set_operator(cairo.OPERATOR_OVER) #DEST_ATOP
				pixbuf = self.backimagearea
				self.cr.set_source_pixbuf(pixbuf, 0, 0)
				self.cr.paint()
				
				if isinstance(self.icon1,cairo.Surface):
					self.ctx.paint_with_alpha(self.iconopacity[0])
				if isinstance(self.icon2,cairo.Surface):
					self.ctx.paint_with_alpha(self.iconopacity[1])
				if isinstance(self.icon3,cairo.Surface):
					self.ctx.paint_with_alpha(self.iconopacity[2])
				if isinstance(self.icon4,cairo.Surface):
					self.ctx.paint_with_alpha(self.iconopacity[3])				
			
	def move(self,x,y):
		# Relocate the window
		self.frame_window.set_uposition(x,y)


	def resize(self,w,h):
		self.frame_window.set_size_request(w,h)

	def resizematch(self,w,h):
		self.frame_window.set_size_request(w,h)
	
	def destroy(self,event):
		# Remove the window
		self.frame_window.destroy()
		gtk.main_quit()

	def update(self):
		# Update the screen profile on request
		self.screen_changed(self.frame_window)
		
	def updateimage(self,index,imagefile):

			# All .face files will load through this routine, even though they may be 'png' format 

			# Update the graphic being displayed (first image has size priority)

		if index==0:
			#FRAME

			pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(imagefile,self.w,self.h)
			# Resize the image and create the cairo surface to be used
			self.icon1 = self.frame_window.window.cairo_create()
			self.temp = self.icon1.set_source_pixbuf(pixbuf, 0, 0)
		if index==1:
			#.FACE
			pixbuf = gtk.gdk.pixbuf_new_from_file(imagefile).scale_simple(self.iw,self.iw,gtk.gdk.INTERP_BILINEAR)
			# Resize the image and create the cairo surface to be used
			self.icon2 = self.frame_window.window.cairo_create()
			self.temp = self.icon2.set_source_pixbuf(pixbuf, self.ix, self.iy)
			if Globals.MenuHasFade != 1:
				self.iconopacity = [1,1,-1,-1]
		if index==2:
			#1ST ICON
			pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(imagefile,self.w,self.h)
			# Resize the image and create the cairo surface to be used
			self.icon3 = self.frame_window.window.cairo_create()
			self.temp = self.icon3.set_source_pixbuf(pixbuf, 0, 0)
		if index==3:
			#2ND ICON
			pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(imagefile,self.w,self.h)
			# Resize the image and create the cairo surface to be used
			self.icon4 = self.frame_window.window.cairo_create()
			self.temp = self.icon4.set_source_pixbuf(pixbuf, 0, 0)
		#self.Redraw()

class GtkSearchBar(gtk.Entry):
	def __init__(self):
		gtk.Entry.__init__(self)
		if Globals.Settings['GtkColors'] == 0:
			self.modify_base(gtk.STATE_NORMAL, Globals.ThemeColorCode)

		self.connect("expose_event", self.expose)
		try:
			if self.text != _('Search'):
				self.font_desc = pango.FontDescription('sans italic')
			else:
				self.font_desc = pango.FontDescription('sans')
			self.modify_font(self.font_desc)
		except:pass
		if Globals.Settings['GtkColors'] == 0:
			self.modify_text(gtk.STATE_NORMAL, Globals.NegativeThemeColorCode)
	   
	def expose (self, widget, event):
		try:
			if self.text != _('Search'):
				self.font_desc = pango.FontDescription('sans italic')
			else:
				self.font_desc = pango.FontDescription('sans')
			self.modify_font(self.font_desc)
		except:pass
				
class CairoSearchBar(gtk.Entry):
 #   __gsignals__ = {
  #           'expose-event':   'override'}
	def __init__(self,BackColor="#FFFFFF",BorderColor="#000000",TextColor="#000000"):
		gtk.Entry.__init__(self)
		if Globals.Settings['GtkColors'] == 1:
			self.Backcolor = Globals.GtkColorCode
		else:
			self.Backcolor = gtk.gdk.color_parse(BackColor)
		self.Backcolor_r = (self.Backcolor.red)/65535.0
		self.Backcolor_g = (self.Backcolor.green)/65535.0
		self.Backcolor_b = (self.Backcolor.blue)/65535.0
		self.Bordercolor = gtk.gdk.color_parse(BorderColor)
		self.Bordercolor_r = (self.Bordercolor.red)/65535.0
		self.Bordercolor_g = (self.Bordercolor.green)/65535.0
		self.Bordercolor_b = (self.Bordercolor.blue)/65535.0
		#for state in [gtk.STATE_ACTIVE, gtk.STATE_NORMAL,gtk.STATE_PRELIGHT, gtk.STATE_SELECTED]: 
		self.modify_bg(gtk.STATE_NORMAL, self.Backcolor)
		self.modify_base(gtk.STATE_NORMAL, self.Backcolor)
		self.modify_text(gtk.STATE_NORMAL, gtk.gdk.color_parse(TextColor))
		self.connect("expose_event", self.expose)
		try:
			if self.text != _('Search'):
				self.font_desc = pango.FontDescription('sans italic')
			else:
				self.font_desc = pango.FontDescription('sans')
			self.modify_font(self.font_desc)
		except:pass
			   
	def expose (self, widget, event):
		self.cr = widget.window.cairo_create()
		self.cr.save()
		self.allocation = widget.allocation
		if self.is_composited() is True:	
			self.cr.set_source_rgba(1, 1, 1, 0)
		else:
			self.cr.set_source_rgb(1, 1, 1)
		self.cr.set_operator (cairo.OPERATOR_SOURCE)
		self.cr.paint()
		self.cr.restore()
		#self.cr.set_operator(cairo.OPERATOR_OVER) #DEST_ATOP
		r=5
		x0=0
		x1=x0+self.allocation.width
		y0=0
		y1=y0+self.allocation.height
		self.cr.rectangle(x0+1, y0+1, x1-1, y1-1)
		self.cr.set_source_rgb(self.Backcolor_r,self.Backcolor_g,self.Backcolor_b)
		self.cr.fill()
		self.cr.rectangle(x0, y0, x1, y1)
		self.cr.set_source_rgb(self.Bordercolor_r,self.Bordercolor_g,self.Bordercolor_b)
		self.cr.stroke()
		try:
			if self.text != _('Search'):
				self.font_desc = pango.FontDescription('sans italic')
			else:
				self.font_desc = pango.FontDescription('sans')
			self.modify_font(self.font_desc)
		except:pass

class CustomSearchBar_new:
	def __init__(self, base, BackImageFile=None, InitialText="",TextColor="#000000",SearchX=0,SearchY=0,SearchW=0,SearchH=0, X=4, Y=15,colorpb=None):
		self.backimagearea = None
		self.Button = gtk.EventBox()
		self.Frame = gtk.Fixed()
		if not self.Button.is_composited():
	 
			self.supports_alpha = False
		else:
			self.supports_alpha = True
		self.Button.connect("composited-changed", self.composite_changed)
		self.Frame.connect("expose_event", self.expose)
		self.Button.add(self.Frame)

class CustomSearchBar(gtk.Widget):
	def __init__(self, BackImageFile=None, InitialText="",TextColor="#000000",SearchX=0,SearchY=0,SearchW=0,SearchH=0, X=4, Y=15,colorpb=None):
		gtk.Widget.__init__(self)
		self.connect("expose_event", self.expose)#enter-notify-event

		self.colorpb = colorpb
		# Text Settings
		self.text = ""
		self.initialtext = InitialText
		self.TextColor = TextColor
		self.cursor = 0
		self.selection = False
		self.cursorblink = False
		self.cursorvisible = False
		color = gtk.gdk.color_parse(TextColor)
		self.color_r = (color.red)/65535.0
		self.color_g = (color.green)/65535.0
		self.color_b = (color.blue)/65535.0		
		self.originalw = 0
		self.originalh = 0
		# Graphical Settings
		self.sx = SearchX
		self.sy = SearchY
		self.sw = SearchW
		self.sh = SearchH
		self.x = X
		self.y = Y
		self.hasrectangle = False
		self.cornerradius = 12
		self.backimage = BackImageFile
		self.backimagepb = gtk.gdk.pixbuf_new_from_file(self.backimage)
		self.BackImageBuffer = None
		if Globals.flip == False:

			self.backimagearea = self.colorpb.subpixbuf(self.sx,Globals.MenuHeight - self.sy-self.sh,self.sw,self.sh)
			self.backimagearea = self.backimagearea.flip(Globals.flip)
	
		else:
			self.backimagearea = self.colorpb.subpixbuf(self.sx,self.sy,self.sw,self.sh)
		if not self.is_composited():
	 
			self.supports_alpha = False
		else:
			self.supports_alpha = True


	def enter(self, widget, event):
		self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.XTERM))

	def leave(self, widget, event):
		self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.ARROW))
		
	def do_realize(self):
		# Create events
		self.set_flags(self.flags() | gtk.REALIZED | gtk.CAN_FOCUS | gtk.HAS_FOCUS)
		
		# Create window for widget to be displayed in
			
		self.window = gtk.gdk.Window(
			self.get_parent_window(),
			width=self.allocation.width,
			height=self.allocation.height,
			window_type=gdk.WINDOW_CHILD,
			wclass=gdk.INPUT_OUTPUT,
			event_mask=self.get_events() | gtk.gdk.EXPOSURE_MASK | gtk.gdk.KEY_PRESS_MASK  | gtk.gdk.KEY_RELEASE_MASK | gtk.gdk.FOCUS_CHANGE_MASK | gtk.gdk.BUTTON1_MOTION_MASK | gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.POINTER_MOTION_HINT_MASK 
| gtk.gdk.ENTER_NOTIFY_MASK | gtk.gdk.LEAVE_NOTIFY_MASK)

		
				
				
		# Associate the gdk.Window with ourselves, Gtk+ needs a reference
		# between the widget and the gdk window
		self.window.set_user_data(self)
		
		# Attach the style to the gdk.Window, a style contains colors and
		# GC contextes used for drawing
		self.style.attach(self.window)
		

		# The default color of the background should be what
		# the style (theme engine) tells us.
		self.style.set_background(self.window, gtk.STATE_NORMAL)

		if Globals.Settings['GtkColors'] == 1:
			bgcolor = Globals.GtkColorCode
			self.t_color_r = 65535.0 - (bgcolor.red*255)/65535.0
			self.t_color_g = 65535.0- (bgcolor.green*255)/65535.0
			self.t_color_b = 65535.0- (bgcolor.blue*255)/65535.0
		else:
			color = gtk.gdk.color_parse(self.TextColor)
			self.t_color_r = (color.red)/65535.0
			self.t_color_g = (color.green)/65535.0
			self.t_color_b = (color.blue)/65535.0
		self.window.move_resize(*self.allocation)
		
		# self.style is a gtk.Style object, self.style.fg_gc is
		# an array or graphic contexts used for drawing the forground
		# colours	
		self.gc = self.style.fg_gc[gtk.STATE_NORMAL]
		self.connect("key_press_event", self.do_keypress)
		self.connect("enter_notify_event", self.enter)
		self.connect("leave_notify_event", self.leave)
		#if self.cursorvisible:
		gobject.timeout_add(700,self.blinkcursor)
		
	def do_keypress(self,widget,event):
		key = event.hardware_keycode
		if key==9:
			self.text=""
			self.window.invalidate_rect(None,False)						
		elif key==22 and self.cursor>0:
			self.text = self.text[0:len(self.text)-1]
			self.window.invalidate_rect(None,False)
		else:
			self.text=self.text+event.string
			self.cursor = self.cursor + 1
			self.window.invalidate_rect(None,False)
	
	def set_text(self,text):
		self.text = text
		self.window.invalidate_rect(None,False)
	
	def get_text(self):
		return self.text

	def expose(self, widget, event):
		# Redraw the window
		self.context = widget.window.cairo_create()
		# Set the region to be redrawn
		self.context.rectangle(event.area.x, event.area.y, event.area.width, event.area.height)
		self.context.clip()
		self.context.set_operator (cairo.OPERATOR_SOURCE)
		self.context.set_source_pixbuf(self.backimagearea, 0, 0)
		self.context.paint()
		self.context.set_operator (cairo.OPERATOR_OVER)
		self.draw(self.context)
		return False
	
	def blinkcursor(self):
		self.cursorblink = not self.cursorblink
		self.window.invalidate_rect(None,False)
		#Fixme Invalidate only the leading cursor-edge region
		return True
	
	def draw(self,context):
		# Get widget dimensions
		rect = self.get_allocation()
		x = rect.x + rect.width / 2
		y = rect.y + rect.height / 2
		w = self.allocation.width
		h = self.allocation.height
		
		# If button has changed shape, redraw it's background
		if w!=self.originalw or h!=self.originalh:
			self.BuildBackground(w,h)
			self.originalw = w
			self.originalh = h

		# Draw background
		context.set_source_surface(self.buttonsurface,0,0)
		context.paint()
		
		# Draw text to the text box
		context.move_to(self.x,self.y)
		if self.text == "" or self.text == _('Search'):
			context.select_font_face("Sans",cairo.FONT_SLANT_ITALIC,cairo.FONT_WEIGHT_NORMAL)
			context.set_font_size(12)
			context.set_source_rgba(self.t_color_r,self.t_color_g,self.t_color_b,0.6)
			context.show_text (_('Search'))
			if self.cursorblink:
				context.set_source_rgba(self.t_color_r,self.t_color_g,self.t_color_b,0.6)
				context.show_text ('|')
		else:
			context.select_font_face("Sans",cairo.FONT_SLANT_NORMAL,cairo.FONT_WEIGHT_NORMAL)
			context.set_font_size(12)
			context.set_source_rgba(self.t_color_r,self.t_color_g,self.t_color_b,1)
			context.show_text (self.text)
			if self.cursorblink:
				context.set_source_rgba(self.t_color_r,self.t_color_g,self.t_color_b,0.8)
				context.show_text ('|')

	def BuildBackground(self,w,h):
		self.buttonsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h)
		context = cairo.Context(self.buttonsurface)
		self.ct = gtk.gdk.CairoContext(context)
		if Globals.Settings['GtkColors'] == 1:
			cairo_drawing.draw_image_gtk(self.ct,0,0,self.backimage,w,h,Globals.GtkColorCode,None,False)
		else:
			cairo_drawing.draw_image(self.ct,0,0,self.backimage,False)
		if self.BackImageBuffer:
			context.set_source_surface(self.BackImageBuffer, 0, 0)			
			context.paint()
		if self.hasrectangle:
			# Draw the box
			self.DrawRoundedRect(context,0,0,w,h,self.cornerradius)
			# Fill
			context.set_source_rgba(self.color_r,self.color_g,self.color_b,1)
			context.paint()
		

	def DrawRoundedRect(self,context,x0,y0,w,h,radius):
		x1=x0+w
		y1=y0+h
		context.move_to(x0, y0 + radius)
		context.curve_to(x0 , y0, x0 , y0, x0 + radius, y0)
		context.line_to(x1 - radius, y0)
		context.curve_to(x1, y0, x1, y0, x1, y0 + radius)
		context.line_to(x1 , y1 - radius)
		context.curve_to(x1, y1, x1, y1, x1 - radius, y1)
		context.line_to(x0 + radius, y1)
		context.curve_to(x0, y1, x0, y1, x0, y1- radius)		 
		context.close_path()

class TreeProgramList(gobject.GObject):

	__gsignals__ = {
        'activate': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
        'menu': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
        'clicked': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
        'right-clicked': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ())
        }
	def __init__(self):
		gobject.GObject.__init__ (self)
		#Create the Base Menu Template and an XDG menu object
		self.XDG = XDGMenu()
		self.XDG.connect('changed', self.menu_callback)
		#if Globals.flip == False:
		#	self.backimagearea = backimage.subpixbuf(Globals.PG_buttonframe[0],Globals.MenuHeight - Globals.PG_buttonframe[1] - Globals.PG_buttonframedimensions[1],Globals.PG_buttonframedimensions[0],Globals.PG_buttonframedimensions[1])
		#	self.backimagearea = self.backimagearea.flip(Globals.flip)
		#else:
		#	self.backimagearea = backimage.subpixbuf(Globals.PG_buttonframe[0],Globals.PG_buttonframe[1] ,Globals.PG_buttonframedimensions[0],Globals.PG_buttonframedimensions[1])
#=================================================================  
#GRAPHICAL CODE FOR MENU
#=================================================================  
	def menu_callback(self,event):
		
		self.Restart('previous')

	def ProgramListPopulate(self,Frame,Destroyer):
		self.BanFocusSteal = False
		self.Destroyer=Destroyer
		self.Frame=Frame
		self.ConstructGTKObjectsMenu(self.Frame)
		self.PopulateButtons()
        
	def ConstructGTKObjectsMenu(self, Frame):
		# Create components Frame -> ScrollFrame -> EventBox -> VBox -> Buttons
		self.ScrollFrame = gtk.ScrolledWindow()
		self.VBoxOut = gtk.VBox(False)
		self.EBox = gtk.EventBox()
		self.tree1 = gtk.TreeView()
		self.Button = gtk.Button()
   		self.render = gtk.CellRendererPixbuf()
		self.cell1 = gtk.CellRendererText()
		self.column1 = gtk.TreeViewColumn("", self.render,pixbuf=0)
		self.column2 = gtk.TreeViewColumn("", self.cell1,text=1)
		self.Separator = None
		self.gtkicontheme = gtk.icon_theme_get_default()
		self.gtkicontheme.connect('changed', self.update_icons) 
		targets = [('text/uri-list', 0, 0)]
		#self.tree1.connect("expose_event", self.expose)
		#self.EBox.connect("expose_event", self.expose)	
		#self.VBoxOut.connect("expose_event", self.expose)
		#self.ScrollFrame.connect("expose_event", self.expose)	
		#if Globals.Settings['GtkColors'] == 0:
			
			#self.VBoxOut.modify_bg(gtk.STATE_NORMAL, Globals.ThemeColorCode)
			#self.ScrollFrame.modify_bg(gtk.STATE_NORMAL, Globals.ThemeColorCode)

		#self.ScrollFrame.connect_after("map-event", self.map_event)
		self.ScrollFrame.set_size_request(Globals.PG_buttonframedimensions[0],Globals.PG_buttonframedimensions[1])	  
		self.ScrollFrame.set_shadow_type(gtk.SHADOW_NONE)
		self.ScrollFrame.set_policy(gtk.POLICY_NEVER,gtk.POLICY_AUTOMATIC)

		self.VBoxOut.pack_start(self.ScrollFrame, True,True, 0)
		self.ScrollFrame.add(self.tree1)
		self.EBox.add(self.VBoxOut)
		self.Frame.put(self.EBox,Globals.PG_buttonframe[0],Globals.PG_buttonframe[1])
		self.tree1.set_headers_visible (0)
		self.tree1.append_column(self.column1)
		self.tree1.append_column(self.column2)

		if Globals.Settings['Show_Tips']:
			
			self.column3 = gtk.TreeViewColumn("", self.cell1,text=1)
			self.column3.set_visible(False)
			self.tree1.append_column(self.column3)
			self.tree1.set_tooltip_column(2)
			

		
		self.tree1.set_cursor_on_cell((0,0), focus_column=None,focus_cell=None, start_editing=False)
		if Globals.Settings['Show_Tips']:
			self.model = gtk.ListStore(gtk.gdk.Pixbuf, gobject.TYPE_STRING, gobject.TYPE_STRING)
		else:
			self.model = gtk.ListStore(gtk.gdk.Pixbuf, gobject.TYPE_STRING)
		self.tree1.connect("key-press-event", self.PGListButtonKey)
		self.tree1.connect("drag-data-get", self.drag_data_get)
		self.tree1.drag_source_set(gtk.gdk.BUTTON1_MASK,targets,gtk.gdk.ACTION_COPY)
		self.tree1.drag_source_add_text_targets()
		self.tree1.connect("button-press-event", self.drag_begin)
		self.tree1.connect("button-release-event", self.treeclick)
		self.cell1.set_property('ellipsize', pango.ELLIPSIZE_END)
		self.tree1.set_model(self.model)
		if Globals.Settings['GtkColors'] == 0:
			self.EBox.modify_bg(gtk.STATE_NORMAL, Globals.ThemeColorCode)
			#self.cell1.set_property('background', Globals.ThemeColorCode)
			self.cell1.set_property('cell-background', Globals.ThemeColorCode)
			self.render.set_property('cell-background', Globals.ThemeColorCode)
			#self.tree1.modify_bg(gtk.STATE_NORMAL, Globals.ThemeColorCode)
			self.tree1.modify_base(gtk.STATE_NORMAL, Globals.ThemeColorCode)
			self.cell1.set_property('foreground',Globals.NegativeThemeColorCode)

		self.tree1.set_hover_selection(True)
		
		#gc.collect()

	def drag_begin(self, widget, drag_context):
		selection = widget.get_selection()
		selection.set_mode('single')
		model, iter = selection.get_selected()
		if iter:
			self.index = int(model.get_path(iter)[0])
			self.tree1.drag_source_set_icon_pixbuf(model.get_value(iter,0))

	def drag_data_get (self, widget, drag_context, selection_data, info, timestamp):
		uri_list = None
		if self.XDG.allgio is not None:
			for z in self.XDG.allgio:
				if z.get_name() == self.XDG.L_Names[self.index]:
					uri_list = 'file:///usr/share/applications/%s' % z.get_id()
					break
		if uri_list is None:
			name = str(self.XDG.L_Execs[self.index]).replace('%F','').replace('%f','').replace('%u','').replace('%U','')
			if name.startswith ('file:/'):
				uri_list = name
			elif name.startswith ('/'):
				uri_list = 'file://%s' % name
			else:
				uri_list = 'file:///usr/bin/%s' % name
		
		selection_data.set(selection_data.target, 8,uri_list)

	def update_icons(self,client, connection_id=None, entry=None, args=None):
		print 'icons changed'
		self.XDG.Icon_change()
		self.Restart('previous')

	def Restart(self,data='all'):

		if self.XDG.Restart(data):
			self.PopulateButtons()
		#gc.collect()

	def expose(self, widget, event):
		#widget.window.set_composited(1)
		cr = widget.window.cairo_create()
		if widget.is_composited() is True:	
			cr.set_source_rgba(1, 1, 1, 0)
		else:
			cr.set_source_rgb(1, 1, 1)
		cr.set_operator (cairo.OPERATOR_SOURCE)
		cr.paint()
		#cairo_drawing.draw_pixbuf(cr,self.backimagearea)

	def treeclick(self,widget,event):
		"""activated when clicking in the tree"""
		selection = widget.get_selection()
		selection.set_mode('single')
		rows = selection.get_selected_rows()[1]
		if rows:
			self.index = int(rows[0][0])
			self.ActivateButton(event)

	def map_event(self, widget, event):
		print 'map'
		self.PopulateButtons()


	def RemoveButtons(self):
		self.tree1.set_model(None)
		if self.Separator:
			self.Separator.destroy()
		try:
			self.Button.destroy()
		except:pass
		try:
			self.Label.destroy()
		except:pass
		# doing the following is faster then self.model.clear()
		if Globals.Settings['Show_Tips']:
			self.model = gtk.ListStore(gtk.gdk.Pixbuf, gobject.TYPE_STRING, gobject.TYPE_STRING)
		else:
			self.model = gtk.ListStore(gtk.gdk.Pixbuf, gobject.TYPE_STRING)
		
		self.tree1.freeze_child_notify()

		

	def PopulateButtons(self):
		self.RemoveButtons()
		self.Buttonlist = []
		#a = time.clock()
		for i in range(0,len(self.XDG.L_Names)):
			typ = self.XDG.L_Types[i]
			if typ==8:
				self.dummy()#self.AddSeparator())
			elif typ==9:
				self.AddLabel(self.XDG.L_Names[i])
			elif typ==2:
				self.AddBackButton(self.XDG.L_Names[i],self.XDG.L_Icons[i],i)
			else:
				self.AddButton(self.XDG.L_Names[i],self.XDG.L_Icons[i],i)
		#print time.clock() 
		#self.SetInputFocus()
		#gc.collect()
		self.tree1.set_model(self.model)
		self.tree1.thaw_child_notify()
		self.ScrollFrame.get_vscrollbar().set_value(0)


	def AddBackButton(self,name,icon,i):
		if name == _('Back'):
			if not icon:
				icon = gtk.gdk.pixbuf_new_from_file_at_size(Globals.BrokenImage, Globals.PG_iconsize, Globals.PG_iconsize)

		
			self.Button = gtk.Button(name)
			self.Img = gtk.Image()
			self.Img.set_from_pixbuf(icon)
			self.Button.set_image(self.Img)
			self.Button.set_alignment(0,0)
			self.Button.set_tooltip_text(_('Return to last menu'))
			self.PG_buttonwidth = Globals.PG_buttonframedimensions[0] - 12
			self.Button.set_size_request(self.PG_buttonwidth, Globals.PG_iconsize+8)
			self.Button.set_relief(gtk.RELIEF_NONE)
			self.ScrollFrame.set_size_request(Globals.PG_buttonframedimensions[0],self.ScrollFrame.get_size_request()[1] - 	self.Button.get_size_request()[1])
			self.AddSeparator2()
			self.VBoxOut.pack_start(self.Button, True,True, 0)
			self.Button.connect("button-release-event", self.PGListButtonClick,i)
			self.Button.connect("key-press-event", self.PGListButtonKey,i)
			self.Button.show()
			image,label =  self.Button.get_children()[0].get_children()[0].get_children()
			if Globals.Settings['GtkColors'] == 0:
				label.modify_fg(gtk.STATE_NORMAL, Globals.NegativeThemeColorCode)
			label.set_property("ellipsize", pango.ELLIPSIZE_END) 
			label.set_max_width_chars(int(Globals.PG_buttonframedimensions[0]/11))
			self.Buttonlist.append(self.Button)
			icon = None
		else:
			self.AddButton(name,icon,i)

	def AddButton(self,name,icon,i):

		if not icon:
			icon = gtk.gdk.pixbuf_new_from_file_at_size(Globals.BrokenImage, Globals.PG_iconsize, Globals.PG_iconsize)

		self.ScrollFrame.set_size_request(Globals.PG_buttonframedimensions[0],Globals.PG_buttonframedimensions[1])
		if Globals.Settings['Show_Tips']:
			try:
				comment = self.XDG.ItemComments[name]
			except KeyError: 
				comment = name
			self.model.insert(i,[icon,name,comment])
		else:
			self.model.insert(i,[icon,name])
		icon = None
		

	def AddLabel(self,name):
		self.Label = gtk.Label(name)
		self.Label.set_line_wrap(True)
		self.Label.set_property("ellipsize", pango.ELLIPSIZE_END) 
		self.PG_buttonwidth = Globals.PG_buttonframedimensions[0] - 12
		if self.Separator:
			self.Separator.set_size_request(self.PG_buttonwidth, 1)
		self.VBoxOut.pack_start(self.Label, False,False, 0)
		if Globals.Settings['GtkColors'] == 0:
			self.Label.modify_fg(gtk.STATE_NORMAL, Globals.NegativeThemeColorCode)
		self.Label.show()
		self.ScrollFrame.set_size_request(Globals.PG_buttonframedimensions[0],Globals.PG_buttonframedimensions[1]- self.Label.size_request()[1]-1)
	


	def AddSeparator2(self):
		self.Separator = gtk.HSeparator()
		self.PG_buttonwidth = Globals.PG_buttonframedimensions[0] - 12
		self.Separator.set_size_request(self.PG_buttonwidth, 1)
			
		self.VBoxOut.pack_start(self.Separator, False,False, 0)
		self.Separator.show()
		return self.Separator

	def dummy(self):
		pass

	def AddSeparator(self):
		self.Separator = gtk.HSeparator()
		self.model.append([None,'',''])
		

	def PGListButtonClick(self, widget, event,i):
		"""activated when clicking a button"""
		self.index = i
		self.ActivateButton(event)
		if event.button == 3:
			self.emit('menu')
		
	def ActivateButton(self,event):
		if event.type == gtk.gdk.KEY_PRESS:event_button = 1
		elif event.type == gtk.gdk.BUTTON_PRESS:event_button = event.button
		elif event.type ==  gtk.gdk.BUTTON_RELEASE:event_button = event.button

		self.type = self.XDG.L_Types[self.index]
		a = self.XDG.ButtonClick(self.index,event)
		if event_button == 1:
			if a==1:
				self.Destroyer()
			self.PopulateButtons()
			self.emit('clicked')
			#gc.collect()
		elif event_button == 3:
			self.emit('right-clicked')

	def PGListButtonKey(self, widget, event,i=None):
		key = event.hardware_keycode
		if widget == self.tree1:
			if key == 36 or key == 65 or key == 114:	#Enter or Space or right
				selection = widget.get_selection()
				selection.set_mode('single')
				rows = selection.get_selected_rows()[1]
				if rows:
					self.index = int(rows[0][0])
					self.ActivateButton(event)
	
			elif key == 113: #Left
				self.Restart('previous')
		else:
			if key == 36 or key == 65 or key == 114:	#Enter or Space or right
				self.index = i
				self.ActivateButton(event)
			
			
	def SetInputFocus(self):
		# Give keyboard input focus to last item on list or to sub menu program group start
		pass

	def SetFirstButton(self,event):
		pass#self.Buttonlist[0].grab_focus()

	def SetLastButton(self,event):
		pass#self.Buttonlist[len(self.XDG.L_Names)-1].grab_focus()

#=================================================================  
#EXTRA FUNCTION PASSTHROUGH TO XDG
#See XDG module for command opcodes
#=================================================================  

	def CallSpecialMenu(self,command,data=None):
		self.XDG.CallSpecialMenu(command,data)
		self.PopulateButtons()
		#gc.collect()

	def destroy(self):
		self.XDG.destroy() #Allows XDG to de-initialse correctly (VERY IMPORTANT)




class CellRendererImage(gtk.GenericCellRenderer):

	__gproperties__ = {
		"image": (gobject.TYPE_OBJECT, "Image",
		"Image", gobject.PARAM_READWRITE),
	}

	def __init__(self):
		self.__gobject_init__()
		self.image = None

	def do_set_property(self, pspec, value):
		setattr(self, pspec.name, value)

	def do_get_property(self, pspec):
		return getattr(self, pspec.name)

	def func(self, model, path, iter, (image, tree)):
		if model.get_value(iter, 0) == image:
			self.redraw = 1
			cell_area = tree.get_cell_area(path, tree.get_column(0))
			tree.queue_draw_area(cell_area.x, cell_area.y, cell_area.width, \

				cell_area.height)

	def animation_timeout(self, tree, image):
		if image.get_storage_type() == gtk.IMAGE_ANIMATION:
			self.redraw = 0
			image.get_data('iter').advance()
			model = tree.get_model()
			model.foreach(self.func, (image, tree))
			if self.redraw:
				gobject.timeout_add(image.get_data('iter').get_delay_time(), \
					self.animation_timeout, tree, image)
			else:
				image.set_data('iter', None)

	def on_render(self, window, widget, background_area,cell_area, \
		expose_area, flags):
		if not self.image:
			return
		pix_rect = gtk.gdk.Rectangle()
		pix_rect.x, pix_rect.y, pix_rect.width, pix_rect.height = \
			self.on_get_size(widget, cell_area)

		pix_rect.x += cell_area.x
		pix_rect.y += cell_area.y
		pix_rect.width  -= 2 * self.get_property("xpad")
		pix_rect.height -= 2 * self.get_property("ypad")

		draw_rect = cell_area.intersect(pix_rect)
		draw_rect = expose_area.intersect(draw_rect)

		if self.image.get_storage_type() == gtk.IMAGE_ANIMATION:

			if not self.image.get_data('iter'):
				animation = self.image.get_animation()
				self.image.set_data('iter', animation.get_iter())
				gobject.timeout_add(self.image.get_data('iter').get_delay_time(), \
					self.animation_timeout, widget, self.image)

			pix = self.image.get_data('iter').get_pixbuf()
		elif self.image.get_storage_type() == gtk.IMAGE_PIXBUF:
			pix = self.image.get_pixbuf()
		else:
			return
		window.draw_pixbuf(widget.style.black_gc, pix, \
			draw_rect.x-pix_rect.x, draw_rect.y-pix_rect.y, draw_rect.x, \
			draw_rect.y+2, draw_rect.width, draw_rect.height, \
			gtk.gdk.RGB_DITHER_NONE, 0, 0)

	def on_get_size(self, widget, cell_area):
		if not self.image:
			return 0, 0, 0, 0
		if self.image.get_storage_type() == gtk.IMAGE_ANIMATION:
			animation = self.image.get_animation()
			pix = animation.get_iter().get_pixbuf()
		elif self.image.get_storage_type() == gtk.IMAGE_PIXBUF:
			pix = self.image.get_pixbuf()
		else:
			return 0, 0, 0, 0
		pixbuf_width  = pix.get_width()
		pixbuf_height = pix.get_height()
		calc_width  = self.get_property("xpad") * 2 + pixbuf_width
		calc_height = self.get_property("ypad") * 2 + pixbuf_height
		x_offset = 0
		y_offset = 0
		if cell_area and pixbuf_width > 0 and pixbuf_height > 0:
			x_offset = self.get_property("xalign") * (cell_area.width - \
				calc_width -  self.get_property("xpad"))
			y_offset = self.get_property("yalign") * (cell_area.height - \
				calc_height -  self.get_property("ypad"))
		return x_offset, y_offset, calc_width, calc_height


class IconProgramList(gobject.GObject):

	__gsignals__ = {
        'activate': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
        'menu': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
        'clicked': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
        'right-clicked': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ())
        }
	def __init__(self):
		gobject.GObject.__init__ (self)
		#Create the Base Menu Template and an XDG menu object
		self.XDG = XDGMenu()
		self.XDG.connect('changed', self.menu_callback)
		#if Globals.flip == False:
		#	self.backimagearea = backimage.subpixbuf(Globals.PG_buttonframe[0],Globals.MenuHeight - Globals.PG_buttonframe[1] - Globals.PG_buttonframedimensions[1],Globals.PG_buttonframedimensions[0],Globals.PG_buttonframedimensions[1])
		#	self.backimagearea = self.backimagearea.flip(Globals.flip)
		#else:
		#	self.backimagearea = backimage.subpixbuf(Globals.PG_buttonframe[0],Globals.PG_buttonframe[1] ,Globals.PG_buttonframedimensions[0],Globals.PG_buttonframedimensions[1])
#=================================================================  
#GRAPHICAL CODE FOR MENU
#=================================================================  
	def menu_callback(self,event):
		
		self.Restart('previous')

	def ProgramListPopulate(self,Frame,Destroyer):
		self.BanFocusSteal = False
		self.Destroyer=Destroyer
		self.Frame=Frame
		self.ConstructGTKObjectsMenu(self.Frame)
		self.PopulateButtons()
        
	def ConstructGTKObjectsMenu(self, Frame):
		# Create components Frame -> ScrollFrame -> EventBox -> VBox -> Buttons
		self.ScrollFrame = gtk.ScrolledWindow()
		self.VBoxOut = gtk.VBox(False)
		self.EBox = gtk.EventBox()
		self.tree1 = gtk.IconView()
		self.Button = gtk.Button()
		self.Separator = None
		self.gtkicontheme = gtk.icon_theme_get_default()
		self.gtkicontheme.connect('changed', self.update_icons) 
		targets = [('text/uri-list', 0, 0)]
		#self.tree1.connect("expose_event", self.expose)
		#self.EBox.connect("expose_event", self.expose)	
		#self.VBoxOut.connect("expose_event", self.expose)
		#self.ScrollFrame.connect("expose_event", self.expose)	
		if Globals.Settings['GtkColors'] == 0:
			self.EBox.modify_bg(gtk.STATE_NORMAL, Globals.ThemeColorCode)
			#self.VBoxOut.modify_bg(gtk.STATE_NORMAL, Globals.ThemeColorCode)
			#self.ScrollFrame.modify_bg(gtk.STATE_NORMAL, Globals.ThemeColorCode)

		
		self.ScrollFrame.set_size_request(Globals.PG_buttonframedimensions[0],Globals.PG_buttonframedimensions[1])	  
		self.ScrollFrame.set_shadow_type(gtk.SHADOW_NONE)
		self.ScrollFrame.set_policy(gtk.POLICY_NEVER,gtk.POLICY_AUTOMATIC)
		self.VBoxOut.pack_start(self.ScrollFrame, True,True, 0)
		self.VBoxOut.set_border_width(0)
		self.ScrollFrame.add(self.tree1)
		self.EBox.add(self.VBoxOut)
		self.Frame.put(self.EBox,Globals.PG_buttonframe[0],Globals.PG_buttonframe[1])
		self.tree1.set_text_column(1)
		self.tree1.set_pixbuf_column(0)
		
		self.tree1.set_size_request(Globals.PG_buttonframedimensions[0], -1)

		
		self.tree1.set_orientation( gtk.ORIENTATION_HORIZONTAL)
		if Globals.Settings['Show_Tips']:
			self.tree1.set_tooltip_column (1)
		#Globals.PG_buttonframedimensions[0],self.ScrollFrame.get_size_request()[1]

		self.tree1.set_selection_mode(gtk.SELECTION_SINGLE)
		self.tree1.set_item_width(Globals.PG_buttonframedimensions[0]-2)
		cell = self.tree1.get_cells()[0]
		cell.set_property('ellipsize', pango.ELLIPSIZE_END)
		cell.set_fixed_size(-1,Globals.PG_iconsize)#+((Globals.PG_iconsize *8)/28))
		cell.set_property('ypad', (Globals.PG_iconsize *8)/28)
		#self.tree1.get_cells()[0].set_property('yalign', 0.1)
		try:
			self.tree1.set_item_padding(0)
		except:pass
		self.tree1.get_cells()[0].set_property('xpad', 6)
		if Globals.Settings['GtkColors'] == 0:
			cell.set_property('cell-background', Globals.ThemeColorCode)
			self.tree1.get_cells()[1].set_property('cell-background', Globals.ThemeColorCode)
			#self.tree1.modify_bg(gtk.STATE_NORMAL, Globals.ThemeColorCode)
			self.tree1.modify_base(gtk.STATE_NORMAL, Globals.ThemeColorCode)
			cell.set_property('foreground',Globals.NegativeThemeColorCode)
		
		self.tree1.set_row_spacing(0)
		self.tree1.set_margin(0)
		self.tree1.set_spacing(0)

		#self.tree1.set_cursor_on_cell((0,0), focus_column=None,focus_cell=None, start_editing=False)
		self.model = gtk.ListStore(gtk.gdk.Pixbuf, gobject.TYPE_STRING)
		self.tree1.set_events(gtk.gdk.ALL_EVENTS_MASK)
		self.tree1.connect("key-press-event", self.PGListButtonKey)
		self.tree1.connect("motion-notify-event", self.move)
		self.tree1.connect("leave-notify-event", self.leave)
		self.tree1.connect("drag-data-get", self.drag_data_get)
		self.tree1.connect("drag-begin", self.drag_begin)
		self.tree1.drag_source_set(gtk.gdk.BUTTON1_MASK,targets,gtk.gdk.ACTION_COPY)
		self.tree1.drag_source_add_text_targets()
		self.tree1.connect("button-press-event", self.drag_begin)
		self.tree1.connect("button-release-event", self.treeclick)
		self.tree1.set_model(self.model)
		#if Globals.Settings['GtkColors'] == 0:
			
			#self.tree1.modify_bg(gtk.STATE_NORMAL, Globals.ThemeColorCode)
			#self.tree1.modify_base(gtk.STATE_NORMAL, Globals.ThemeColorCode)
		self.ScrollFrame.get_vscrollbar().set_events(gtk.gdk.ALL_EVENTS_MASK)
		self.ScrollFrame.get_vscrollbar().connect_after("map-event", self.map_event,'map')
		self.ScrollFrame.get_vscrollbar().connect_after("unmap-event", self.map_event,'unmap')
		#gc.collect()

	def leave(self, widget, event):
		self.tree1.unselect_path(self.index)


	def map_event(self,widget,event,a):
		if a == 'map':
			self.tree1.set_item_width(Globals.PG_buttonframedimensions[0]-self.ScrollFrame.get_vscrollbar().size_request()[0]-4)
		else:
			self.tree1.set_item_width(Globals.PG_buttonframedimensions[0]-2)

	def move(self, widget, event):
		mouse = widget.get_pointer()
	
		x = mouse[0]
		y = int(mouse[1] + self.ScrollFrame.get_vscrollbar().get_value())
		path = self.tree1.get_path_at_pos(x, y)
		if path:
			self.index = path[0]
			self.tree1.select_path(path)
			#self.tree1.set_cursor(path)

	def drag_begin(self, widget, drag_context):
		selection = widget.get_selected_items()
		if selection != []:
			self.index = int(selection[0][0])
			self.tree1.drag_source_set_icon_pixbuf(self.XDG.L_Icons[self.index])

	def drag_data_get (self, widget, drag_context, selection_data, info, timestamp):
		uri_list = None
		if self.XDG.allgio is not None:
			for z in self.XDG.allgio:
				if z.get_name() == self.XDG.L_Names[self.index]:
					uri_list = 'file:///usr/share/applications/%s' % z.get_id()
					break
		if uri_list is None:
			name = str(self.XDG.L_Execs[self.index]).replace('%F','').replace('%f','').replace('%u','').replace('%U','')
			if name.startswith ('file:/'):
				uri_list = name
			elif name.startswith ('/'):
				uri_list = 'file://%s' % name
			else:
				uri_list = 'file:///usr/bin/%s' % name
		
		selection_data.set(selection_data.target, 8,uri_list)

	def update_icons(self,client, connection_id=None, entry=None, args=None):
		print 'icons changed'
		self.XDG.Icon_change()
		self.Restart('previous')

	def Restart(self,data='all'):

		if self.XDG.Restart(data):
			self.PopulateButtons()
		#gc.collect()

	def expose(self, widget, event):
		#widget.window.set_composited(1)
		cr = widget.window.cairo_create()
		if widget.is_composited() is True:	
			cr.set_source_rgba(1, 1, 1, 0)
		else:
			cr.set_source_rgb(1, 1, 1)
		cr.set_operator (cairo.OPERATOR_SOURCE)
		cr.paint()
		#cairo_drawing.draw_pixbuf(cr,self.backimagearea)

	def treeclick(self,widget,event):
		"""activated when clicking in the tree"""
		selection = widget.get_selected_items()
		if selection != []:
			self.index = int(selection[0][0])
			self.ActivateButton(event)

	#def map_event(self, widget, event):
	#	print 'map'
	#	self.PopulateButtons()


	def RemoveButtons(self):
		self.tree1.set_model(None)
		if self.Separator:
			self.Separator.destroy()
		try:
			self.Button.destroy()
		except:pass
		try:
			self.Label.destroy()
		except:pass
		# doing the following is faster then self.model.clear()
		self.model = gtk.ListStore(gtk.gdk.Pixbuf, gobject.TYPE_STRING)
		self.tree1.freeze_child_notify()
		

	def PopulateButtons(self):
		self.RemoveButtons()
		self.Buttonlist = []
		#a = time.clock()

		for i in range(0,len(self.XDG.L_Names)):
			typ = self.XDG.L_Types[i]
			if typ==8:
				self.dummy()#self.AddSeparator())
			elif typ==9:
				self.AddLabel(self.XDG.L_Names[i])
			elif typ==2:
				self.AddBackButton(self.XDG.L_Names[i],self.XDG.L_Icons[i],i)
			else:
				self.AddButton(self.XDG.L_Names[i],self.XDG.L_Icons[i],i)
		#print time.clock()-a
		#if a * Globals.PG_iconsize > Globals.PG_buttonframedimensions[1]:
		#	self.tree1.set_item_width(Globals.PG_buttonframedimensions[0]-self.ScrollFrame.get_vscrollbar().size_request()[0]-4)
		#else:
		#	self.tree1.set_item_width(Globals.PG_buttonframedimensions[0]-2)
		#print time.clock() 
		#self.SetInputFocus()
		#gc.collect()
		#print Globals.PG_buttonframedimensions[0]-self.ScrollFrame.size_request()[0]
		self.tree1.set_model(self.model)
		self.tree1.thaw_child_notify()
		self.ScrollFrame.get_vscrollbar().set_value(0)

	def AddBackButton(self,name,icon,i):
		if name == _('Back'):
			if not icon:
				icon = gtk.gdk.pixbuf_new_from_file_at_size(Globals.BrokenImage, Globals.PG_iconsize, Globals.PG_iconsize)

		
			self.Button = gtk.Button(name)
			self.Img = gtk.Image()
			self.Img.set_from_pixbuf(icon)
			self.Button.set_image(self.Img)
			self.Button.set_alignment(0,0)
			self.Button.set_tooltip_text(_('Return to last menu'))
			self.PG_buttonwidth = Globals.PG_buttonframedimensions[0] - 12
			self.Button.set_size_request(self.PG_buttonwidth, Globals.PG_iconsize+8)
			self.Button.set_relief(gtk.RELIEF_NONE)
			self.ScrollFrame.set_size_request(Globals.PG_buttonframedimensions[0],self.ScrollFrame.get_size_request()[1] - 	self.Button.get_size_request()[1])
			self.AddSeparator2()
			self.VBoxOut.pack_start(self.Button, True,True, 0)
			self.Button.connect("button-release-event", self.PGListButtonClick,i)
			self.Button.connect("key-press-event", self.PGListButtonKey,i)
			self.Button.show()
			image,label =  self.Button.get_children()[0].get_children()[0].get_children()
			if Globals.Settings['GtkColors'] == 0:
				label.modify_fg(gtk.STATE_NORMAL, Globals.NegativeThemeColorCode)
			label.set_property("ellipsize", pango.ELLIPSIZE_END) 
			label.set_max_width_chars(int(Globals.PG_buttonframedimensions[0]/11))
			self.Buttonlist.append(self.Button)
			icon = None
		else:
			self.AddButton(name,icon,i)

	def AddButton(self,name,icon,i):

		if not icon:
			icon = gtk.gdk.pixbuf_new_from_file_at_size(Globals.BrokenImage, Globals.PG_iconsize, Globals.PG_iconsize)

		self.ScrollFrame.set_size_request(Globals.PG_buttonframedimensions[0],Globals.PG_buttonframedimensions[1])
		if Globals.Settings['Show_Tips']:
			pass
		self.model.insert(i,[icon,name])
		icon = None
		

	def AddLabel(self,name):
		self.Label = gtk.Label(name)
		self.Label.set_line_wrap(True)
		self.Label.set_property("ellipsize", pango.ELLIPSIZE_END) 
		self.PG_buttonwidth = Globals.PG_buttonframedimensions[0] - 12
		if self.Separator:
			self.Separator.set_size_request(self.PG_buttonwidth, 1)
		self.VBoxOut.pack_start(self.Label, False,False, 0)
		if Globals.Settings['GtkColors'] == 0:
			self.Label.modify_fg(gtk.STATE_NORMAL, Globals.NegativeThemeColorCode)
		self.Label.show()
		self.ScrollFrame.set_size_request(Globals.PG_buttonframedimensions[0],Globals.PG_buttonframedimensions[1]- self.Label.size_request()[1]-1)
	


	def AddSeparator2(self):
		self.Separator = gtk.HSeparator()
		self.PG_buttonwidth = Globals.PG_buttonframedimensions[0] - 12
		self.Separator.set_size_request(self.PG_buttonwidth, 1)
			
		self.VBoxOut.pack_start(self.Separator, False,False, 0)
		self.Separator.show()
		return self.Separator

	def dummy(self):
		pass

	def AddSeparator(self):
		self.Separator = gtk.HSeparator()
		self.model.append([None,'',''])
		

	def PGListButtonClick(self, widget, event,i):
		"""activated when clicking a button"""
		self.index = i
		self.ActivateButton(event)
		if event.button == 3:
			self.emit('menu')
		
	def ActivateButton(self,event):
		if event.type == gtk.gdk.KEY_PRESS:event_button = 1
		elif event.type == gtk.gdk.BUTTON_PRESS:event_button = event.button
		elif event.type ==  gtk.gdk.BUTTON_RELEASE:event_button = event.button

		self.type = self.XDG.L_Types[self.index]
		a = self.XDG.ButtonClick(self.index,event)
		if event_button == 1:
			if a==1:
				self.Destroyer()
			self.PopulateButtons()
			self.emit('clicked')
			#gc.collect()
		elif event_button == 3:
			self.emit('right-clicked')

	def PGListButtonKey(self, widget, event,i=None):
		key = event.hardware_keycode
		
		if widget == self.tree1:
			
			if key == 36 or key == 65 or key == 114:	#Enter or Space or right
				selection = widget.get_selected_items()
				if selection != []:
					self.index = int(selection[0][0])
					self.ActivateButton(event)
			elif key == 113: #Left
				self.Restart('previous')
		else:
			if key == 36 or key == 65 or key == 114:	#Enter or Space or right
				self.index = i
				self.ActivateButton(event)
			
			
	def SetInputFocus(self):
		# Give keyboard input focus to last item on list or to sub menu program group start
		pass

	def SetFirstButton(self,event):
		pass#self.Buttonlist[0].grab_focus()

	def SetLastButton(self,event):
		pass#self.Buttonlist[len(self.XDG.L_Names)-1].grab_focus()

#=================================================================  
#EXTRA FUNCTION PASSTHROUGH TO XDG
#See XDG module for command opcodes
#=================================================================  

	def CallSpecialMenu(self,command,data=None):
		self.XDG.CallSpecialMenu(command,data)
		self.PopulateButtons()
		#gc.collect()

	def destroy(self):
		self.XDG.destroy() #Allows XDG to de-initialse correctly (VERY IMPORTANT)

class ProgramList(gobject.GObject):

	__gsignals__ = {
        'activate': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
        'menu': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
        'clicked': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
        'right-clicked': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ())
        }
	def __init__(self):
		gobject.GObject.__init__ (self)
		#Create the Base Menu Template and an XDG menu object
		self.XDG = XDGMenu()
		self.XDG.connect('changed', self.menu_callback)
		self.Buttonlist = []
		#if Globals.flip == False:
		#	self.backimagearea = backimage.subpixbuf(Globals.PG_buttonframe[0],Globals.MenuHeight - Globals.PG_buttonframe[1] - Globals.PG_buttonframedimensions[1],Globals.PG_buttonframedimensions[0],Globals.PG_buttonframedimensions[1])
		#	self.backimagearea = self.backimagearea.flip(Globals.flip)
		#else:
		#	self.backimagearea = backimage.subpixbuf(Globals.PG_buttonframe[0],Globals.PG_buttonframe[1] ,Globals.PG_buttonframedimensions[0],Globals.PG_buttonframedimensions[1])
#=================================================================  
#GRAPHICAL CODE FOR MENU
#=================================================================  
	def menu_callback(self,event):
		
		self.Restart('previous')

	def ProgramListPopulate(self,Frame,Destroyer):
		self.BanFocusSteal = False
		self.Destroyer=Destroyer
		self.Frame=Frame
		self.ConstructGTKObjectsMenu(self.Frame)
		self.PopulateButtons()
        
	def ConstructGTKObjectsMenu(self, Frame):
		# Create components Frame -> ScrollFrame -> EventBox -> VBox -> Buttons
		self.PrevSelButtons = []
		self.PrevSelButton = -1
		self.ScrollFrame = gtk.ScrolledWindow()
		self.VBoxIn = gtk.VBox(False)
		self.VBoxOut = gtk.VBox(False)
		self.VBoxOut.pack_start(self.ScrollFrame, True,True, 0)
		self.ScrollFrame.connect_after("map-event", self.map_event)
		#self.ScrollFrame.connect("expose_event", self.expose)
		#self.VBoxOut.connect("expose_event", self.expose)
		#self.VBoxIn.connect("expose_event", self.expose)
		self.ScrollFrame.set_size_request(Globals.PG_buttonframedimensions[0],Globals.PG_buttonframedimensions[1])      
		self.ScrollFrame.set_shadow_type(gtk.SHADOW_NONE)
		self.ScrollFrame.set_policy(gtk.POLICY_NEVER,gtk.POLICY_AUTOMATIC)
		#Build structure
		self.ScrollFrame.add_with_viewport(self.VBoxIn)
		self.ScrollFrame.get_children()[0].set_shadow_type(gtk.SHADOW_NONE)
		if Globals.Settings['GtkColors'] == 0:
		

			self.VBoxOut.modify_bg(gtk.STATE_NORMAL, Globals.ThemeColorCode)
			self.VBoxIn.modify_bg(gtk.STATE_NORMAL, Globals.ThemeColorCode)
			self.ScrollFrame.modify_bg(gtk.STATE_NORMAL, Globals.ThemeColorCode)
			self.ScrollFrame.get_children()[0].modify_bg(gtk.STATE_NORMAL, Globals.ThemeColorCode)

		
		
		self.Frame.put(self.VBoxOut,Globals.PG_buttonframe[0],Globals.PG_buttonframe[1])
		#Show newly created widgets
		
		self.ScrollFrame.set_shadow_type(gtk.SHADOW_NONE)
		self.gtkicontheme = gtk.icon_theme_get_default()
		self.gtkicontheme.connect('changed', self.update_icons) 
		self.Separator = None
      		#gtk.rc_parse_string ("""
	         #      style \"GnoMenu-Button\"
	          #     {
	           #      GtkButton::inner-border = {0,0,0,0}
	            #   }
	             #  widget \"*.GnoMenuButton\" style \"GnoMenu-Button\"
	              # """)
	

	def update_icons(self,client, connection_id=None, entry=None, args=None):
		print 'icons changed'
		self.XDG.Icon_change()
		self.Restart('previous')

	def Restart(self,data='all'):
	
		if self.XDG.Restart(data):
			self.PopulateButtons()
		#gc.collect()

	def expose(self, widget, event):
		cr = widget.window.cairo_create()
		if widget.is_composited() is True:	
			cr.set_source_rgba(1, 1, 1, 0)
		else:
			cr.set_source_rgb(1, 1, 1)
		cr.set_operator (cairo.OPERATOR_SOURCE)
		cr.paint()
		#cairo_drawing.draw_pixbuf(cr,self.backimagearea)
		#pass


	def map_event(self, widget, event):
		print 'map'
		self.PopulateButtons()

	def PopulateButtons(self):
		self.RemoveButtons()
		self.Buttonlist = []
		for i in range(0,len(self.XDG.L_Names)):
			typ = self.XDG.L_Types[i]
			if typ==8:
				self.AddSeparator()
			elif typ==9:
				self.AddLabel(self.XDG.L_Names[i])
			else:
				self.AddButton(self.XDG.L_Names[i],self.XDG.L_Icons[i],i)
		
		self.SetInputFocus()
		#gc.collect()
		try:
			self.VBoxIn.get_children()[0].grab_focus()
		except:pass
		self.ScrollFrame.get_vscrollbar().set_value(0)
		
		
	def AddButton(self,name,icon,i):
		self.Button = gtk.Button(name)

		if icon:
			self.Pic = icon
		else:
			self.Pic = gtk.gdk.pixbuf_new_from_file_at_size(Globals.BrokenImage, Globals.PG_iconsize, Globals.PG_iconsize)

		self.Img = gtk.Image()
		self.Img.set_from_pixbuf(self.Pic)
		self.Button.set_alignment(0,0)
		
		self.Button.set_image(self.Img)
		self.PG_buttonwidth = Globals.PG_buttonframedimensions[0] - 12
		self.Button.set_size_request(self.PG_buttonwidth, Globals.PG_iconsize+10)
		self.Button.set_relief(gtk.RELIEF_NONE)

		if name ==_('Back'):
			self.Button.set_tooltip_text(_('Return to last menu'))
			self.ScrollFrame.set_size_request(Globals.PG_buttonframedimensions[0],self.ScrollFrame.get_size_request()[1] - self.Button.get_size_request()[1])
			self.AddSeparator2()
			self.VBoxOut.pack_start(self.Button, True,True, 0)
			self.Buttonlist.append(self.Button)
		else:
			self.ScrollFrame.set_size_request(Globals.PG_buttonframedimensions[0],Globals.PG_buttonframedimensions[1])
			if Globals.Settings['Prog_List'] == 1:
				self.VBoxIn.pack_start(self.Button, True,True, 0)
			elif Globals.Settings['Prog_List'] == 2:
				self.VBoxIn.pack_start(self.Button, False,False, 0)
			if Globals.Settings['Show_Tips']:
				if name in self.XDG.ItemComments:
					self.Button.set_tooltip_text(self.XDG.ItemComments[name])
				else:
					self.Button.set_tooltip_text(name)
		self.Button.connect("drag-data-get", self.drag_data_get,i)
		targets = [('text/uri-list', 0, 0)]
		self.Button.drag_source_set(gtk.gdk.BUTTON1_MASK,targets,gtk.gdk.ACTION_COPY)
		self.Button.drag_source_add_text_targets()
		#self.tree1.connect("drag-begin", self.drag_begin)
		self.Button.connect("button-press-event", self.drag_begin)
		self.Button.connect("button-release-event", self.PGListButtonClick,i)
		self.Button.connect("key-press-event", self.PGListButtonKey,i)
		self.Button.show()
		image,label =  self.Button.get_children()[0].get_children()[0].get_children()
		if Globals.Settings['GtkColors'] == 0:
			label.modify_fg(gtk.STATE_NORMAL, Globals.NegativeThemeColorCode)
		label.set_property("ellipsize", pango.ELLIPSIZE_END) 
		label.set_alignment(0, label.get_alignment()[1])
		label.set_padding(5,0)
		label.set_size_request(Globals.PG_buttonframedimensions[0]-Globals.PG_iconsize*2,-1)
		#label.set_max_width_chars(int(Globals.PG_buttonframedimensions[0]/11))
		iconfile = None
		return self.Button


	def drag_begin(self, widget, drag_context):
		
		widget.drag_source_set_icon_pixbuf(widget.get_image().get_pixbuf())

	def drag_data_get (self, widget, drag_context, selection_data, info, timestamp,i):
		self.index = i
		uri_list = None
		
		if self.XDG.allgio is not None:
			for z in self.XDG.allgio:
				if z.get_name() == self.XDG.L_Names[self.index]:
					uri_list = 'file:///usr/share/applications/%s' % z.get_id()
					break
					
		
		if uri_list is None:
			name = str(self.XDG.L_Execs[self.index]).replace('%F','').replace('%f','').replace('%u','').replace('%U','')
			if name.startswith ('file:/'):
				uri_list = name
			elif name.startswith ('/'):
				uri_list = 'file://%s' % name
			else:
				uri_list = 'file:///usr/bin/%s' % name
		
		selection_data.set(selection_data.target, 8,uri_list)

	def AddLabel(self,name):
		self.Label = gtk.Label(name)
		self.Label.set_line_wrap(True)
		self.Label.set_property("ellipsize", pango.ELLIPSIZE_END) 
		self.PG_buttonwidth = Globals.PG_buttonframedimensions[0] - 12
		if self.Separator:
			self.Separator.set_size_request(self.PG_buttonwidth, 1)
		self.VBoxOut.pack_start(self.Label, True,True, 0)
		if Globals.Settings['GtkColors'] == 0:
			self.Label.modify_fg(gtk.STATE_NORMAL, Globals.NegativeThemeColorCode)
		self.Label.show()
		self.ScrollFrame.set_size_request(Globals.PG_buttonframedimensions[0],Globals.PG_buttonframedimensions[1]- self.Label.size_request()[1]-1)
		self.Buttonlist.append(self.Label)

	def AddSeparator2(self):
		self.Separator = gtk.HSeparator()
		self.PG_buttonwidth = Globals.PG_buttonframedimensions[0] - 12
		self.Separator.set_size_request(self.PG_buttonwidth, 1)
		self.VBoxOut.pack_start(self.Separator, True,True, 0)
		self.Separator.show()
		return self.Separator

	def AddSeparator(self):
		self.Separator = gtk.HSeparator()
		self.PG_buttonwidth = Globals.PG_buttonframedimensions[0] - 12
		self.Separator.set_size_request(self.PG_buttonwidth, 1)
		self.VBoxIn.pack_start(self.Separator, True,True, 0)
		self.Separator.show()
		self.Buttonlist.append(self.Separator)

	def PGListButtonClick(self, widget, event,i):
		mouse = widget.get_pointer()
		x = 0
		y = 0
		w = x + widget.get_allocation().width
		h = y + widget.get_allocation().height
		if mouse[0] > x and mouse[0] < w and mouse[1] > y and mouse[1] < h:
			
			self.index = i
			self.ActivateButton(event,self.index)
			if event.button == 3:
				self.emit('menu')
		
	def ActivateButton(self,event,i):
		if event.type == gtk.gdk.KEY_PRESS:event_button = 1
		elif event.type == gtk.gdk.BUTTON_PRESS:event_button = event.button
		elif event.type ==  gtk.gdk.BUTTON_RELEASE:event_button = event.button
		self.index = i
		self.type = self.XDG.L_Types[self.index]
		a = self.XDG.ButtonClick(self.index,event)
		if event_button == 1:
			if a==1:
				self.Destroyer()
			self.PopulateButtons()
			self.emit('clicked')
			#gc.collect()
		elif event_button == 3:
			self.emit('right-clicked')



	def RemoveButtons(self):
		#TODO this is still slow, try to make is faster
		if self.Separator:
			self.Separator.destroy()
		self.VBoxIn.foreach(lambda widget:self.VBoxIn.remove(widget))
		for item in self.Buttonlist:
			item.destroy()

	def PGListButtonKey(self, widget, event,i):
		
		self.index = i
		key = event.hardware_keycode
		#98 up    104 dn
		if key == 98 or key == 111:	#Up (menu loop-around)
			if self.index == 0:
				# Set timeout to call last button (as key press has not gone through yet)
				gobject.timeout_add(100,self.SetFirstButton, self)
				
			inc = self.ScrollFrame.get_vscrollbar().get_adjustment().get_value() - self.ScrollFrame.get_vscrollbar().get_adjustment().get_step_increment()
			if inc < self.ScrollFrame.get_vscrollbar().get_adjustment().get_lower(): inc = self.ScrollFrame.get_vscrollbar().get_adjustment().get_lower()
			if self.index < len(self.VBoxIn.get_children())-1:
				self.ScrollFrame.get_vscrollbar().get_adjustment().set_value(inc)
		elif key == 104 or key == 116:	#Down
			if self.index == len(self.XDG.L_Names)-1:
				# Set timeout to call last button (as key press has not gone through yet)
				gobject.timeout_add(100,self.SetLastButton, self)
			inc = self.ScrollFrame.get_vscrollbar().get_adjustment().get_value() + self.ScrollFrame.get_vscrollbar().get_adjustment().get_step_increment() 
			if inc + self.ScrollFrame.get_vscrollbar().get_adjustment().get_page_size() > self.ScrollFrame.get_vscrollbar().get_adjustment().get_upper(): inc = self.ScrollFrame.get_vscrollbar().get_adjustment().get_upper() - self.ScrollFrame.get_vscrollbar().get_adjustment().get_page_size()


			if self.index > 0:
				self.ScrollFrame.get_vscrollbar().get_adjustment().set_value(inc)

		elif key == 102 or key == 144 or key == 114:	#Right
			self.type = self.XDG.L_Types[self.index]
			if self.type == 0:
				self.ActivateButton(event,self.index)
				self.PrevSelButtons.append(self.index)
		elif key == 100 or key == 113 or key == 22:	#Left
			if self.XDG.PrevMenu:
				self.XDG.CallSpecialMenu(0)
				if self.PrevSelButtons:
					self.PrevSelButton = self.PrevSelButtons.pop()
				self.PopulateButtons()
			#gc.collect()
		elif key == 36 or key == 65:	#Enter or Space
			self.ActivateButton(event,self.index)
		else:
			pass
			
	def SetInputFocus(self):
		# Give keyboard input focus to last item on list or to sub menu program group start
		if self.BanFocusSteal == False:
			try:
				if self.PrevSelButton == -1:
					if self.XDG.PrevMenu and len(self.XDG.L_Names) > 4 and self.XDG.searchresults==0:	
						self.VBoxIn.get_children()[3].grab_focus()
					else:
						self.VBoxIn.get_children()[len(self.VBoxIn.get_children())-1].grab_focus()

				else:
					self.VBoxIn.get_children()[self.PrevSelButton].grab_focus()
					self.PrevSelButton = -1
			except:pass

	def SetFirstButton(self,event):
		self.VBoxIn.get_children()[0].grab_focus()

	def SetLastButton(self,event):
		self.VBoxIn.get_children()[len(self.VBoxIn.get_children())-1].grab_focus()

#=================================================================  
#EXTRA FUNCTION PASSTHROUGH TO XDG
#See XDG module for command opcodes
#=================================================================  

	def CallSpecialMenu(self,command,data=None):
		self.XDG.CallSpecialMenu(command,data)
		self.PopulateButtons()
		#gc.collect()

	def destroy(self):
		self.XDG.destroy() #Allows XDG to de-initialse correctly (VERY IMPORTANT)



class MenuArea(gtk.DrawingArea):
	__gsignals__ = {
                    'button-press-event' : 'override',
                    'button-release-event' : 'override',
                    'motion-notify-event' : 'override',
					'scroll-event' : 'override',
					'key-press-event' : 'override',
					'leave-notify-event' : 'override',
					'enter-notify-event' : 'override',
					
					"show-scrollbar" : (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ()),
					"hide-scrollbar" : (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ()),
					"update-scrollbar": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, [gobject.TYPE_INT, gobject.TYPE_INT]),
					"scroll-scrollbar": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, [gobject.TYPE_INT]),
					"reset-scrollbar": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ()),
                    }
	def __init__(self):
		gtk.DrawingArea.__init__(self)
		#self.MenuEngine = MenuSource()
		#self.MenuEngine.connect("update-menu", self.update_menu)
		self.Buttons = []
		self.scroll = 0
		self.width = 0	# Cache last drawn width for context menu placement
		self.netheight = 0
		self.visibleheight = 0
		self.mouse_in_region = False
		self.selected_button = None
		#self.padding = 1
		self.pointer_x = 0
		self.pointer_y = 0
		self.add_events(gtk.gdk.BUTTON_MOTION_MASK | gtk.gdk.ENTER_NOTIFY_MASK | gtk.gdk.LEAVE_NOTIFY_MASK | gtk.gdk.BUTTON_PRESS_MASK |
				gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.SCROLL_MASK | gtk.gdk.KEY_PRESS_MASK)

	def scrollbar_changed(self,value):
		self.scroll = value
		self.force_redraw()
		
	#def ChangeMenu(self,menu):
		# Menu is changed externally (e.g. by search or by other menu button)
	#	self.MenuEngine.ChangeMenu(menu)
	#	self.CreateButtons(self.MenuEngine.Menu)
	#	self.emit("reset-scrollbar")
	#	self.force_redraw()
	
	def CreateButtons(self,menu):
		self.selected_button = None
		self.Buttons = []	# Clean unload of memory?
		if menu:
			for item in menu:
				self.Buttons.append(internalbutton(item))
			if self.Buttons:
				self.selected_button = self.Buttons[0]
	
	def Map_Coords_To_Button(self, x, y):
		if self.mouse_in_region == False:
			return None
		step_y = globals.menuitempadding - self.scroll
		for item in self.Buttons:
			if y >= step_y and y <= step_y + item.last_reported_height: 
				return item
			step_y = step_y + item.last_reported_height + globals.menuitempadding
	
	def Map_Button_To_Coords(self, button):
		step_y = globals.menuitempadding - self.scroll
		for item in self.Buttons:
			if item == button:
				return int(self.width / 2), int(step_y + item.last_reported_height)
			step_y = step_y + item.last_reported_height + globals.menuitempadding
		return 0,0
	
	def draw(self, cr, width, height):
		cr.set_source_rgb(*globals.menucolor)
		cr.rectangle(0, 0, width, height)
		cr.fill()
		
		self.width = width
		
		# Calculate the total height of the list
		self.visibleheight = height
		netheight = globals.menuitempadding
		for item in self.Buttons:
			netheight += item.get_height(cr) + globals.menuitempadding
		if netheight != self.netheight:
			self.netheight = netheight
			if self.netheight > height:
				self.emit("show-scrollbar")
				self.emit("update-scrollbar", netheight - height, height)
				
			else:
				self.emit("hide-scrollbar")
				
		
		y = globals.menuitempadding - self.scroll
		for item in self.Buttons:
			pattern = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width - globals.menuitempadding * 2), int(item.get_height(cr)))
			cr2 = cairo.Context(pattern)
			if item == self.selected_button:
				item.selected = True
			else:
				item.selected = False
			# Only draw if in region
			if y >= - item.get_height(cr) and y < height:
				item.draw(cr2,width - globals.menuitempadding * 2,item.get_height(cr))
				cr.set_source_surface(pattern,globals.menuitempadding,y)
				cr.paint()
			y = y + item.get_height(cr) + globals.menuitempadding
			
	def do_motion_notify_event(self, event):
		self.pointer_x = event.x
		self.pointer_y = event.y
		self.select_button()

	def select_button(self):
		if self.mouse_in_region:
			item = self.Map_Coords_To_Button(self.pointer_x,self.pointer_y)
			if item != self.selected_button:
				self.selected_button = item
				self.force_redraw()

	def Key_Navigate(self,event):
		if event.keyval == 65362: #up
			if self.selected_button:
				if self.Buttons != []:
					if self.selected_button != self.Buttons[0]:
						#prevheight = self.selected_button.get_height()
						self.selected_button = self.Buttons[self.Buttons.index(self.selected_button) - 1]
						# Only scroll if new button is about to become offscreen
						if self.Map_Button_To_Coords(self.selected_button)[1] <= self.selected_button.get_height():
							scrollheight = 0 - self.selected_button.get_height() - globals.menuitempadding
						else:
							scrollheight = 0
							
					elif self.selected_button == self.Buttons[0]:
						self.selected_button = self.Buttons[-1]
						scrollheight = self.Map_Button_To_Coords(self.selected_button)[1]
					self.emit("scroll-scrollbar", scrollheight)
			else:
				if len(self.Buttons) >= 1:
					self.selected_button = self.Buttons[0]
				self.emit("scroll-scrollbar", -25)
			self.force_redraw()
		elif event.keyval == 65364: #Down
			if self.selected_button:
				if self.Buttons != []:
					if self.selected_button != self.Buttons[-1]:
						self.selected_button = self.Buttons[self.Buttons.index(self.selected_button) + 1]
						# Only scroll if new button is about to become offscreen
						if self.Map_Button_To_Coords(self.selected_button)[1] >= self.visibleheight:
							scrollheight = self.selected_button.get_height() + globals.menuitempadding
							self.emit("scroll-scrollbar", scrollheight)
					elif self.selected_button == self.Buttons [-1]:
						self.selected_button = self.Buttons[0]
						self.emit("reset-scrollbar")
			else:
				if len(self.Buttons) >= 1:
					self.selected_button = self.Buttons[0]
				self.emit("scroll-scrollbar", 25)
			self.force_redraw()
		elif event.keyval == 65361: #Left
			self.MenuEngine.Navigate_Back()
		elif event.keyval == 65363 or event.keyval == 65421 or event.keyval == 65293: #Enter, Right
			if self.selected_button:
				self.MenuEngine.ButtonClicked(1, self.selected_button.xdgbutton)
		elif event.keyval == 65383:	#Menu key
			if self.selected_button:
				self.MenuEngine.ButtonClicked(3, self.selected_button.xdgbutton, event.get_time(), self.PopUpMenuAlignment)
	
	def PopUpMenuAlignment(self,menu):
#		lambda p : (lambda f : self.Map_Button_To_Coords(self.selected_button), True)
		coords = self.Map_Button_To_Coords(self.selected_button)
		return coords[0], coords[1], True
	
	def do_scroll_event(self,event):
		if event.direction == gtk.gdk.SCROLL_UP:
			self.emit("scroll-scrollbar", -25)
		elif event.direction == gtk.gdk.SCROLL_DOWN:
			self.emit("scroll-scrollbar", 25)
		elif event.direction == gtk.gtk.SCROLL_LEFT:
			self.MenuEngine.Navigate_Back()
		elif event.direction == gtk.gdk.SCROLL_RIGHT:
			if self.selected_button:
				self.MenuEngine.ButtonClicked(1, self.selected_button.xdgbutton)

	def do_enter_notify_event(self, event):
		self.pointer_x = event.x
		self.pointer_y = event.y
		self.mouse_in_region = True

	def do_button_press_event(self, event):
		self.pointer_x = event.x
		self.pointer_y = event.y
		self.select_button()
			
	def do_button_release_event(self, event):
		self.pointer_x = event.x
		self.pointer_y = event.y
		self.select_button()
		if self.selected_button:
			self.MenuEngine.ButtonClicked(event.button, self.selected_button.xdgbutton, event.get_time())
				

	def update_menu(self,event):
		self.emit("reset-scrollbar")
		self.CreateButtons(self.MenuEngine.Menu)
		self.force_redraw()
			
	def do_leave_notify_event(self, event):
		self.pointer_x = event.x
		self.pointer_y = event.y
		self.mouse_in_region = False
		self.selected_button = None
		
	def force_redraw(self):
		if self.window:
			rect = gtk.gdk.Rectangle(0, 0, *self.window.get_size())
			self.window.invalidate_rect(rect, True)

class internalbutton:
	def __init__(self, button):
		self.xdgbutton = button
		self.text = button.title
		self.icon = create_image_surface(button.icon)
		self.selected = False
		self.last_reported_height = 0

	def get_width(self):
		return 0
	
	def get_height(self, cr=None):
		if cr:
			text_w, text_h = cr.text_extents(self.text)[2:4]
			if text_h * (self.text.count("\n") + 1) + globals.v_text_padding > globals.buttonheight - 2:
				self.last_reported_height = text_h * (self.text.count("\n") + 1) + globals.v_text_padding
				return self.last_reported_height
		#self.last_reported_height = globals.buttonheight
		return self.last_reported_height
	
	def draw(self,cr, width, height):
		# Draw image underlay when selected
		if self.selected:
			draw_rounded_rect(cr,0,0,width,height,globals.buttoncornerradius)	
			pat = cairo.LinearGradient (0, 0, 0, height)
			for item in globals.selectedbuttongradient:
				pat.add_color_stop_rgba (*item)
			cr.set_source(pat)
			cr.fill_preserve()
			cr.set_source_rgba(*globals.buttonbordercolor)
			cr.set_line_width(globals.buttonborderwidth)
			cr.stroke()

		# Draw icon, preserve aspect ratio of icon, and pass on space settings to the text renderer
		if self.icon:
			if width > height:
				h = height - globals.buttoniconpadding
				w = (float(height) / float(self.icon.get_height())) * self.icon.get_width() - globals.buttoniconpadding
			elif height <= width:
				w = width - globals.buttoniconpadding
				h = (float(width) / float(self.icon.get_width())) * self.icon.get_height() - globals.buttoniconpadding
			x,y = 0, height / 2 - h / 2				
			draw_scaled_image(cr, self.icon, x, y, w, h)
			
		else:
			x = 0; y = 0; w = 0; h = 0

		if self.text:
			offset_y = 0
			text_size_reduction = 0
			for item in self.text.split("\n"):
				cr.select_font_face(globals.font, globals.fontitalic, globals.fontbold)
				renderstyle = cairo.FontOptions()
				renderstyle.set_antialias(cairo.ANTIALIAS_DEFAULT)
				cr.set_font_options(renderstyle)
				cr.set_font_size(globals.fontsize - text_size_reduction)
				if self.selected:
					cr.set_source_rgb(*globals.fontselectcolor)
				else:
					cr.set_source_rgb(*globals.fontcolor)
				text_w, text_h = cr.text_extents(item)[2:4]
				if self.xdgbutton.textrightjustify:
					tx = width - globals.buttonpadding - cr.text_extents(item)[4]
					if tx < x + w + globals.buttonpadding:
						while tx < x + w + globals.buttonpadding:
							text_size_reduction += 1
							cr.set_font_size(globals.fontsize - text_size_reduction)
							tx = width - globals.buttonpadding - cr.text_extents(item)[4]		
					cr.move_to(tx, height / 2 + 4 + offset_y - text_h * self.text.count("\n") / 2 + self.text.count("\n")) # border width
				else:
					cr.move_to(x + w + globals.buttonpadding, height / 2 + 4 + offset_y - text_h * self.text.count("\n") / 2 + self.text.count("\n")) # border width
				cr.show_text(item)
				cr.stroke()
				offset_y = offset_y + text_h
				text_size_reduction = 3




class CairoProgramList:
	__gsignals__ = {
        'activate': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
        'menu': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ())
        }
	def __init__(self):
		#Create the Base Menu Template and an XDG menu object		
		self.XDG = XDGMenu()

#=================================================================  
#GRAPHICAL CODE FOR MENU
#=================================================================  

	def ProgramListPopulate(self,Frame,Destroyer):
		self.Destroyer=Destroyer
		self.Frame = Frame
		self.ConstructGTKObjectsMenu(Frame)
		
		#self.PopulateButtons()
        
	def ConstructGTKObjectsMenu(self, Frame):
		self.menu = CairoMenuObject()
		self.menu.set_events(gtk.gdk.POINTER_MOTION_MASK |
                              gtk.gdk.POINTER_MOTION_HINT_MASK |
                              gtk.gdk.BUTTON_PRESS_MASK)
		self.menu.connect("motion_notify_event", self.mousemove)
		self.menu.connect("button-press-event", self.buttonpress)
		self.menu.set_size_request(Globals.PG_buttonframedimensions[0],Globals.PG_buttonframedimensions[1])      
		Frame.put(self.menu, Globals.PG_buttonframe[0],Globals.PG_buttonframe[1])
		Frame.show_all()
		self.menu.UpdateButtons(self.XDG.L_Names)
		self.menu.InitiateAnimation(1)
		gobject.timeout_add(10,self.UpdateAnimation)
		
	def UpdateAnimation(self):
		self.Frame.queue_draw_area(Globals.PG_buttonframe[0],Globals.PG_buttonframe[1],Globals.PG_buttonframedimensions[0],Globals.PG_buttonframedimensions[1])
		#gtk.gdk.window_process_all_updates()
		if self.menu.inanimation==1:
			return True
		else:
			return False
		
	def mousemove(self,widget,event):
		a = self.menu.seltext
		self.menu.seltext=self.menu.Unmap(event.x,event.y)
		if a != self.menu.seltext:
			self.menu.UpdateButtons(self.XDG.L_Names)		
			self.Frame.queue_draw_area(Globals.PG_buttonframe[0],Globals.PG_buttonframe[1],Globals.PG_buttonframedimensions[0],Globals.PG_buttonframedimensions[1])
	
	def buttonpress(self,widget,event):
		a=self.XDG.L_Types[self.menu.seltext]
		self.XDG.ButtonClick(self.menu.seltext)
		self.menu.NameBuffer = self.XDG.L_Names
		if a==0:		#forward menu movement
			self.menu.InitiateAnimation(2)
			gobject.timeout_add(10,self.UpdateAnimation)

		elif a==2:	#back menu movement
			self.menu.InitiateAnimation(3)
			gobject.timeout_add(10,self.UpdateAnimation)

#=================================================================  
#EXTRA FUNCTION PASSTHROUGH TO XDG
#See XDG module for command opcodes
#=================================================================  

	def CallSpecialMenu(self,command,data=None):
#		for item in self.Buttonlist:
#			item.destroy()
		self.XDG.CallSpecialMenu(command,data)
#		self.PopulateButtons()

		self.menu.UpdateButtons(self.XDG.L_Names)
		self.menu.InitiateAnimation(1)
		gobject.timeout_add(10,self.UpdateAnimation)

	def SetInputFocus(self):
		# Give keyboard input focus to last item on list or to sub menu program group start
		pass

	def SetFirstButton(self,event):
		pass#self.Buttonlist[0].grab_focus()

	def SetLastButton(self,event):
		pass#self.Buttonlist[len(self.XDG.L_Names)-1].grab_focus()
		

class CairoMenuObject(gtk.DrawingArea):
    
    def __init__(self):
		import math as math
		self.math = math
		gtk.DrawingArea.__init__(self)
		self.connect("expose_event", self.expose)
		# Screen dimensions
		self.x,self.y=Globals.PG_buttonframe[0],Globals.PG_buttonframe[1]
		self.w,self.h=Globals.PG_buttonframedimensions[0],Globals.PG_buttonframedimensions[1]
		#Standard settings
		self.font_size=[] 
		#Animation status
		self.inanimation=0
		self.activitycount=0
		self.deffont_size=10
		self.seltext = 0
		#Motion registers
		self.leftshift=0
		self.inleftshift=0
		self.leftshifti=0
		
    def expose(self, widget, event):
        self.context = widget.window.cairo_create()
        # set a clip region for the expose event
        self.context.rectangle(event.area.x, event.area.y,event.area.width, event.area.height)
        self.context.clip()
        self.draw(self.context)
        return False
    
    	
    def draw(self, context):
		x,y,w,h=self.x,self.y,self.w,self.h
		# Update animation handlers
		# Left shift
		if self.inleftshift==1:
			self.leftshifti=self.leftshifti+0.2
			self.leftshift=self.leftshiftd * w - (self.leftshiftd * self.math.sin(self.leftshifti)*w)
			if self.leftshifti>=self.math.pi/2:
				self.inleftshift=0
				self.leftshift=0
				self.activitycount = self.activitycount - 1
				if self.activitycount==0:
					self.inanimation=0
					
			self.UpdateButtons(self.NameBuffer)
			
		#Draw flat gradient background
		pat = cairo.LinearGradient (x, y,  w, h)
		pat.add_color_stop_rgba (0, .5, .5, .5, 1)
		pat.add_color_stop_rgba (1, .3, .3, 1, 1)
		context.set_source(pat)
		context.paint()
		context.set_source_rgba(0,0,0,.1)
		context.move_to(0, 0)
		context.curve_to(0, 250, w, h-150, w,h)
		context.line_to(w,0)
		context.move_to(w,0)
		context.fill_preserve()
		#Paint the button text onto the draw surface
		if isinstance(self.textsurface,cairo.Surface):
			context.set_source_surface(self.textsurface,self.leftshift,0)
			context.paint()
		if self.leftshiftdlw==-1:
			context.set_source_surface(self.prevtextsurface,self.leftshift+w,0)
			context.paint()
		elif self.leftshiftdlw==1:
			context.set_source_surface(self.prevtextsurface,self.leftshift-w,0)
			context.paint()

    def UpdateButtons(self,L_Names):
    	#Draw the button page overlay
		self.NameBuffer = L_Names
		if len(self.font_size) != len(self.NameBuffer):
			self.font_size = []
			self.font_move = []
			self.font_movec = []
			for i in range(len(self.NameBuffer)):
				self.font_size.append(10)
				self.font_move.append(0)
				self.font_movec.append(0)
		
		x,y,w,h=self.x,self.y,self.w,self.h
		self.textsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, self.w, self.h)
		context = cairo.Context(self.textsurface)
		self.DrawButton(w,30)
		#Draw text col1
		context.select_font_face("Sans",cairo.FONT_SLANT_NORMAL,cairo.FONT_WEIGHT_BOLD)
		for i in range(0,len(L_Names)):
			if L_Names[i] != '<separator>':
				context.set_source_surface(self.buttonsurface,0,y+i*32-40)
				context.paint()
			
	
				if i==self.seltext:
					context.set_font_size(self.font_size[i]+1)
					context.set_source_rgba(1,1,1,1)
					context.move_to(15-3,y+i*32-22)
					context.show_text (L_Names[i])
				else:
					context.set_font_size(self.font_size[i])
					context.set_source_rgba(0,0,0,1)
					context.move_to(15-3,y+i*32-22)
					context.show_text (L_Names[i])
			
    def Unmap(self,x,y):
    	#Reverse map a mouse location to a specific button
		i = int(((y+40)-self.y)/32)
		if i>len(self.NameBuffer)-1:
			i=len(self.NameBuffer)-1
		return i
		
    def DrawButton(self,w,h):
		x0=0
		y0=0
		radius=8
		x1=x0+w
		y1=y0+h
		self.buttonsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, self.w, self.h)
		context = cairo.Context(self.buttonsurface)
		context.move_to(x0, y0 + radius)
		context.curve_to(x0 , y0, x0 , y0, x0 + radius, y0)
		context.line_to(x1 - radius, y0)
		context.curve_to(x1, y0, x1, y0, x1, y0 + radius)
		context.line_to(x1 , y1 - radius)
		context.curve_to(x1, y1, x1, y1, x1 - radius, y1)
		context.line_to(x0 + radius, y1)
		context.curve_to(x0, y1, x0, y1, x0, y1- radius)
		 
		context.close_path()
		pat = cairo.LinearGradient (x0, y0,  x0, y1)
		pat.add_color_stop_rgba (0, .1, .1, 1, 1)
		pat.add_color_stop_rgba (1, 1, 1, 1, 1)
		context.set_source(pat)
		context.fill_preserve()
		context.set_source_rgba(0, 0, 0, 1)
		context.set_line_width(1.0)
		context.stroke()

    def InitiateAnimation(self,opcode,data=None):
		if opcode==0:		#Abort all and reset environment registers
			self.inanimation=0
			self.activitycount=0
			self.leftshift=0
		elif opcode==1:		#Leftshift
			self.activitycount=self.activitycount+1		#Animation activity
			self.inanimation=1							#Active animation flag
			self.leftshift=-self.w						#Initial offset
			self.leftshiftd=-1							#Page shift direction
			self.leftshifti=0							#Increment counter
			self.leftshiftdlw=0							#Display previous page, to what side
			self.inleftshift=1							#Animation specific activity flag
		elif opcode==2:		#Rightshift w/ pttl
			self.activitycount=self.activitycount+1
			self.inanimation=1
			self.leftshift=self.w
			self.leftshiftd=1
			self.leftshiftdlw=1
			self.leftshifti=0
			self.prevtextsurface=self.textsurface		#Backup previous text surface for frameshifting
			self.inleftshift=1
		elif opcode==3:		#Leftshift w/ pttr
			self.activitycount=self.activitycount+1
			self.inanimation=1
			self.leftshiftd=-1
			self.leftshift=-self.w
			self.leftshifti=0
			self.leftshiftdlw=-1
			self.prevtextsurface=self.textsurface
			self.inleftshift=1



