static gboolean
um_crop_area_expose (GtkWidget      *widget,
                     GdkEventExpose *event)
{
        cairo_t *cr;
        GdkRectangle area;
        GdkRectangle crop;
        gint width, height;
        UmCropArea *uarea = UM_CROP_AREA (widget);

        if (uarea->priv->browse_pixbuf == NULL)
                return FALSE;

        update_pixbufs (uarea);

        width = gdk_pixbuf_get_width (uarea->priv->pixbuf);
        height = gdk_pixbuf_get_height (uarea->priv->pixbuf);
        crop_to_widget (uarea, &crop);

        area.x = 0;
        area.y = 0;
        area.width = width;
        area.height = crop.y;
        gdk_rectangle_intersect (&area, &event->area, &area);
        gdk_draw_pixbuf (widget->window,
                         widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
                         uarea->priv->color_shifted,
                         area.x, area.y,
                         area.x, area.y,
                         area.width, area.height,
                         GDK_RGB_DITHER_NONE, 0, 0);

        area.x = 0;
        area.y = crop.y;
        area.width = crop.x;
        area.height = crop.height;
        gdk_rectangle_intersect (&area, &event->area, &area);
        gdk_draw_pixbuf (widget->window,
                         widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
                         uarea->priv->color_shifted,
                         area.x, area.y,
                         area.x, area.y,
                         area.width, area.height,
                         GDK_RGB_DITHER_NONE, 0, 0);

        area.x = crop.x;
        area.y = crop.y;
        area.width = crop.width;
        area.height = crop.height;
        gdk_rectangle_intersect (&area, &event->area, &area);
        gdk_draw_pixbuf (widget->window,
                         widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
                         uarea->priv->pixbuf,
                         area.x, area.y,
                         area.x, area.y,
                         area.width, area.height,
                         GDK_RGB_DITHER_NONE, 0, 0);

        area.x = crop.x + crop.width;
        area.y = crop.y;
        area.width = width - area.x;
        area.height = crop.height;
        gdk_rectangle_intersect (&area, &event->area, &area);
        gdk_draw_pixbuf (widget->window,
                         widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
                         uarea->priv->color_shifted,
                         area.x, area.y,
                         area.x, area.y,
                         area.width, area.height,
                         GDK_RGB_DITHER_NONE, 0, 0);

        area.x = 0;
        area.y = crop.y + crop.height;
        area.width = width;
        area.height = height - area.y;
        gdk_rectangle_intersect (&area, &event->area, &area);
        gdk_draw_pixbuf (widget->window,
                         widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
                         uarea->priv->color_shifted,
                         area.x, area.y,
                         area.x, area.y,
                         area.width, area.height,
                         GDK_RGB_DITHER_NONE, 0, 0);

        cr = gdk_cairo_create (widget->window);
        gdk_cairo_rectangle (cr, &event->area);
        cairo_clip (cr);

        if (uarea->priv->active_region != OUTSIDE) {
                gint x1, x2, y1, y2;
                gdk_cairo_set_source_color (cr, &widget->style->white);
                cairo_set_line_width (cr, 1.0);
                x1 = crop.x + crop.width / 3.0;
                x2 = crop.x + 2 * crop.width / 3.0;
                y1 = crop.y + crop.height / 3.0;
                y2 = crop.y + 2 * crop.height / 3.0;

                cairo_move_to (cr, x1 + 0.5, crop.y);
                cairo_line_to (cr, x1 + 0.5, crop.y + crop.height);

                cairo_move_to (cr, x2 + 0.5, crop.y);
                cairo_line_to (cr, x2 + 0.5, crop.y + crop.height);

                cairo_move_to (cr, crop.x, y1 + 0.5);
                cairo_line_to (cr, crop.x + crop.width, y1 + 0.5);

                cairo_move_to (cr, crop.x, y2 + 0.5);
                cairo_line_to (cr, crop.x + crop.width, y2 + 0.5);
                cairo_stroke (cr);
        }

        gdk_cairo_set_source_color (cr, &widget->style->black);
        cairo_set_line_width (cr, 1.0);
        cairo_rectangle (cr,
                         crop.x + 0.5,
                         crop.y + 0.5,
                         crop.width - 1.0,
                         crop.height - 1.0);
        cairo_stroke (cr);

        gdk_cairo_set_source_color (cr, &widget->style->white);
        cairo_set_line_width (cr, 2.0);
        cairo_rectangle (cr,
                         crop.x + 2.0,
                         crop.y + 2.0,
                         crop.width - 4.0,
                         crop.height - 4.0);
        cairo_stroke (cr);

        cairo_destroy (cr);

        return FALSE;
}
static void
ag_chart_renderer_render(GtkCellRenderer      *renderer,
                         cairo_t              *cr,
                         GtkWidget            *widget,
                         const GdkRectangle   *background_area,
                         const GdkRectangle   *cell_area,
                         GtkCellRendererState flags)
{
    AgChartRendererPrivate *priv = ag_chart_renderer_get_instance_private(
            AG_CHART_RENDERER(renderer)
        );
    int             margin;
    GtkStyleContext *context = gtk_widget_get_style_context(widget);
    GdkPixbuf       *pixbuf;

    gtk_style_context_save(context);
    gtk_style_context_add_class(context, "ag-chart-renderer");

    if (priv->css_class) {
        gtk_style_context_add_class(context, priv->css_class);
    }

    cairo_save(cr);
    gdk_cairo_rectangle(cr, cell_area);
    cairo_clip(cr);

    cairo_translate(cr, cell_area->x, cell_area->y);

    margin = MAX(
            AG_CHART_RENDERER_TILE_MARGIN,
            (int)((cell_area->width - AG_CHART_RENDERER_TILE_SIZE) / 2)
        );

    g_object_get(renderer, "pixbuf", &pixbuf, NULL);

    if (pixbuf != NULL) {
        GdkRectangle area = {
                margin,
                margin,
                AG_CHART_RENDERER_TILE_SIZE,
                AG_CHART_RENDERER_TILE_SIZE
            };

        GTK_CELL_RENDERER_CLASS(ag_chart_renderer_parent_class)->render(
                renderer,
                cr,
                widget,
                &area,
                &area,
                flags
            );
    } else {
        gtk_render_frame(
                context,
                cr,
                margin,
                margin,
                AG_CHART_RENDERER_TILE_SIZE,
                AG_CHART_RENDERER_TILE_SIZE
            );
        gtk_render_background(
                context,
                cr,
                margin,
                margin,
                AG_CHART_RENDERER_TILE_SIZE,
                AG_CHART_RENDERER_TILE_SIZE
            );
    }

    gtk_style_context_restore(context);

    if (priv->toggle_visible) {
        gint xpad,
             ypad,
             x_offset,
             check_x,
             check_y;

        gtk_cell_renderer_get_padding(
                GTK_CELL_RENDERER(renderer),
                &xpad, &ypad
            );

        if (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL) {
            x_offset = xpad;
        } else {
            x_offset = cell_area->width
                - AG_CHART_RENDERER_CHECK_ICON_SIZE
                - xpad;
        }

        check_x = x_offset;
        check_y = cell_area->height - AG_CHART_RENDERER_CHECK_ICON_SIZE - ypad;

        gtk_style_context_save(context);
        gtk_style_context_add_class(context, GTK_STYLE_CLASS_CHECK);

        if (priv->checked) {
            gtk_style_context_set_state(context, GTK_STATE_FLAG_CHECKED);
        }

        gtk_render_background(
                context,
                cr,
                check_x,
                check_y,
                AG_CHART_RENDERER_CHECK_ICON_SIZE,
                AG_CHART_RENDERER_CHECK_ICON_SIZE
            );
        gtk_render_frame(
                context,
                cr,
                check_x,
                check_y,
                AG_CHART_RENDERER_CHECK_ICON_SIZE,
                AG_CHART_RENDERER_CHECK_ICON_SIZE
            );
        gtk_render_check(
                context,
                cr,
                check_x,
                check_y,
                AG_CHART_RENDERER_CHECK_ICON_SIZE,
                AG_CHART_RENDERER_CHECK_ICON_SIZE
            );

        gtk_style_context_restore(context);
    }

    cairo_restore(cr);
}
/*! \brief Actually renders the swatch */
static void
ghid_cell_renderer_visibility_render (GtkCellRenderer      *cell,
                                      GdkWindow            *window,
                                      GtkWidget            *widget,
                                      GdkRectangle         *background_area,
                                      GdkRectangle         *cell_area,
                                      GdkRectangle         *expose_area,
                                      GtkCellRendererState  flags)
{
  GHidCellRendererVisibility *pcb_cell;
  GdkRectangle toggle_rect;
  GdkRectangle draw_rect;
  gint xpad, ypad;

  pcb_cell = GHID_CELL_RENDERER_VISIBILITY (cell);
  ghid_cell_renderer_visibility_get_size (cell, widget, cell_area,
                                          &toggle_rect.x,
                                          &toggle_rect.y,
                                          &toggle_rect.width,
                                          &toggle_rect.height);
  gtk_cell_renderer_get_padding (cell, &xpad, &ypad);

  toggle_rect.x      += cell_area->x + xpad;
  toggle_rect.y      += cell_area->y + ypad;
  toggle_rect.width  -= xpad * 2;
  toggle_rect.height -= ypad * 2;

  if (toggle_rect.width <= 0 || toggle_rect.height <= 0)
    return;

  if (gdk_rectangle_intersect (expose_area, cell_area, &draw_rect))
    {
      GdkColor color;
      cairo_t *cr = gdk_cairo_create (window);
      cairo_pattern_t *pattern;

      if (expose_area)
        {
          gdk_cairo_rectangle (cr, expose_area);
          cairo_clip (cr);
        }
      cairo_set_line_width (cr, 1);

      cairo_rectangle (cr, toggle_rect.x + 0.5, toggle_rect.y + 0.5,
                           toggle_rect.width - 1, toggle_rect.height - 1);
      cairo_set_source_rgb (cr, 1, 1, 1);
      cairo_fill_preserve (cr);
      cairo_set_source_rgb (cr, 0, 0, 0);
      cairo_stroke (cr);

      gdk_color_parse (pcb_cell->color, &color);
      if (flags & GTK_CELL_RENDERER_PRELIT)
        {
          color.red = (4*color.red + 65535) / 5;
          color.green = (4*color.green + 65535) / 5;
          color.blue = (4*color.blue + 65535) / 5;
        }

      pattern = cairo_pattern_create_radial ((toggle_rect.width  - 1.) * 0.75 + toggle_rect.x + 0.5,
                                             (toggle_rect.height - 1.) * 0.75 + toggle_rect.y + 0.5,
                                             0.,
                                             (toggle_rect.width  - 1.) * 0.50 + toggle_rect.x + 0.5,
                                             (toggle_rect.height - 1.) * 0.50 + toggle_rect.y + 0.5,
                                             (toggle_rect.width  - 1.) * 0.71);

      cairo_pattern_add_color_stop_rgb (pattern, 0.0,
                                        (color.red   / 65535. * 4. + 1.) / 5.,
                                        (color.green / 65535. * 4. + 1.) / 5.,
                                        (color.blue  / 65535. * 4. + 1.) / 5.);
      cairo_pattern_add_color_stop_rgb (pattern, 1.0,
                                        (color.red   / 65535. * 5. + 0.) / 5.,
                                        (color.green / 65535. * 5. + 0.) / 5.,
                                        (color.blue  / 65535. * 5. + 0.) / 5.);
      cairo_set_source (cr, pattern);
      cairo_pattern_destroy (pattern);

      if (pcb_cell->active)
        cairo_rectangle (cr, toggle_rect.x + 0.5, toggle_rect.y + 0.5,
                             toggle_rect.width - 1, toggle_rect.height - 1);
      else
        {
          cairo_move_to (cr, toggle_rect.x + 1, toggle_rect.y + 1);
          cairo_rel_line_to (cr, toggle_rect.width / 2, 0);
          cairo_rel_line_to (cr, -toggle_rect.width / 2, toggle_rect.width / 2);
          cairo_close_path (cr);
        }
      cairo_fill (cr);

      cairo_destroy (cr);
    }
}
Esempio n. 4
0
static gint
expose_event (GtkWidget      *widget, 
              GdkEventExpose *event, 
              gpointer        data)
#endif
{
  MateColorButton *color_button = MATE_COLOR_BUTTON (data);
  GtkAllocation allocation;
  cairo_pattern_t *checkered;
#if !GTK_CHECK_VERSION (3, 0, 0)
  cairo_t *cr;

  cr = gdk_cairo_create (event->window);

  gtk_widget_get_allocation (widget, &allocation);
  gdk_cairo_rectangle (cr, &allocation);
  cairo_clip (cr);
#endif

  if (mate_color_button_has_alpha (color_button))
    {
      cairo_save (cr);

      cairo_set_source_rgb (cr, CHECK_DARK, CHECK_DARK, CHECK_DARK);
      cairo_paint (cr);

      cairo_set_source_rgb (cr, CHECK_LIGHT, CHECK_LIGHT, CHECK_LIGHT);
      cairo_scale (cr, CHECK_SIZE, CHECK_SIZE);

      checkered = mate_color_button_get_checkered ();
      cairo_mask (cr, checkered);
      cairo_pattern_destroy (checkered);

      cairo_restore (cr);

      cairo_set_source_rgba (cr,
                             color_button->priv->color.red / 65535.,
                             color_button->priv->color.green / 65535.,
                             color_button->priv->color.blue / 65535.,
                             color_button->priv->alpha / 65535.);
    }
  else
    {
      gdk_cairo_set_source_color (cr, &color_button->priv->color);
    }

  cairo_paint (cr);

  if (!gtk_widget_is_sensitive (GTK_WIDGET (color_button)))
    {
      gdk_cairo_set_source_color (cr, &gtk_widget_get_style (GTK_WIDGET(color_button))->bg[GTK_STATE_INSENSITIVE]);
      checkered = mate_color_button_get_checkered ();
      cairo_mask (cr, checkered);
      cairo_pattern_destroy (checkered);
    }

#if !GTK_CHECK_VERSION (3, 0, 0)
  cairo_destroy (cr);
#endif

  return FALSE;
}
/* Call gtk_source_gutter_renderer_begin() on each renderer. */
static void
begin_draw (GtkSourceGutter *gutter,
            GtkTextView     *view,
            GArray          *renderer_widths,
            LinesInfo       *info,
            cairo_t         *cr)
{
    GdkRectangle background_area;
    GdkRectangle cell_area;
    GList *l;
    gint renderer_num;

    background_area.x = 0;
    background_area.height = info->total_height;

    gtk_text_view_buffer_to_window_coords (view,
                                           gutter->priv->window_type,
                                           0,
                                           g_array_index (info->buffer_coords, gint, 0),
                                           NULL,
                                           &background_area.y);

    cell_area = background_area;

    for (l = gutter->priv->renderers, renderer_num = 0;
            l != NULL;
            l = l->next, renderer_num++)
    {
        Renderer *renderer = l->data;
        gint width;
        gint xpad;

        width = g_array_index (renderer_widths, gint, renderer_num);

        if (!gtk_source_gutter_renderer_get_visible (renderer->renderer))
        {
            g_assert_cmpint (width, ==, 0);
            continue;
        }

        gtk_source_gutter_renderer_get_padding (renderer->renderer,
                                                &xpad,
                                                NULL);

        background_area.width = width;

        cell_area.width = background_area.width - 2 * xpad;
        cell_area.x = background_area.x + xpad;

        cairo_save (cr);

        gdk_cairo_rectangle (cr, &background_area);
        cairo_clip (cr);

        gtk_source_gutter_renderer_begin (renderer->renderer,
                                          cr,
                                          &background_area,
                                          &cell_area,
                                          &info->start,
                                          &info->end);

        cairo_restore (cr);

        background_area.x += background_area.width;
    }
Esempio n. 6
0
 static gboolean expose(GtkWidget *widget, GdkEventExpose *event, void *t)
 {
#if GTK_CHECK_VERSION(2,14,0)
	GdkWindow *window = gtk_widget_get_window(widget);
#else
	GdkWindow *window = widget->window;
#endif
 	cairo_t *cr	= gdk_cairo_create(window);

 	if(!pixmap_terminal)
 	{
 		// Rebuild pixmap
 		gint width;
 		gint height;
		gdk_drawable_get_size(window,&width,&height);
		pixmap_terminal = gdk_pixmap_new(window,width,height,-1);
		g_object_set_data_full(G_OBJECT(pixmap_terminal),"cached_gc",gdk_gc_new(GDK_DRAWABLE(pixmap_terminal)),g_object_unref);
		update_terminal_contents();
 	}

    gdk_cairo_set_source_pixmap(cr, pixmap_terminal, 0, 0);
    gdk_cairo_rectangle(cr, &event->area);
    cairo_fill(cr);

	if((cMode & CURSOR_MODE_ENABLED))
	{
		if(!get_cursor_pixmap())
		{
			pixmap_cursor = gdk_pixmap_new(window,rCursor.width,rCursor.height,-1);
			update_cursor_pixmap();
		}

		if( (cMode & (CURSOR_MODE_BASE|CURSOR_MODE_SHOW)) == (CURSOR_MODE_BASE|CURSOR_MODE_SHOW) )
		{
			gdk_cairo_set_source_pixmap(cr, get_cursor_pixmap(), rCursor.x, rCursor.y);

			if(Toggled(INSERT))
				cairo_rectangle(cr, rCursor.x, rCursor.y, rCursor.width, rCursor.height);
			else
				cairo_rectangle(cr, rCursor.x, rCursor.y+terminal_font_info.ascent, rCursor.width, terminal_font_info.descent);

			cairo_fill(cr);

/*
			GtkStyle	*style	= gtk_widget_get_style(widget);
			gdk_draw_drawable(		widget->window,	style->fg_gc[GTK_STATE_NORMAL],
									GDK_DRAWABLE(get_cursor_pixmap()),
									0,0,
									rCursor.x,rCursor.y,
									rCursor.width,rCursor.height);
*/
		}


		if(cMode & CURSOR_MODE_CROSS)
		{
			// Draw cross-hair cursor
			int			width;
			int			height;

			gdk_drawable_get_size(window,&width,&height);

			gdk_cairo_set_source_color(cr,color+TERMINAL_COLOR_CROSS_HAIR);
			cairo_rectangle(cr, rCursor.x, 0, 1, view.top+2+(terminal_font_info.spacing*view.rows));
			cairo_rectangle(cr, 0, rCursor.y+fontAscent, width,1);
			cairo_fill(cr);
		}
	}

    cairo_destroy(cr);

	return 0;
 }
Esempio n. 7
0
cairo_surface_t *
gb_widget_snapshot (GtkWidget *widget,
                    gint       width,
                    gint       height,
                    gdouble    alpha,
                    gboolean   draw_border)
{
    cairo_surface_t *surface;
    GtkAllocation alloc;
    gdouble x_ratio = 1.0;
    gdouble y_ratio = 1.0;
    cairo_t *cr;

    /*
     * XXX: This function conflates the drawing of borders and snapshoting.
     *      Totally not ideal, but we can clean that up later.
     */

    g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);

    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
    cr = cairo_create (surface);

    gtk_widget_get_allocation (widget, &alloc);

    if ((width != alloc.width) || (height != alloc.height))
    {
        if (alloc.width > alloc.height)
        {
            x_ratio = (gdouble) width / (gdouble) alloc.width;
            y_ratio = (gdouble) width / (gdouble) alloc.width;
        }
        else
        {
            x_ratio = (gdouble) height / (gdouble) alloc.height;
            y_ratio = (gdouble) height / (gdouble) alloc.height;
        }
        cairo_scale (cr, x_ratio, y_ratio);
    }

    gtk_widget_draw (widget, cr);

    cairo_destroy (cr);

    {
        cairo_surface_t *other;
        GdkRectangle rect = {
            3,
            3,
            ceil (alloc.width * x_ratio) - 6,
            ceil (alloc.height * y_ratio) - 6
        };

        other = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
        cr = cairo_create (other);

        cairo_save (cr);

        if (draw_border)
        {
            gdk_cairo_rectangle (cr, &rect);
            cairo_clip (cr);
        }

        cairo_set_source_surface (cr, surface, 0, 0);
        cairo_paint_with_alpha (cr, alpha);

        cairo_restore (cr);

        if (draw_border)
        {
            GdkRGBA rgba;

            gb_cairo_rounded_rectangle (cr, &rect, 3, 3);

            gdk_rgba_parse (&rgba, "#729fcf");
            gb_rgba_shade (&rgba, &rgba, 0.8);
            gdk_cairo_set_source_rgba (cr, &rgba);
            cairo_set_line_width (cr, 3.0);

            cairo_stroke (cr);

            gb_cairo_rounded_rectangle (cr, &rect, 1, 1);

            gdk_rgba_parse (&rgba, "#729fcf");
            gb_rgba_shade (&rgba, &rgba, 1.2);
            gdk_cairo_set_source_rgba (cr, &rgba);

            cairo_set_line_width (cr, 1.0);
            cairo_stroke (cr);
        }

        cairo_surface_destroy (surface);
        surface = other;
    }

    return surface;
}
Esempio n. 8
0
static void fm_cell_renderer_text_render(GtkCellRenderer *cell,
                                         GdkDrawable *window,
                                         GtkWidget *widget,
                                         GdkRectangle *background_area,
                                         GdkRectangle *cell_area,
                                         GdkRectangle *expose_area,
                                         GtkCellRendererState flags)
#endif
{
    FmCellRendererText *self = FM_CELL_RENDERER_TEXT(cell);
#if GTK_CHECK_VERSION(3, 0, 0)
    GtkStyleContext* style;
    GtkStateFlags state;
#else
    GtkStyle* style;
    GtkStateType state;
#endif
    gchar* text;
    gint text_width;
    gint text_height;
    gint x_offset;
    gint y_offset;
    gint x_align_offset;
    GdkRectangle rect;
    PangoWrapMode wrap_mode;
    gint wrap_width;
    PangoAlignment alignment;
    gfloat xalign, yalign;
    gint xpad, ypad;

    /* FIXME: this is time-consuming since it invokes pango_layout.
     *        if we want to fix this, we must implement the whole cell
     *        renderer ourselves instead of derived from GtkCellRendererText. */
    PangoContext* context = gtk_widget_get_pango_context(widget);

    PangoLayout* layout = pango_layout_new(context);

    g_object_get(G_OBJECT(cell),
                 "wrap-mode" , &wrap_mode,
                 "wrap-width", &wrap_width,
                 "alignment" , &alignment,
                 "text", &text,
                 NULL);

    pango_layout_set_alignment(layout, alignment);

    /* Setup the wrapping. */
    if (wrap_width < 0)
    {
        pango_layout_set_width(layout, -1);
        pango_layout_set_wrap(layout, PANGO_WRAP_CHAR);
    }
    else
    {
        pango_layout_set_width(layout, wrap_width * PANGO_SCALE);
        pango_layout_set_wrap(layout, wrap_mode);
        if(self->height > 0)
        {
            /* FIXME: add custom ellipsize from object? */
            pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
            pango_layout_set_height(layout, self->height * PANGO_SCALE);
        }
        else
            pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
    }

    pango_layout_set_text(layout, text, -1);

    pango_layout_set_auto_dir(layout, TRUE);

    pango_layout_get_pixel_size(layout, &text_width, &text_height);

    gtk_cell_renderer_get_alignment(cell, &xalign, &yalign);
    gtk_cell_renderer_get_padding(cell, &xpad, &ypad);
    /* Calculate the real x and y offsets. */
    x_offset = ((gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL) ? (1.0 - xalign) : xalign)
             * (cell_area->width - text_width - (2 * xpad));
    x_offset = MAX(x_offset, 0);

    y_offset = yalign * (cell_area->height - text_height - (2 * ypad));
    y_offset = MAX (y_offset, 0);

    if(flags & (GTK_CELL_RENDERER_SELECTED|GTK_CELL_RENDERER_FOCUSED))
    {
        rect.x = cell_area->x + x_offset;
        rect.y = cell_area->y + y_offset;
        rect.width = text_width + (2 * xpad);
        rect.height = text_height + (2 * ypad);
    }

#if GTK_CHECK_VERSION(3, 0, 0)
    style = gtk_widget_get_style_context(widget);
#else
    style = gtk_widget_get_style(widget);
#endif
    if(flags & GTK_CELL_RENDERER_SELECTED) /* item is selected */
    {
#if GTK_CHECK_VERSION(3, 0, 0)
        GdkRGBA clr;

        if(flags & GTK_CELL_RENDERER_INSENSITIVE) /* insensitive */
            state = GTK_STATE_FLAG_INSENSITIVE;
        else
            state = GTK_STATE_FLAG_SELECTED;

        gtk_style_context_get_background_color(style, state, &clr);
        gdk_cairo_rectangle(cr, &rect);
        gdk_cairo_set_source_rgba(cr, &clr);
#else
        cairo_t *cr = gdk_cairo_create (window);
        GdkColor clr;

        if(flags & GTK_CELL_RENDERER_INSENSITIVE) /* insensitive */
            state = GTK_STATE_INSENSITIVE;
        else
            state = GTK_STATE_SELECTED;

        clr = style->bg[state];

        /* paint the background */
        if(expose_area)
        {
            gdk_cairo_rectangle(cr, expose_area);
            cairo_clip(cr);
        }
        gdk_cairo_rectangle(cr, &rect);

        cairo_set_source_rgb(cr, clr.red / 65535., clr.green / 65535., clr.blue / 65535.);
#endif
        cairo_fill (cr);

#if !GTK_CHECK_VERSION(3, 0, 0)
        cairo_destroy (cr);
#endif
    }
#if !GTK_CHECK_VERSION(3, 0, 0)
    else
        state = GTK_STATE_NORMAL;
#endif

    x_align_offset = (alignment == PANGO_ALIGN_CENTER) ? (wrap_width - text_width) / 2 : 0;

#if GTK_CHECK_VERSION(3, 0, 0)
    gtk_render_layout(style, cr,
                      cell_area->x + x_offset + xpad - x_align_offset,
                      cell_area->y + y_offset + ypad, layout);
#else
    gtk_paint_layout(style, window, state, TRUE,
                     expose_area, widget, "cellrenderertext",
                     cell_area->x + x_offset + xpad - x_align_offset,
                     cell_area->y + y_offset + ypad, layout);
#endif

    g_object_unref(layout);

    if(G_UNLIKELY( flags & GTK_CELL_RENDERER_FOCUSED) ) /* focused */
    {
#if GTK_CHECK_VERSION(3, 0, 0)
        gtk_render_focus(style, cr, rect.x, rect.y, rect.width, rect.height);
#else
        gtk_paint_focus(style, window, state, background_area,
                        widget, "cellrenderertext", rect.x, rect.y,
                        rect.width, rect.height);
#endif
    }

    if(flags & GTK_CELL_RENDERER_PRELIT) /* hovered */
        g_object_set(G_OBJECT(widget), "tooltip-text", text, NULL);
    else
        g_object_set(G_OBJECT(widget), "tooltip-text", NULL, NULL);
    g_free(text);
}
Esempio n. 9
0
static gboolean
on_view_draw (GtkSourceView   *view,
              cairo_t         *cr,
              GtkSourceGutter *gutter)
{
	GdkWindow *window;
	GtkTextView *text_view;
	GArray *sizes;
	GdkRectangle clip;
	gint x, y;
	gint y1, y2;
	GArray *numbers;
	GArray *pixels;
	GArray *heights;
	GtkTextIter cur;
	gint cur_line;
	gint count;
	gint i;
	GList *item;
	GtkTextIter start;
	GtkTextIter end;
	GtkTextBuffer *buffer;
	GdkRectangle background_area;
	GdkRectangle cell_area;
	GtkTextIter selection_start;
	GtkTextIter selection_end;
	gboolean has_selection;
	gint idx;
	GtkStyleContext *style_context;
	GdkRGBA fg_color;

	window = gtk_source_gutter_get_window (gutter);

	if (window == NULL || !gtk_cairo_should_draw_window (cr, window))
	{
		return FALSE;
	}

	gtk_cairo_transform_to_window (cr, GTK_WIDGET (view), window);

	text_view = GTK_TEXT_VIEW (view);

	if (!gdk_cairo_get_clip_rectangle (cr, &clip))
	{
		return FALSE;
	}

	gutter->priv->is_drawing = TRUE;

	buffer = gtk_text_view_get_buffer (text_view);

	gdk_window_get_pointer (window, &x, &y, NULL);

	y1 = clip.y;
	y2 = y1 + clip.height;

	/* get the extents of the line printing */
	gtk_text_view_window_to_buffer_coords (text_view,
	                                       gutter->priv->window_type,
	                                       0,
	                                       y1,
	                                       NULL,
	                                       &y1);

	gtk_text_view_window_to_buffer_coords (text_view,
	                                       gutter->priv->window_type,
	                                       0,
	                                       y2,
	                                       NULL,
	                                       &y2);

	numbers = g_array_new (FALSE, FALSE, sizeof (gint));
	pixels = g_array_new (FALSE, FALSE, sizeof (gint));
	heights = g_array_new (FALSE, FALSE, sizeof (gint));
	sizes = g_array_new (FALSE, FALSE, sizeof (gint));

	calculate_gutter_size (gutter, sizes);

	i = 0;
	x = 0;

	background_area.x = 0;
	background_area.height = get_lines (text_view,
	                                    y1,
	                                    y2,
	                                    pixels,
	                                    heights,
	                                    numbers,
	                                    &count,
	                                    &start,
	                                    &end);

	cell_area.x = gutter->priv->xpad;
	cell_area.height = background_area.height;

	gtk_text_view_buffer_to_window_coords (text_view,
	                                       gutter->priv->window_type,
	                                       0,
	                                       g_array_index (pixels, gint, 0),
	                                       NULL,
	                                       &background_area.y);

	cell_area.y = background_area.y;

	item = gutter->priv->renderers;
	idx = 0;

	style_context = gtk_widget_get_style_context (GTK_WIDGET (view));

	gtk_style_context_get_color (style_context,
	                             gtk_widget_get_state (GTK_WIDGET (view)),
	                             &fg_color);

	gdk_cairo_set_source_rgba (cr, &fg_color);

	while (item)
	{
		Renderer *renderer = item->data;
		gint xpad;
		gint width;

		width = g_array_index (sizes, gint, idx++);

		if (gtk_source_gutter_renderer_get_visible (renderer->renderer))
		{
			gtk_source_gutter_renderer_get_padding (renderer->renderer,
			                                        &xpad,
			                                        NULL);

			background_area.width = width;

			cell_area.width = width - 2 * xpad;
			cell_area.x = background_area.x + xpad;

			cairo_save (cr);

			gdk_cairo_rectangle (cr, &background_area);
			cairo_clip (cr);

			gtk_source_gutter_renderer_begin (renderer->renderer,
			                                  cr,
			                                  &background_area,
			                                  &cell_area,
			                                  &start,
			                                  &end);

			cairo_restore (cr);

			background_area.x += background_area.width;
		}

		item = g_list_next (item);
	}

	gtk_text_buffer_get_iter_at_mark (buffer,
	                                  &cur,
	                                  gtk_text_buffer_get_insert (buffer));

	cur_line = gtk_text_iter_get_line (&cur);

	gtk_text_buffer_get_selection_bounds (buffer,
	                                      &selection_start,
	                                      &selection_end);

	has_selection = !gtk_text_iter_equal (&selection_start, &selection_end);

	if (has_selection)
	{
		if (!gtk_text_iter_starts_line (&selection_start))
		{
			gtk_text_iter_set_line_offset (&selection_start, 0);
		}

		if (!gtk_text_iter_ends_line (&selection_end))
		{
			gtk_text_iter_forward_to_line_end (&selection_end);
		}
	}

	for (i = 0; i < count; ++i)
	{
		gint pos;
		gint line_to_paint;

		end = start;

		if (!gtk_text_iter_ends_line (&end))
		{
			gtk_text_iter_forward_to_line_end (&end);
		}

		gtk_text_view_buffer_to_window_coords (text_view,
		                                       gutter->priv->window_type,
		                                       0,
		                                       g_array_index (pixels, gint, i),
		                                       NULL,
		                                       &pos);

		line_to_paint = g_array_index (numbers, gint, i);

		background_area.y = pos;
		background_area.height = g_array_index (heights, gint, i);
		background_area.x = 0;

		idx = 0;

		for (item = gutter->priv->renderers; item; item = g_list_next (item))
		{
			Renderer *renderer;
			gint width;
			GtkSourceGutterRendererState state;
			gint xpad;
			gint ypad;

			renderer = item->data;
			width = g_array_index (sizes, gint, idx++);

			if (!gtk_source_gutter_renderer_get_visible (renderer->renderer))
			{
				continue;
			}

			gtk_source_gutter_renderer_get_padding (renderer->renderer,
			                                        &xpad,
			                                        &ypad);

			background_area.width = width;

			cell_area.y = background_area.y + ypad;
			cell_area.height = background_area.height - 2 * ypad;

			cell_area.x = background_area.x + xpad;
			cell_area.width = background_area.width - 2 * xpad;

			state = GTK_SOURCE_GUTTER_RENDERER_STATE_NORMAL;

			if (line_to_paint == cur_line)
			{
				state |= GTK_SOURCE_GUTTER_RENDERER_STATE_CURSOR;
			}

			if (has_selection &&
			    gtk_text_iter_in_range (&start,
			                            &selection_start,
			                            &selection_end))
			{
				state |= GTK_SOURCE_GUTTER_RENDERER_STATE_SELECTED;
			}

			if (renderer->prelit >= 0 && cell_area.y <= renderer->prelit && cell_area.y + cell_area.height >= renderer->prelit)
			{
				state |= GTK_SOURCE_GUTTER_RENDERER_STATE_PRELIT;
			}

			gtk_source_gutter_renderer_query_data (renderer->renderer,
			                                       &start,
			                                       &end,
			                                       state);

			cairo_save (cr);

			gdk_cairo_rectangle (cr, &background_area);

			cairo_clip (cr);

			/* Call render with correct area */
			gtk_source_gutter_renderer_draw (renderer->renderer,
			                                 cr,
			                                 &background_area,
			                                 &cell_area,
			                                 &start,
			                                 &end,
			                                 state);

			cairo_restore (cr);

			background_area.x += background_area.width;
		}

		gtk_text_iter_forward_line (&start);
	}

	for (item = gutter->priv->renderers; item; item = g_list_next (item))
	{
		Renderer *renderer = item->data;

		if (gtk_source_gutter_renderer_get_visible (renderer->renderer))
		{
			gtk_source_gutter_renderer_end (renderer->renderer);
		}
	}

	g_array_free (numbers, TRUE);
	g_array_free (pixels, TRUE);
	g_array_free (heights, TRUE);

	g_array_free (sizes, TRUE);

	gutter->priv->is_drawing = FALSE;

	return FALSE;
}