Logo Search packages:      
Sourcecode: ia32-libs-gtk version File versions  Download package

ubuntulooks_draw.c

#include "ubuntulooks_draw.h"
#include "ubuntulooks_style.h"
#include "ubuntulooks_types.h"

#include "support.h"

#include <cairo.h>

#define M_PI 3.14159265358979323846

void
ubuntulooks_rounded_rectangle (cairo_t *cr,
                                 double x, double y, double w, double h,
                                 double radius, uint8 corners)
{
      if (corners & CL_CORNER_TOPLEFT)
            cairo_move_to (cr, x+radius, y);
      else
            cairo_move_to (cr, x, y);
      
      if (corners & CL_CORNER_TOPRIGHT)
            cairo_arc (cr, x+w-radius, y+radius, radius, M_PI * 1.5, M_PI * 2);
      else
            cairo_line_to (cr, x+w, y);
      
      if (corners & CL_CORNER_BOTTOMRIGHT)
            cairo_arc (cr, x+w-radius, y+h-radius, radius, 0, M_PI * 0.5);
      else
            cairo_line_to (cr, x+w, y+h);
      
      if (corners & CL_CORNER_BOTTOMLEFT)
            cairo_arc (cr, x+radius,   y+h-radius, radius, M_PI * 0.5, M_PI);
      else
            cairo_line_to (cr, x, y+h);
      
      if (corners & CL_CORNER_TOPLEFT)
            cairo_arc (cr, x+radius,   y+radius,   radius, M_PI, M_PI * 1.5);
      else
            cairo_line_to (cr, x, y);
}


/* KEEP IN MIND, MIRROR TAKES PLACE BEFORE ROTATION */
/* ROTATES ANTI-CLOCKWISE, I THINK :P */
/* TODO: Do I really need THREE matrices? */
static void
rotate_mirror_translate (cairo_t *cr, double radius, double x, double y,
                         boolean mirror_horizontally, boolean mirror_vertically)
{
      cairo_matrix_t matrix_rotate;
      cairo_matrix_t matrix_mirror;
      cairo_matrix_t matrix_result;
      
      double r_cos = cos(radius);
      double r_sin = sin(radius);
      
      cairo_matrix_init (&matrix_rotate, r_cos,
                                         r_sin,
                                         r_sin,
                                         r_cos,
                                         x, y);
      
      cairo_matrix_init (&matrix_mirror, mirror_horizontally ? -1 : 1,
                                         0,
                                         0,
                                         mirror_vertically ? -1 : 1,
                                                         0, 0);

      cairo_matrix_multiply (&matrix_result, &matrix_mirror, &matrix_rotate);

      cairo_set_matrix (cr, &matrix_result);
}

void
ubuntulooks_draw_inset (cairo_t *cr, int width, int height,
                       double radius, uint8 corners)
{
      double top_x1 = 0, top_x2 = width, bot_x1 = 0, bot_x2 = width;
      
      if (corners & CL_CORNER_TOPLEFT)
            top_x1 = radius-1;
      
      if (corners & CL_CORNER_TOPRIGHT)
            top_x2 = width-radius+1;
      
      if (corners & CL_CORNER_BOTTOMLEFT)
            bot_x1 = radius-1;
      
      if (corners & CL_CORNER_BOTTOMRIGHT)
            bot_x2 = width-radius+1;
      
      cairo_set_line_width (cr, 1);
      cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.04);
      cairo_move_to (cr, top_x1, 0.0);
      cairo_line_to (cr, top_x2, 0.0);
      cairo_stroke (cr);
      
      cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.5);
      cairo_move_to (cr, bot_x1, height);
      cairo_line_to (cr, bot_x2, height);
      cairo_stroke (cr);
}

static void
ubuntulooks_draw_shadow (cairo_t *cr, int width, int height)
{
      cairo_set_line_width (cr, 1.0);
      
      cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.1);
      
      cairo_move_to (cr, width, 3.0);
      cairo_arc (cr, width-4.0, height-4.0, 4.0, 0, M_PI/2);
      cairo_line_to (cr, 3.0, height);

      cairo_stroke (cr);
}

static void
ubuntulooks_draw_top_left_highlight (cairo_t *cr,
                                    const WidgetParameters *params,
                                    int width, int height, gdouble radius)
{
      double light_y1 = params->ythickness-1,
             light_y2 = height - params->ythickness - 1,
             light_x1 = params->xthickness-1,
             light_x2 = width - params->xthickness - 1;

      cairo_move_to         (cr, light_x1, light_y2);
      
      if (params->corners & CL_CORNER_TOPLEFT)
            cairo_arc         (cr, light_x1+radius, light_y1+radius, radius, M_PI, 270*(M_PI/180));
      else
            cairo_line_to     (cr, light_x1, light_y1);
      
      cairo_line_to         (cr, light_x2, light_y1);
      cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.6);
      cairo_stroke          (cr);
}

#warning seems to be very slow in scrollbar_stepper
static void
ubuntulooks_draw_highlight_and_ul_shade (cairo_t *cr,
                                     const ShadowParameters *params,
                                     int width, int height, gdouble radius)
{
      uint8 corners = params->corners;
      double x = 1.0;
      double y = 1.0;
      
      width  -= 3;
      height -= 3;
      
      cairo_save (cr);
      
      /* Draw top/left */
      if (corners & CL_CORNER_BOTTOMLEFT)
            cairo_move_to (cr, x, y+height-radius);
      else
            cairo_move_to (cr, x, y+height);
      
      if (corners & CL_CORNER_TOPLEFT)
            cairo_arc (cr, x+radius, y+radius, radius, M_PI, 270*(M_PI/180));
      else
            cairo_line_to (cr, x, y);
      
      if (corners & CL_CORNER_TOPRIGHT)
            cairo_line_to (cr, x+width-radius, y);
      else
            cairo_line_to (cr, x+width, y);
      
      if (params->shadow & CL_SHADOW_OUT)
            cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.5);
      else
            cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.05);
            
      cairo_stroke (cr);
      
      /* Drop bottom/right */
      
      if (corners & CL_CORNER_TOPRIGHT)
      {
            cairo_move_to (cr, x+width-radius, y);
            cairo_arc (cr, x+width-radius, y+radius, radius, M_PI + M_PI*0.5, M_PI*2);
      }
      else
            cairo_move_to (cr, x+width, y);
      
      if (corners & CL_CORNER_BOTTOMRIGHT)
            cairo_arc (cr, x+width-radius, y+height-radius, radius, 0, M_PI/2);
      else
            cairo_line_to (cr, x+width, y+height);
      
      if (corners & CL_CORNER_BOTTOMLEFT)
            cairo_arc (cr, x+radius, y+height-radius, radius, M_PI/2, M_PI);
      else
            cairo_line_to (cr, x, y+height);
      
      if (params->shadow & CL_SHADOW_OUT)
            cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.05);
      else
            cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.5);
      
      cairo_stroke (cr);
      
      cairo_restore (cr);
}

void
ubuntulooks_draw_gripdots (cairo_t *cr, int x, int y,
                          int width, int height, int xr, int yr,
                          float contrast)
{
      int i, j;
      int xoff, yoff;
      
      for ( i = 0; i < xr; i++ ) {
            for ( j = 0; j < yr; j++ ) {
                  xoff = x -(xr * 3 / 2) + 3 * i;
                  yoff = y -(yr * 3 / 2) + 3 * j; 
                  
                  cairo_rectangle (cr, width/2+0.5+xoff, height/2+0.5+yoff, 2, 2);
                  cairo_set_source_rgba (cr, 1., 1., 1., 0.8+contrast);
                  cairo_fill (cr);
                  cairo_rectangle (cr, width/2+0.5+xoff, height/2+0.5+yoff, 1, 1);
                  cairo_set_source_rgba (cr, 0, 0, 0, 0.2+contrast);
                  cairo_fill (cr);
            }
      }
}


static void
ubuntulooks_draw_button_gradient (cairo_t *cr,
                                  double x, double y, int width, int height,
                                  CairoColor *color, boolean fill, boolean disabled)
{
      CairoColor a, b, c, d, e;
      cairo_pattern_t *pt;

      if (fill)
      {
            ul_shade (color, &a, 1.48);
            ul_shade (color, &b, 1.24);
            ul_shade (color, &c, 0.98);
            ul_shade (color, &d, 1.0 );
            ul_shade (color, &e, 1.42);
      } else {
            ul_shade (color, &a, disabled? 1.03 : 1.05);
            ul_shade (color, &b, disabled? 1.01 : 1.02);
            ul_shade (color, &c, disabled? 0.99 : 0.98);
            ul_shade (color, &d, 1.0 );
            ul_shade (color, &e, disabled? 1.01 : 1.02);
      }

      pt = cairo_pattern_create_linear (x, y, x, y+height);
      cairo_pattern_add_color_stop_rgb (pt, 0.0,  a.r, a.g, a.b);
      cairo_pattern_add_color_stop_rgb (pt, 0.5,  b.r, b.g, b.b);
      cairo_pattern_add_color_stop_rgb (pt, 0.5,  c.r, c.g, c.b);
      cairo_pattern_add_color_stop_rgb (pt, 0.75, d.r, d.g, d.b);
      cairo_pattern_add_color_stop_rgb (pt, 0.85, e.r, e.g, e.b);
      cairo_pattern_add_color_stop_rgb (pt, 1.0,  d.r, d.g, d.b);

      cairo_set_source (cr, pt);
      cairo_rectangle (cr, x, y, width, height);
      cairo_fill (cr);
      
      cairo_pattern_destroy (pt);
}


void
ubuntulooks_draw_button (cairo_t *cr,
                        const UbuntulooksColors *colors,
                        const WidgetParameters *params,
                        const ShadowParameters *shadow,
                        int x, int y, int width, int height)
{
      const float RADIUS = 3.0;

      double xoffset = 0, yoffset = 0;
      CairoColor fill                   = colors->bg[params->state_type];
      const CairoColor *border_normal   = &colors->shade[7];
      const CairoColor *border_disabled = &colors->shade[4];
      const CairoColor *gradient_bottom = &colors->shade[3];

      cairo_pattern_t *pattern;
      
      cairo_translate (cr, x, y);
      cairo_set_line_width (cr, 1.0);

      if (params->xthickness == 3 || params->ythickness == 3)
      {
            cairo_translate (cr, 0.5, 0.5);
            
            if (params->prelight && params->enable_glow)
            {
                  const CairoColor *glow = &colors->spot[0];
                  ubuntulooks_rounded_rectangle (cr, 0, 0, width-1, height-1, RADIUS+1, params->corners);
                  cairo_set_source_rgb (cr, glow->r, glow->g, glow->b);
                  cairo_stroke (cr);
            }
            if (!params->active && shadow->shadow != CL_SHADOW_IN)
                  ubuntulooks_draw_shadow (cr, width-1, height-1);
            else
                  ubuntulooks_draw_inset (cr, width-1, height-1, RADIUS, params->corners);
            
            cairo_translate (cr, -0.5, -0.5);
            
            if (params->xthickness == 3)
                  xoffset = 1;
            if (params->ythickness == 3)
                  yoffset = 1;
      }
      
      if (params->active && params->prelight)
      {
            fill = colors->bg[CL_STATE_ACTIVE];
            ul_shade (&fill, &fill, 1.05);
      }

      ubuntulooks_draw_button_gradient (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, height-(yoffset*2)-2, &fill, FALSE, params->disabled);
      
      if (params->active)
      {
            cairo_rectangle (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, 3);
      
            pattern = cairo_pattern_create_linear (xoffset+1, yoffset+1, xoffset+1, yoffset+4);
            cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0.0, 0.0, 0.0, params->disabled ? 0.08 : 0.10);
            cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0.0, 0.0, 0.0, 0.00);
            cairo_set_source (cr, pattern);
            cairo_fill (cr);
            cairo_pattern_destroy (pattern);
      }
      
      /* Draw the default inside "glow" */
      if (params->is_default && !params->active && !params->disabled)
      {
            const CairoColor *glow = &colors->spot[0];
            double hh = (height-5)/2.0 + 1;
            
            cairo_rectangle (cr, 3.5, 3.5, width-7, height-7);
            cairo_set_source_rgb (cr, glow->r, glow->g, glow->b);
            cairo_stroke (cr);

            glow = &colors->spot[0];
            cairo_move_to (cr, 2.5, 2.5+hh); cairo_rel_line_to (cr, 0, -hh);
            cairo_rel_line_to (cr, width-5, 0); cairo_rel_line_to (cr, 0, hh);
            cairo_set_source_rgb (cr, glow->r, glow->g, glow->b);
            cairo_stroke (cr);
            
            hh--;

            glow = &colors->spot[1];
            cairo_move_to (cr, 2.5, 2.5+hh); cairo_rel_line_to (cr, 0, hh);
            cairo_rel_line_to (cr, width-5, 0); cairo_rel_line_to (cr, 0, -hh);
            cairo_set_source_rgb (cr, glow->r, glow->g, glow->b);
            cairo_stroke (cr);
      }
      
      
      /* Draw the border */
      if (params->is_default || (params->prelight && params->enable_glow))
            border_normal = &colors->spot[2];
      
      if (params->disabled)
      {
            cairo_set_source_rgb (cr, border_disabled->r,
                                      border_disabled->g,
                                      border_disabled->b);
      }
      else
      {
            cairo_set_source_rgb (cr, border_normal->r,
                                      border_normal->g,
                                      border_normal->b);
      }
      
      ubuntulooks_rounded_rectangle (cr, xoffset + 0.5, yoffset + 0.5,
                                  width-(xoffset*2)-1, height-(yoffset*2)-1,
                                  RADIUS, params->corners);
      cairo_stroke (cr);
      

}

void
ubuntulooks_draw_entry (cairo_t *cr,
                       const UbuntulooksColors *colors,
                       const WidgetParameters *params,
                       int x, int y, int width, int height)
{
      const float RADIUS = 3.0;
      
      const CairoColor *base = &colors->base[params->state_type];
      const CairoColor *border;
      
      if (params->focus)
            border = &colors->spot[2];
      else
            border = &colors->shade[params->disabled ? 4 : 6];

      cairo_translate (cr, x+0.5, y+0.5);
      cairo_set_line_width (cr, 1.0);
      
      /* Fill the background (shouldn't have to) */
      cairo_rectangle (cr, -0.5, -0.5, width, height);
      cairo_set_source_rgb (cr, params->parentbg.r, 
                                params->parentbg.g, 
                                params->parentbg.b);
      cairo_fill (cr);

      /* Fill the entry's base color (why isn't is large enough by default?) */
      cairo_rectangle (cr, 1.5, 1.5, width-4, height-4);
      cairo_set_source_rgb (cr, base->r, 
                                base->g, 
                                base->b);
      cairo_fill (cr);
      
      ubuntulooks_draw_inset (cr, width-1, height-1, 2.0, params->corners);

      /* Draw the inner shadow */
      if (params->focus)
      {
            cairo_rectangle (cr, 2, 2, width-5, height-5);
      //    ubuntulooks_rounded_rectangle (cr, 2, 2, width-5, height-5, RADIUS-1, params->corners);
            cairo_set_source_rgb (cr, colors->spot[0].r, colors->spot[0].g, colors->spot[0].b);
            cairo_stroke (cr);
      }
      else
      {
            cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, params->disabled ? 0.05 : 0.1);
            /*
            cairo_move_to (cr, 2, height-3);
            cairo_arc (cr, params->xthickness+RADIUS-1, params->ythickness+RADIUS-1, RADIUS, M_PI, 270*(M_PI/180));
            cairo_line_to (cr, width-3, 2);*/
            cairo_move_to (cr, 2, height-3);
            cairo_line_to (cr, 2, 2);
            cairo_line_to (cr, width-3, 2);
            cairo_stroke (cr);
      }

      /* Draw the border */
      cairo_set_source_rgb (cr, border->r, border->g, border->b);
      ubuntulooks_rounded_rectangle (cr, 1, 1, width-3, height-3, RADIUS, params->corners);
      cairo_stroke (cr);
}

void
ubuntulooks_draw_spinbutton (cairo_t *cr,
                            const UbuntulooksColors *colors,
                            const WidgetParameters *params,
                            int x, int y, int width, int height)
{
      ShadowParameters shadow = { CL_CORNER_ALL, CL_SHADOW_IN };
      
      ubuntulooks_draw_button (cr, colors, params, &shadow, x, y, width, height);

      cairo_set_line_width (cr, 1);
      
      /* Seperator */
      cairo_move_to (cr, params->xthickness      , 0.5 + (height/2));
      cairo_line_to (cr, width-params->xthickness, 0.5 + (height/2));
      cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.3);
      cairo_stroke (cr);

      cairo_move_to (cr, params->xthickness,       0.5 + (height/2)+1);
      cairo_line_to (cr, width-params->xthickness, 0.5 + (height/2)+1);
      cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.7);
      cairo_stroke (cr);      
}

void
ubuntulooks_draw_spinbutton_down (cairo_t *cr,
                                 const UbuntulooksColors *colors,
                                 const WidgetParameters *params,
                                 int x, int y, int width, int height)
{
      cairo_pattern_t *pattern;
      
      cairo_translate (cr, x+1, y+1);
      
      ubuntulooks_rounded_rectangle (cr, 1, 1, width-4, height-4, 3, params->corners);
      
      cairo_set_source_rgb (cr, colors->bg[params->state_type].r,
                                colors->bg[params->state_type].g, 
                                colors->bg[params->state_type].b);
      
      cairo_fill_preserve (cr);
      
      pattern = cairo_pattern_create_linear (0, 0, 0, height);
      cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0.0, 0.0, 0.0, 0.3);
      cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0.0, 0.0, 0.0, 0.0);
      
      cairo_set_source (cr, pattern);
      cairo_fill (cr);
      
      cairo_pattern_destroy (pattern);
}

static void
ubuntulooks_scale_draw_gradient (cairo_t *cr,
                                const CairoColor *c1,
                                const CairoColor *c2,
                                const CairoColor *c3,
                                int x, int y, int width, int height,
                                boolean horizontal)
{
      cairo_pattern_t *pattern;

      pattern = cairo_pattern_create_linear (0, 0, horizontal ? 0 :  width, horizontal ? height : 0);
      cairo_pattern_add_color_stop_rgb (pattern, 0.0, c1->r, c1->g, c1->b);
      cairo_pattern_add_color_stop_rgb (pattern, 1.0, c2->r, c2->g, c2->b);

      cairo_rectangle (cr, x+0.5, y+0.5, width-1, height-1);      
      cairo_set_source (cr, pattern);
      cairo_fill (cr);
      cairo_pattern_destroy (pattern);
      
      cairo_rectangle (cr, x, y, width, height);      
      cairo_set_source_rgb (cr, c3->r, c3->g, c3->b);
      cairo_stroke (cr);
}

#define TROUGH_SIZE 6
void
ubuntulooks_draw_scale_trough (cairo_t *cr,
                              const UbuntulooksColors *colors,
                              const WidgetParameters *params,
                              const SliderParameters *slider,
                              int x, int y, int width, int height)
{
      int     fill_x, fill_y, fill_width, fill_height; /* Fill x,y,w,h */
      int     trough_width, trough_height;
      double  translate_x, translate_y;
      int     fill_size = slider->fill_size;

      if (slider->horizontal)
      {
            if (fill_size > width-3)
                  fill_size = width-3;

            fill_x        = slider->inverted ? width - fill_size - 3 : 0;
            fill_y        = 0;
            fill_width    = fill_size;                
            fill_height   = TROUGH_SIZE-2;
            
            trough_width  = width-3;
            trough_height = TROUGH_SIZE-2;
            
            translate_x   = x + 0.5;
            translate_y   = y + 0.5 + (height/2) - (TROUGH_SIZE/2);
      }
      else
      {
            if (fill_size > height-3)
                  fill_size = height-3;

            fill_x        = 0;
            fill_y        = slider->inverted ? height - fill_size - 3 : 0;
            fill_width    = TROUGH_SIZE-2;
            fill_height   = fill_size;                
            
            trough_width  = TROUGH_SIZE-2;
            trough_height = height-3;
            
            translate_x   = x + 0.5 + (width/2) - (TROUGH_SIZE/2);
            translate_y  = y + 0.5;
      }

      cairo_set_line_width (cr, 1.0);
      cairo_translate (cr, translate_x, translate_y);
      
      ubuntulooks_draw_inset (cr, trough_width+2, trough_height+2, 0, 0);
      
      cairo_translate (cr, 1, 1);
      ubuntulooks_scale_draw_gradient (cr, &colors->shade[3], /* top */
                                          &colors->shade[2], /* bottom */
                                          &colors->shade[6], /* border */
                                          0, 0, trough_width, trough_height,
                                          slider->horizontal);
      
      if (params->disabled)
      {
            ubuntulooks_scale_draw_gradient (cr, &colors->shade[5], /* top    */
                                             &colors->shade[3], /* bottom */
                                             &colors->shade[6], /* border */
                                             fill_x, fill_y, fill_width, fill_height,
                                             slider->horizontal);       
      }
      else
      {
            ubuntulooks_scale_draw_gradient (cr, &colors->spot[1], /* top    */
                                             &colors->spot[0], /* bottom */
                                             &colors->spot[2], /* border */
                                             fill_x, fill_y, fill_width, fill_height,
                                             slider->horizontal);
      }
}

void
ubuntulooks_draw_slider (cairo_t *cr,
                        const UbuntulooksColors *colors,
                        const WidgetParameters *params,
                        int x, int y, int width, int height)
{
      const CairoColor  *border = &colors->shade[params->disabled ? 4 : 6];
      const CairoColor  *spot = &colors->spot[1];
      CairoColor      highlight;
      CairoColor      fill;
      cairo_pattern_t *pattern;
      
      cairo_set_line_width (cr, 1.0);
      
      ubuntulooks_rounded_rectangle (cr, x+0.5, y+0.5, width-2, height-2, 3.0, params->corners);

      /* Fill the thing */
      //if ( params->prelight ) {
      //    fill = colors->bg[CL_STATE_NORMAL];
      //} else {
            fill = colors->shade[2];
      //}
      cairo_set_source_rgb (cr, fill.r, fill.g, fill.b);
      cairo_fill_preserve (cr);
      
      /* Fake light */
      if (!params->disabled)
      {
            pattern     = cairo_pattern_create_linear (x, y, 0, height);
            cairo_pattern_add_color_stop_rgba (pattern, 0.0,  1.0, 1.0, 1.0, 0.8);
            cairo_pattern_add_color_stop_rgba (pattern, 1.0,  1.0, 1.0, 1.0, 0.0);
            cairo_set_source (cr, pattern);
            cairo_fill (cr);
            cairo_pattern_destroy (pattern);
      }

      /* Set the clip */
      cairo_rectangle (cr, x+0.5, y+0.5, 6, height-2);
      cairo_rectangle (cr, x+width-7.5, y+0.5, 6 , height-2);
      cairo_clip (cr);
      
      cairo_new_path (cr);
      
      /* Draw the handles */
      ubuntulooks_rounded_rectangle (cr, x+0.5, y+0.5, width-1, height-1, 3.0, params->corners);
      pattern = cairo_pattern_create_linear (0, 0, 0, height);
      if ( params->prelight ) {
            ul_shade (&colors->bg[GTK_STATE_SELECTED], &highlight, 1.7);      
            cairo_pattern_add_color_stop_rgb (pattern, 0.0, highlight.r, highlight.g, highlight.b);
            cairo_pattern_add_color_stop_rgb (pattern, 1.0, spot->r, spot->g, spot->b);
            cairo_set_source (cr, pattern);
      } else {
            cairo_set_source_rgba (cr, 1, 1, 1, 0.5);
      }
      cairo_fill (cr);
      cairo_pattern_destroy (pattern);
      
      cairo_reset_clip (cr);

      /* Draw the border */
      ubuntulooks_rounded_rectangle (cr, x+0, y+0, width-1, height-1, 3.0, params->corners);
      cairo_set_source_rgb (cr, border->r,
                                border->g,
                                border->b);
      cairo_stroke (cr);
      
      /* Draw handle lines */
      cairo_move_to (cr, x+6, 0.5);
      cairo_line_to (cr, x+6, height-0.5);
      
      cairo_move_to (cr, x+width-7, 0.5);
      cairo_line_to (cr, x+width-7, height-0.5);
      
      cairo_set_line_width (cr, 1.0);
      cairo_set_source_rgba (cr, border->r,
                                 border->g,
                                 border->b,
                                 0.3);
      cairo_stroke (cr);      
}

void
ubuntulooks_draw_slider_button (cairo_t *cr,
                               const UbuntulooksColors *colors,
                               const WidgetParameters *params,
                               const SliderParameters *slider,
                               int x, int y, int width, int height)
{
      const CairoColor *border = &colors->shade[6];
      CairoColor        top, bottom;
      cairo_pattern_t *pattern;

      cairo_set_line_width (cr, 1.0);
      
      if (slider->horizontal)
            rotate_mirror_translate (cr, 0, x+0.5, y+0.5, FALSE, FALSE);
      else
      {
            int tmp = height;
            rotate_mirror_translate (cr, M_PI/2, x+0.5, y+0.5, FALSE, FALSE);
            height = width;
            width = tmp;
      }
      
      ubuntulooks_draw_shadow (cr, width-1, height-1);
      ubuntulooks_draw_slider (cr, colors, params, 1, 1, width-2, height-2);
      ubuntulooks_draw_gripdots (cr, 1, 1, width-2, height-2, 3, 3, 0);
}

static cairo_surface_t*
ubuntulooks_progressbar_create_cell (int size, const CairoColor *color, gboolean fill)
{
      cairo_t *cr;
      cairo_surface_t *cell;
      cairo_pattern_t *pt;
      CairoColor a, b, c, d, e;

      if (fill)
      {
            ul_shade (color, &a, 1.48);
            ul_shade (color, &b, 1.24);
            ul_shade (color, &c, 0.98);
            ul_shade (color, &d, 1.0);
            ul_shade (color, &e, 1.42);
      } else {
            ul_shade (color, &a, 1.05);
            ul_shade (color, &b, 1.02);
            ul_shade (color, &c, 0.98);
            ul_shade (color, &d, 1.0);
            ul_shade (color, &e, 1.03);
      }
      cell = cairo_image_surface_create (CAIRO_FORMAT_RGB24, size, size);
      cr = cairo_create (cell);

      pt = cairo_pattern_create_linear (0, 0, 0, size);
      cairo_pattern_add_color_stop_rgb (pt, 0.0,  a.r, a.g, a.b);
      cairo_pattern_add_color_stop_rgb (pt, 0.5,  b.r, b.g, b.b);
      cairo_pattern_add_color_stop_rgb (pt, 0.5,  c.r, c.g, c.b);
      cairo_pattern_add_color_stop_rgb (pt, 0.75,  d.r, d.g, d.b);
      cairo_pattern_add_color_stop_rgb (pt, 0.85, e.r, e.g, e.b);
      cairo_pattern_add_color_stop_rgb (pt, 1.0,  d.r, d.g, d.b);

      cairo_set_source (cr, pt);
      cairo_rectangle (cr, 0, 0, size, size);
      cairo_fill (cr);

      cairo_set_line_width (cr, 1);

      cairo_set_source_rgba (cr, 1, 1, 1, 0.4);
      cairo_move_to (cr, 0, 0);
      cairo_line_to (cr, 0, size);
      cairo_stroke (cr);

      cairo_set_source_rgba (cr, 0, 0, 0, 0.1);
      cairo_move_to (cr, size-0.5, 0);
      cairo_line_to (cr, size-0.5, size);
      cairo_stroke (cr);

      cairo_pattern_destroy (pt);
      cairo_destroy (cr);

      return cell;
}

void
ubuntulooks_draw_progressbar_trough (cairo_t *cr,
                                    const UbuntulooksColors      *colors,
                                    const WidgetParameters      *params,
                                    const ProgressBarParameters *progressbar,
                                    int x, int y, int width, int height)
{
      boolean           is_horizontal = progressbar->orientation < 2;
      const CairoColor *border = &colors->shade[7];
      cairo_pattern_t  *pt;
      int               size;
      
      cairo_set_line_width (cr, 1.0);
      
      /* Fill with bg color */
      cairo_set_source_rgb (cr, colors->bg[params->state_type].r,
                                colors->bg[params->state_type].g,
                                colors->bg[params->state_type].b);
      
      cairo_rectangle (cr, x, y, width, height);      
      cairo_fill (cr);

      if (is_horizontal)
            size = height - params->ythickness*2;
      else
            size = width - params->xthickness*2;

      /* Draw the border before anything else... */
      ubuntulooks_rounded_rectangle (cr, x + params->xthickness - 0.5,
                                        y + params->ythickness - 0.5,
                                        width - params->xthickness - 1,
                                        height - params->ythickness - 1, 1.5, CL_CORNER_ALL);
      cairo_set_source_rgb (cr, colors->shade[7].r, colors->shade[7].g, colors->shade[7].b);
      cairo_stroke (cr);

      /* Create cell image surface, create a pattern from it */
      cairo_surface_t *cell = ubuntulooks_progressbar_create_cell (size, &colors->bg[params->state_type], FALSE);
      pt = cairo_pattern_create_for_surface (cell);
      cairo_pattern_set_extend (pt, CAIRO_EXTEND_REPEAT);

      cairo_matrix_t m;
      cairo_matrix_init_translate (&m, -1, -1);
      cairo_pattern_set_matrix (pt, &m);

      if (is_horizontal)
      {
            rotate_mirror_translate (cr, 0, x, y, FALSE, FALSE);
            cairo_matrix_init_translate (&m, x-1, 0);
      }
      else
      {
            int tmp = height;
            height  = width;
            width   = tmp;

            rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
            cairo_matrix_init_translate (&m, y-1, 0);
      }

      cairo_set_source (cr, pt);
      cairo_pattern_destroy (pt);
      cairo_rectangle (cr, params->xthickness, params->ythickness, width-params->xthickness*2, height-params->ythickness*2);
      cairo_fill (cr);
      cairo_surface_destroy (cell);

      if (params->xthickness > 1 && params->ythickness > 1)
      {
            cairo_translate (cr, -0.5, -0.5);
            ubuntulooks_draw_shadow (cr, width, height);
      }
}

void
ubuntulooks_draw_progressbar_fill (cairo_t *cr,
                                  const UbuntulooksColors *colors,
                                  const WidgetParameters *params,
                                  const ProgressBarParameters *progressbar,
                                  int x, int y, int width, int height,
                                  gint offset)
{
      boolean          is_horizontal = progressbar->orientation < 2;
      double           tile_pos = 0;
      double           stroke_width;
      int               x_step;

      cairo_pattern_t *pt;
      CairoColor       shade1;
      cairo_matrix_t m;
      
      cairo_rectangle (cr, x, y, width, height);
      cairo_clip (cr);
      cairo_new_path (cr);

      if (is_horizontal)
      {
            rotate_mirror_translate (cr, 0, x, y, FALSE, FALSE);
            cairo_matrix_init_translate (&m, x-1, 0);
      }
      else
      {
            int tmp = height;
            height  = width;
            width   = tmp;

            rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
            cairo_matrix_init_translate (&m, y-1, 0);
      }

      /* Create cell image surface, create a pattern from it */
      cairo_surface_t *cell = ubuntulooks_progressbar_create_cell (height, &colors->spot[1], TRUE);
      pt = cairo_pattern_create_for_surface (cell);
      cairo_pattern_set_extend (pt, CAIRO_EXTEND_REPEAT);
      cairo_pattern_set_matrix (pt, &m);
      cairo_set_source (cr, pt);
      cairo_pattern_destroy (pt);
      
      cairo_rectangle (cr, 0, 0, width, height);
      cairo_fill (cr);

      cairo_surface_destroy (cell);
}

void
ubuntulooks_draw_optionmenu (cairo_t *cr,
                            const UbuntulooksColors *colors,
                            const WidgetParameters *params,
                            const OptionMenuParameters *optionmenu,
                            int x, int y, int width, int height)
{
      ShadowParameters shadow = { CL_CORNER_ALL, CL_SHADOW_NONE };

      int offset = params->ythickness + 1;
      
      ubuntulooks_draw_button (cr, colors, params, &shadow, x, y, width, height);
      
      cairo_set_line_width  (cr, 1.0);
      cairo_translate       (cr, optionmenu->linepos + 0.5, 0.5);
      
      cairo_move_to         (cr, 0.0, offset);
      cairo_line_to         (cr, 0.0, height - offset - params->ythickness + 1);
      cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.2);
      cairo_stroke          (cr);
      
      cairo_move_to         (cr, 1.0, offset);
      cairo_line_to         (cr, 1.0, height - offset - params->ythickness + 1);
      cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.8);
      cairo_stroke          (cr);
}

void
ubuntulooks_draw_menubar (cairo_t *cr,
                         const UbuntulooksColors *colors,
                         const WidgetParameters *params,
                         int x, int y, int width, int height)
{
      CairoColor lower;
      cairo_pattern_t *pattern;
      
      ul_shade (&colors->bg[0], &lower, 0.95);
      
      cairo_translate (cr, x, y);
      cairo_rectangle (cr, 0, 0, width, height);
      
      /* Draw the gradient */
      pattern = cairo_pattern_create_linear (0, 0, 0, height);
      cairo_pattern_add_color_stop_rgb (pattern, 0.0, colors->bg[0].r,
                                                      colors->bg[0].g,
                                                      colors->bg[0].b);
      cairo_pattern_add_color_stop_rgb (pattern, 1.0, lower.r,
                                                      lower.g,
                                                      lower.b);
      cairo_set_source      (cr, pattern);
      cairo_fill            (cr);
      cairo_pattern_destroy (pattern);
      
      /* Draw bottom line */
      cairo_set_line_width  (cr, 1.0);
      cairo_move_to         (cr, 0, height-0.5);
      cairo_line_to         (cr, width, height-0.5);
      cairo_set_source_rgb  (cr, colors->shade[3].r,
                                 colors->shade[3].g,
                                 colors->shade[3].b);
      cairo_stroke          (cr);
}

static void
ubuntulooks_get_frame_gap_clip (int x, int y, int width, int height, 
                               FrameParameters     *frame,
                               UbuntulooksRectangle *bevel,
                               UbuntulooksRectangle *border)
{
      if (frame->gap_side == CL_GAP_TOP)
      {
            UBUNTULOOKS_RECTANGLE_SET ((*bevel),  1.5 + frame->gap_x,  -0.5,
                                                                   frame->gap_width - 3, 2.0);
            UBUNTULOOKS_RECTANGLE_SET ((*border), 0.5 + frame->gap_x,  -0.5,
                                                                   frame->gap_width - 2, 2.0);
      }
      else if (frame->gap_side == CL_GAP_BOTTOM)
      {
            UBUNTULOOKS_RECTANGLE_SET ((*bevel),  1.5 + frame->gap_x,  height - 2.5,
                                                                   frame->gap_width - 3, 2.0);
            UBUNTULOOKS_RECTANGLE_SET ((*border), 0.5 + frame->gap_x,  height - 1.5,
                                                                   frame->gap_width - 2, 2.0);        
      }
      else if (frame->gap_side == CL_GAP_LEFT)
      {
            UBUNTULOOKS_RECTANGLE_SET ((*bevel),  -0.5, 1.5 + frame->gap_x,
                                                                   2.0, frame->gap_width - 3);
            UBUNTULOOKS_RECTANGLE_SET ((*border), -0.5, 0.5 + frame->gap_x,
                                                                   1.0, frame->gap_width - 2);              
      }
      else if (frame->gap_side == CL_GAP_RIGHT)
      {
            UBUNTULOOKS_RECTANGLE_SET ((*bevel),  width - 2.5, 1.5 + frame->gap_x,
                                                                   2.0, frame->gap_width - 3);
            UBUNTULOOKS_RECTANGLE_SET ((*border), width - 1.5, 0.5 + frame->gap_x,
                                                                   1.0, frame->gap_width - 2);              
      }
}

void
ubuntulooks_draw_frame            (cairo_t *cr,
                                  const UbuntulooksColors     *colors,
                                  const WidgetParameters     *params,
                                  const FrameParameters      *frame,
                                  int x, int y, int width, int height)
{
      const float RADIUS = 3.0;
      CairoColor *border = frame->border;
      UbuntulooksRectangle bevel_clip;
      UbuntulooksRectangle frame_clip;
      
      if (frame->shadow == CL_SHADOW_NONE)
            return;
      
      if (frame->gap_x != -1)
            ubuntulooks_get_frame_gap_clip (x, y, width, height,
                                           (FrameParameters*)frame,
                                           &bevel_clip, &frame_clip);
      
      cairo_set_line_width (cr, 1.0);
      cairo_translate      (cr, x+0.5, y+0.5);
      
      /* Set clip for the bevel */
      if (frame->gap_x != -1)
      {
            /* Set clip for gap */
            cairo_set_fill_rule  (cr, CAIRO_FILL_RULE_EVEN_ODD);
            cairo_rectangle      (cr, -0.5, -0.5, width, height);
            cairo_rectangle      (cr, bevel_clip.x, bevel_clip.y, bevel_clip.width, bevel_clip.height);
            cairo_clip           (cr);
            cairo_new_path       (cr);
      }
      
      /* Draw the bevel */
      if (frame->shadow == CL_SHADOW_ETCHED_IN || frame->shadow == CL_SHADOW_ETCHED_OUT)
      {
            cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.8 );
            if (frame->shadow == CL_SHADOW_ETCHED_IN)
                  cairo_rectangle       (cr, 1, 1, width-2, height-2);
            else
                  cairo_rectangle       (cr, 0, 0, width-2, height-2);
            cairo_stroke          (cr);
      }
      else if (frame->shadow != CL_SHADOW_NONE)
      {
            ShadowParameters shadow;
            shadow.corners = params->corners;
            shadow.shadow  = frame->shadow;
            ubuntulooks_draw_highlight_and_ul_shade (cr, &shadow, width, height, RADIUS);
      }
      
      /* Set clip for the frame */
      cairo_reset_clip     (cr);
      if (frame->gap_x != -1)
      {
            /* Set clip for gap */
            cairo_set_fill_rule  (cr, CAIRO_FILL_RULE_EVEN_ODD);
            cairo_rectangle      (cr, -0.5, -0.5, width, height);
            cairo_rectangle      (cr, frame_clip.x, frame_clip.y, frame_clip.width, frame_clip.height);
            cairo_clip           (cr);
            cairo_new_path       (cr);
      }

      /* Draw frame */
      if (frame->shadow == CL_SHADOW_ETCHED_IN || frame->shadow == CL_SHADOW_ETCHED_OUT)
      {
            cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.2 );
            if (frame->shadow == CL_SHADOW_ETCHED_IN)
                  cairo_rectangle       (cr, 0, 0, width-2, height-2);
            else
                  cairo_rectangle       (cr, 1, 1, width-2, height-2);
      }
      else
      {
            cairo_set_source_rgb (cr, border->r, border->g, border->b );
            cairo_rectangle      (cr, 0, 0, width-1, height-1);
      }
      cairo_stroke         (cr);
}

void
ubuntulooks_draw_tab (cairo_t *cr,
                     const UbuntulooksColors *colors,
                     const WidgetParameters *params,
                     const TabParameters    *tab,
                     int x, int y, int width, int height)
{
      const float RADIUS = 3.0;
      const CairoColor    *border1       = &colors->shade[6];
      const CairoColor    *stripe_fill   = &colors->spot[1];
      const CairoColor    *stripe_border = &colors->spot[2];
      const CairoColor    *fill;

      cairo_pattern_t     *pattern;
      
      int                  corners;
      double               strip_size;
            
      /* Set clip */
      cairo_rectangle      (cr, x, y, width, height);
      cairo_clip           (cr);
      cairo_new_path       (cr);

      /* Translate and set line width */  
      cairo_set_line_width (cr, 1.0);
      cairo_translate      (cr, x+0.5, y+0.5);


      /* Make the tabs slightly bigger than they should be, to create a gap */
      /* And calculate the strip size too, while you're at it */
      if (tab->gap_side == CL_GAP_TOP || tab->gap_side == CL_GAP_BOTTOM)
      {
            height += RADIUS;
            strip_size = 1.0 / height * 1.0;
            
            if (tab->gap_side == CL_GAP_TOP)
            {
                  cairo_translate (cr, 0.0, -4.0); /* gap at the other side */
                  corners = CL_CORNER_BOTTOMLEFT | CL_CORNER_BOTTOMRIGHT;
            }
            else
                  corners = CL_CORNER_TOPLEFT | CL_CORNER_TOPRIGHT;
      }
      else
      {
            width += RADIUS;
            strip_size = 1.0 / width * 1.0;
            
            if (tab->gap_side == CL_GAP_LEFT) 
            {
                  cairo_translate (cr, -4.0, 0.0); /* gap at the other side */
                  corners = CL_CORNER_TOPRIGHT | CL_CORNER_BOTTOMRIGHT;       
            }
            else
                  corners = CL_CORNER_TOPLEFT | CL_CORNER_BOTTOMLEFT;   
      }
      
      /* Set the fill color */
      if (params->active)
            fill = &colors->bg[params->state_type];
      else
            fill = &params->parentbg;
      

      /* Set tab shape */
      ubuntulooks_rounded_rectangle (cr, 0,
                                           0,
                                           width-1,
                                           height-1,
                                           RADIUS, corners);
      
      /* Draw fill */
      cairo_set_source_rgb  (cr, fill->r, fill->g, fill->b);
      cairo_fill_preserve   (cr);
      
      /* Draw highlight */
      if (!params->active)
      {
            ShadowParameters shadow;
            
            shadow.shadow  = CL_SHADOW_OUT;
            shadow.corners = corners;
            
            ubuntulooks_draw_highlight_and_ul_shade (cr, &shadow,
                                                 width,
                                                 height, RADIUS);
      }
      

      if (params->active)
      {
            cairo_set_line_width (cr, 1);
            cairo_set_source_rgba (cr, 1, 1, 1, 0.4);
            
            if (tab->gap_side == CL_GAP_TOP || tab->gap_side == CL_GAP_BOTTOM)
                  cairo_rectangle (cr, 1, 1, width-3, height-3);
            else
                  cairo_rectangle (cr, 1, 1, width-3, height-3);
            
            cairo_stroke (cr);

            cairo_rectangle (cr, 1, 1, width-3, height-3);
            
            /* bling overlay */
/*          ubuntulooks_rounded_rectangle (cr, 1, 1,
                                          width-2,
                                          height-2,
                                          3.0, params->corners);*/
            pattern = cairo_pattern_create_linear (0, 0, 0, height);
            cairo_pattern_add_color_stop_rgba (pattern, 0.0, 1.0, 1.0, 1.0, 0.6);
            cairo_pattern_add_color_stop_rgba (pattern, 0.4, 1.0, 1.0, 1.0, 0.3);
            cairo_pattern_add_color_stop_rgba (pattern, 0.5, 1.0, 1.0, 1.0, 0.15);
            cairo_pattern_add_color_stop_rgba (pattern, 0.6, 1.0, 1.0, 1.0, 0.2);
            cairo_pattern_add_color_stop_rgba (pattern, 1.0, 1.0, 1.0, 1.0, 0.6);
            cairo_set_source (cr, pattern);
            cairo_fill (cr);
            cairo_pattern_destroy (pattern);    
      }
      else
      {
            /* Draw shade */
            pattern = cairo_pattern_create_linear ( tab->gap_side == CL_GAP_LEFT   ? width-2  : 0,
                                                    tab->gap_side == CL_GAP_TOP    ? height-2 : 0,
                                                    tab->gap_side == CL_GAP_RIGHT  ? width    : 0,
                                                    tab->gap_side == CL_GAP_BOTTOM ? height   : 0 );
      
            ubuntulooks_rounded_rectangle (cr, 0,
                                           0,
                                           width-1,
                                           height-1,
                                           RADIUS, corners);
            
            cairo_pattern_add_color_stop_rgb  (pattern, 0.0,        stripe_fill->r, stripe_fill->g, stripe_fill->b);
            cairo_pattern_add_color_stop_rgb  (pattern, strip_size, stripe_fill->r, stripe_fill->g, stripe_fill->b);
            cairo_pattern_add_color_stop_rgba (pattern, strip_size, 1.0, 1.0, 1.0, 0.5);
            cairo_pattern_add_color_stop_rgba (pattern, 0.8,        1.0, 1.0, 1.0, 0.0);
            cairo_set_source (cr, pattern);
            cairo_fill (cr);
            cairo_pattern_destroy (pattern);
      }

      
      ubuntulooks_rounded_rectangle (cr, 0,
                                           0,
                                           width-1,
                                           height-1,
                                           RADIUS, corners);
      
      
      if (params->active)
      {
            cairo_set_source_rgb  (cr, border1->r, border1->g, border1->b);   
            cairo_stroke (cr);
      }
      else
      {
            pattern = cairo_pattern_create_linear ( tab->gap_side == CL_GAP_LEFT   ? width-2  : 2,
                                                    tab->gap_side == CL_GAP_TOP    ? height-2 : 2,
                                                    tab->gap_side == CL_GAP_RIGHT  ? width    : 2,
                                                    tab->gap_side == CL_GAP_BOTTOM ? height   : 2 );
            
            cairo_pattern_add_color_stop_rgb (pattern, 0.0,        stripe_border->r, stripe_border->g, stripe_border->b);
            cairo_pattern_add_color_stop_rgb (pattern, strip_size, stripe_border->r, stripe_border->g, stripe_border->b);
            cairo_pattern_add_color_stop_rgb (pattern, strip_size, border1->r,       border1->g,       border1->b);
            cairo_pattern_add_color_stop_rgb (pattern, 1.0,        border1->r,       border1->g,       border1->b);
            cairo_set_source (cr, pattern);
            cairo_stroke (cr);
            cairo_pattern_destroy (pattern);
      }
}

void
ubuntulooks_draw_separator (cairo_t *cr,
                           const UbuntulooksColors     *colors,
                           const WidgetParameters     *widget,
                           const SeparatorParameters  *separator,
                           int x, int y, int width, int height)
{
      if (separator->horizontal)
      {
            cairo_set_line_width  (cr, 1.0);
            cairo_translate       (cr, x, y+0.5);
            
            cairo_move_to         (cr, 0.0,     0.0);
            cairo_line_to         (cr, width+1, 0.0);
            cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.2);
            cairo_stroke          (cr);
            
            cairo_move_to         (cr, 0.0,   1.0);
            cairo_line_to         (cr, width, 1.0);
            cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.8);
            cairo_stroke          (cr);                     
      }
      else
      {
            cairo_set_line_width  (cr, 1.0);
            cairo_translate       (cr, x+0.5, y);
            
            cairo_move_to         (cr, 0.0, 0.0);
            cairo_line_to         (cr, 0.0, height);
            cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.2);
            cairo_stroke          (cr);
            
            cairo_move_to         (cr, 1.0, 0.0);
            cairo_line_to         (cr, 1.0, height);
            cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.8);
            cairo_stroke          (cr);         
      }
}

void
ubuntulooks_draw_list_view_header (cairo_t *cr,
                                  const UbuntulooksColors          *colors,
                                  const WidgetParameters          *widget,
                                  const ListViewHeaderParameters  *header,
                                  int x, int y, int width, int height)
{
      const CairoColor *border = &colors->shade[5];
      cairo_pattern_t  *pattern;
      
      cairo_translate (cr, x, y);
      cairo_set_line_width (cr, 1.0);
      
      /* Draw highlight */
      if (header->order == CL_ORDER_FIRST)
      {
            cairo_move_to (cr, 0.5, height-1);
            cairo_line_to (cr, 0.5, 0.5);
      }
      else
            cairo_move_to (cr, 0.0, 0.5);
      
      cairo_line_to (cr, width, 0.5);
      
      cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.5);
      cairo_stroke (cr);
      
      /* Draw bottom border */
      cairo_move_to (cr, 0.0, height-0.5);
      cairo_line_to (cr, width, height-0.5);
      cairo_set_source_rgb (cr, border->r,
                                border->g,
                                border->b);
      cairo_stroke (cr);

      /* Draw bottom shade */ 
      pattern = cairo_pattern_create_linear (0.0, height-5.0, 0.0, height-1.0);
      cairo_pattern_add_color_stop_rgba     (pattern, 0.0, 0.0, 0.0, 0.0, 0.0);
      cairo_pattern_add_color_stop_rgba     (pattern, 1.0, 0.0, 0.0, 0.0, 0.1);

      cairo_rectangle       (cr, 0.0, height-5.0, width, 4.0);
      cairo_set_source      (cr, pattern);
      cairo_fill            (cr);
      cairo_pattern_destroy (pattern);
      
      /* Draw resize grip */
      if (header->order != CL_ORDER_LAST || header->resizable)
      {
            SeparatorParameters separator;
            separator.horizontal = FALSE;
            
            ubuntulooks_draw_separator (cr, colors, widget, &separator,
                                       width-1.5, 4.0, 2, height-8.0);
      }
}

/* We can't draw transparent things here, since it will be called on the same
 * surface multiple times, when placed on a handlebox_bin or dockitem_bin */
void
ubuntulooks_draw_toolbar (cairo_t *cr,
                         const UbuntulooksColors          *colors,
                         const WidgetParameters          *widget,
                         int x, int y, int width, int height)
{
      const CairoColor *light = &colors->shade[0];
      const CairoColor *dark  = &colors->shade[3];
      
      cairo_set_line_width (cr, 1.0);
      
      /* Draw highlight */
      cairo_translate       (cr, x, y);
      cairo_move_to         (cr, 0, 0.5);
      cairo_line_to         (cr, width-1, 0.5);
      cairo_set_source_rgb  (cr, light->r, light->g, light->b);
      cairo_stroke          (cr);

      /* Draw shadow */
      cairo_move_to         (cr, 0, height-0.5);
      cairo_line_to         (cr, width-1, height-0.5);
      cairo_set_source_rgb  (cr, dark->r, dark->g, dark->b);
      cairo_stroke          (cr);
}

void
ubuntulooks_draw_menuitem (cairo_t *cr,
                          const UbuntulooksColors          *colors,
                          const WidgetParameters          *widget,
                          int x, int y, int width, int height)
{
      const CairoColor *fill = &colors->spot[1];
      CairoColor        fill_shade;
      CairoColor        border_top, border_bottom;
      cairo_pattern_t  *pattern;
      
      ul_shade (fill, &fill_shade, 0.85);
      
      ul_shade (fill, &border_top, 0.9);
      ul_shade (fill, &border_bottom, 0.8);
      
      cairo_translate      (cr, x+0.5, y+0.5);
      cairo_set_line_width (cr, 1.0);
      
//    ubuntulooks_rounded_rectangle (cr, 0, 0, width-1, height-1, 1.25, widget->corners);
      cairo_rectangle (cr, 0, 0, width-1, height-1);
      
      pattern = cairo_pattern_create_linear (0, 0, 0, height);
      cairo_pattern_add_color_stop_rgb (pattern, 0,   fill->r, fill->g, fill->b);
      cairo_pattern_add_color_stop_rgb (pattern, 1.0, fill_shade.r, fill_shade.g, fill_shade.b);
      
      cairo_set_source (cr, pattern);
      cairo_fill (cr);
      cairo_pattern_destroy (pattern);

      ubuntulooks_rounded_rectangle (cr, 0, 0, width-1, height-1, 1.25, widget->corners);
      
      pattern = cairo_pattern_create_linear (0, 0, 0, height);
      cairo_pattern_add_color_stop_rgb (pattern, 0,   border_top.r, border_top.g, border_top.b);
      cairo_pattern_add_color_stop_rgb (pattern, 1.0, border_bottom.r, border_bottom.g, border_bottom.b);
      
      cairo_set_source (cr, pattern);
      cairo_stroke               (cr);
      cairo_pattern_destroy (pattern);
}

void
ubuntulooks_draw_scrollbar_trough (cairo_t *cr,
                                  const UbuntulooksColors          *colors,
                                  const WidgetParameters           *params,
                                  const ScrollBarParameters        *scrollbar,
                                  int x, int y, int width, int height)
{
      const CairoColor *bg     = &colors->shade[params->disabled ? 2 : 3];
      const CairoColor *border = &colors->shade[params->disabled ? 4 : 6];
      CairoColor        bg_shade;
      cairo_pattern_t  *pattern;
      
      ul_shade (bg, &bg_shade, 0.95);
      
      cairo_set_line_width (cr, 1);
      //cairo_translate (cr, x, y);
      
      if (scrollbar->horizontal)
      {
            int tmp = height;
            rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
            height = width;
            width = tmp;
      }
      else
      {
            cairo_translate (cr, x, y);   
      }

      /* Draw fill */
      cairo_rectangle (cr, 1, 0, width-2, height);
      cairo_set_source_rgb (cr, bg->r, bg->g, bg->b);
      cairo_fill (cr);

      /* Draw shadow */
      if (!params->disabled)
      {
            pattern = cairo_pattern_create_linear (1, 0, 3, 0);
            cairo_pattern_add_color_stop_rgb (pattern, 0,   bg_shade.r, bg_shade.g, bg_shade.b);
            cairo_pattern_add_color_stop_rgb (pattern, 1.0, bg->r,      bg->g,      bg->b);     
            cairo_rectangle (cr, 1, 0, 4, height);
            cairo_set_source (cr, pattern);
            cairo_fill (cr);
            cairo_pattern_destroy (pattern);
      }

      /* Draw border */
      cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
      cairo_set_source_rgb (cr, border->r, border->g, border->b);
      cairo_stroke (cr);
}

void
ubuntulooks_draw_scrollbar_stepper (cairo_t *cr,
                                   const UbuntulooksColors           *colors,
                                   const WidgetParameters           *widget,
                                   const ScrollBarParameters        *scrollbar,
                                   const ScrollBarStepperParameters *stepper,
                                   int x, int y, int width, int height)
{
      UbuntulooksCorners corners = CL_CORNER_NONE;
      const CairoColor *border = &colors->shade[ widget->disabled ? 4 : 6];
      const CairoColor *bg     = &colors->bg[widget->state_type];
      CairoColor        bg_shade1, bg_shade2;
      cairo_pattern_t *pattern;
      ShadowParameters shadow;
      
      if (scrollbar->horizontal)
      {
            if (stepper->stepper == CL_STEPPER_A)
                  corners = CL_CORNER_TOPLEFT | CL_CORNER_BOTTOMLEFT;
            else if (stepper->stepper == CL_STEPPER_D)
                  corners = CL_CORNER_TOPRIGHT | CL_CORNER_BOTTOMRIGHT;
      }
      else
      {
            if (stepper->stepper == CL_STEPPER_A)
                  corners = CL_CORNER_TOPLEFT | CL_CORNER_TOPRIGHT;
            else if (stepper->stepper == CL_STEPPER_D)
                  corners = CL_CORNER_BOTTOMLEFT | CL_CORNER_BOTTOMRIGHT;
      }
      
      if (widget->prelight || widget->active || widget->disabled)
            bg = &colors->bg[widget->state_type];
      
      ul_shade (bg, &bg_shade1, 1.05);
      ul_shade (bg, &bg_shade2, 0.95);
      
      cairo_translate (cr, x, y);
      cairo_set_line_width (cr, 1);
      
      cairo_rectangle (cr, 1, 1, width-2, height-2);

      if (widget->disabled)
      {
            cairo_set_source_rgb (cr, bg->r, bg->r, bg->g);
      }
      else
      {
            if (scrollbar->horizontal)
                  pattern = cairo_pattern_create_linear (0, 0, 0, height);
            else
                  pattern = cairo_pattern_create_linear (0, 0, width, 0);
            
            cairo_pattern_add_color_stop_rgb (pattern, 0,   bg_shade1.r, bg_shade1.g, bg_shade1.b);
            cairo_pattern_add_color_stop_rgb (pattern, 1,   bg_shade2.r, bg_shade2.g, bg_shade2.b);
            cairo_set_source (cr, pattern);
            cairo_pattern_destroy (pattern);
      }

      cairo_fill (cr);

      ubuntulooks_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, 3.0, corners);      
      cairo_set_source_rgb (cr, border->r, border->g, border->b);
      cairo_stroke (cr);
}

void
ubuntulooks_draw_scrollbar_slider (cairo_t *cr,
                                   const UbuntulooksColors          *colors,
                                   const WidgetParameters          *widget,
                                   const ScrollBarParameters       *scrollbar,
                                   int x, int y, int width, int height)
{
      if (scrollbar->junction & CL_JUNCTION_BEGIN)
      {
            if (scrollbar->horizontal)
            {
                  x -= 1;
                  width += 1;
            }
            else
            {
                  y -= 1;
                  height += 1;
            }
      }
      if (scrollbar->junction & CL_JUNCTION_END)
      {
            if (scrollbar->horizontal)
                  width += 1;
            else
                  height += 1;
      }
      
      if (scrollbar->horizontal)
      {
            cairo_translate (cr, x+0.5, y+0.5); 
      }
      else
      {
            int tmp = height;
            rotate_mirror_translate (cr, M_PI/2, x+0.5, y+0.5, FALSE, FALSE);
            height = width;
            width = tmp;
      }

      if (scrollbar->has_color)
      {
            const CairoColor *border  = &colors->shade[widget->disabled ? 4 : 6];
            CairoColor        fill    = scrollbar->color;
            CairoColor        hilight;
            CairoColor        shade1, shade2, shade3;
            cairo_pattern_t  *pattern;
      
            if (widget->prelight)
                  ul_shade (&fill, &fill, 1.1);
                  
            cairo_set_line_width (cr, 1);
            
            ul_shade (&fill, &hilight, 1.2);
            ul_shade (&fill, &shade1, 1.1);
            ul_shade (&fill, &shade2, 1.05);
            ul_shade (&fill, &shade3, 0.98);
            
            pattern = cairo_pattern_create_linear (2, 2, 2, height-4);
            cairo_pattern_add_color_stop_rgb (pattern, 0,   shade1.r, shade1.g, shade1.b);
            cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b);
            cairo_pattern_add_color_stop_rgb (pattern, 1, fill.r,  fill.g,  fill.b);
            cairo_pattern_add_color_stop_rgb (pattern, 0.5,   shade3.r, shade3.g, shade3.b);    
            cairo_rectangle (cr, 2, 2, width-4, height-4);
            cairo_set_source (cr, pattern);
            cairo_fill (cr);
            cairo_pattern_destroy (pattern);
            
            cairo_rectangle (cr, 1.5, 1.5, width-3, height-3);
            cairo_set_source_rgb (cr, hilight.r, hilight.g, hilight.b);
            cairo_stroke (cr);
      
            cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
            cairo_set_source_rgb (cr, border->r, border->g, border->b);
            cairo_stroke (cr);            
      }
      else
      {
            ubuntulooks_draw_slider (cr, colors, widget, 0, 0, width, height);      
            ubuntulooks_draw_gripdots (cr, 0, 0, width, height, 6, 3, 0);
      }
      
}

void
ubuntulooks_draw_statusbar (cairo_t *cr,
                           const UbuntulooksColors          *colors,
                           const WidgetParameters          *widget,
                           int x, int y, int width, int height)
{
      cairo_set_line_width  (cr, 1);
      cairo_translate       (cr, x, y+0.5);
      cairo_move_to         (cr, 0, 0);
      cairo_line_to         (cr, width, 0);
      cairo_set_source_rgba (cr, 0, 0, 0, 0.2);
      cairo_stroke          (cr);

      cairo_translate       (cr, 0, 1);
      cairo_move_to         (cr, 0, 0);
      cairo_line_to         (cr, width, 0);
      cairo_set_source_rgba (cr, 1, 1, 1, 0.8);
      cairo_stroke          (cr);
}

void
ubuntulooks_draw_menu_frame (cairo_t *cr,
                            const UbuntulooksColors          *colors,
                            const WidgetParameters          *widget,
                            int x, int y, int width, int height)
{
      const CairoColor *border = &colors->shade[5];
      cairo_translate      (cr, x, y);
      cairo_set_line_width (cr, 1);

      cairo_rectangle      (cr, 0.5, 0.5, width-1, height-1);
      cairo_set_source_rgb (cr, border->r, border->g, border->b);
      
      cairo_stroke         (cr);
}

void
ubuntulooks_draw_handle (cairo_t *cr,
                        const UbuntulooksColors          *colors,
                        const WidgetParameters          *widget,
                        const HandleParameters          *handle,
                        int x, int y, int width, int height)
{
      
      const CairoColor *fill  = &colors->bg[widget->state_type];
//    CairoColor *light = &colors->shade[0];
      
      int num_bars, bar_spacing;
      
      if (handle->type == CL_HANDLE_TOOLBAR)
      {
            num_bars    = 8;
            bar_spacing = 3;
      }
      else if (handle->type == CL_HANDLE_SPLITTER)
      {
            num_bars    = 16;
            bar_spacing = 3;
      }

      if (widget->prelight)
      {
            cairo_rectangle (cr, x, y, width, height);
            cairo_set_source_rgb (cr, fill->r, fill->g, fill->b);
            cairo_fill (cr);
      }
      
      cairo_translate (cr, x+0.5, y+0.5);
      
      cairo_set_line_width (cr, 1);
      
      if (handle->horizontal)
      {
            ubuntulooks_draw_gripdots (cr, 0, 0, width, height, num_bars, 2, 0.1);
      }
      else
      {
            ubuntulooks_draw_gripdots (cr, 0, 0, width, height, 2, num_bars, 0.1);
      }
}

static void
ubuntulooks_draw_normal_arrow (cairo_t *cr, const CairoColor *color,
                              double x, double y, double width, double height)
{
      const int ARROW_WIDTH  = 10.0;
      const int ARROW_HEIGHT = 5.0;

      cairo_set_line_width (cr, 1);
      
      cairo_move_to   (cr, x-ARROW_WIDTH/2, y-ARROW_HEIGHT/2);
      cairo_line_to   (cr, x, y+ARROW_HEIGHT/2);
      cairo_line_to   (cr, x+ARROW_WIDTH/2, y-ARROW_HEIGHT/2);
      
      cairo_set_source_rgb (cr, color->r, color->g, color->b);
      cairo_fill (cr);  
}

static void
ubuntulooks_draw_combo_arrow (cairo_t *cr, const CairoColor *fill,
                             double x, double y, double width, double height)
{
      const int ARROW_WIDTH   = 7.0;
      const int ARROW_HEIGHT  = 5.0;
      const int ARROW_SPACING = 8;
      
      cairo_set_line_width (cr, 1);

      y -= ARROW_SPACING/2;
      
      cairo_move_to (cr, x-ARROW_WIDTH/2, y+ ARROW_HEIGHT/2);
      cairo_line_to   (cr, x, y-ARROW_HEIGHT/2);
      cairo_line_to   (cr, x+ARROW_WIDTH/2, y+ARROW_HEIGHT/2);
      cairo_set_source_rgb (cr, fill->r, fill->g, fill->b); 
      cairo_fill (cr);
      
      y += ARROW_SPACING;
      
      cairo_move_to (cr, x-ARROW_WIDTH/2, y + -ARROW_HEIGHT/2);
      cairo_line_to   (cr, x, y+ARROW_HEIGHT/2);
      cairo_line_to   (cr, x+ARROW_WIDTH/2, y-ARROW_HEIGHT/2);
      cairo_set_source_rgb (cr, fill->r, fill->g, fill->b); 
      cairo_fill (cr);
}

static void
_ubuntulooks_draw_arrow (cairo_t *cr, const CairoColor *color,
                        UbuntulooksDirection dir, UbuntulooksArrowType type,
                        double x, double y, double width, double height)
{
      double rotate;
      
      if (dir == CL_DIRECTION_LEFT)
            rotate = M_PI*1.5;
      else if (dir == CL_DIRECTION_RIGHT)
            rotate = M_PI*0.5;
      else if (dir == CL_DIRECTION_UP)
            rotate = M_PI;
      else
            rotate = 0;
      
      if (dir == CL_DIRECTION_UP || dir == CL_DIRECTION_DOWN)
            x++;
      
      if (type == CL_ARROW_NORMAL)
      {
            rotate_mirror_translate (cr, rotate, x, y, FALSE, FALSE);         
            ubuntulooks_draw_normal_arrow (cr, color, -0.5, -0.5, width, height);
      }
      else if (type == CL_ARROW_COMBO)
      {
            cairo_translate (cr, x, y);
            ubuntulooks_draw_combo_arrow (cr, color, -0.5, -0.5, width, height);
      }
}

void
ubuntulooks_draw_arrow (cairo_t *cr,
                       const UbuntulooksColors          *colors,
                       const WidgetParameters          *widget,
                       const ArrowParameters           *arrow,
                       int x, int y, int width, int height)
{
      //CairoColor *color = &colors->shade[7];
      CairoColor black = {0,0,0};
      const CairoColor *color = &black;
      gdouble tx, ty;
      
      if (arrow->direction == CL_DIRECTION_DOWN || arrow->direction == CL_DIRECTION_UP)
      {
            tx = x + width/2;
            ty = (y + height/2) + 0.5;
      }
      else
      {
            tx = (x + width/2) + 0.5;
            ty = y + height/2;
      }
      
      if (widget->disabled)
      {
            _ubuntulooks_draw_arrow (cr, &colors->shade[0],
                                    arrow->direction, arrow->type,
                                    tx+0.5, ty+0.5, width, height);
            
            color = &colors->shade[4];
      }

      cairo_identity_matrix (cr);
      
      _ubuntulooks_draw_arrow (cr, color, arrow->direction, arrow->type,
                              tx, ty, width, height);
}

void
ubuntulooks_draw_resize_grip (cairo_t *cr,
                             const UbuntulooksColors          *colors,
                             const WidgetParameters          *widget,
                             const ResizeGripParameters      *grip,
                             int x, int y, int width, int height)
{
      int lx, ly;
 
      cairo_set_line_width (cr, 1);
      
      for (ly=0; ly<4; ly++) // vertically, four rows of dots
      {
            for (lx=0; lx<=ly; lx++) // horizontally
            {
                  int ny = (3.5-ly) * 3;
                  int nx = lx * 3;

                  cairo_set_source_rgba (cr, 1, 1, 1, 1.2);
                  cairo_rectangle (cr, x+width-nx-1, y+height-ny-1, 2, 2);
                  cairo_fill (cr);

                  cairo_set_source_rgba (cr, 0, 0, 0, 0.4);
                  cairo_rectangle (cr, x+width-nx-1, y+height-ny-1, 1, 1);
                  cairo_fill (cr);
            }
      }
}

void
ubuntulooks_draw_checkbox (cairo_t *cr,
                          const UbuntulooksColors  *colors,
                          const WidgetParameters  *widget,
                          const CheckboxParameters *checkbox,
                          int x, int y, int width, int height)
{
      CairoColor border, top, bottom;
      cairo_pattern_t *pattern;
      gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN);

      
      cairo_set_line_width (cr, 1.0);
      
      if (!checkbox->in_menu)
      {
            if ( (checkbox->shadow_type == CL_SHADOW_IN || 
                  checkbox->shadow_type == CL_SHADOW_ETCHED_IN || 
                  widget->active) && !widget->disabled && !checkbox->in_cell )
            {
                  border = top = bottom = colors->spot[1];
                  
                  if (widget->prelight)
                  {
                        ul_shade (&top, &top, 1.1);
                        ul_shade (&border, &border, 0.8);
                  }
                  
                  ul_shade (&top, &top, 1.2);
                  ul_shade (&bottom, &bottom, 0.9);
                  ul_shade (&border, &border, 0.6);
            }
            else if (widget->disabled)
            {
                  if (checkbox->in_cell) {
                        border = top = bottom = colors->shade[3];
                  } else {
                        border = top = bottom = colors->shade[3];
                  }
            }     
            else
            {
                  top = bottom = colors->base[widget->state_type];
                  
                  if (widget->prelight)
                  {
                        ul_shade (&top, &top, 1.2);
                        border = colors->spot[2];
                        
                  }
                  else
                  {
                        border = colors->base[widget->state_type];
                        ul_shade(&border, &border, 0.4);
                  }
                  
                  ul_shade (&top, &top, 0.98);
                  ul_shade (&bottom, &bottom, 0.85);
            }
            
            if (widget->state_type != GTK_STATE_INSENSITIVE)
            {
                  // glow
                  if ((widget->prelight || (widget->active && !draw_bullet)) && !checkbox->in_cell) 
                  {
                        const CairoColor *glow = &colors->spot[0];
                        ubuntulooks_rounded_rectangle (cr, x+1.5, y+1.5, width - 1, height - 1, 2, widget->corners);
                        cairo_set_source_rgba (cr, glow->r, glow->g, glow->b, 0.5);
                        cairo_stroke (cr);
                  }
                  
                  // shadow
                  if (checkbox->in_cell) {
                        ubuntulooks_rounded_rectangle (cr, x+0.5, y+0.5, width, height, 1, widget->corners);
                  } else {
                        ubuntulooks_rounded_rectangle (cr, x+3.5, y+3.5, width - 3, height - 3, 1, widget->corners);
                  }
                  cairo_set_source_rgba (cr, 0., 0., 0., 0.2);
                  cairo_stroke (cr);
            
                  if (checkbox->in_cell) {
                        ubuntulooks_rounded_rectangle (cr, x+0.5, y+0.5, width, height, 1, widget->corners);
                  } else {
                        ubuntulooks_rounded_rectangle (cr, x+2.5, y+2.5, width - 3, height - 3, 1, widget->corners);
                  }
                  pattern = cairo_pattern_create_linear (x, y, x+width, y+height);
                  cairo_pattern_add_color_stop_rgb (pattern, 0.0, 1.0, 1.0, 1.0);
                  cairo_pattern_add_color_stop_rgb (pattern, 0.4, top.r, top.g, top.b);
                  cairo_pattern_add_color_stop_rgb (pattern, 1.0, bottom.r, bottom.g, bottom.b);
                  cairo_set_source (cr, pattern);
                  cairo_fill (cr);
                  cairo_pattern_destroy (pattern);
            }
            
            if (checkbox->in_cell) {
                  ubuntulooks_rounded_rectangle (cr, x+0.5, y+0.5, width, height, 1, widget->corners);
            } else {
                  ubuntulooks_rounded_rectangle (cr, x+2.5, y+2.5, width - 3, height - 3, 1, widget->corners);
            }
            
            cairo_set_source_rgb (cr, border.r, border.g, border.b);
            cairo_stroke (cr);
            
            if (checkbox->in_cell) {
                  ubuntulooks_rounded_rectangle (cr, x+1.5, y+1.5, width - 2, height - 2, 1, widget->corners);
            } else {
                  ubuntulooks_rounded_rectangle (cr, x+3.5, y+3.5, width - 5, height - 5, 1, widget->corners);
            }
            cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.4);
            cairo_stroke (cr);
            
      }
      
      /* To offset this checkmark, one should probably use a translation */
      if (draw_bullet)
      {
            if (checkbox->in_cell)
            {
                  cairo_translate (cr, -2, -2);
            }
            else if (checkbox->in_menu)
            {
                  cairo_translate (cr, -2, -2);
            }
      
            cairo_move_to (cr, x + 4, y + 8);
            cairo_rel_line_to (cr,   5,   4);
            cairo_rel_curve_to (cr,  1.4,  -5,   -1,  -1,   5.7,  -12.5);
            cairo_rel_curve_to (cr, -4,   4,  -4,   4,  -6.7,    9.3);
            cairo_rel_line_to (cr,  -2.3,  -2.5);
            
            
            cairo_set_source_rgb (cr, colors->text[widget->state_type].r,
                                      colors->text[widget->state_type].g,
                                      colors->text[widget->state_type].b);
            cairo_fill (cr);
      }
}

void
ubuntulooks_draw_radiobutton (cairo_t *cr,
                             const UbuntulooksColors  *colors,
                             const WidgetParameters  *widget,
                             const CheckboxParameters *checkbox,
                             int x, int y, int width, int height)
{
      CairoColor border, top, bottom;
      cairo_pattern_t *pattern;
      gboolean draw_bullet = (checkbox->shadow_type == CL_SHADOW_IN || checkbox->shadow_type == CL_SHADOW_ETCHED_IN);
      
      cairo_set_line_width (cr, 1.0);
      
      if (checkbox->in_menu)
      {
            cairo_translate (cr, -2, -1);
      }

      if ( (checkbox->shadow_type == CL_SHADOW_IN || 
            checkbox->shadow_type == CL_SHADOW_ETCHED_IN || 
            widget->active) && !widget->disabled )
      {
            border = top = bottom = colors->spot[1];
            
            if (widget->prelight)
            {
                  ul_shade (&top, &top, 1.1);
                  ul_shade (&border, &border, 0.8);
            }
            
            ul_shade (&top, &top, 1.2);
            ul_shade (&bottom, &bottom, 0.9);
            ul_shade (&border, &border, 0.6);
      }
      else if (widget->disabled)
      {
            border = top = bottom = colors->shade[3];
      }
      else
      {           
            top = bottom = colors->base[widget->state_type];
            
            if (widget->prelight)
            {
                  ul_shade (&top, &top, 1.2);
                  border = colors->spot[2];
                  
            }
            else
            {
                  border = colors->base[widget->state_type];
                  ul_shade(&border, &border, 0.4);
            }
            
            ul_shade (&top, &top, 0.98);
            ul_shade (&bottom, &bottom, 0.85);
      }
      
      if ( widget->state_type != GTK_STATE_INSENSITIVE )
      {
            // glow
            if (widget->prelight || (widget->active && !draw_bullet)) 
            {
                  const CairoColor *glow = &colors->spot[0];
                  cairo_arc (cr, x+width/2.0 + 0.5, y+height/2.0 + 0.5, width/2.0, 0, 2 * M_PI);
                  cairo_set_source_rgba (cr, glow->r, glow->g, glow->b, 1.0);
                  cairo_stroke (cr);
            }
      
            // shadow
            cairo_arc (cr, x+width/2.0+1, y+height/2.0+1, width/2.0 - 1.0, 0, 2 * M_PI);
            cairo_set_source_rgba (cr, 0., 0., 0., 0.2);
            cairo_stroke (cr);
            
            cairo_arc (cr, x+width/2., y+height/2.0, width/2.0 - 1.0, 0, 2 * M_PI); 
            pattern = cairo_pattern_create_linear (x, y, x+width, y+height);
            cairo_pattern_add_color_stop_rgb (pattern, 0.0, 1.0, 1.0, 1.0);
            cairo_pattern_add_color_stop_rgb (pattern, 0.4, top.r, top.g, top.b);
            cairo_pattern_add_color_stop_rgb (pattern, 1.0, bottom.r, bottom.g, bottom.b);
            cairo_set_source (cr, pattern);
            cairo_fill(cr);
            cairo_pattern_destroy (pattern);
      }
      cairo_translate (cr, 0.5, 0.5);
      cairo_arc (cr, x+width/2.0, y+height/2.0, width/2.0 - 1.0, 0, 2 * M_PI);
      
      cairo_set_source_rgb (cr, border.r, border.g, border.b);
      cairo_stroke (cr);
      
      cairo_arc (cr, x+width/2., y+height/2.0, width/2.0 - 2.0, 0, 2 * M_PI);
      cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.4);
      cairo_stroke (cr);
      
      // draw the bullet
      if (draw_bullet)
      {
            cairo_arc (cr, x+width/2., y+height/2., 2.5, 0, 2 * M_PI);
            if (widget->disabled)
            {
                  cairo_set_source_rgb (cr, colors->text[widget->state_type].r,
                                            colors->text[widget->state_type].g,
                                            colors->text[widget->state_type].b);
            }
            else
            {
                  pattern = cairo_pattern_create_radial (x+width/2. - 1.25, y+height/2. - 1.25, 0.1, x+width/2. - 1.25, y+height/2. - 1.25, 4);
                  cairo_pattern_add_color_stop_rgb (pattern, 0.0, 0.4, 0.4, 0.4);
                  cairo_pattern_add_color_stop_rgb (pattern, 1.0, colors->text[widget->state_type].r,
                                                                  colors->text[widget->state_type].g,
                                                                  colors->text[widget->state_type].b);
                  cairo_set_source (cr, pattern);
                  cairo_pattern_destroy (pattern);
            }
            cairo_fill_preserve (cr);
      }
}

void
ubuntulooks_draw_prelightbox (cairo_t *cr,
                              const UbuntulooksColors         *colors,
                              const WidgetParameters          *widget,
                              int x, int y, int width, int height)
{
      const CairoColor  *bg = &colors->bg[CL_STATE_PRELIGHT];

      ubuntulooks_rounded_rectangle (cr, x, y, width, height, 5.0, widget->corners);
      cairo_set_source_rgb (cr, bg->r, bg->g, bg->b);
      cairo_fill (cr);
}

void
ubuntulooks_draw_tooltip (cairo_t *cr,
                          const UbuntulooksColors         *colors,
                          const WidgetParameters          *widget,
                          int x, int y, int width, int height)
{
      const CairoColor  *bg = &colors->bg[CL_STATE_NORMAL];
      CairoColor        tmp;
      cairo_pattern_t  *pattern;
            
      cairo_set_line_width (cr, 1.0);
            
      ul_shade (bg, &tmp, 0.9);
      
      cairo_translate (cr, x, y);
      
      cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
      
      pattern = cairo_pattern_create_linear (0, 0, width, 0);
      cairo_pattern_add_color_stop_rgb (pattern, 0.0, tmp.r, tmp.g, tmp.b);
      cairo_pattern_add_color_stop_rgb (pattern, 0.5, bg->r, bg->g, bg->b);
      cairo_pattern_add_color_stop_rgb (pattern, 1.0, tmp.r, tmp.g, tmp.b);
      cairo_set_source (cr, pattern);
      cairo_fill_preserve (cr);
      cairo_pattern_destroy (pattern);
      
      cairo_set_source_rgb (cr, 0, 0, 0);
      cairo_stroke (cr);
}

void
ubuntulooks_draw_gdm_window (cairo_t *cr,
                             const UbuntulooksColors         *colors,
                             const WidgetParameters          *widget,
                             int x, int y, int width, int height)
{
      const CairoColor  *bg = &colors->bg[CL_STATE_NORMAL];
      CairoColor        tmp;
      cairo_pattern_t  *pattern;

      cairo_translate (cr, x, y);

      ul_shade (bg, &tmp, 0.9);

      cairo_rectangle (cr, 0, 0, width, height);
      pattern = cairo_pattern_create_linear (0, 0, width, 0);
      cairo_pattern_add_color_stop_rgb (pattern, 0.0, tmp.r, tmp.g, tmp.b);
      cairo_pattern_add_color_stop_rgb (pattern, 0.5, bg->r, bg->g, bg->b);
      cairo_pattern_add_color_stop_rgb (pattern, 1.0, tmp.r, tmp.g, tmp.b);
      cairo_set_source (cr, pattern);
      cairo_fill (cr);
      cairo_pattern_destroy (pattern);
}

void
ubuntulooks_draw_gdm_menu_frame (cairo_t *cr,
                                 const UbuntulooksColors         *colors,
                                 const WidgetParameters          *widget,
                                 int x, int y, int width, int height)
{
      cairo_pattern_t  *pattern;
      CairoColor        tmp1, tmp2;
      const CairoColor *spot = &colors->spot[1];

      cairo_translate      (cr, x, y);
      cairo_set_line_width (cr, 1);
      cairo_rectangle      (cr, 0.5, 0.5, width-1, height-1);
      cairo_set_source_rgb (cr, 0, 0, 0);
      cairo_stroke_preserve (cr);

      ul_shade (spot, &tmp1, 1.6);
      ul_shade (spot, &tmp2, 1.5);

      pattern = cairo_pattern_create_linear (0, 0, width, 0);
      cairo_pattern_add_color_stop_rgb (pattern, 0.0, tmp1.r, tmp1.g, tmp1.b);
      cairo_pattern_add_color_stop_rgb (pattern, 1.0, tmp2.r, tmp2.g, tmp2.b);
      cairo_set_source (cr, pattern);
      cairo_fill (cr);
      cairo_pattern_destroy (pattern);
}

void
ubuntulooks_draw_list_selection (cairo_t *cr,
                                 const UbuntulooksColors         *colors,
                                 const WidgetParameters          *widget,
                                 int x, int y, int width, int height)
{
      cairo_pattern_t *pattern;
      CairoColor       lower_color;
      CairoColor       upper_color;

      cairo_translate (cr, x, y);

      if (widget->focus)
            upper_color = colors->base[widget->state_type];
      else
            upper_color = colors->base[GTK_STATE_ACTIVE];

      ul_shade (&upper_color, &lower_color, 0.9);

      pattern = cairo_pattern_create_linear (0, 0, 0, height);
      cairo_pattern_add_color_stop_rgb (pattern, 0.0, upper_color.r,
                                                      upper_color.g,
                                                      upper_color.b);
      cairo_pattern_add_color_stop_rgb (pattern, 1.0, lower_color.r,
                                                      lower_color.g,
                                                      lower_color.b);

      cairo_set_source (cr, pattern);
      cairo_rectangle  (cr, 0, 0, width, height);
      cairo_fill       (cr);

      cairo_pattern_destroy (pattern);
}


Generated by  Doxygen 1.6.0   Back to index