Esempio n. 1
0
 def draw_items(self, cr, rect):
     # Draw items.
     if len(self.items) > 0:
         with cairo_state(cr):
             scrolled_window = get_match_parent(self, ["ScrolledWindow"])
             vadjust_value = int(scrolled_window.get_vadjustment().get_value())
             hadjust_value = int(scrolled_window.get_hadjustment().get_value())
             
             # Draw on drawing area.
             (item_width, item_height, columns, start_index, end_index) = self.get_render_item_info()
             for (index, item) in enumerate(self.items[start_index:end_index]):
                 row = int((start_index + index) / columns)
                 column = (start_index + index) % columns
                 render_x = self.padding_x + column * item_width - hadjust_value
                 render_y = self.padding_y + row * item_height - vadjust_value
                 
                 # Draw row background.
                 self.draw_row_mask(cr, gtk.gdk.Rectangle(render_x, render_y, rect.width, item_height), row)
                 
                 item.row_index = row
                 
                 with cairo_state(cr):
                     # Don't allow draw out of item area.
                     cr.rectangle(render_x, render_y, item_width, item_height)
                     cr.clip()
                     
                     item.render(cr, gtk.gdk.Rectangle(render_x, render_y, item_width, item_height))
Esempio n. 2
0
def draw_window_shadow(cr, x, y, w, h, r, p, color_window_shadow):
    '''Draw window shadow.'''
    color_infos = color_window_shadow.get_color_info()
    with cairo_state(cr):
        # Clip four corner.
        cr.rectangle(x, y, r - 1, r - 1) # top-left
        cr.rectangle(x + r - 1, y, 1, r - 2) # vertical
        cr.rectangle(x, y + r - 1, r - 2, 1) # horizontal
        
        cr.rectangle(x + w - r + 1, y, r - 1, r - 1) # top-right
        cr.rectangle(x + w - r, y, 1, r - 2)         # vertical
        cr.rectangle(x + w - r + 2, y + r - 1, r - 2, 1) # horizontal
        
        cr.rectangle(x, y + h - r + 1, r - 1, r - 1) # bottom-left
        cr.rectangle(x + r - 1, y + h - r + 2, 1, r - 2) # vertical
        cr.rectangle(x, y + h - r, r - 2, 1)     # horizontal
        
        cr.rectangle(x + w - r + 1, y + h - r + 1, r - 1, r - 1) # bottom-right
        cr.rectangle(x + w - r, y + h - r + 2, 1, r - 2)         # vertical
        cr.rectangle(x + w - r + 2, y + h - r, r - 2, 1) # horizontal
        
        cr.clip()
        
        # Draw four round.
        draw_radial_round(cr, x + r, y + r, r, color_infos)
        draw_radial_round(cr, x + r, y + h - r, r, color_infos)
        draw_radial_round(cr, x + w - r, y + r, r, color_infos)
        draw_radial_round(cr, x + w - r, y + h - r, r, color_infos)
    
    with cairo_state(cr):
        # Clip four side.
        cr.rectangle(x, y + r, p, h - r * 2)
        cr.rectangle(x + w - p, y + r, p, h - r * 2)
        cr.rectangle(x + r, y, w - r * 2, p)
        cr.rectangle(x + r, y + h - p, w - r * 2, p)
        cr.clip()
        
        # Draw four side.
        draw_vlinear(
            cr, 
            x + r, y, 
            w - r * 2, r, color_infos)
        draw_vlinear(
            cr, 
            x + r, y + h - r, 
            w - r * 2, r, color_infos, 0, False)
        draw_hlinear(
            cr, 
            x, y + r, 
            r, h - r * 2, color_infos)
        draw_hlinear(
            cr, 
            x + w - r, y + r, 
            r, h - r * 2, color_infos, 0, False)
Esempio n. 3
0
def draw_window_shadow(cr, x, y, w, h, r, p, color_window_shadow):
    '''
    Draw window shadow.

    @param cr: Cairo context.
    @param x: X coordinate of draw area.
    @param y: Y coordinate of draw area.
    @param w: Width of draw area.
    @param h: Height of draw area.
    @param r: Radious of window shadow corner.
    @param p: Padding between window shadow and window frame.
    @param color_window_shadow: theme.DyanmicShadowColor.
    '''
    color_infos = color_window_shadow.get_color_info()
    with cairo_state(cr):
        # Clip four corner.
        cr.rectangle(x, y, r - 1, r - 1)  # top-left
        cr.rectangle(x + r - 1, y, 1, r - 2)  # vertical
        cr.rectangle(x, y + r - 1, r - 2, 1)  # horizontal

        cr.rectangle(x + w - r + 1, y, r - 1, r - 1)  # top-right
        cr.rectangle(x + w - r, y, 1, r - 2)  # vertical
        cr.rectangle(x + w - r + 2, y + r - 1, r - 2, 1)  # horizontal

        cr.rectangle(x, y + h - r + 1, r - 1, r - 1)  # bottom-left
        cr.rectangle(x + r - 1, y + h - r + 2, 1, r - 2)  # vertical
        cr.rectangle(x, y + h - r, r - 2, 1)  # horizontal

        cr.rectangle(x + w - r + 1, y + h - r + 1, r - 1,
                     r - 1)  # bottom-right
        cr.rectangle(x + w - r, y + h - r + 2, 1, r - 2)  # vertical
        cr.rectangle(x + w - r + 2, y + h - r, r - 2, 1)  # horizontal

        cr.clip()

        # Draw four round.
        draw_radial_round(cr, x + r, y + r, r, color_infos)
        draw_radial_round(cr, x + r, y + h - r, r, color_infos)
        draw_radial_round(cr, x + w - r, y + r, r, color_infos)
        draw_radial_round(cr, x + w - r, y + h - r, r, color_infos)

    with cairo_state(cr):
        # Clip four side.
        cr.rectangle(x, y + r, p, h - r * 2)
        cr.rectangle(x + w - p, y + r, p, h - r * 2)
        cr.rectangle(x + r, y, w - r * 2, p)
        cr.rectangle(x + r, y + h - p, w - r * 2, p)
        cr.clip()

        # Draw four side.
        draw_vlinear(cr, x + r, y, w - r * 2, r, color_infos)
        draw_vlinear(cr, x + r, y + h - r, w - r * 2, r, color_infos, 0, False)
        draw_hlinear(cr, x, y + r, r, h - r * 2, color_infos)
        draw_hlinear(cr, x + w - r, y + r, r, h - r * 2, color_infos, 0, False)
Esempio n. 4
0
def draw_shadow(cr, x, y, w, h, r, color_window_shadow):
    '''
    Draw window shadow.
    
    @param cr: Cairo context.
    @param x: X coordinate of draw area.
    @param y: Y coordinate of draw area.
    @param w: Width of draw area.
    @param h: Height of draw area.
    @param r: Radious of window shadow corner.
    @param color_window_shadow: theme.DyanmicShadowColor.
    '''
    color_infos = color_window_shadow.get_color_info()
    with cairo_state(cr):
        # Clip four corner.
        cr.rectangle(x, y, r, r)
        cr.rectangle(x + w - r, y, r, r)
        cr.rectangle(x, y + h - r, r, r)
        cr.rectangle(x + w - r, y + h - r, r, r)
        
        cr.clip()
        
        # Draw four round.
        draw_radial_round(cr, x + r, y + r, r, color_infos)
        draw_radial_round(cr, x + r, y + h - r, r, color_infos)
        draw_radial_round(cr, x + w - r, y + r, r, color_infos)
        draw_radial_round(cr, x + w - r, y + h - r, r, color_infos)
        
    with cairo_state(cr):
        # Draw four side.
        draw_vlinear(
            cr, 
            x + r, y, 
            w - r * 2, r, color_infos)
        draw_vlinear(
            cr, 
            x + r, y + h - r, 
            w - r * 2, r, color_infos, 0, False)
        draw_hlinear(
            cr, 
            x, y + r, 
            r, h - r * 2, color_infos)
        draw_hlinear(
            cr, 
            x + w - r, y + r, 
            r, h - r * 2, color_infos, 0, False)
        
    # Fill inside.
    cr.set_source_rgba(*alpha_color_hex_to_cairo(color_infos[-1][1]))    
    cr.rectangle(x + r, y + r, w - r * 2, h - r * 2)
    cr.fill()
Esempio n. 5
0
 def render(self, cr, rect):
     # Init.
     x, y, w, h = rect.x, rect.y, rect.width, rect.height
     
     # Draw background frame.
     with cairo_state(cr):
         cr.rectangle(x, y + 1, w, h - 2)
         cr.rectangle(x + 1, y, w - 2, h)
         cr.clip()
         
         cr.set_source_rgb(*color_hex_to_cairo(ui_theme.get_color("progressbar_background_frame").get_color()))
         cr.rectangle(x, y, w, h)
         cr.set_line_width(1)
         cr.stroke()
         
     # Draw background.
     with cairo_state(cr):
         cr.rectangle(x + 1, y + 1, w - 2, h - 2)
         cr.clip()
         
         draw_vlinear(cr, x + 1, y + 1, w - 2, h - 2,
                      ui_theme.get_shadow_color("progressbar_background").get_color_info(), 
                      )
         
     if self.progress > 0:    
         # Draw foreground frame.
         with cairo_state(cr):
             cr.rectangle(x, y + 1, w, h - 2)
             cr.rectangle(x + 1, y, w - 2, h)
             cr.clip()
         
             cr.set_antialias(cairo.ANTIALIAS_NONE)
             cr.set_source_rgb(*color_hex_to_cairo(ui_theme.get_color("progressbar_foreground_frame").get_color()))
             cr.rectangle(x + 1, y + 1, int(w * self.progress / 100) - 1, h - 1)
             cr.set_line_width(1)
             cr.stroke()
             
         # Draw foreground.
         with cairo_state(cr):
             cr.rectangle(x + 1, y + 1, w - 2, h - 2)
             cr.clip()
             
             draw_vlinear(cr, x + 1, y + 1, int(w * self.progress / 100) - 2, h - 2,
                          ui_theme.get_shadow_color("progressbar_foreground").get_color_info(), 
                          )
         
     # Draw light.
     with cairo_disable_antialias(cr):
         cr.set_source_rgba(1, 1, 1, 0.5)
         cr.rectangle(x + 1, y + 1, w - 2, 1)
         cr.fill()
Esempio n. 6
0
def draw_icon_view_mask(widget, x, y, w, h, render_callback):
    '''
    Draw icon view mask with given render method.

    @param widget: Target widget.
    @param x: X coordinate of draw area.
    @param y: Y coordinate of draw area.
    @param w: Width of draw area.
    @param h: Height of draw area.
    @param render_callback: Render callback.
    '''
    cr = widget.window.cairo_create()
    viewport = get_match_parent(widget, ["Viewport"])
    toplevel = widget.get_toplevel()
    (offset_x, offset_y) = viewport.translate_coordinates(toplevel, 0, 0)
    (shadow_x, shadow_y) = get_window_shadow_size(toplevel)

    with cairo_state(cr):
        cr.rectangle(x, y, w, h)
        cr.clip()

        render_callback(
            cr,
            x - offset_x + shadow_x,
            y - offset_y + shadow_y,
            toplevel.allocation.width,
            toplevel.allocation.height)
Esempio n. 7
0
 def draw_text(self, cr, rect):
     x, y, w, h = rect.x, rect.y, rect.width, rect.height
     with cairo_state(cr):
         draw_x = x + self.padding_x
         draw_y = y + self.padding_y
         draw_width = w - self.padding_x * 2
         draw_height = h - self.padding_y * 2
         cr.rectangle(draw_x, draw_y, draw_width, draw_height)
         cr.clip()
         
         # pango context
         context = pangocairo.CairoContext(cr)
         
         # pango layout
         layout = context.create_layout()
         layout.set_font_description(pango.FontDescription("%s %s" % (DEFAULT_FONT, self.font_size)))
         
         text = self.__buffer.get_text()
         layout.set_text(text)
         
         (text_width, text_height) = layout.get_pixel_size()
         cr.move_to(x + self.padding_x , y + self.padding_y)
         
         cr.set_source_rgb(0,0,0)
         context.update_layout(layout)
         context.show_layout(layout)
Esempio n. 8
0
def draw_scrolled_window_mask(widget, x, y, w, h, render_callback):
    '''
    Draw scrolled window mask with given render method.

    @param widget: Target widget.
    @param x: X coordinate of draw area.
    @param y: Y coordinate of draw area.
    @param w: Width of draw area.
    @param h: Height of draw area.
    @param render_callback: Render callback.
    '''
    # Init.
    cr = widget.window.cairo_create()
    toplevel = widget.get_toplevel()
    (offset_x, offset_y) = widget.translate_coordinates(toplevel, 0, 0)

    with cairo_state(cr):
        cr.rectangle(x, y, w, h)
        cr.clip()

        render_callback(
            cr,
            x - offset_x,
            y - offset_y,
            toplevel.allocation.width,
            toplevel.allocation.height)
Esempio n. 9
0
 def expose_icon_view(self, widget, event):
     '''
     Internal callback for `expose-event` signal.
     '''
     # Update vadjustment.
     self.update_vadjustment()    
     
     # Init.
     cr = widget.window.cairo_create()
     rect = widget.allocation
     
     # Get offset.
     (offset_x, offset_y, viewport) = self.get_offset_coordinate(widget)
         
     # Draw background.
     with cairo_state(cr):
         scrolled_window = get_match_parent(self, ["ScrolledWindow"])
         cr.translate(-scrolled_window.allocation.x, -scrolled_window.allocation.y)
         cr.rectangle(offset_x, offset_y, 
                      scrolled_window.allocation.x + scrolled_window.allocation.width, 
                      scrolled_window.allocation.y + scrolled_window.allocation.height)
         cr.clip()
         
         (shadow_x, shadow_y) = get_window_shadow_size(self.get_toplevel())
         skin_config.render_background(cr, self, offset_x + shadow_x, offset_y + shadow_y)
         
     # Draw mask.
     self.draw_mask(cr, offset_x, offset_y, viewport.allocation.width, viewport.allocation.height)
     
     # Draw items.
     self.draw_items(cr, rect, offset_x, offset_y, viewport)
Esempio n. 10
0
def draw_hlinear(cr, x, y, w, h, color_infos, radius=0, left_to_right=True):
    '''
    Draw linear area horticulturally.
    
    @param cr: Cairo context.
    @param x: X coordinate of draw area.
    @param y: Y coordinate of draw area.
    @param w: Width of draw area.
    @param h: Height of draw area.
    @param color_infos: A list of ColorInfo, ColorInfo format: (color_stop_position, (color_hex_value, color_alpha))
    @param radius: Rectangle corner radious.
    @param left_to_right: Draw direction, default is from left to right, function will draw from right to left if set option as False.
    '''
    with cairo_state(cr):
        # Translate x coordinate, otherwise x is too big for LinearGradient cause render bug.
        cr.translate(x, 0)
        
        if left_to_right:
            pat = cairo.LinearGradient(0, 0, w, 0)
        else:
            pat = cairo.LinearGradient(w, 0, 0, 0)
        for (pos, color_info) in color_infos:
            add_color_stop_rgba(pat, pos, color_info)
        cr.set_operator(cairo.OPERATOR_OVER)
        cr.set_source(pat)
        draw_round_rectangle(cr, 0, y, w, h, radius)
        cr.fill()
Esempio n. 11
0
def draw_radial_ring(cr, x, y, outer_radius, inner_radius, color_infos, clip_corner=None):
    '''
    Draw radial ring.

    @param cr: Cairo context.
    @param x: X coordinate of draw area.
    @param y: Y coordinate of draw area.
    @param outer_radius: Radious for outter ring.
    @param inner_radius: Radious for inner ring.
    @param color_infos: A list of ColorInfo, ColorInfo format as [(color_pos, (color_hex_value, color_alpha))].
    '''
    with cairo_state(cr):
        # Clip corner.
        if clip_corner:
            if clip_corner == "top-left":
                cr.rectangle(x - outer_radius, y - outer_radius, outer_radius, outer_radius)
            elif clip_corner == "top-right":
                cr.rectangle(x, y - outer_radius, outer_radius, outer_radius)
            elif clip_corner == "bottom-left":
                cr.rectangle(x - outer_radius, y, outer_radius, outer_radius)
            elif clip_corner == "bottom-right":
                cr.rectangle(x, y, outer_radius, outer_radius)

            cr.clip()

        # Clip.
        cr.arc(x, y, outer_radius, 0, pi * 2)
        cr.arc(x, y, inner_radius, 0, pi * 2)
        cr.set_fill_rule(cairo.FILL_RULE_EVEN_ODD)
        cr.clip()

        # Draw radial round.
        draw_radial_round(cr, x, y, outer_radius, color_infos)
Esempio n. 12
0
    def expose_tab_content_box(self, widget, event):
        '''
        Internal function to `expose-event` signal.
        '''
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation
        self.tab_box_width = rect.width

        # Draw background.
        toplevel = widget.get_toplevel()
        coordinate = widget.translate_coordinates(toplevel, 0, 0)
        (offset_x, offset_y) = coordinate

        with cairo_state(cr):
            cr.rectangle(rect.x, rect.y, rect.width, rect.height)
            cr.clip()

            (shadow_x, shadow_y) = get_window_shadow_size(self.get_toplevel())
            skin_config.render_background(cr, self, shadow_x, shadow_y)

        # Draw mask.
        cr.set_source_rgba(
            *alpha_color_hex_to_cairo((self.tab_select_bg_color.get_color(),
                                       0.93)))
        cr.rectangle(rect.x, rect.y, rect.width, rect.height)
        cr.fill()
Esempio n. 13
0
def draw_hlinear(cr, x, y, w, h, color_infos, radius=0, left_to_right=True):
    '''
    Draw linear area horticulturally.

    @param cr: Cairo context.
    @param x: X coordinate of draw area.
    @param y: Y coordinate of draw area.
    @param w: Width of draw area.
    @param h: Height of draw area.
    @param color_infos: A list of ColorInfo, ColorInfo format: (color_stop_position, (color_hex_value, color_alpha))
    @param radius: Rectangle corner radious.
    @param left_to_right: Draw direction, default is from left to right, function will draw from right to left if set option as False.
    '''
    with cairo_state(cr):
        # Translate x coordinate, otherwise x is too big for LinearGradient cause render bug.
        cr.translate(x, 0)

        if left_to_right:
            pat = cairo.LinearGradient(0, 0, w, 0)
        else:
            pat = cairo.LinearGradient(w, 0, 0, 0)
        for (pos, color_info) in color_infos:
            add_color_stop_rgba(pat, pos, color_info)
        cr.set_operator(cairo.OPERATOR_OVER)
        cr.set_source(pat)
        draw_round_rectangle(cr, 0, y, w, h, radius)
        cr.fill()
Esempio n. 14
0
 def draw_title_background(self, cr, widget):
     (offset_x, offset_y) = widget.translate_coordinates(self.get_toplevel(), 0, 0)
     with cairo_state(cr):
         cr.translate(-offset_x, -offset_y)
         
         (shadow_x, shadow_y) = get_window_shadow_size(self.get_toplevel())
         skin_config.render_background(cr, widget, shadow_x, shadow_y)
Esempio n. 15
0
    def expose_tab_content_box(self, widget, event):
        '''
        Internal function to `expose-event` signal.
        '''
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation
        self.tab_box_width = rect.width

        # Draw background.
        toplevel = widget.get_toplevel()
        coordinate = widget.translate_coordinates(toplevel, 0, 0)
        (offset_x, offset_y) = coordinate

        with cairo_state(cr):
            cr.rectangle(rect.x, rect.y, rect.width, rect.height)
            cr.clip()
            
            (shadow_x, shadow_y) = get_window_shadow_size(self.get_toplevel())
            skin_config.render_background(cr, self, shadow_x, shadow_y)
        
        # Draw mask.
        cr.set_source_rgba(*alpha_color_hex_to_cairo((self.tab_select_bg_color.get_color(), 0.93)))
        cr.rectangle(rect.x, rect.y, rect.width, rect.height)
        cr.fill()
Esempio n. 16
0
    def draw_title_background(self, cr, widget):
        (offset_x,
         offset_y) = widget.translate_coordinates(self.get_toplevel(), 0, 0)
        with cairo_state(cr):
            cr.translate(-offset_x, -offset_y)

            (shadow_x, shadow_y) = get_window_shadow_size(self.get_toplevel())
            skin_config.render_background(cr, widget, shadow_x, shadow_y)
Esempio n. 17
0
def draw_radial_ring(cr, x, y, outer_radius, inner_radius, color_infos):
    '''Draw radial ring.'''
    with cairo_state(cr):
        # Clip.
        cr.arc(x, y, outer_radius, 0, pi * 2)
        cr.arc(x, y, inner_radius, 0, pi * 2)
        cr.set_fill_rule(cairo.FILL_RULE_EVEN_ODD)
        cr.clip()
        
        # Draw radial round.
        draw_radial_round(cr, x, y, outer_radius, color_infos)
Esempio n. 18
0
    def expose_window(self, widget, event):
        '''
        Internal function to expose the window.

        @param widget: A window of type Gtk.Widget.
        @param event: The expose event of type gtk.gdk.Event.

        @return: Always return True.
        '''
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation
        x, y, w, h = rect.x, rect.y, rect.width, rect.height

        # Draw background.
        self.draw_background(cr, rect.x, rect.y, rect.width, rect.height)

        # Draw skin and mask.
        with cairo_state(cr):
            if self.window.get_state(
            ) & gtk.gdk.WINDOW_STATE_MAXIMIZED != gtk.gdk.WINDOW_STATE_MAXIMIZED:
                cr.rectangle(x + 2, y, w - 4, 1)
                cr.rectangle(x + 1, y + 1, w - 2, 1)
                cr.rectangle(x, y + 2, w, h - 4)
                cr.rectangle(x + 2, y + h - 1, w - 4, 1)
                cr.rectangle(x + 1, y + h - 2, w - 2, 1)

                cr.clip()

            self.draw_skin(cr, x, y, w, h)

            # Draw mask.
            self.draw_mask(cr, x, y, w, h)

        # Draw window frame.
        if self.window.get_state(
        ) & gtk.gdk.WINDOW_STATE_MAXIMIZED != gtk.gdk.WINDOW_STATE_MAXIMIZED:
            draw_window_frame(
                cr,
                x,
                y,
                w,
                h,
                ui_theme.get_alpha_color("window_frame_outside_1"),
                ui_theme.get_alpha_color("window_frame_outside_2"),
                ui_theme.get_alpha_color("window_frame_outside_3"),
                ui_theme.get_alpha_color("window_frame_inside_1"),
                ui_theme.get_alpha_color("window_frame_inside_2"),
            )

        # Propagate expose.
        propagate_expose(widget, event)

        return True
Esempio n. 19
0
def draw_window_mask(widget, x, y, w, h, render_callback):
    '''Draw window skin mask.'''
    # Init.
    cr = widget.window.cairo_create()

    with cairo_state(cr):
        cr.rectangle(x + 1, y, w - 2, 1)
        cr.rectangle(x, y + 1, w, h - 2)
        cr.rectangle(x + 1, y + h - 1, w - 2, 1)
        cr.clip()
        
        render_callback(cr, x, y, w, h)
Esempio n. 20
0
def draw_shadow(cr, x, y, w, h, r, color_window_shadow):
    '''
    Draw window shadow.

    @param cr: Cairo context.
    @param x: X coordinate of draw area.
    @param y: Y coordinate of draw area.
    @param w: Width of draw area.
    @param h: Height of draw area.
    @param r: Radious of window shadow corner.
    @param color_window_shadow: theme.DyanmicShadowColor.
    '''
    color_infos = color_window_shadow.get_color_info()
    with cairo_state(cr):
        # Clip four corner.
        cr.rectangle(x, y, r, r)
        cr.rectangle(x + w - r, y, r, r)
        cr.rectangle(x, y + h - r, r, r)
        cr.rectangle(x + w - r, y + h - r, r, r)

        cr.clip()

        # Draw four round.
        draw_radial_round(cr, x + r, y + r, r, color_infos)
        draw_radial_round(cr, x + r, y + h - r, r, color_infos)
        draw_radial_round(cr, x + w - r, y + r, r, color_infos)
        draw_radial_round(cr, x + w - r, y + h - r, r, color_infos)

    with cairo_state(cr):
        # Draw four side.
        draw_vlinear(cr, x + r, y, w - r * 2, r, color_infos)
        draw_vlinear(cr, x + r, y + h - r, w - r * 2, r, color_infos, 0, False)
        draw_hlinear(cr, x, y + r, r, h - r * 2, color_infos)
        draw_hlinear(cr, x + w - r, y + r, r, h - r * 2, color_infos, 0, False)

    # Fill inside.
    cr.set_source_rgba(*alpha_color_hex_to_cairo(color_infos[-1][1]))
    cr.rectangle(x + r, y + r, w - r * 2, h - r * 2)
    cr.fill()
Esempio n. 21
0
    def draw_items(self, cr, rect):
        # Draw items.
        if len(self.items) > 0:
            with cairo_state(cr):
                scrolled_window = get_match_parent(self, ["ScrolledWindow"])
                vadjust_value = int(
                    scrolled_window.get_vadjustment().get_value())
                hadjust_value = int(
                    scrolled_window.get_hadjustment().get_value())

                # Draw on drawing area.
                (item_width, item_height, columns, start_index,
                 end_index) = self.get_render_item_info()
                for (index,
                     item) in enumerate(self.items[start_index:end_index]):
                    row = int((start_index + index) / columns)
                    column = (start_index + index) % columns
                    render_x = self.padding_x + column * item_width - hadjust_value
                    render_y = self.padding_y + row * item_height - vadjust_value

                    # Draw row background.
                    self.draw_row_mask(
                        cr,
                        gtk.gdk.Rectangle(render_x, render_y, rect.width,
                                          item_height), row)

                    item.row_index = row

                    with cairo_state(cr):
                        # Don't allow draw out of item area.
                        cr.rectangle(render_x, render_y, item_width,
                                     item_height)
                        cr.clip()

                        item.render(
                            cr,
                            gtk.gdk.Rectangle(render_x, render_y, item_width,
                                              item_height))
Esempio n. 22
0
    def expose_tab_switcher(self, widget, event):
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation
        
        with cairo_state(cr):
            cr.rectangle(rect.x, rect.y, rect.width, rect.height)
            cr.clip()

            # Draw tab line.
            cr.set_source_rgb(*color_hex_to_cairo(self.line_dcolor.get_color()))
            cr.rectangle(rect.x + self.padding_x, 
                         rect.y + self.tab_height,
                         rect.width - self.padding_x * 2, 
                         self.tab_line_height)
            cr.fill()
            
            # Draw tab.
            draw_start_x = rect.x + (rect.width - self.tab_width * self.tab_number) / 2
            if self.in_animiation:
                cr.rectangle(self.tab_animation_x,
                             rect.y,
                             self.tab_width,
                             self.tab_height)
            else:
                cr.rectangle(draw_start_x + self.tab_index * self.tab_width,
                             rect.y,
                             self.tab_width,
                             self.tab_height)
            cr.fill()
            
            # Draw tab name.
            for (tab_index, tab_name) in enumerate(self.tab_names):
                if self.in_animiation:
                    tab_name_color = "#000000"
                elif tab_index == self.tab_index:
                    tab_name_color = "#FFFFFF"
                else:
                    tab_name_color = "#000000"
                draw_text(cr,
                          tab_name,
                          draw_start_x + tab_index * self.tab_width,
                          rect.y,
                          self.tab_width,
                          self.tab_height,
                          text_size=self.tab_name_size,
                          text_color=tab_name_color,
                          alignment=pango.ALIGN_CENTER,
                          )
Esempio n. 23
0
    def expose_window(self, widget, event):
        """
        Internal function to expose the window.

        @param widget: A window of type Gtk.Widget.
        @param event: The expose event of type gtk.gdk.Event.

        @return: Always return True.
        """
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation
        x, y, w, h = rect.x, rect.y, rect.width, rect.height
        
        # Clear color to transparent window.
        cr.set_source_rgba(*self.background_color)
        cr.set_operator(cairo.OPERATOR_SOURCE)
        cr.paint()
        
        # Draw background.
        with cairo_state(cr):
            if self.window.get_state() != gtk.gdk.WINDOW_STATE_MAXIMIZED:
                cr.rectangle(x + 2, y, w - 4, 1)
                cr.rectangle(x + 1, y + 1, w - 2, 1)
                cr.rectangle(x, y + 2, w, h - 4)
                cr.rectangle(x + 2, y + h - 1, w - 4, 1)
                cr.rectangle(x + 1, y + h - 2, w - 2, 1)
                
                cr.clip()
            
            skin_config.render_background(cr, self, x, y)
        
            # Draw mask.
            self.draw_mask(cr, x, y, w, h)
            
        # Draw window frame.
        if self.window.get_state() != gtk.gdk.WINDOW_STATE_MAXIMIZED:
            draw_window_frame(cr, x, y, w, h,
                              ui_theme.get_alpha_color("window_frame_outside_1"),
                              ui_theme.get_alpha_color("window_frame_outside_2"),
                              ui_theme.get_alpha_color("window_frame_outside_3"),
                              ui_theme.get_alpha_color("window_frame_inside_1"),
                              ui_theme.get_alpha_color("window_frame_inside_2"),
                              )
        
        # Propagate expose.
        propagate_expose(widget, event)
        
        return True
Esempio n. 24
0
def draw_hlinear(cr, x, y, w, h, color_infos, radius=0, left_to_right=True):
    '''Draw linear rectangle.'''
    with cairo_state(cr):
        # Translate x coordinate, otherwise x is too big for LinearGradient cause render bug.
        cr.translate(x, 0)
        
        if left_to_right:
            pat = cairo.LinearGradient(0, 0, w, 0)
        else:
            pat = cairo.LinearGradient(w, 0, 0, 0)
        for (pos, color_info) in color_infos:
            add_color_stop_rgba(pat, pos, color_info)
        cr.set_operator(cairo.OPERATOR_OVER)
        cr.set_source(pat)
        draw_round_rectangle(cr, 0, y, w, h, radius)
        cr.fill()
Esempio n. 25
0
    def expose_window(self, widget, event):
        '''
        Internal function to expose the window.

        @param widget: A window of type Gtk.Widget.
        @param event: The expose event of type gtk.gdk.Event.

        @return: Always return True.
        '''
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation
        x, y, w, h = rect.x, rect.y, rect.width, rect.height

        # Draw background.
        self.draw_background(cr, rect.x, rect.y, rect.width, rect.height)

        # Draw skin and mask.
        with cairo_state(cr):
            if self.window.get_state() & gtk.gdk.WINDOW_STATE_MAXIMIZED != gtk.gdk.WINDOW_STATE_MAXIMIZED:
                cr.rectangle(x + 2, y, w - 4, 1)
                cr.rectangle(x + 1, y + 1, w - 2, 1)
                cr.rectangle(x, y + 2, w, h - 4)
                cr.rectangle(x + 2, y + h - 1, w - 4, 1)
                cr.rectangle(x + 1, y + h - 2, w - 2, 1)

                cr.clip()

            self.draw_skin(cr, x, y, w, h)

            # Draw mask.
            self.draw_mask(cr, x, y, w, h)

        # Draw window frame.
        if self.window.get_state() & gtk.gdk.WINDOW_STATE_MAXIMIZED != gtk.gdk.WINDOW_STATE_MAXIMIZED:
            draw_window_frame(cr, x, y, w, h,
                              ui_theme.get_alpha_color("window_frame_outside_1"),
                              ui_theme.get_alpha_color("window_frame_outside_2"),
                              ui_theme.get_alpha_color("window_frame_outside_3"),
                              ui_theme.get_alpha_color("window_frame_inside_1"),
                              ui_theme.get_alpha_color("window_frame_inside_2"),
                              )

        # Propagate expose.
        propagate_expose(widget, event)

        return True
Esempio n. 26
0
 def expose_dragable_tabbar(self, widget, event):
     '''
     docs
     '''
     # Init.
     cr = widget.window.cairo_create()
     rect = widget.allocation
     x, w, h = rect.x, rect.width, rect.height
     y = 0
     
     # Draw background.
     (offset_x, offset_y) = widget.translate_coordinates(self.get_toplevel(), 0, 0)
     with cairo_state(cr):
         cr.translate(-offset_x, -offset_y)
         
         (shadow_x, shadow_y) = get_window_shadow_size(self.get_toplevel())
         skin_config.render_background(cr, widget, shadow_x, shadow_y)
     
     # Draw inactive tab.
     draw_x_list = []
     width_offset = 0
     for (index, tab_name) in enumerate(self.names):
         draw_x_list.append(x + width_offset)
         width_offset += (self.name_widths[index] - (self.triangle_width + self.tab_radious * 2))
         
     for (index, tab_name) in enumerate(reversed(self.names)):
         tab_index = len(self.names) - index - 1
         if tab_index != self.active_index:
             self.draw_tab(cr, draw_x_list[tab_index], y, tab_name, tab_index)
             
     # Draw active tab.
     self.draw_tab(cr, draw_x_list[self.active_index], y, self.names[self.active_index], self.active_index)        
     
     # Draw bottom line.
     frame_color = alpha_color_hex_to_cairo(ui_theme.get_alpha_color("dragable_tab_bottom_active_frame").get_color_info())        
     cr.set_source_rgba(*frame_color)
     cr.rectangle(x, 
                  y + h - 1, 
                  draw_x_list[self.active_index],
                  1)
     cr.rectangle(x + draw_x_list[self.active_index] + self.name_widths[self.active_index], 
                  y + h - 1,
                  w - draw_x_list[self.active_index] - self.name_widths[self.active_index],
                  1)
     cr.fill()
     
     return True
Esempio n. 27
0
    def redraw_bg(self, widget, event):
        '''
        Internal callback function to "expose-event" signal.

        @param widget: gtk.EventBox
        @param event: event of type gtk.gdk.event
        '''
        cr = widget.window.cairo_create()
        rect = widget.allocation

        # Draw backgroud.
        with cairo_state(cr):
            cr.set_source_rgba(*alpha_color_hex_to_cairo(("#def5ff", 1)))
            cr.rectangle(rect.x, rect.y, rect.width, rect.height)
            cr.fill()

        return False
Esempio n. 28
0
    def redraw_bg(self, widget, event):
        '''
        Internal callback function to "expose-event" signal.

        @param widget: gtk.EventBox
        @param event: event of type gtk.gdk.event
        '''
        cr = widget.window.cairo_create()
        rect = widget.allocation

        # Draw backgroud.
        with cairo_state(cr):
            cr.set_source_rgba(*alpha_color_hex_to_cairo(("#def5ff", 1)))
            cr.rectangle(rect.x, rect.y, rect.width, rect.height)
            cr.fill()

        return False
Esempio n. 29
0
def draw_scrolled_window_mask(widget, x, y, w, h, render_callback):
    '''Draw window skin mask.'''
    # Init.
    cr = widget.window.cairo_create()
    toplevel = widget.get_toplevel()
    (offset_x, offset_y) = widget.translate_coordinates(toplevel, 0, 0)

    with cairo_state(cr):
        cr.rectangle(x, y, w, h)
        cr.clip()
        
        render_callback(
            cr, 
            x - offset_x, 
            y - offset_y,
            toplevel.allocation.width,
            toplevel.allocation.height)
Esempio n. 30
0
 def draw_background(self, widget, cr):
     with cairo_state(cr):
         scrolled_window = get_match_parent(self, ["ScrolledWindow"])
         (shadow_x, shadow_y) = get_window_shadow_size(self.get_toplevel())
         (offset_x, offset_y) = self.translate_coordinates(self.get_toplevel(), 0, 0)
         vadjust = scrolled_window.get_vadjustment()    
         vadjust_value = int(vadjust.get_value())
         hadjust = scrolled_window.get_hadjustment()    
         hadjust_value = int(hadjust.get_value())
         
         x = shadow_x - offset_x
         y = shadow_y - offset_y
         
         cr.rectangle(hadjust_value, vadjust_value, scrolled_window.allocation.width, scrolled_window.allocation.height)
         cr.clip()
         cr.translate(x, y)
         skin_config.render_background(cr, widget, 0, 0)
Esempio n. 31
0
def draw_list_view_mask(widget, x, y, w, h, render_callback):
    '''Draw skin preview view mask.'''
    cr = widget.window.cairo_create()
    viewport = get_match_parent(widget, ["Viewport"])
    toplevel = widget.get_toplevel()
    (offset_x, offset_y) = viewport.translate_coordinates(toplevel, 0, 0)
    (shadow_x, shadow_y) = get_window_shadow_size(toplevel)
    
    with cairo_state(cr):
        cr.rectangle(x, y, w, h)
        cr.clip()
        
        render_callback(
            cr, 
            x - offset_x + shadow_x, 
            y - offset_y + shadow_y,
            toplevel.allocation.width,
            toplevel.allocation.height)
Esempio n. 32
0
    def draw_background(self, widget, cr):
        with cairo_state(cr):
            scrolled_window = get_match_parent(self, ["ScrolledWindow"])
            (shadow_x, shadow_y) = get_window_shadow_size(self.get_toplevel())
            (offset_x,
             offset_y) = self.translate_coordinates(self.get_toplevel(), 0, 0)
            vadjust = scrolled_window.get_vadjustment()
            vadjust_value = int(vadjust.get_value())
            hadjust = scrolled_window.get_hadjustment()
            hadjust_value = int(hadjust.get_value())

            x = shadow_x - offset_x
            y = shadow_y - offset_y

            cr.rectangle(hadjust_value, vadjust_value,
                         scrolled_window.allocation.width,
                         scrolled_window.allocation.height)
            cr.clip()
            cr.translate(x, y)
            skin_config.render_background(cr, widget, 0, 0)
Esempio n. 33
0
def draw_radial_ring(cr, x, y, outer_radius, inner_radius, color_infos):
    '''
    Draw radial ring.
    
    @param cr: Cairo context.
    @param x: X coordinate of draw area.
    @param y: Y coordinate of draw area.
    @param outer_radius: Radious for outter ring.
    @param inner_radius: Radious for inner ring.
    @param color_infos: A list of ColorInfo, ColorInfo format as [(color_pos, (color_hex_value, color_alpha))].
    '''
    with cairo_state(cr):
        # Clip.
        cr.arc(x, y, outer_radius, 0, pi * 2)
        cr.arc(x, y, inner_radius, 0, pi * 2)
        cr.set_fill_rule(cairo.FILL_RULE_EVEN_ODD)
        cr.clip()
        
        # Draw radial round.
        draw_radial_round(cr, x, y, outer_radius, color_infos)
Esempio n. 34
0
 def expose_progressbar(self, widget, event):
     '''Expose progressbar.'''
     # Init.
     cr = widget.window.cairo_create()
     rect = widget.allocation
     
     # Draw frame.
     cr.set_source_rgba(*alpha_color_hex_to_cairo(ui_theme.get_alpha_color("progressbar_frame").get_color_info()))
     cr.set_operator(cairo.OPERATOR_OVER)
     draw_round_rectangle(cr, rect.x, rect.y, rect.width, rect.height, 1)
     cr.stroke()
     
     # Draw background.
     draw_vlinear(cr, rect.x, rect.y, rect.width, rect.height, 
                  ui_theme.get_shadow_color("progressbar_background").get_color_info(), 
                  1)
 
     # Draw foreground.
     draw_vlinear(cr, rect.x, rect.y, rect.width * self.progress / 100.0, rect.height, 
                  ui_theme.get_shadow_color("progressbar_foreground").get_color_info(), 
                  1)
     
     # Draw font.
     draw_text(cr, str(self.progress) + "%", 
               rect.x, rect.y, rect.width, rect.height, 
               rect.height - 5, "#000000",
               alignment=pango.ALIGN_CENTER)
     
     # Draw light.
     light_radius = rect.height * 4
     light_offset_x = min(self.light_ticker % 150, 100) / 100.0 * (rect.width + light_radius * 2)
     with cairo_state(cr):
         cr.rectangle(rect.x, rect.y, rect.width * self.progress / 100.0, rect.height)
         cr.clip()
         draw_radial_round(cr, rect.x + light_offset_x - light_radius, rect.y - light_radius / 2, light_radius, 
                           ui_theme.get_shadow_color("progressbar_light").get_color_info())
            
     # Propagate expose.
     propagate_expose(widget, event)
     
     return True        
Esempio n. 35
0
def draw_window_mask(widget, x, y, w, h, render_callback):
    '''
    Draw window mask with given render method.

    @param widget: Target widget.
    @param x: X coordinate of draw area.
    @param y: Y coordinate of draw area.
    @param w: Width of draw area.
    @param h: Height of draw area.
    @param render_callback: Render callback.
    '''
    # Init.
    cr = widget.window.cairo_create()

    with cairo_state(cr):
        cr.rectangle(x + 1, y, w - 2, 1)
        cr.rectangle(x, y + 1, w, h - 2)
        cr.rectangle(x + 1, y + h - 1, w - 2, 1)
        cr.clip()

        render_callback(cr, x, y, w, h)
Esempio n. 36
0
def draw_window_mask(widget, x, y, w, h, render_callback):
    """
    Draw window mask with given render method.
    
    @param widget: Target widget.
    @param x: X coordinate of draw area.
    @param y: Y coordinate of draw area.
    @param w: Width of draw area.
    @param h: Height of draw area.
    @param render_callback: Render callback.
    """
    # Init.
    cr = widget.window.cairo_create()

    with cairo_state(cr):
        cr.rectangle(x + 1, y, w - 2, 1)
        cr.rectangle(x, y + 1, w, h - 2)
        cr.rectangle(x + 1, y + h - 1, w - 2, 1)
        cr.clip()

        render_callback(cr, x, y, w, h)
Esempio n. 37
0
def draw_radial_ring(cr,
                     x,
                     y,
                     outer_radius,
                     inner_radius,
                     color_infos,
                     clip_corner=None):
    '''
    Draw radial ring.

    @param cr: Cairo context.
    @param x: X coordinate of draw area.
    @param y: Y coordinate of draw area.
    @param outer_radius: Radious for outter ring.
    @param inner_radius: Radious for inner ring.
    @param color_infos: A list of ColorInfo, ColorInfo format as [(color_pos, (color_hex_value, color_alpha))].
    '''
    with cairo_state(cr):
        # Clip corner.
        if clip_corner:
            if clip_corner == "top-left":
                cr.rectangle(x - outer_radius, y - outer_radius, outer_radius,
                             outer_radius)
            elif clip_corner == "top-right":
                cr.rectangle(x, y - outer_radius, outer_radius, outer_radius)
            elif clip_corner == "bottom-left":
                cr.rectangle(x - outer_radius, y, outer_radius, outer_radius)
            elif clip_corner == "bottom-right":
                cr.rectangle(x, y, outer_radius, outer_radius)

            cr.clip()

        # Clip.
        cr.arc(x, y, outer_radius, 0, pi * 2)
        cr.arc(x, y, inner_radius, 0, pi * 2)
        cr.set_fill_rule(cairo.FILL_RULE_EVEN_ODD)
        cr.clip()

        # Draw radial round.
        draw_radial_round(cr, x, y, outer_radius, color_infos)
Esempio n. 38
0
 def expose_window(self, widget, event):
     '''Expose window.'''
     # Init.
     cr = widget.window.cairo_create()
     rect = widget.allocation
     x, y, w, h = rect.x, rect.y, rect.width, rect.height
     
     # Clear color to transparent window.
     cr.set_source_rgba(0.0, 0.0, 0.0, 0.0)
     cr.set_operator(cairo.OPERATOR_SOURCE)
     cr.paint()
     
     # Draw background.
     with cairo_state(cr):
         cr.rectangle(x + 2, y, w - 4, 1)
         cr.rectangle(x + 1, y + 1, w - 2, 1)
         cr.rectangle(x, y + 2, w, h - 4)
         cr.rectangle(x + 2, y + h - 1, w - 4, 1)
         cr.rectangle(x + 1, y + h - 2, w - 2, 1)
         
         cr.clip()
         
         skin_config.render_background(cr, self, x, y)
     
         # Draw mask.
         self.draw_mask(cr, x, y, w, h)
         
     # Draw window frame.
     draw_window_frame(cr, x, y, w, h,
                       ui_theme.get_alpha_color("window_frame_outside_1"),
                       ui_theme.get_alpha_color("window_frame_outside_2"),
                       ui_theme.get_alpha_color("window_frame_outside_3"),
                       ui_theme.get_alpha_color("window_frame_inside_1"),
                       ui_theme.get_alpha_color("window_frame_inside_2"),
                       )
     
     # Propagate expose.
     propagate_expose(widget, event)
     
     return True
Esempio n. 39
0
    def render(self, cr, rect):
        # Draw label content.
        with cairo_state(cr):
            if self.is_expandable:
                content_height = int(rect.height - self.label_expand_height) / self.label_line_height * self.label_line_height
                cr.rectangle(rect.x, rect.y, rect.width, content_height)
            else:
                content_height = rect.height
                cr.rectangle(rect.x, rect.y, rect.width, content_height)
            cr.clip()

            draw_text(
                cr,
                self.label_content,
                rect.x + (rect.width - self.label_wrap_width) / 2,
                rect.y,
                rect.width,
                content_height,
                text_size=self.label_font_size,
                text_color=self.label_font_color,
                wrap_width=self.label_wrap_width
                )

        # Draw expand button.
        if self.is_expandable:
            if self.has_expand:
                text = self.shrink_button_content
                text_width, text_height = self.shrink_button_width, self.shrink_button_height
            else:
                text = self.expand_button_content
                text_width, text_height = self.expand_button_width, self.expand_button_height
            draw_text(
                cr,
                text,
                rect.x + rect.width - (rect.width - self.label_wrap_width) / 2 - text_width,
                rect.y + rect.height - text_height,
                text_width,
                text_height,
                )
Esempio n. 40
0
def draw_scrolled_window_mask(widget, x, y, w, h, render_callback):
    '''
    Draw scrolled window mask with given render method.

    @param widget: Target widget.
    @param x: X coordinate of draw area.
    @param y: Y coordinate of draw area.
    @param w: Width of draw area.
    @param h: Height of draw area.
    @param render_callback: Render callback.
    '''
    # Init.
    cr = widget.window.cairo_create()
    toplevel = widget.get_toplevel()
    (offset_x, offset_y) = widget.translate_coordinates(toplevel, 0, 0)

    with cairo_state(cr):
        cr.rectangle(x, y, w, h)
        cr.clip()

        render_callback(cr, x - offset_x, y - offset_y,
                        toplevel.allocation.width, toplevel.allocation.height)
Esempio n. 41
0
 def render(self, cr, rect):
     # Draw label content.
     with cairo_state(cr):
         if self.is_expandable:
             content_height = int(rect.height - self.label_expand_height) / self.label_line_height * self.label_line_height
             cr.rectangle(rect.x, rect.y, rect.width, content_height)
         else:
             content_height = rect.height
             cr.rectangle(rect.x, rect.y, rect.width, content_height)
         cr.clip()
         
         draw_text(
             cr,
             self.label_content,
             rect.x + (rect.width - self.label_wrap_width) / 2,
             rect.y,
             rect.width,
             content_height,
             text_size=self.label_font_size,
             text_color=self.label_font_color,
             wrap_width=self.label_wrap_width
             )
         
     # Draw expand button.
     if self.is_expandable:
         if self.has_expand:
             text = self.shrink_button_content
             text_width, text_height = self.shrink_button_width, self.shrink_button_height
         else:
             text = self.expand_button_content
             text_width, text_height = self.expand_button_width, self.expand_button_height
         draw_text(
             cr,
             text,
             rect.x + rect.width - (rect.width - self.label_wrap_width) / 2 - text_width,
             rect.y + rect.height - text_height,
             text_width,
             text_height,
             )
Esempio n. 42
0
def draw_icon_view_mask(widget, x, y, w, h, render_callback):
    '''
    Draw icon view mask with given render method.

    @param widget: Target widget.
    @param x: X coordinate of draw area.
    @param y: Y coordinate of draw area.
    @param w: Width of draw area.
    @param h: Height of draw area.
    @param render_callback: Render callback.
    '''
    cr = widget.window.cairo_create()
    viewport = get_match_parent(widget, ["Viewport"])
    toplevel = widget.get_toplevel()
    (offset_x, offset_y) = viewport.translate_coordinates(toplevel, 0, 0)
    (shadow_x, shadow_y) = get_window_shadow_size(toplevel)

    with cairo_state(cr):
        cr.rectangle(x, y, w, h)
        cr.clip()

        render_callback(cr, x - offset_x + shadow_x, y - offset_y + shadow_y,
                        toplevel.allocation.width, toplevel.allocation.height)
Esempio n. 43
0
    def expose_window_background(self, widget, event):
        '''
        Internal function to expose the window background.

        @param widget: A window of type Gtk.Widget.
        @param event: The expose event of type gtk.gdk.Event.
        @return: Always return True.
        '''
        if self.expose_background_function:
            self.expose_background_function(widget, event)
        else:
            # Init.
            cr = widget.window.cairo_create()
            rect = widget.allocation

            # Draw background.
            self.draw_background(cr, rect.x, rect.y, rect.width, rect.height)

            # Save cairo context.
            if self.shadow_is_visible:
                x = rect.x + self.shadow_padding
                y = rect.y + self.shadow_padding
                w = rect.width - self.shadow_padding * 2
                h = rect.height - self.shadow_padding * 2
            else:
                x, y, w, h = rect.x, rect.y, rect.width, rect.height

            # Draw skin and mask.
            with cairo_state(cr):
                if self.window.get_state(
                ) & gtk.gdk.WINDOW_STATE_MAXIMIZED != gtk.gdk.WINDOW_STATE_MAXIMIZED:
                    cr.rectangle(x + 2, y, w - 4, 1)
                    cr.rectangle(x + 1, y + 1, w - 2, 1)
                    cr.rectangle(x, y + 2, w, h - 4)
                    cr.rectangle(x + 2, y + h - 1, w - 4, 1)
                    cr.rectangle(x + 1, y + h - 2, w - 2, 1)

                    cr.clip()

                # Draw background.
                self.draw_skin(cr, x, y, w, h)

                # Draw mask.
                self.draw_mask(cr, x, y, w, h)

            # Draw corner shadow.
            with cairo_state(cr):
                cr.set_source_rgba(*alpha_color_hex_to_cairo(
                    ui_theme.get_alpha_color(
                        "window_shadow_corner").get_color_info()))

                cr.rectangle(x, y + 1, 1, 1)  # top-left
                cr.rectangle(x + 1, y, 1, 1)

                cr.rectangle(x + w - 1, y + 1, 1, 1)  # top-right
                cr.rectangle(x + w - 2, y, 1, 1)

                cr.rectangle(x, y + h - 2, 1, 1)  # bottom-left
                cr.rectangle(x + 1, y + h - 1, 1, 1)

                cr.rectangle(x + w - 1, y + h - 2, 1, 1)  # bottom-right
                cr.rectangle(x + w - 2, y + h - 1, 1, 1)

                cr.fill()

            # Draw background corner.
            with cairo_state(cr):
                cr.rectangle(x, y + 1, 1, 1)  # top-left
                cr.rectangle(x + 1, y, 1, 1)

                cr.rectangle(x + w - 1, y + 1, 1, 1)  # top-right
                cr.rectangle(x + w - 2, y, 1, 1)

                cr.rectangle(x, y + h - 2, 1, 1)  # bottom-left
                cr.rectangle(x + 1, y + h - 1, 1, 1)

                cr.rectangle(x + w - 1, y + h - 2, 1, 1)  # bottom-right
                cr.rectangle(x + w - 2, y + h - 1, 1, 1)

                cr.clip()

                self.draw_skin(cr, x, y, w, h)

            # Propagate expose.
            propagate_expose(widget, event)

        return True
Esempio n. 44
0
    def expose_tab_title_box(self, widget, event):
        '''
        Internal callback for `expose-event` signal.
        '''
        cr = widget.window.cairo_create()
        rect = widget.allocation
        if self.dockfill:
            self.update_tab_title_widths(rect.width)

        # Draw background.
        self.draw_title_background(cr, widget)
            
        if len(self.tab_items) > 0:    
            # Draw title unselect tab.
            tab_title_width = sum(self.tab_title_widths)
            
            with cairo_state(cr):
                with cairo_disable_antialias(cr):
                    cr.set_source_rgba(*alpha_color_hex_to_cairo((self.tab_unselect_bg_color.get_color(), 0.7)))
                    cr.rectangle(1, 1, tab_title_width, self.tab_height)
                    cr.fill()
                        
                    cr.set_line_width(1)
                    cr.set_source_rgba(*alpha_color_hex_to_cairo((self.tab_unselect_frame_color.get_color(), 1.0)))
                    cr.rectangle(1, 1, tab_title_width, self.tab_height)
                    cr.stroke()
                    
                    for (index, width) in enumerate(self.tab_title_widths[:-1]):
                        cr.set_source_rgba(*alpha_color_hex_to_cairo((self.tab_unselect_frame_color.get_color(), 1.0)))
                        cr.rectangle(1 + sum(self.tab_title_widths[0:index]) + width,
                                     1,
                                     1,
                                     self.tab_height)
                        cr.fill()
                        
                    cr.set_source_rgb(*color_hex_to_cairo(self.tab_select_frame_color.get_color()))    
                    cr.rectangle(0,
                                 rect.height - 1,
                                 sum(self.tab_title_widths[0:self.tab_index]),
                                 1)
                    cr.fill()
                
                    cr.set_source_rgb(*color_hex_to_cairo(self.tab_select_frame_color.get_color()))    
                    cr.rectangle(1 + sum(self.tab_title_widths[0:self.tab_index]),
                                 rect.height - 1,
                                 rect.width - sum(self.tab_title_widths[0:self.tab_index]),
                                 1)
                    cr.fill()
                            
            for (index, item) in enumerate(self.tab_items):
                # Draw title background.
                title = item[0]
                
                # Draw title tab.
                with cairo_disable_antialias(cr):
                    if index == self.tab_index:
                        # Draw title select tab.
                        cr.set_source_rgba(*alpha_color_hex_to_cairo((self.tab_select_bg_color.get_color(), 0.93)))    
                        if index == 0:
                            cr.rectangle(sum(self.tab_title_widths[0:index]),
                                         1,
                                         self.tab_title_widths[index] + 1,
                                         self.tab_height)
                        else:
                            cr.rectangle(1 + sum(self.tab_title_widths[0:index]),
                                         1,
                                         self.tab_title_widths[index],
                                         self.tab_height)
                        cr.fill()
                        
                        if index == 0:
                            cr.rectangle(0,
                                         0,
                                         rect.width,
                                         self.tab_height)
                            cr.clip()
                            
                        cr.set_line_width(1)
                        cr.set_source_rgb(*color_hex_to_cairo(self.tab_select_frame_color.get_color()))    
                        if index == 0:
                            cr.rectangle(sum(self.tab_title_widths[0:index]),
                                         1,
                                         self.tab_title_widths[index] + 2,
                                         self.tab_height)
                        else:
                            cr.rectangle(1 + sum(self.tab_title_widths[0:index]),
                                         1,
                                         self.tab_title_widths[index] + 1,
                                         self.tab_height)
                        cr.stroke()
                        
                draw_text(cr, title, 
                          sum(self.tab_title_widths[0:index]) + self.tab_padding_x,
                          self.tab_padding_y,
                          self.tab_title_widths[index] - self.tab_padding_x * 2,
                          self.tab_height - self.tab_padding_y * 2,
                          )
                
                # Draw close button.
                if self.can_close_tab:
                    button_x = sum(self.tab_title_widths[0:index + 1]) - self.close_button_padding_x - self.close_button_size
                    button_y = self.close_button_padding_y
                    
                    if self.hover_close_button_index == index:
                        cr.set_source_rgb(*color_hex_to_cairo(self.close_button_select_background_color))
                        draw_round_rectangle(
                            cr,
                            button_x - self.close_button_frame_size,
                            button_y - self.close_button_frame_size,
                            self.close_button_size + self.close_button_frame_size * 2,
                            self.close_button_size + self.close_button_frame_size * 2,
                            2
                            )
                        cr.fill()
                    
                    cr.set_line_width(1.5)
                    if self.hover_close_button_index == index:
                        cr.set_source_rgb(*color_hex_to_cairo(self.close_button_select_foreground_color))
                    else:
                        cr.set_source_rgb(*color_hex_to_cairo(self.close_button_color))
                    cr.move_to(button_x, button_y)
                    cr.line_to(button_x + self.close_button_size, button_y + self.close_button_size)
                    cr.stroke()

                    cr.move_to(button_x + self.close_button_size, button_y)
                    cr.line_to(button_x, button_y + self.close_button_size)
                    cr.stroke()
        else:
            cr.set_source_rgba(*alpha_color_hex_to_cairo((self.tab_select_bg_color.get_color(), 0.93)))
            cr.rectangle(0, 0, rect.width, rect.height)
            cr.fill()
Esempio n. 45
0
def render_text(
    cr,
    markup,
    x,
    y,
    w,
    h,
    text_size=DEFAULT_FONT_SIZE,
    text_color="#000000",
    text_font=DEFAULT_FONT,
    alignment=pango.ALIGN_LEFT,
    wrap_width=None,
    underline=False,
    vertical_alignment=TEXT_ALIGN_MIDDLE,
    clip_line_count=None,
    ellipsize=pango.ELLIPSIZE_END,
):
    '''
    Render text for function L{ I{draw_text} <draw_text>}, you can use this function individually.

    @param cr: Cairo context.
    @param markup: Pango markup string.
    @param x: X coordinate of draw area.
    @param y: Y coordinate of draw area.
    @param w: Width of draw area.
    @param h: Height of draw area.
    @param text_size: Text size, default is DEFAULT_FONT_SIZE.
    @param text_color: Text color, default is \"#000000\".
    @param text_font: Text font, default is DEFAULT_FONT.
    @param alignment: Font alignment option, default is pango.ALIGN_LEFT. You can set pango.ALIGN_MIDDLE or pango.ALIGN_RIGHT.
    @param wrap_width: Wrap width of text, default is None.
    @param underline: Whether draw underline for text, default is False.
    @param vertical_alignment: Vertical alignment value, default is TEXT_ALIGN_MIDDLE, can use below value:
     - TEXT_ALIGN_TOP
     - TEXT_ALIGN_MIDDLE
     - TEXT_ALIGN_BOTTOM
    @param clip_line_count: The line number to clip text area, if set 2, all lines that above 2 will clip out, default is None.
    @param ellipsize: Ellipsize style of text when text width longer than draw area, it can use below value:
     - pango.ELLIPSIZE_START
     - pango.ELLIPSIZE_CENTER
     - pango.ELLIPSIZE_END
    '''
    with cairo_state(cr):
        # Set color.
        cr.set_source_rgb(*color_hex_to_cairo(text_color))

        # Create pangocairo context.
        context = pangocairo.CairoContext(cr)

        # Set layout.
        layout = context.create_layout()
        layout.set_font_description(
            pango.FontDescription("%s %s" % (text_font, text_size)))
        layout.set_markup(markup)
        layout.set_alignment(alignment)
        if wrap_width == None:
            layout.set_single_paragraph_mode(True)
            layout.set_width(w * pango.SCALE)
            layout.set_ellipsize(ellipsize)
        else:
            layout.set_width(wrap_width * pango.SCALE)
            layout.set_wrap(pango.WRAP_WORD)

        (text_width, text_height) = layout.get_pixel_size()

        if underline:
            if alignment == pango.ALIGN_LEFT:
                cr.rectangle(x, y + text_height + (h - text_height) / 2,
                             text_width, 1)
            elif alignment == pango.ALIGN_CENTER:
                cr.rectangle(x + (w - text_width) / 2,
                             y + text_height + (h - text_height) / 2,
                             text_width, 1)
            else:
                cr.rectangle(x + w - text_width,
                             y + text_height + (h - text_height) / 2,
                             text_width, 1)
            cr.fill()

        # Set render y coordinate.
        if vertical_alignment == TEXT_ALIGN_TOP:
            render_y = y
        elif vertical_alignment == TEXT_ALIGN_MIDDLE:
            render_y = y + max(0, (h - text_height) / 2)
        else:
            render_y = y + max(0, h - text_height)

        # Clip area.
        if clip_line_count:
            line_count = layout.get_line_count()
            if line_count > 0:
                line_height = text_height / line_count
                cr.rectangle(x, render_y, text_width,
                             line_height * clip_line_count)
                cr.clip()

        # Draw text.
        cr.move_to(x, render_y)
        context.update_layout(layout)
        context.show_layout(layout)
Esempio n. 46
0
    def expose_icon_view(self, widget, event):
        '''
        Internal callback for `expose-event` signal.
        '''
        # Update vadjustment.
        self.update_vadjustment()

        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation

        # Get offset.
        (offset_x, offset_y, viewport) = self.get_offset_coordinate(widget)

        # Draw background on widget cairo.
        self.draw_background(widget, cr)

        # Draw mask on widget cairo.
        scrolled_window = get_match_parent(self, ["ScrolledWindow"])
        vadjust = scrolled_window.get_vadjustment()
        vadjust_value = int(vadjust.get_value())
        hadjust = scrolled_window.get_hadjustment()
        hadjust_value = int(hadjust.get_value())
        self.draw_mask(cr, hadjust_value, vadjust_value,
                       viewport.allocation.width, viewport.allocation.height)

        # We need clear render surface every time.
        with cairo_state(self.render_surface_cr):
            self.render_surface_cr.set_operator(cairo.OPERATOR_CLEAR)
            self.render_surface_cr.paint()

        if self.is_loading:
            load_text = _("Loading...")
            load_width, load_height = get_content_size(load_text)
            draw_text(cr, load_text, rect.x + (rect.width - load_width) / 2,
                      rect.y + rect.height - load_height, rect.width,
                      load_height)

        # Draw items on surface cairo.
        self.draw_items(self.render_surface_cr, rect)

        # Draw bound mask.
        scrolled_window = get_match_parent(self, ["ScrolledWindow"])
        width = scrolled_window.allocation.width
        height = scrolled_window.allocation.height
        vadjust_value = int(scrolled_window.get_vadjustment().get_value())
        vadjust_upper = int(scrolled_window.get_vadjustment().get_upper())
        vadjust_page_size = int(
            scrolled_window.get_vadjustment().get_page_size())
        hadjust_value = int(scrolled_window.get_hadjustment().get_value())

        if vadjust_value == 0:
            with cairo_state(cr):
                cr.rectangle(hadjust_value, vadjust_value, width,
                             self.mask_bound_height)
                cr.clip()
                cr.set_source_surface(self.render_surface, hadjust_value,
                                      vadjust_value)
                cr.paint()
        elif self.mask_bound_height > 0:
            i = 0
            while (i <= self.mask_bound_height):
                with cairo_state(cr):
                    cr.rectangle(hadjust_value, vadjust_value + i, width, 1)
                    cr.clip()

                    cr.set_source_surface(self.render_surface, hadjust_value,
                                          vadjust_value)
                    cr.paint_with_alpha(
                        math.sin(i * math.pi / 2 / self.mask_bound_height))

                i += 1

        with cairo_state(cr):
            cr.rectangle(hadjust_value, vadjust_value + self.mask_bound_height,
                         width, height - self.mask_bound_height * 2)
            cr.clip()
            cr.set_source_surface(self.render_surface, hadjust_value,
                                  vadjust_value)
            cr.paint()

        if vadjust_value + vadjust_page_size == vadjust_upper:
            with cairo_state(cr):
                cr.rectangle(hadjust_value,
                             vadjust_value + height - self.mask_bound_height,
                             width, self.mask_bound_height)
                cr.clip()
                cr.set_source_surface(self.render_surface, hadjust_value,
                                      vadjust_value)
                cr.paint()
        elif self.mask_bound_height > 0:
            i = 0
            while (i < self.mask_bound_height):
                with cairo_state(cr):
                    cr.rectangle(
                        hadjust_value,
                        vadjust_value + height - self.mask_bound_height + i,
                        width, 1)
                    cr.clip()
                    cr.set_source_surface(self.render_surface, hadjust_value,
                                          vadjust_value)
                    cr.paint_with_alpha(1.0 -
                                        (math.sin(i * math.pi / 2 /
                                                  self.mask_bound_height)))

                i += 1

        return False
Esempio n. 47
0
    def expose_tab_title_box(self, widget, event):
        '''
        Internal callback for `expose-event` signal.
        '''
        cr = widget.window.cairo_create()
        rect = widget.allocation
        if self.dockfill:
            self.update_tab_title_widths(rect.width)

        # Draw background.
        self.draw_title_background(cr, widget)

        if len(self.tab_items) > 0:
            # Draw title unselect tab.
            tab_title_width = sum(self.tab_title_widths)

            with cairo_state(cr):
                with cairo_disable_antialias(cr):
                    cr.set_source_rgba(*alpha_color_hex_to_cairo((
                        self.tab_unselect_bg_color.get_color(), 0.7)))
                    cr.rectangle(1, 1, tab_title_width, self.tab_height)
                    cr.fill()

                    cr.set_line_width(1)
                    cr.set_source_rgba(*alpha_color_hex_to_cairo((
                        self.tab_unselect_frame_color.get_color(), 1.0)))
                    cr.rectangle(1, 1, tab_title_width, self.tab_height)
                    cr.stroke()

                    for (index,
                         width) in enumerate(self.tab_title_widths[:-1]):
                        cr.set_source_rgba(*alpha_color_hex_to_cairo((
                            self.tab_unselect_frame_color.get_color(), 1.0)))
                        cr.rectangle(
                            1 + sum(self.tab_title_widths[0:index]) + width, 1,
                            1, self.tab_height)
                        cr.fill()

                    cr.set_source_rgb(*color_hex_to_cairo(
                        self.tab_select_frame_color.get_color()))
                    cr.rectangle(0, rect.height - 1,
                                 sum(self.tab_title_widths[0:self.tab_index]),
                                 1)
                    cr.fill()

                    cr.set_source_rgb(*color_hex_to_cairo(
                        self.tab_select_frame_color.get_color()))
                    cr.rectangle(
                        1 + sum(self.tab_title_widths[0:self.tab_index]),
                        rect.height - 1, rect.width -
                        sum(self.tab_title_widths[0:self.tab_index]), 1)
                    cr.fill()

            for (index, item) in enumerate(self.tab_items):
                # Draw title background.
                title = item[0]

                # Draw title tab.
                with cairo_disable_antialias(cr):
                    if index == self.tab_index:
                        # Draw title select tab.
                        cr.set_source_rgba(*alpha_color_hex_to_cairo((
                            self.tab_select_bg_color.get_color(), 0.93)))
                        if index == 0:
                            cr.rectangle(sum(self.tab_title_widths[0:index]),
                                         1, self.tab_title_widths[index] + 1,
                                         self.tab_height)
                        else:
                            cr.rectangle(
                                1 + sum(self.tab_title_widths[0:index]), 1,
                                self.tab_title_widths[index], self.tab_height)
                        cr.fill()

                        if index == 0:
                            cr.rectangle(0, 0, rect.width, self.tab_height)
                            cr.clip()

                        cr.set_line_width(1)
                        cr.set_source_rgb(*color_hex_to_cairo(
                            self.tab_select_frame_color.get_color()))
                        if index == 0:
                            cr.rectangle(sum(self.tab_title_widths[0:index]),
                                         1, self.tab_title_widths[index] + 2,
                                         self.tab_height)
                        else:
                            cr.rectangle(
                                1 + sum(self.tab_title_widths[0:index]), 1,
                                self.tab_title_widths[index] + 1,
                                self.tab_height)
                        cr.stroke()

                draw_text(
                    cr,
                    title,
                    sum(self.tab_title_widths[0:index]) + self.tab_padding_x,
                    self.tab_padding_y,
                    self.tab_title_widths[index] - self.tab_padding_x * 2,
                    self.tab_height - self.tab_padding_y * 2,
                )

                # Draw close button.
                if self.can_close_tab:
                    button_x = sum(
                        self.tab_title_widths[0:index + 1]
                    ) - self.close_button_padding_x - self.close_button_size
                    button_y = self.close_button_padding_y

                    if self.hover_close_button_index == index:
                        cr.set_source_rgb(*color_hex_to_cairo(
                            self.close_button_select_background_color))
                        draw_round_rectangle(
                            cr, button_x - self.close_button_frame_size,
                            button_y - self.close_button_frame_size,
                            self.close_button_size +
                            self.close_button_frame_size * 2,
                            self.close_button_size +
                            self.close_button_frame_size * 2, 2)
                        cr.fill()

                    cr.set_line_width(1.5)
                    if self.hover_close_button_index == index:
                        cr.set_source_rgb(*color_hex_to_cairo(
                            self.close_button_select_foreground_color))
                    else:
                        cr.set_source_rgb(
                            *color_hex_to_cairo(self.close_button_color))
                    cr.move_to(button_x, button_y)
                    cr.line_to(button_x + self.close_button_size,
                               button_y + self.close_button_size)
                    cr.stroke()

                    cr.move_to(button_x + self.close_button_size, button_y)
                    cr.line_to(button_x, button_y + self.close_button_size)
                    cr.stroke()
        else:
            cr.set_source_rgba(*alpha_color_hex_to_cairo((
                self.tab_select_bg_color.get_color(), 0.93)))
            cr.rectangle(0, 0, rect.width, rect.height)
            cr.fill()
Esempio n. 48
0
    def render(self, cr, rect):
        # Init.
        x, y, w, h = rect.x, rect.y, rect.width, rect.height

        # Draw background frame.
        with cairo_state(cr):
            cr.rectangle(x, y + 1, w, h - 2)
            cr.rectangle(x + 1, y, w - 2, h)
            cr.clip()

            cr.set_source_rgb(*color_hex_to_cairo(
                ui_theme.get_color(
                    "progressbar_background_frame").get_color()))
            cr.rectangle(x, y, w, h)
            cr.set_line_width(1)
            cr.stroke()

        # Draw background.
        with cairo_state(cr):
            cr.rectangle(x + 1, y + 1, w - 2, h - 2)
            cr.clip()

            draw_vlinear(
                cr,
                x + 1,
                y + 1,
                w - 2,
                h - 2,
                ui_theme.get_shadow_color(
                    "progressbar_background").get_color_info(),
            )

        if self.progress > 0:
            # Draw foreground frame.
            with cairo_state(cr):
                cr.rectangle(x, y + 1, w, h - 2)
                cr.rectangle(x + 1, y, w - 2, h)
                cr.clip()

                cr.set_antialias(cairo.ANTIALIAS_NONE)
                cr.set_source_rgb(*color_hex_to_cairo(
                    ui_theme.get_color(
                        "progressbar_foreground_frame").get_color()))
                cr.rectangle(x + 1, y + 1,
                             int(w * self.progress / 100) - 1, h - 1)
                cr.set_line_width(1)
                cr.stroke()

            # Draw foreground.
            with cairo_state(cr):
                cr.rectangle(x + 1, y + 1, w - 2, h - 2)
                cr.clip()

                draw_vlinear(
                    cr,
                    x + 1,
                    y + 1,
                    int(w * self.progress / 100) - 2,
                    h - 2,
                    ui_theme.get_shadow_color(
                        "progressbar_foreground").get_color_info(),
                )

        # Draw light.
        with cairo_disable_antialias(cr):
            cr.set_source_rgba(1, 1, 1, 0.5)
            cr.rectangle(x + 1, y + 1, w - 2, 1)
            cr.fill()
Esempio n. 49
0
    def expose_window_background(self, widget, event):
        '''
        Internal function to expose the window background.

        @param widget: A window of type Gtk.Widget.
        @param event: The expose event of type gtk.gdk.Event.
        @return: Always return True.
        '''
        if self.expose_background_function:
            self.expose_background_function(widget, event)
        else:
            # Init.
            cr = widget.window.cairo_create()
            rect = widget.allocation
            
            # Draw background.
            self.draw_background(cr, rect.x, rect.y, rect.width, rect.height)
            
            # Save cairo context.
            if self.shadow_is_visible:
                x = rect.x + self.shadow_padding
                y = rect.y + self.shadow_padding
                w = rect.width - self.shadow_padding * 2
                h = rect.height - self.shadow_padding * 2
            else:
                x, y, w, h = rect.x, rect.y, rect.width, rect.height
                
            # Draw skin and mask.
            with cairo_state(cr):
                if self.window.get_state() & gtk.gdk.WINDOW_STATE_MAXIMIZED != gtk.gdk.WINDOW_STATE_MAXIMIZED:
                    cr.rectangle(x + 2, y, w - 4, 1)
                    cr.rectangle(x + 1, y + 1, w - 2, 1)
                    cr.rectangle(x, y + 2, w, h - 4)
                    cr.rectangle(x + 2, y + h - 1, w - 4, 1)
                    cr.rectangle(x + 1, y + h - 2, w - 2, 1)
                    
                    cr.clip()
                
                # Draw background.
                self.draw_skin(cr, x, y, w, h)
            
                # Draw mask.
                self.draw_mask(cr, x, y, w, h)
                
            # Draw corner shadow.
            with cairo_state(cr):
                cr.set_source_rgba(*alpha_color_hex_to_cairo(ui_theme.get_alpha_color("window_shadow_corner").get_color_info()))
                
                cr.rectangle(x, y + 1, 1, 1) # top-left
                cr.rectangle(x + 1, y, 1, 1)
                
                cr.rectangle(x + w - 1, y + 1, 1, 1) # top-right
                cr.rectangle(x + w - 2, y, 1, 1)
                
                cr.rectangle(x, y + h - 2, 1, 1) # bottom-left
                cr.rectangle(x + 1, y + h - 1, 1, 1)
                
                cr.rectangle(x + w - 1, y + h - 2, 1, 1) # bottom-right
                cr.rectangle(x + w - 2, y + h - 1, 1, 1)
                
                cr.fill()
                
            # Draw background corner.
            with cairo_state(cr):
                cr.rectangle(x, y + 1, 1, 1) # top-left
                cr.rectangle(x + 1, y, 1, 1)
                
                cr.rectangle(x + w - 1, y + 1, 1, 1) # top-right
                cr.rectangle(x + w - 2, y, 1, 1)
                
                cr.rectangle(x, y + h - 2, 1, 1) # bottom-left
                cr.rectangle(x + 1, y + h - 1, 1, 1)
                
                cr.rectangle(x + w - 1, y + h - 2, 1, 1) # bottom-right
                cr.rectangle(x + w - 2, y + h - 1, 1, 1)
                
                cr.clip()
                
                self.draw_skin(cr, x, y, w, h)
                
            # Propagate expose.
            propagate_expose(widget, event)
            
        return True