import gtk from gtk import gdk import logging class Rating(gtk.Widget): """ Controls that display the rating of a tutorial using colored stars """ def __init__(self,tutorial,controller, rating=0,editable = False): """ Constructor @param the controller to link the view with @param tutorial The tutorial for which this rating is @param rating The rating to show @param editable True if the rating may be edited """ gtk.Widget.__init__(self) self.tutorial = tutorial self.controller = controller self.editable = editable self.rating = rating #star size is 24 pixels by 24 pixels self.image_length = 24 def do_realize(self): self.set_flags(self.flags() | gtk.REALIZED) 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.BUTTON_PRESS_MASK) self.window.set_user_data(self) self.style.attach(self.window) self.style.set_background(self.window, gtk.STATE_NORMAL) self.window.move_resize(*self.allocation) #load the stars pixbuf = gtk.gdk.pixbuf_new_from_file('full_star.png') self.full_star,mask = pixbuf.render_pixmap_and_mask() pixbuf = gtk.gdk.pixbuf_new_from_file('half_star.png') self.half_star,mask = pixbuf.render_pixmap_and_mask() image = gtk.Image() pixbuf = gtk.gdk.pixbuf_new_from_file('grayed_star.png') self.empty_star,mask =pixbuf.render_pixmap_and_mask() self.gc = self.style.fg_gc[gtk.STATE_NORMAL] def do_unrealize(self): self.window.destroy() def do_size_request(self, requisition): requisition.height = self.image_length requisition.width = (self.image_length * 5) def do_size_allocate(self, allocation): self.allocation = allocation if self.flags() & gtk.REALIZED: self.window.move_resize(*allocation) def do_expose_event(self, event): """ The widget is drawn here """ value = self.rating stars = [0,0,0,0,0] if value > 0: for x in range(5): if value -1 > 0: stars[x]=1 elif value -1 == -0.5: stars[x] = 0.5 break else: stars[x]=1 break value -= 1 for x in range(0,5): if stars[x] == 0: self.window.draw_drawable(self.gc, self.empty_star, 0, 0 , x*self.image_length , 0,-1, -1) elif stars[x] == 0.5: self.window.draw_drawable(self.gc, self.half_star, 0, 0 , x*self.image_length , 0,-1, -1) elif stars[x] == 1: self.window.draw_drawable(self.gc, self.full_star, 0, 0 , x*self.image_length , 0,-1, -1) def do_button_press_event(self, event): """When the button is pressed""" # make sure it was the first button if self.editable: if event.button == 1: #check for new stars self.check_for_new_stars(event.x) return True def check_for_new_stars(self, xPos): """ Computes the star number based on where the click was """ new_stars = int(xPos / self.image_length) half_star = xPos % self.image_length logging.info("xpos: %d, new_stars: %d, half_star: %d",xPos,new_stars,half_star) if half_star > self.image_length/2: new_stars +=1 else: new_stars = new_stars+0.5 logging.info("rating: %f",new_stars) self.controller.rate_tutorial(self.tutorial,new_stars) self.set_value(new_stars) def set_value(self, value): """ Sets the value and force a redraw """ if (value >= 0): self.rating = value #check for the maximum if (self.rating > 5): self.rating = 5 # redraw the widget self.queue_draw()