import gtk import gtk.glade import pango import os import Player import Grid import Resources class Render: SCAN_NONE,SCAN_V,SCAN_H,SCAN_VH,SCAN_WAIT,SCAN_MENU_V,SCAN_MENU_VH=range(7) def __init__(self,drawingarea): print "[Render] Init" self.selected=(0,0) self.drawingarea=drawingarea self.menu_h=40 self.stack_h=160 self.stack_w=160 self.pixbuf_rsrc={} self.layout_rsrc={} self.pointer_pixbuf=None self.default_pixbuf=None self.grids=[] self.grid=None self.menu_grid=None self.pictogram_stack=[] self.touch_callback=None self.mouse_device=None self.scan_mode=Render.SCAN_NONE self.scan_cycles=0 self.resources=Resources.Resources() print "[Render] Creating drawing context" self.gc=self.drawingarea.get_window().new_gc(foreground=gtk.gdk.Color(0xFFFF,0xFFFF,0xFFFF,0),background=gtk.gdk.Color(0xFFFF,0xFFFF,0,0)) self.pgc=self.drawingarea.create_pango_context() self.layout=pango.Layout(self.pgc) self.layout.set_alignment(pango.ALIGN_CENTER) #self.layout.set_font_description(pango.FontDescription("Purisa 16")) self.layout.set_font_description(pango.FontDescription("Arial 12")) print "[Render] Expose hook" self.drawingarea.connect("expose_event",self.OnDrawingAreaExpose) self.drawingarea.add_events(gtk.gdk.BUTTON_PRESS_MASK) self.drawingarea.connect("button-press-event",self.OnClick) self.pointer_pixbuf=gtk.gdk.pixbuf_new_from_file(self.resources.get_rsrc()+"/frame.png") self.pointer_blue_pixbuf=gtk.gdk.pixbuf_new_from_file(self.resources.get_rsrc()+"/frameb.png") def log(self,txt): print("[Render]:%s" % (txt)) def SetMenu(self,grid): self.menu_grid=grid for x in range(self.menu_grid.width): for y in range(self.menu_grid.height): self.LoadPixbuf(self.menu_grid.pictograms[x][y].image) self.LoadLayout(self.menu_grid.pictograms[x][y].font) def LoadGrid(self,grid): self.grids.append(grid) if self.grid==None: self.grid=grid self.selected=(0,0) self.layout.set_width(-1) self.layout.set_text(grid.name) tw,th=self.layout.get_pixel_size() grid.tabsize=tw+20 for x in range(grid.width): for y in range(grid.height): self.LoadPixbuf(grid.pictograms[x][y].image) self.LoadLayout(grid.pictograms[x][y].font) self.drawingarea.queue_draw() def LoadPixbuf(self,name): if name=="": self.log("Null image name") return if not name in self.pixbuf_rsrc: self.log("Loading pixbuf:" + self.resources.get_custom_images()+os.path.sep+name) if os.path.exists(self.resources.get_custom_images()+os.path.sep+name): self.log("File exists") self.pixbuf_rsrc[name]=gtk.gdk.pixbuf_new_from_file(self.resources.get_custom_images()+os.path.sep+name) elif os.path.exists(self.resources.get_images()+os.path.sep+name): self.log("File does not exists, trying in: "+self.resources.get_images()+os.path.sep+name) self.pixbuf_rsrc[name]=gtk.gdk.pixbuf_new_from_file(self.resources.get_images()+os.path.sep+name) else: self.log("File not found, using fallback") if self.default_pixbuf==None: self.log("Loading fallback pixbuf") theme=gtk.icon_theme_get_default() icon_info=theme.lookup_icon("gtk-cancel",128,gtk.ICON_LOOKUP_FORCE_SVG) self.default_pixbuf=icon_info.load_icon() self.pixbuf_rsrc[name]=self.default_pixbuf def LoadLayout(self,name): if not name=="" and not name in self.layout_rsrc: self.log("Loading layout:"+name) layout=pango.Layout(self.pgc) layout.set_alignment(pango.ALIGN_CENTER) layout.set_font_description(pango.FontDescription(name)) self.layout_rsrc[name]=layout def SetGrid(self,grid): self.grid=grid self.drawingarea.queue_draw() def ConnectTouch(self,funct): self.touch_callback=funct #************************************ # Click hook #************************************ def OnClick(self,widget,event): if not self.grid==None: #print event.device.name #print event #print "click " + str(event.device.axes) #print event.device.get_state(widget.window) if event.device.name==self.mouse_device: self.PushInput() self.drawingarea.queue_draw() return mouse_pos,mouse_mask=event.device.get_state(widget.window) mx,my=mouse_pos button1 = mouse_mask & gtk.gdk.BUTTON1_MASK #print mouse_pos #print mouse_mask if my>self.menu_h: #touch mode if button1==gtk.gdk.BUTTON1_MASK: w,h=self.drawingarea.get_window().get_size() tile_x=w/self.grid.width tile_y=(h-self.menu_h-self.stack_h)/(self.grid.height+1) tx=int(mx/tile_x) ty=int((my-self.menu_h)/tile_y) self.log("tile "+str(tx)+","+str(ty)) #self.selected=(tx,ty) self.drawingarea.queue_draw() self.log("ty:"+str(ty)) #running pictogram actions #self.pictogram_stack.append(self.grid.pictograms[tx][ty]) if not ty==0: action=self.grid.pictograms[tx][ty-1].action if self.touch_callback!=None: self.touch_callback(self.grid.pictograms[tx][ty-1]) else: tile_x=w/self.menu_grid.width tx=int(mx/tile_x) self.log("menu:"+self.menu_grid.pictograms[tx][0].caption) self.touch_callback(self.menu_grid.pictograms[tx][0]) else: self.log("scan mode mouse event") else: self.log("clicked on menu") pos=0 last=self.grids[0] selected=None for g in self.grids: pos=pos+g.tabsize if mx=self.grid.height: self.scan_mode=Render.SCAN_MENU_V self.selected=(x,y) self.drawingarea.queue_draw() if self.scan_mode==Render.SCAN_MENU_VH: x,y=self.selected x=x+1 if x>=self.menu_grid.width: x=0 self.scan_cycles+=1 if self.scan_cycles>1: self.scan_mode=Render.SCAN_V self.selected=(x,y) self.drawingarea.queue_draw() if self.scan_mode==Render.SCAN_VH: x,y=self.selected x=x+1 if x>=self.grid.width: x=0 self.scan_cycles+=1 if self.scan_cycles>1: self.scan_mode=Render.SCAN_V self.selected=(x,y) self.drawingarea.queue_draw() if self.scan_mode==Render.SCAN_WAIT: self.selected=(0,0) self.scan_mode=Render.SCAN_V #************************************ # Compute event #************************************ def PushInput(self): if self.scan_mode==Render.SCAN_MENU_V: self.scan_mode=Render.SCAN_MENU_VH self.selected=(0,0) self.drawingarea.queue_draw() self.scan_cycles=0 return if self.scan_mode==Render.SCAN_V: self.scan_mode=Render.SCAN_VH self.scan_cycles=0 return if self.scan_mode==Render.SCAN_MENU_VH: tx,ty=self.selected action=self.menu_grid.pictograms[tx][0].action self.log("MENU PICTOGRAM "+self.menu_grid.pictograms[tx][0].name) if self.touch_callback!=None: self.touch_callback(self.menu_grid.pictograms[tx][0]) self.scan_mode=Render.SCAN_V return if self.scan_mode==Render.SCAN_VH: self.scan_mode=Render.SCAN_WAIT #running pictogram actions tx,ty=self.selected action=self.grid.pictograms[tx][ty].action self.log("PICTOGRAM "+self.grid.pictograms[tx][ty].name) if self.touch_callback!=None: self.touch_callback(self.grid.pictograms[tx][ty]) return #************************************ # Render Hook method #************************************ def OnDrawingAreaExpose(self,widget,event): if self.grid==None: return w,h=self.drawingarea.get_window().get_size() tile_x=w/self.grid.width tile_y=(h-self.menu_h-self.stack_h)/(self.grid.height+1) #drawing grid tabs cr=0 for g in self.grids: self.layout.set_width(-1) self.layout.set_text(g.name) tw,th=self.layout.get_pixel_size() if g==self.grid: self.gc.set_rgb_fg_color(gtk.gdk.Color(0xCCCC,0,0)) else: self.gc.set_rgb_fg_color(gtk.gdk.Color(0,0,0)) self.drawingarea.get_window().draw_layout(self.gc,10+cr,(self.menu_h-th)*0.5,self.layout) self.drawingarea.get_window().draw_rectangle(self.gc,False,cr,0,tw+20,self.menu_h) cr=cr+tw+20 self.gc.set_rgb_fg_color(gtk.gdk.Color(0,0,0)) self.drawingarea.get_window().draw_line(self.gc,0,self.menu_h,w,self.menu_h) #drawing menu grid tile_x=w/self.menu_grid.width for x in range(0,self.menu_grid.width): y=0 stile_x=tile_x*0.8 stile_y=tile_y*0.8 self.gc.set_rgb_fg_color(self.menu_grid.pictograms[x][y].background) self.drawingarea.get_window().draw_rectangle(self.gc,True,(x*tile_x),(y*tile_y)+self.menu_h,tile_x,tile_y) if self.menu_grid.pictograms[x][y].image in self.pixbuf_rsrc: tpix=self.pixbuf_rsrc[self.menu_grid.pictograms[x][y].image].scale_simple(stile_x, stile_y, gtk.gdk.INTERP_BILINEAR) else: tpix=self.default_pixbuf.scale_simple(stile_x, stile_y, gtk.gdk.INTERP_BILINEAR) self.drawingarea.get_window().draw_pixbuf(self.gc,tpix,0,0,int((tile_x-stile_x)/2)+(x*tile_x),int((tile_y-stile_y)/2)+(y*tile_y)+self.menu_h) if self.scan_mode==Render.SCAN_MENU_V: pbuf=self.pointer_pixbuf.scale_simple(int(stile_x), int(stile_y), gtk.gdk.INTERP_BILINEAR) self.drawingarea.get_window().draw_pixbuf(self.gc,pbuf,0,0,int((tile_x-stile_x)/2)+(x*tile_x),int((tile_y-stile_y)/2)+(y*tile_y)+self.menu_h) if self.scan_mode==Render.SCAN_MENU_VH: if x==self.selected[0]: pbuf=self.pointer_blue_pixbuf.scale_simple(stile_x, stile_y, gtk.gdk.INTERP_BILINEAR) self.drawingarea.get_window().draw_pixbuf(self.gc,pbuf,0,0,int((tile_x-stile_x)/2)+(x*tile_x),int((tile_y-stile_y)/2)+(y*tile_y)+self.menu_h) self.gc.set_rgb_fg_color(self.menu_grid.pictograms[x][y].fontcolor) layout=self.layout_rsrc[self.menu_grid.pictograms[x][y].font] layout.set_width(pango.SCALE*tile_x) layout.set_text(self.menu_grid.pictograms[x][y].caption) tw,th=layout.get_pixel_size() self.drawingarea.get_window().draw_layout(self.gc,(x*tile_x),(y*tile_y)+self.menu_h+(tile_y-th-3),layout) self.gc.set_rgb_fg_color(gtk.gdk.Color(0,0,0)) self.gc.set_line_attributes(3,gtk.gdk.LINE_SOLID,gtk.gdk.CAP_ROUND,gtk.gdk.JOIN_MITER) for x in range(0,self.menu_grid.width+1): self.drawingarea.get_window().draw_line(self.gc,x*tile_x,self.menu_h,x*tile_x,self.menu_h+tile_y) tile_x=w/self.grid.width #drawing images and text for x in range(0,self.grid.width): for y in range(0,self.grid.height): stile_x=tile_x*0.8 stile_y=tile_y*0.8 self.gc.set_rgb_fg_color(self.grid.pictograms[x][y].background) self.drawingarea.get_window().draw_rectangle(self.gc,True,(x*tile_x),(y*tile_y)+self.menu_h+tile_y,tile_x,tile_y) if self.grid.pictograms[x][y].image in self.pixbuf_rsrc: tpix=self.pixbuf_rsrc[self.grid.pictograms[x][y].image].scale_simple(int(stile_x), int(stile_y), gtk.gdk.INTERP_BILINEAR) else: tpix=self.default_pixbuf.scale_simple(stile_x, stile_y, gtk.gdk.INTERP_BILINEAR) self.drawingarea.get_window().draw_pixbuf(self.gc,tpix,0,0,int((tile_x-stile_x)/2)+(x*tile_x),int((tile_y-stile_y)/2)+(y*tile_y)+self.menu_h+tile_y) if self.scan_mode==Render.SCAN_V: if y==self.selected[1]: pbuf=self.pointer_pixbuf.scale_simple(int(stile_x), int(stile_y), gtk.gdk.INTERP_BILINEAR) self.drawingarea.get_window().draw_pixbuf(self.gc,pbuf,0,0,int((tile_x-stile_x)/2)+(x*tile_x),int((tile_y-stile_y)/2)+(y*tile_y)+self.menu_h+tile_y) if self.scan_mode==Render.SCAN_VH: if x==self.selected[0] and y==self.selected[1]: pbuf=self.pointer_blue_pixbuf.scale_simple(stile_x, stile_y, gtk.gdk.INTERP_BILINEAR) self.drawingarea.get_window().draw_pixbuf(self.gc,pbuf,0,0,int((tile_x-stile_x)/2)+(x*tile_x),int((tile_y-stile_y)/2)+(y*tile_y)+self.menu_h+tile_y) self.gc.set_rgb_fg_color(self.grid.pictograms[x][y].fontcolor) layout=self.layout_rsrc[self.grid.pictograms[x][y].font] layout.set_width(pango.SCALE*tile_x) layout.set_text(self.grid.pictograms[x][y].caption) tw,th=layout.get_pixel_size() #self.gc.set_rgb_fg_color(self.grid.pictograms[x][y].background) #self.drawingarea.get_window().draw_rectangle(self.gc,True,5+(x*tile_x),(y*tile_y)+(tile_y-th)-3+self.menu_h,tile_x-10,th) self.gc.set_rgb_fg_color(self.grid.pictograms[x][y].fontcolor) self.drawingarea.get_window().draw_layout(self.gc,x*tile_x,(y*tile_y)+(tile_y-th)-3+self.menu_h+tile_y,layout) #drawing grid self.gc.set_rgb_fg_color(gtk.gdk.Color(0,0,0)) self.gc.set_line_attributes(3,gtk.gdk.LINE_SOLID,gtk.gdk.CAP_ROUND,gtk.gdk.JOIN_MITER) for x in range(1,self.grid.width): self.drawingarea.get_window().draw_line(self.gc,x*tile_x,self.menu_h+tile_y,x*tile_x,h-self.stack_h) for y in range(0,self.grid.height+1): self.drawingarea.get_window().draw_line(self.gc,0,self.menu_h+tile_y+(y*tile_y),w,self.menu_h+tile_y+(y*tile_y)) #drawing pictogram stack pos=0 for pict in self.pictogram_stack: if pict.image in self.pixbuf_rsrc: tpix=self.pixbuf_rsrc[pict.image].scale_simple(self.stack_w, int(self.stack_h*0.8), gtk.gdk.INTERP_BILINEAR) else: tpix=self.default_pixbuf.scale_simple(self.stack_w, self.stack_h, gtk.gdk.INTERP_BILINEAR) self.drawingarea.get_window().draw_pixbuf(self.gc,tpix,0,0,self.stack_w*pos,h-self.stack_h) layout=self.layout_rsrc[pict.font] layout.set_width(pango.SCALE*self.stack_w) layout.set_text(pict.caption) self.drawingarea.get_window().draw_layout(self.gc,pos*self.stack_w,h-int(self.stack_h*0.1)-5,layout) pos=pos+1