static void
get_size_full( TorrentCellRenderer * cell,
               GtkWidget           * widget,
               gint                * width,
               gint                * height )
{
    int xpad, ypad;
    GtkRequisition icon_size;
    GtkRequisition name_size;
    GtkRequisition stat_size;
    GtkRequisition prog_size;
    const char * name;
    GdkPixbuf * icon;

    struct TorrentCellRendererPrivate * p = cell->priv;
    const tr_torrent * tor = p->tor;
    const tr_stat * st = tr_torrentStatCached( (tr_torrent*)tor );
    const tr_info * inf = tr_torrentInfo( tor );
    GString * gstr_prog = p->gstr1;
    GString * gstr_stat = p->gstr2;

    icon = get_icon( tor, FULL_ICON_SIZE, widget );
    name = tr_torrentName( tor );
    g_string_truncate( gstr_stat, 0 );
    getStatusString( gstr_stat, tor, st, p->upload_speed_KBps, p->download_speed_KBps );
    g_string_truncate( gstr_prog, 0 );
    getProgressString( gstr_prog, tor, inf, st );
    gtk_cell_renderer_get_padding( GTK_CELL_RENDERER( cell ), &xpad, &ypad );

    /* get the idealized cell dimensions */
    g_object_set( p->icon_renderer, "pixbuf", icon, NULL );
    gtr_cell_renderer_get_preferred_size( p->icon_renderer, widget, NULL, &icon_size );
    g_object_set( p->text_renderer, "text", name, "weight", PANGO_WEIGHT_BOLD, "scale", 1.0, "ellipsize", PANGO_ELLIPSIZE_NONE, NULL );
    gtr_cell_renderer_get_preferred_size( p->text_renderer, widget, NULL, &name_size );
    g_object_set( p->text_renderer, "text", gstr_prog->str, "weight", PANGO_WEIGHT_NORMAL, "scale", SMALL_SCALE, NULL );
    gtr_cell_renderer_get_preferred_size( p->text_renderer, widget, NULL, &prog_size );
    g_object_set( p->text_renderer, "text", gstr_stat->str, NULL );
    gtr_cell_renderer_get_preferred_size( p->text_renderer, widget, NULL, &stat_size );

    /**
    *** LAYOUT
    **/

    if( width != NULL )
        *width = xpad * 2 + icon_size.width + GUI_PAD + MAX3( name_size.width, prog_size.width, stat_size.width );
    if( height != NULL )
        *height = ypad * 2 + name_size.height + prog_size.height + GUI_PAD_SMALL + p->bar_height + GUI_PAD_SMALL + stat_size.height;

    /* cleanup */
    g_object_unref( icon );
}
static void get_size_compact(TorrentCellRenderer* cell, GtkWidget* widget, gint* width, gint* height)
{
    int xpad;
    int ypad;
    GtkRequisition icon_size;
    GtkRequisition name_size;
    GtkRequisition stat_size;
    char const* name;
    GdkPixbuf* icon;

    struct TorrentCellRendererPrivate* p = cell->priv;
    tr_torrent const* tor = p->tor;
    tr_stat const* st = tr_torrentStatCached((tr_torrent*)tor);
    GString* gstr_stat = p->gstr1;

    icon = get_icon(tor, COMPACT_ICON_SIZE, widget);
    name = tr_torrentName(tor);
    g_string_truncate(gstr_stat, 0);
    getShortStatusString(gstr_stat, tor, st, p->upload_speed_KBps, p->download_speed_KBps);
    gtk_cell_renderer_get_padding(GTK_CELL_RENDERER(cell), &xpad, &ypad);

    /* get the idealized cell dimensions */
    g_object_set(p->icon_renderer, "pixbuf", icon, NULL);
    gtr_cell_renderer_get_preferred_size(p->icon_renderer, widget, NULL, &icon_size);
    g_object_set(p->text_renderer, "text", name, "ellipsize", PANGO_ELLIPSIZE_NONE, "scale", 1.0, NULL);
    gtr_cell_renderer_get_preferred_size(p->text_renderer, widget, NULL, &name_size);
    g_object_set(p->text_renderer, "text", gstr_stat->str, "scale", SMALL_SCALE, NULL);
    gtr_cell_renderer_get_preferred_size(p->text_renderer, widget, NULL, &stat_size);

    /**
    *** LAYOUT
    **/

#define BAR_WIDTH 50

    if (width != NULL)
    {
        *width = xpad * 2 + icon_size.width + GUI_PAD + name_size.width + GUI_PAD + BAR_WIDTH + GUI_PAD + stat_size.width;
    }

    if (height != NULL)
    {
        *height = ypad * 2 + MAX(name_size.height, p->bar_height);
    }

    /* cleanup */
    g_object_unref(icon);
}
static void
gossip_cell_renderer_expander_render (GtkCellRenderer      *cell,
                                      cairo_t              *cr,
                                      GtkWidget            *widget,
                                      const GdkRectangle   *background_area,
                                      const GdkRectangle   *cell_area,
                                      GtkCellRendererState  flags)
{
    GossipCellRendererExpander     *expander;
    GossipCellRendererExpanderPriv *priv;
    GtkExpanderStyle                expander_style;
    gint                            x_offset, y_offset;
    gint                            xpad, ypad;

    expander = (GossipCellRendererExpander*) cell;
    priv = GET_PRIV (expander);

    if (priv->animation_node) {
        GtkTreePath *path;
        GdkRectangle rect;

        /* Not sure if I like this ... */
        path = gtk_tree_row_reference_get_path (priv->animation_node);
        gtk_tree_view_get_background_area (priv->animation_view, path,
                                           NULL, &rect);
        gtk_tree_path_free (path);

        if (background_area->y == rect.y)
            expander_style = priv->animation_style;
        else
            expander_style = priv->expander_style;
    } else
        expander_style = priv->expander_style;

    gossip_cell_renderer_expander_get_size (cell, widget, cell_area,
                                            &x_offset, &y_offset,
                                            NULL, NULL);
    gtk_cell_renderer_get_padding (cell, &xpad, &ypad);

    gtk_paint_expander (gtk_widget_get_style (widget),
                        cr,
                        GTK_STATE_NORMAL,
                        widget,
                        "treeview",
                        cell_area->x + x_offset + xpad + priv->expander_size / 2,
                        cell_area->y + y_offset + ypad + priv->expander_size / 2,
                        expander_style);
}
示例#4
0
static void
gimp_cell_renderer_dashes_get_size (GtkCellRenderer    *cell,
                                    GtkWidget          *widget,
                                    const GdkRectangle *cell_area,
                                    gint               *x_offset,
                                    gint               *y_offset,
                                    gint               *width,
                                    gint               *height)
{
  gfloat xalign, yalign;
  gint   xpad, ypad;

  gtk_cell_renderer_get_alignment (cell, &xalign, &yalign);
  gtk_cell_renderer_get_padding (cell, &xpad, &ypad);

  if (cell_area)
    {
      if (x_offset)
        {
          gdouble align;

          align = ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ?
                   1.0 - xalign : xalign);

          *x_offset = align * (cell_area->width - DASHES_WIDTH);
          *x_offset = MAX (*x_offset, 0) + xpad;
        }

      if (y_offset)
        {
          *y_offset = yalign * (cell_area->height - DASHES_HEIGHT);
          *y_offset = MAX (*y_offset, 0) + ypad;
        }
    }
  else
    {
      if (x_offset)
        *x_offset = 0;

      if (y_offset)
        *y_offset = 0;
    }

  *width  = DASHES_WIDTH  + 2 * xpad;
  *height = DASHES_HEIGHT + 2 * ypad;
}
示例#5
0
static gint
get_cell_renderer_width (GtkWidget *widget, GtkCellRenderer *cell, const gchar *text, gint weight)
{
	PangoLayout	*layout = gtk_widget_create_pango_layout (widget, text);
	PangoAttrList	*attrbs = pango_attr_list_new();
	PangoRectangle	rect;
	gint		xpad = 0;

	pango_attr_list_insert (attrbs, pango_attr_weight_new (weight));
	pango_layout_set_attributes (layout, attrbs);
	pango_attr_list_unref (attrbs);
	pango_layout_get_pixel_extents (layout, NULL, &rect);
	g_object_unref (G_OBJECT (layout));

	gtk_cell_renderer_get_padding (cell, &xpad, NULL);
	return (xpad * 2) + rect.x + rect.width;
}
static void
gossip_cell_renderer_expander_get_size (GtkCellRenderer     *cell,
                                        GtkWidget           *widget,
                                        const GdkRectangle  *cell_area,
                                        gint                *x_offset,
                                        gint                *y_offset,
                                        gint                *width,
                                        gint                *height)
{
    GossipCellRendererExpander     *expander;
    GossipCellRendererExpanderPriv *priv;
    gint                            xpad, ypad;
    gfloat                          xalign, yalign;

    expander = (GossipCellRendererExpander*) cell;
    priv = GET_PRIV (expander);
    gtk_cell_renderer_get_padding (cell, &xpad, &ypad);

    if (cell_area) {

        gtk_cell_renderer_get_alignment (cell, &xalign, &yalign);

        if (x_offset) {
            *x_offset = xalign * (cell_area->width - (priv->expander_size + (2 * xpad)));
            *x_offset = MAX (*x_offset, 0);
        }

        if (y_offset) {
            *y_offset = yalign * (cell_area->height - (priv->expander_size + (2 * ypad)));
            *y_offset = MAX (*y_offset, 0);
        }
    } else {
        if (x_offset)
            *x_offset = 0;

        if (y_offset)
            *y_offset = 0;
    }

    if (width)
        *width = xpad * 2 + priv->expander_size;

    if (height)
        *height = ypad * 2 + priv->expander_size;
}
示例#7
0
void
gnc_reconcile_view_add_padding (GNCReconcileView *view, gint column, gint xpadding)
{
    GNCQueryView      *qview = GNC_QUERY_VIEW (view);
    GtkTreeViewColumn *col;
    GList             *renderers;
    GtkCellRenderer   *cr0;
    gint xpad, ypad;

    //allow for pointer model column at column 0
    col = gtk_tree_view_get_column (GTK_TREE_VIEW (qview), (column - 1));
    renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (col));
    cr0 = g_list_nth_data (renderers, 0);
    g_list_free (renderers);

    gtk_cell_renderer_get_padding (cr0, &xpad, &ypad);
    gtk_cell_renderer_set_padding (cr0, xpadding, ypad);
}
static void torrent_cell_renderer_get_size(GtkCellRenderer* cell, GtkWidget* widget, GdkRectangle const* cell_area,
    gint* x_offset, gint* y_offset, gint* width, gint* height)
{
    TorrentCellRenderer* self = TORRENT_CELL_RENDERER(cell);

    if (self != NULL && self->priv->tor != NULL)
    {
        int w;
        int h;
        struct TorrentCellRendererPrivate* p = self->priv;

        if (p->compact)
        {
            get_size_compact(TORRENT_CELL_RENDERER(cell), widget, &w, &h);
        }
        else
        {
            get_size_full(TORRENT_CELL_RENDERER(cell), widget, &w, &h);
        }

        if (width != NULL)
        {
            *width = w;
        }

        if (height != NULL)
        {
            *height = h;
        }

        if (x_offset != NULL)
        {
            *x_offset = cell_area ? cell_area->x : 0;
        }

        if (y_offset != NULL)
        {
            int xpad, ypad;
            gtk_cell_renderer_get_padding(cell, &xpad, &ypad);
            *y_offset = cell_area ? (int)((cell_area->height - (ypad * 2 + h)) / 2.0) : 0;
        }
    }
}
示例#9
0
static void
gd_two_lines_renderer_get_preferred_height_for_width (GtkCellRenderer *cell,
                                                      GtkWidget       *widget,
                                                      gint             width,
                                                      gint            *minimum_size,
                                                      gint            *natural_size)
{
  GdTwoLinesRenderer *self = GD_TWO_LINES_RENDERER (cell);
  PangoLayout *layout_one, *layout_two;
  gint text_height, wrap_width;
  gint xpad, ypad;

  gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
  g_object_get (cell, "wrap-width", &wrap_width, NULL);
  gd_two_lines_renderer_prepare_layouts (self, NULL, widget, &layout_one, &layout_two);

  if (wrap_width != -1)
    wrap_width = MIN (width - 2 * xpad, wrap_width);
  else
    wrap_width = width - 2 * xpad;

  pango_layout_set_width (layout_one, wrap_width);
  if (layout_two != NULL)
    pango_layout_set_width (layout_two, wrap_width);

  gd_two_lines_renderer_get_size (cell, widget,
                                  layout_one, layout_two,
                                  NULL, &text_height,
                                  NULL, 
                                  NULL, NULL, NULL);

  text_height += 2 * ypad;

  if (minimum_size != NULL)
    *minimum_size = text_height;

  if (natural_size != NULL)
    *natural_size = text_height;

  g_clear_object (&layout_one);
  g_clear_object (&layout_two);
}
static void
torrent_cell_renderer_get_size( GtkCellRenderer     * cell,
                                GtkWidget           * widget,
#if GTK_CHECK_VERSION( 3,0,0 )
                                const GdkRectangle  * cell_area,
#else
                                GdkRectangle        * cell_area,
#endif
                                gint                * x_offset,
                                gint                * y_offset,
                                gint                * width,
                                gint                * height )
{
    TorrentCellRenderer * self = TORRENT_CELL_RENDERER( cell );

    if( self && self->priv->tor )
    {
        int w, h;
        struct TorrentCellRendererPrivate * p = self->priv;

        if( p->compact )
            get_size_compact( TORRENT_CELL_RENDERER( cell ), widget, &w, &h );
        else
            get_size_full( TORRENT_CELL_RENDERER( cell ), widget, &w, &h );

        if( width )
            *width = w;

        if( height )
            *height = h;

        if( x_offset )
            *x_offset = cell_area ? cell_area->x : 0;

        if( y_offset ) {
            int xpad, ypad;
            gtk_cell_renderer_get_padding( cell, &xpad, &ypad );
            *y_offset = cell_area ? (int)((cell_area->height - (ypad*2 +h)) / 2.0) : 0;
        }
    }
}
示例#11
0
static void
gimp_cell_renderer_dashes_render (GtkCellRenderer      *cell,
                                  cairo_t              *cr,
                                  GtkWidget            *widget,
                                  const GdkRectangle   *background_area,
                                  const GdkRectangle   *cell_area,
                                  GtkCellRendererState  flags)
{
  GimpCellRendererDashes *dashes = GIMP_CELL_RENDERER_DASHES (cell);
  GtkStyleContext        *style  = gtk_widget_get_style_context (widget);
  GtkStateType            state;
  GdkRGBA                 color;
  gint                    xpad, ypad;
  gint                    width;
  gint                    x, y;

  gtk_cell_renderer_get_padding (cell, &xpad, &ypad);

  state = gtk_cell_renderer_get_state (cell, widget, flags);

  y = cell_area->y + (cell_area->height - DASHES_HEIGHT) / 2;
  width = cell_area->width - 2 * xpad;

  for (x = 0; x < width + BLOCK_WIDTH; x += BLOCK_WIDTH)
    {
      guint index = ((guint) x / BLOCK_WIDTH) % N_SEGMENTS;

      if (dashes->segments[index])
        {
          cairo_rectangle (cr,
                           cell_area->x + xpad + x, y,
                           MIN (BLOCK_WIDTH, width - x), DASHES_HEIGHT);
        }
    }

  gtk_style_context_get_color (style, state, &color);
  gdk_cairo_set_source_rgba (cr, &color);

  cairo_fill (cr);
}
static void internal_image_get_size(GtkCellRenderer *cell,
                                    GtkWidget       *widget,
                                    const GdkRectangle    *cell_area,
                                    gint            *x_offset,
                                    gint            *y_offset,
                                    gint            *width,
                                    gint            *height)
{
    CustomCellRendererFlexi *cellflexi = CUSTOM_CELL_RENDERER_FLEXI (cell);
    int image_width = gdk_pixbuf_get_width((GdkPixbuf*)cellflexi->rendered_value);
    int image_height = gdk_pixbuf_get_height((GdkPixbuf*)cellflexi->rendered_value);
    gint calc_width;
    gint calc_height;
    gint xpad;
    gint ypad;

    UNUSED(widget);
    UNUSED(cell_area);

    gtk_cell_renderer_get_padding(cell,&xpad,&ypad);

    calc_width  = xpad * 2 + image_width;
    calc_height = ypad * 2 + image_height;

    if (width)
        *width = calc_width;

    if (height)
        *height = calc_height;

    if (x_offset)
    {
        *x_offset = 0;
    }

    if (y_offset)
    {
        *y_offset = 0;
    }
}
static void internal_text_render(GtkCellRenderer *cell,
                                 cairo_t         *cr,
                                 GtkWidget       *widget,
                                 const GdkRectangle    *background_area,
                                 const GdkRectangle    *cell_area,
                                 guint            flags)
{
    CustomCellRendererFlexi *cellflexi = CUSTOM_CELL_RENDERER_FLEXI (cell);
    PangoLayout 		*layout;
    gint                  	width, height;
    gint                  	x_offset, y_offset;
    gint 			xpad;
    gint 			ypad;

    UNUSED(background_area);
    UNUSED(flags);

    layout = internal_text_create_layout(widget,cellflexi);

    g_assert(layout!=NULL);

    internal_text_get_size_layout (cell, widget, layout,
                                   cell_area,
                                   &x_offset, &y_offset,
                                   &width, &height);

    gtk_cell_renderer_get_padding(cell,&xpad,&ypad);
    width  -= xpad*2;
    height -= ypad*2;

    gtk_render_layout(gtk_widget_get_style_context(widget),
                      cr,
                      cell_area->x + x_offset + xpad,
                      cell_area->y + y_offset + ypad,
                      layout);

    g_object_unref(layout);
}
示例#14
0
static int
calc_char_index (RenderData_t *renderdata, int col, int *dx)
{
	GtkCellRenderer *cell =	stf_preview_get_cell_renderer (renderdata, col);
	PangoLayout *layout;
	PangoFontDescription *font_desc;
	int ci, width, padx;

	gtk_cell_renderer_get_padding (cell, &padx, NULL);

	g_object_get (G_OBJECT (cell), "font_desc", &font_desc, NULL);
	layout = gtk_widget_create_pango_layout (GTK_WIDGET (renderdata->tree_view), "x");
	pango_layout_set_font_description (layout, font_desc);
	pango_layout_get_pixel_size (layout, &width, NULL);
	g_object_unref (layout);
	pango_font_description_free (font_desc);

	if (width < 1) width = 1;
	ci = (*dx < padx) ? 0 : (*dx - padx + width / 2) / width;
	*dx -= ci * width;

	return ci;
}
/*! \brief Calculates the window area the renderer will use */
static void
ghid_cell_renderer_visibility_get_size (GtkCellRenderer *cell,
                                        GtkWidget       *widget,
                                        GdkRectangle    *cell_area,
                                        gint            *x_offset,
                                        gint            *y_offset,
                                        gint            *width,
                                        gint            *height)
{
  GtkStyle *style = gtk_widget_get_style (widget);
  gint w, h;
  gint xpad, ypad;
  gfloat xalign, yalign;

  gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
  gtk_cell_renderer_get_alignment (cell, &xalign, &yalign);

  w = VISIBILITY_TOGGLE_SIZE + 2 * (xpad + style->xthickness);
  h = VISIBILITY_TOGGLE_SIZE + 2 * (ypad + style->ythickness);

  if (width)
    *width = w;
  if (height)
    *height = h;

  if (cell_area)
    {
      if (x_offset)
        {
          if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
            xalign = 1. - xalign;
          *x_offset = MAX (0, xalign * (cell_area->width - w));
        }
      if (y_offset)
        *y_offset = MAX(0, yalign * (cell_area->height - h));
    }
}
static void
get_icon_rectangle (GtkWidget *widget,
		    GtkCellRenderer *cell,
		    const GdkRectangle *cell_area,
		    GdkPixbuf *icon,
		    GdkRectangle *rectangle)
{
  GtkTextDirection direction;
  gint x_offset, y_offset, xpad, ypad;
  gint icon_size;
  gint w = 0, h = 0;
  GdkPixbuf *pixbuf;

  gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
  direction = gtk_widget_get_direction (widget);
  icon_size = gdk_pixbuf_get_width (icon);

  g_object_get (cell, "pixbuf", &pixbuf, NULL);
  if (pixbuf) {
    w = gdk_pixbuf_get_width (pixbuf);
    h = gdk_pixbuf_get_height (pixbuf);
    g_object_unref (pixbuf);
  }

  x_offset = (cell_area->width - w)/2 + 10;
  y_offset = (cell_area->height - h)/2 + 9;

  if (direction == GTK_TEXT_DIR_RTL)
    x_offset += xpad;
  else
    x_offset = cell_area->width - icon_size - xpad - x_offset;

  rectangle->x = cell_area->x + x_offset;
  rectangle->y = cell_area->y + ypad + y_offset;
  rectangle->width = rectangle->height = icon_size;
}
示例#17
0
static gint
gtk_text_cell_accessible_get_offset_at_point (AtkText      *text,
                                              gint          x,
                                              gint          y,
                                              AtkCoordType  coords)
{
  AtkObject *parent;
  GtkRendererCellAccessible *gail_renderer;
  GtkCellRendererText *gtk_renderer;
  GtkRequisition min_size;
  GtkWidget *widget;
  GdkRectangle rendered_rect;
  PangoLayout *layout;
  gchar *renderer_text;
  gfloat xalign, yalign;
  gint x_offset, y_offset, index;
  gint xpad, ypad;
  gint x_window, y_window, x_toplevel, y_toplevel;
  gint x_temp, y_temp;
  gboolean ret;

  if (!GTK_TEXT_CELL_ACCESSIBLE (text)->cell_text)
    return -1;

  gail_renderer = GTK_RENDERER_CELL_ACCESSIBLE (text);
  gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer);
  parent = atk_object_get_parent (ATK_OBJECT (text));

  g_object_get (gtk_renderer, "text", &renderer_text, NULL);
  if (text == NULL)
    {
      g_free (renderer_text);
      return -1;
    }

  if (GTK_IS_CONTAINER_CELL_ACCESSIBLE (parent))
    parent = atk_object_get_parent (parent);

  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));

  g_return_val_if_fail (GTK_IS_CELL_ACCESSIBLE_PARENT (parent), -1);
  _gtk_cell_accessible_parent_get_cell_area (GTK_CELL_ACCESSIBLE_PARENT (parent),
                                             GTK_CELL_ACCESSIBLE (text),
                                             &rendered_rect);

  gtk_cell_renderer_get_preferred_size (GTK_CELL_RENDERER (gtk_renderer),
                                        widget,
                                        &min_size, NULL);
  gtk_cell_renderer_get_alignment (GTK_CELL_RENDERER (gtk_renderer), &xalign, &yalign);
  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
    xalign = 1.0 - xalign;
  x_offset = MAX (0, xalign * (rendered_rect.width - min_size.width));
  y_offset = MAX (0, yalign * (rendered_rect.height - min_size.height));

  layout = create_pango_layout (GTK_TEXT_CELL_ACCESSIBLE (text));

  gtk_cell_renderer_get_padding (gail_renderer->renderer, &xpad, &ypad);

  get_origins (widget, &x_window, &y_window, &x_toplevel, &y_toplevel);

  x_temp =  x - (x_offset + rendered_rect.x + xpad) - x_window;
  y_temp =  y - (y_offset + rendered_rect.y + ypad) - y_window;
  if (coords == ATK_XY_WINDOW)
    {
      x_temp += x_toplevel;
      y_temp += y_toplevel;
    }
  else if (coords != ATK_XY_SCREEN)
    index = -1;

  ret = pango_layout_xy_to_index (layout,
                                  x_temp * PANGO_SCALE,
                                  y_temp * PANGO_SCALE,
                                  &index, NULL);
  if (!ret)
    {
      if (x_temp < 0 || y_temp < 0)
        index = 0;
      else
        index = -1;
    }

  g_object_unref (layout);
  if (index == -1)
    {
      if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
        {
          glong length;

          length = g_utf8_strlen (renderer_text, -1);
          g_free (renderer_text);

          return length;
        }

      g_free (renderer_text);

      return index;
    }
  else
    {
      glong offset;

      offset = g_utf8_pointer_to_offset (renderer_text,
                                         renderer_text + index);
      g_free (renderer_text);

      return offset;
    }
}
static void
nemo_cell_renderer_disk_render (GtkCellRenderer       *cell,
                                cairo_t               *cr,
                                GtkWidget             *widget,
                                const GdkRectangle    *background_area,
                                const GdkRectangle    *cell_area,
                                GtkCellRendererState   flags)
{
    NemoCellRendererDisk *cellprogress = NEMO_CELL_RENDERER_DISK (cell);
    gint                        x, y, w;
    gint                        xpad, ypad;
    gint                        full;
    gboolean                    show = cellprogress->show_disk_full_percent;
    GtkStyleContext *context;

    if (show) {
        context = gtk_widget_get_style_context (widget);
        GdkColor *gdk_bg_color, *gdk_fg_color;
        GdkRGBA bg_color, fg_color;
        gint bar_width, bar_radius, bottom_padding, max_length;

        gtk_style_context_get_style (context,
                                     "disk-full-bg-color",       &gdk_bg_color,
                                     "disk-full-fg-color",       &gdk_fg_color,
                                     "disk-full-bar-width",      &bar_width,
                                     "disk-full-bar-radius",     &bar_radius,
                                     "disk-full-bottom-padding", &bottom_padding,
                                     "disk-full-max-length",     &max_length,
                                     NULL);

        if (gdk_bg_color) {
            convert_color (gdk_bg_color, &bg_color);
            gdk_color_free (gdk_bg_color);
        } else {
            use_default_color (&bg_color);
        }
        if (gdk_fg_color) {
            convert_color (gdk_fg_color, &fg_color);
            gdk_color_free (gdk_fg_color);
        } else {
            use_default_color (&fg_color);
        }

        gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
        x = cell_area->x + xpad;
        y = cell_area->y + cell_area->height - bar_width - bottom_padding;
        w = cell_area->width - xpad * 2;
        w = w < max_length ? w : max_length;
        full = (int) (((float) cellprogress->disk_full_percent / 100.0) * (float) w);

        gtk_style_context_save (context);

        cairo_save (cr);

        gdk_cairo_set_source_rgba (cr, &bg_color);
        cairo_rectangle_with_radius_corners (cr, x, y, w, bar_width, bar_radius);
        cairo_fill (cr);

        cairo_restore (cr);
        cairo_save (cr);

        gdk_cairo_set_source_rgba (cr, &fg_color);
        cairo_rectangle_with_radius_corners (cr, x, y, full, bar_width, bar_radius);
        cairo_fill (cr);

        cairo_restore (cr);

        gtk_style_context_restore (context);
    }

    GTK_CELL_RENDERER_CLASS (parent_class)->render (cell,
                                                    cr,
                                                    widget,
                                                    background_area,
                                                    cell_area,
                                                    flags);
}
示例#19
0
static void
gtk_text_cell_accessible_get_character_extents (AtkText      *text,
                                                gint          offset,
                                                gint         *x,
                                                gint         *y,
                                                gint         *width,
                                                gint         *height,
                                                AtkCoordType  coords)
{
  GtkRendererCellAccessible *gail_renderer;
  GtkRequisition min_size;
  GtkCellRendererText *gtk_renderer;
  GdkRectangle rendered_rect;
  GtkWidget *widget;
  AtkObject *parent;
  PangoRectangle char_rect;
  PangoLayout *layout;
  gchar *renderer_text;
  gfloat xalign, yalign;
  gint x_offset, y_offset, index;
  gint xpad, ypad;
  gint x_window, y_window, x_toplevel, y_toplevel;

  if (!GTK_TEXT_CELL_ACCESSIBLE (text)->cell_text)
    {
      *x = *y = *height = *width = 0;
      return;
    }
  if (offset < 0 || offset >= GTK_TEXT_CELL_ACCESSIBLE (text)->cell_length)
    {
      *x = *y = *height = *width = 0;
      return;
    }
  gail_renderer = GTK_RENDERER_CELL_ACCESSIBLE (text);
  gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer);

  g_object_get (gtk_renderer, "text", &renderer_text, NULL);
  if (text == NULL)
    {
      g_free (renderer_text);
      return;
    }

  parent = atk_object_get_parent (ATK_OBJECT (text));
  if (GTK_IS_CONTAINER_CELL_ACCESSIBLE (parent))
    parent = atk_object_get_parent (parent);
  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
  g_return_if_fail (GTK_IS_CELL_ACCESSIBLE_PARENT (parent));
  _gtk_cell_accessible_parent_get_cell_area (GTK_CELL_ACCESSIBLE_PARENT (parent),
                                             GTK_CELL_ACCESSIBLE (text),
                                             &rendered_rect);

  gtk_cell_renderer_get_preferred_size (GTK_CELL_RENDERER (gtk_renderer),
                                        widget,
                                        &min_size, NULL);

  gtk_cell_renderer_get_alignment (GTK_CELL_RENDERER (gtk_renderer), &xalign, &yalign);
  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
    xalign = 1.0 - xalign;
  x_offset = MAX (0, xalign * (rendered_rect.width - min_size.width));
  y_offset = MAX (0, yalign * (rendered_rect.height - min_size.height));

  layout = create_pango_layout (GTK_TEXT_CELL_ACCESSIBLE (text));

  index = g_utf8_offset_to_pointer (renderer_text, offset) - renderer_text;
  pango_layout_index_to_pos (layout, index, &char_rect);

  gtk_cell_renderer_get_padding (gail_renderer->renderer, &xpad, &ypad);

  get_origins (widget, &x_window, &y_window, &x_toplevel, &y_toplevel);

  *x = (char_rect.x / PANGO_SCALE) + x_offset + rendered_rect.x + xpad + x_window;
  *y = (char_rect.y / PANGO_SCALE) + y_offset + rendered_rect.y + ypad + y_window;
  *height = char_rect.height / PANGO_SCALE;
  *width = char_rect.width / PANGO_SCALE;

  if (coords == ATK_XY_WINDOW)
    {
      *x -= x_toplevel;
      *y -= y_toplevel;
    }
  else if (coords != ATK_XY_SCREEN)
    {
      *x = 0;
      *y = 0;
      *height = 0;
      *width = 0;
    }

  g_free (renderer_text);
  g_object_unref (layout);
}
示例#20
0
static void
marlin_text_renderer_get_size (GtkCellRenderer      *cell,
                               GtkWidget            *widget,
                               const GdkRectangle   *cell_area,
                               gint                 *x_offset,
                               gint                 *y_offset,
                               gint                 *width,
                               gint                 *height)
{
    MarlinTextRenderer *text_renderer = MARLIN_TEXT_RENDERER (cell);
    gint text_length;
    gint text_width;
    gint text_height;
    gint xpad, ypad;

    /* setup the new widget */
    marlin_text_renderer_set_widget (text_renderer, widget);

    gfloat xalign, yalign;
    gtk_cell_renderer_get_alignment (cell, &xalign, &yalign);

    /* we can guess the dimensions if we don't wrap */
    if (text_renderer->wrap_width < 0)
    {
        /* determine the text_length in characters */
        text_length = g_utf8_strlen (text_renderer->text, -1);

        /* the approximation is usually 1-2 chars wrong, so wth */
        text_length += 2;

        /* calculate the appromixate text width/height */
        text_width = text_renderer->char_width * text_length;
        text_height = text_renderer->char_height;
    }
    else
    {
        /* calculate the real text dimension */
        pango_layout_set_ellipsize (text_renderer->layout, PANGO_ELLIPSIZE_END);
        pango_layout_set_height (text_renderer->layout, -3);
        pango_layout_set_width (text_renderer->layout, text_renderer->wrap_width * PANGO_SCALE);
        pango_layout_set_wrap (text_renderer->layout, text_renderer->wrap_mode);
        pango_layout_set_text (text_renderer->layout, text_renderer->text, -1);
        if (xalign == 0.5f)
            pango_layout_set_alignment (text_renderer->layout, PANGO_ALIGN_CENTER);

        pango_layout_get_pixel_size (text_renderer->layout, &text_width, &text_height);
    }

    /* if we have to follow the state manually, we'll need
     * to reserve some space to render the indicator to.
     */
    if (text_renderer->follow_state)
    {
        text_width += 2 * text_renderer->focus_width;
        text_height += 2 * text_renderer->focus_width;
    }

    gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
    /* update width/height */
    if (G_LIKELY (width != NULL))
        *width = text_width + 2 * xpad;
    if (G_LIKELY (height != NULL))
        *height = text_height + 2 * ypad;

    /* update the x/y offsets */
    if (G_LIKELY (cell_area != NULL))
    {
        /*gfloat xalign, yalign;
        gtk_cell_renderer_get_alignment (cell, &xalign, &yalign);*/
        if (G_LIKELY (x_offset != NULL))
        {
            *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);
        }

        if (G_LIKELY (y_offset != NULL))
        {
            *y_offset = yalign * (cell_area->height - text_height - (2 * ypad));
            *y_offset = MAX (*y_offset, 0);
        }
    }
}
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);
}
示例#22
0
static GtkCellEditable*
marlin_text_renderer_start_editing (GtkCellRenderer     *cell,
                                    GdkEvent            *event,
                                    GtkWidget           *widget,
                                    const gchar         *path,
                                    const GdkRectangle  *background_area,
                                    const GdkRectangle  *cell_area,
                                    GtkCellRendererState flags)
{
    MarlinTextRenderer *text_renderer = MARLIN_TEXT_RENDERER (cell);
    gint xpad, ypad;
    gfloat xalign, yalign;
    gboolean mode, visible;

    /* verify that we are visible & editable */
    g_object_get (cell, "visible", &visible, "mode", &mode, NULL);
    if (!(visible && mode == GTK_CELL_RENDERER_MODE_EDITABLE))
        return NULL;
    //g_message ("%s %s\n", G_STRFUNC, path);

    gtk_cell_renderer_get_alignment (cell, &xalign, &yalign);

    /* allocate a new text entry widget to be used for editing */
    /*text_renderer->entry = g_object_new (GTK_TYPE_ENTRY,
                                         "has-frame", FALSE,
                                         "text", text_renderer->text,
                                         "visible", TRUE,
                                         "xalign", xalign,
                                         NULL);*/
    text_renderer->entry = eel_editable_label_new ("Test text");
    eel_editable_label_set_line_wrap (EEL_EDITABLE_LABEL (text_renderer->entry), TRUE);
    eel_editable_label_set_line_wrap_mode (EEL_EDITABLE_LABEL (text_renderer->entry), text_renderer->wrap_mode);
    eel_editable_label_set_draw_outline (EEL_EDITABLE_LABEL (text_renderer->entry), TRUE);

    /* presume we're in POSITION UNDER */
    if (text_renderer->wrap_width > 0)
        eel_editable_label_set_justify (EEL_EDITABLE_LABEL (text_renderer->entry), GTK_JUSTIFY_CENTER);

    //gtk_misc_set_alignment (GTK_MISC (text_renderer->entry), xalign, yalign);
    g_object_set (text_renderer->entry, "yalign", yalign, NULL);
    gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
    gtk_misc_set_padding (GTK_MISC (text_renderer->entry), xpad, ypad);

    if (text_renderer->zoom_level < MARLIN_ZOOM_LEVEL_NORMAL)
        g_object_set (text_renderer->entry, "small-size", TRUE, NULL);

    gtk_widget_set_size_request (text_renderer->entry, text_renderer->wrap_width, -1);
    eel_editable_label_set_text (EEL_EDITABLE_LABEL (text_renderer->entry),
                                 text_renderer->text);
    gtk_widget_show (text_renderer->entry);

    /* remember the tree path that we're editing */
    g_object_set_data_full (G_OBJECT (text_renderer->entry), "marlin-text-renderer-path", g_strdup (path), g_free);

    /* connect required signals */
    g_signal_connect (G_OBJECT (text_renderer->entry), "editing-done", G_CALLBACK (marlin_text_renderer_editing_done), text_renderer);
    g_signal_connect (G_OBJECT (text_renderer->entry), "focus-out-event", G_CALLBACK (marlin_text_renderer_focus_out_event), text_renderer);
    g_signal_connect (G_OBJECT (text_renderer->entry), "populate-popup", G_CALLBACK (marlin_text_renderer_populate_popup), text_renderer);

    return GTK_CELL_EDITABLE (text_renderer->entry);
}
示例#23
0
static void
marlin_text_renderer_render (GtkCellRenderer    *cell,
                             cairo_t            *cr,
                             GtkWidget          *widget,
                             const GdkRectangle *background_area,
                             const GdkRectangle *cell_area,
                             GtkCellRendererState flags)
{
    MarlinTextRenderer *text_renderer = MARLIN_TEXT_RENDERER (cell);
    GtkStyleContext *context;
    GtkStateFlags state;
    gint x0, x1, y0, y1;
    gint text_width;
    gint text_height;
    gint x_offset;
    gint y_offset;
    gint xpad, ypad;
    gfloat xalign, yalign;
    gboolean selected;

    /* setup the new widget */
    marlin_text_renderer_set_widget (text_renderer, widget);

    state = gtk_widget_get_state_flags (widget);
    if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED)
    {
        state |= GTK_STATE_FLAG_SELECTED;
    }
    else if ((flags & GTK_CELL_RENDERER_PRELIT) == GTK_CELL_RENDERER_PRELIT
             && gtk_widget_get_state (widget) == GTK_STATE_PRELIGHT)
    {
        state = GTK_STATE_PRELIGHT;
    }
    else
    {
        state = gtk_widget_get_sensitive (widget) ? GTK_STATE_FLAG_NORMAL : GTK_STATE_INSENSITIVE;
    }

    /* render small/normal text depending on the zoom_level */
    if (text_renderer->zoom_level < MARLIN_ZOOM_LEVEL_NORMAL)
    {
        if (text_renderer->follow_prelit && (flags & GTK_CELL_RENDERER_PRELIT) != 0)
            pango_layout_set_attributes (text_renderer->layout, eel_pango_attr_list_small_underline_single ());
        else
            pango_layout_set_attributes (text_renderer->layout, eel_pango_attr_list_small ());
    } else {
        if (text_renderer->follow_prelit && (flags & GTK_CELL_RENDERER_PRELIT) != 0)
            pango_layout_set_attributes (text_renderer->layout, eel_pango_attr_list_underline_single ());
        else
            pango_layout_set_attributes (text_renderer->layout, NULL);
    }

    /* setup the wrapping */
    if (text_renderer->wrap_width < 0)
    {
        pango_layout_set_width (text_renderer->layout, -1);
        pango_layout_set_wrap (text_renderer->layout, PANGO_WRAP_CHAR);
    }
    else
    {
        pango_layout_set_width (text_renderer->layout, text_renderer->wrap_width * PANGO_SCALE);
        pango_layout_set_wrap (text_renderer->layout, text_renderer->wrap_mode);
    }

    /* ellipsize to max lines except for selected or prelit items */
    pango_layout_set_ellipsize (text_renderer->layout, PANGO_ELLIPSIZE_END);
    pango_layout_set_height (text_renderer->layout, -3);
    if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED ||
            (flags & GTK_CELL_RENDERER_PRELIT) == GTK_CELL_RENDERER_PRELIT) {
        pango_layout_set_ellipsize (text_renderer->layout, PANGO_ELLIPSIZE_NONE);
    }

    gtk_cell_renderer_get_alignment (cell, &xalign, &yalign);
    if (xalign == 0.5f)
        pango_layout_set_alignment (text_renderer->layout, PANGO_ALIGN_CENTER);

    pango_layout_set_text (text_renderer->layout, text_renderer->text, -1);

    /* calculate the real text dimension */
    pango_layout_get_pixel_size (text_renderer->layout, &text_width, &text_height);


    /* take into account the state indicator (required for calculation) */
    if (text_renderer->follow_state)
    {
        text_width += 2 * text_renderer->focus_width;
        text_height += 2 * text_renderer->focus_width;
    }

    gtk_cell_renderer_get_padding (cell, &xpad, &ypad);

    /* calculate the real x-offset */
    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);

    /* calculate the real y-offset */
    y_offset = yalign * (cell_area->height - text_height - (2 * ypad));
    y_offset = MAX (y_offset, 0);

    context = gtk_widget_get_style_context (gtk_widget_get_parent (widget));
    gtk_style_context_save (context);
    gtk_style_context_set_state (context, state);

    selected = ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED && text_renderer->follow_state);

    /* render the state indicator */
    if (selected || text_renderer->background != NULL)
    {
        /* calculate the text bounding box (including the focus padding/width) */
        x0 = cell_area->x + x_offset;
        y0 = cell_area->y + y_offset;
        x1 = x0 + text_width;
        y1 = y0 + text_height;

        cairo_move_to (cr, x0 + 5, y0);
        cairo_line_to (cr, x1 - 5, y0);
        cairo_curve_to (cr, x1 - 5, y0, x1, y0, x1, y0 + 5);
        cairo_line_to (cr, x1, y1 - 5);
        cairo_curve_to (cr, x1, y1 - 5, x1, y1, x1 - 5, y1);
        cairo_line_to (cr, x0 + 5, y1);
        cairo_curve_to (cr, x0 + 5, y1, x0, y1, x0, y1 - 5);
        cairo_line_to (cr, x0, y0 + 5);
        cairo_curve_to (cr, x0, y0 + 5, x0, y0, x0 + 5, y0);

        GdkRGBA color;

        if(text_renderer->background != NULL && !selected)
        {
            if(!gdk_rgba_parse(&color, text_renderer->background))
            {
                g_critical("Can't parse this color value: %s", text_renderer->background);
                gtk_style_context_get_background_color (context, state, &color);
            }

        }
        else
        {
            gtk_style_context_get_background_color (context, state, &color);
        }
        gdk_cairo_set_source_rgba (cr, &color);
        cairo_fill (cr);
    }

    /* draw the focus indicator */
    if (text_renderer->follow_state && (flags & GTK_CELL_RENDERER_FOCUSED) != 0)
    {
        gtk_render_focus (context, cr, cell_area->x + x_offset, cell_area->y + y_offset, text_width, text_height);
    }

    /* get proper sizing for the layout drawing */
    if (text_renderer->follow_state)
    {
        text_width -= 2 * text_renderer->focus_width;
        text_height -= 2 * text_renderer->focus_width;
        x_offset += text_renderer->focus_width;
        y_offset += text_renderer->focus_width;
    }

    /* draw the text */
    if (xalign == 0.5f)
        x_offset = (cell_area->width - text_renderer->wrap_width)/2;

    gtk_render_layout (context, cr,
                       cell_area->x + x_offset + xpad,
                       cell_area->y + y_offset + ypad,
                       text_renderer->layout);

    gtk_style_context_restore (context);
}
static void
gd_two_lines_renderer_render (GtkCellRenderer      *cell,
                              cairo_t              *cr,
                              GtkWidget            *widget,
                              const GdkRectangle   *background_area,
                              const GdkRectangle   *cell_area,
                              GtkCellRendererState  flags)
{
  GdTwoLinesRenderer *self = GD_TWO_LINES_RENDERER (cell);
  GtkStyleContext *context;
  gint line_one_height;
  GtkStateFlags state;
  GdkRectangle render_area = *cell_area;
  gint xpad, ypad, x_offset_1, x_offset_2, y_offset;
  PangoLayout *layout_one, *layout_two;

  context = gtk_widget_get_style_context (widget);
  gd_two_lines_renderer_prepare_layouts (self, widget, &layout_one, &layout_two);
  gd_two_lines_renderer_get_size (cell, widget,
                                  layout_one, layout_two,
                                  NULL, NULL,
                                  cell_area,
                                  &x_offset_1, &x_offset_2, &y_offset);

  gtk_cell_renderer_get_padding (cell, &xpad, &ypad);

  render_area.x += xpad + x_offset_1;
  render_area.y += ypad;

  pango_layout_set_width (layout_one,
                          (cell_area->width - x_offset_1 - 2 * xpad) * PANGO_SCALE);

  gtk_render_layout (context, cr,
                     render_area.x,
                     render_area.y,
                     layout_one);

  if (layout_two != NULL)
    {
      pango_layout_get_pixel_size (layout_one,
                                   NULL, &line_one_height);

      gtk_style_context_save (context);
      gtk_style_context_add_class (context, "dim-label");

      state = gtk_cell_renderer_get_state (cell, widget, flags);
      gtk_style_context_set_state (context, state);

      render_area.x += - x_offset_1 + x_offset_2;
      render_area.y += line_one_height;
      pango_layout_set_width (layout_two,
                              (cell_area->width - x_offset_2 - 2 * xpad) * PANGO_SCALE);

      gtk_render_layout (context, cr,
                         render_area.x,
                         render_area.y,
                         layout_two);

      gtk_style_context_restore (context);
    }

  g_clear_object (&layout_one);
  g_clear_object (&layout_two);
}
示例#25
0
static void
gimp_cell_renderer_toggle_render (GtkCellRenderer      *cell,
                                  cairo_t              *cr,
                                  GtkWidget            *widget,
                                  const GdkRectangle   *background_area,
                                  const GdkRectangle   *cell_area,
                                  GtkCellRendererState  flags)
{
  GimpCellRendererToggle *toggle = GIMP_CELL_RENDERER_TOGGLE (cell);
  GdkRectangle            toggle_rect;
  GdkRectangle            draw_rect;
  GtkStyleContext        *context = gtk_widget_get_style_context (widget);
  GdkRectangle            clip_rect;
  GtkStateFlags           state;
  gboolean                active;
  gint                    xpad;
  gint                    ypad;

  if (! toggle->stock_id)
    {
      GTK_CELL_RENDERER_CLASS (parent_class)->render (cell,
                                                      cr,
                                                      widget,
                                                      background_area,
                                                      cell_area,
                                                      flags);
      return;
    }

  gtk_cell_renderer_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;

  active =
    gtk_cell_renderer_toggle_get_active (GTK_CELL_RENDERER_TOGGLE (cell));

  if (!gtk_cell_renderer_get_sensitive (cell))
    {
      state = GTK_STATE_FLAG_INSENSITIVE;
    }
  else if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED)
    {
      if (gtk_widget_has_focus (widget))
        state = GTK_STATE_FLAG_SELECTED;
      else
        state = GTK_STATE_FLAG_ACTIVE;
    }
  else
    {
      if (gtk_cell_renderer_toggle_get_activatable (GTK_CELL_RENDERER_TOGGLE (cell)))
        state = GTK_STATE_FLAG_NORMAL;
      else
        state = GTK_STATE_FLAG_INSENSITIVE;
    }

  if ((flags & GTK_CELL_RENDERER_PRELIT) &&
      gdk_cairo_get_clip_rectangle(cr, &clip_rect) &&
      gdk_rectangle_intersect (&clip_rect, cell_area, &draw_rect))
    {
      cairo_save (cr);
      gdk_cairo_rectangle (cr, &draw_rect);
      cairo_clip (cr);
      gtk_render_frame (context, //gtk_widget_get_style_context (widget),
                        cr,
                        toggle_rect.x, toggle_rect.y,
                        toggle_rect.width, toggle_rect.height);
      gtk_style_context_restore (context);
      cairo_restore (cr);
    }

  if (active)
    {
      GdkPixbuf *insensitive = NULL;
      GdkPixbuf *pixbuf = toggle->pixbuf;

      GtkBorder  border = { 1, 1, 1, 1 };

#if 0
      /* FIXME: for some reason calling gtk_style_context_get_border
       * makes the icon only visible on hover, so use border = 1
       * for now as a workaround
       */
      gtk_style_context_get_border (context, state, &border);
#endif

      toggle_rect.x      += border.left;
      toggle_rect.y      += border.top;
      toggle_rect.width  -= (border.left + border.right);
      toggle_rect.height -= (border.top + border.bottom);

      if (state & GTK_STATE_FLAG_INSENSITIVE)
        {
	  GtkIconSource *source;

	  source = gtk_icon_source_new ();
	  gtk_icon_source_set_pixbuf (source, pixbuf);
	  /* The size here is arbitrary; since size isn't
	   * wildcarded in the source, it isn't supposed to be
	   * scaled by the engine function
	   */
	  gtk_icon_source_set_size (source, GTK_ICON_SIZE_SMALL_TOOLBAR);
	  gtk_icon_source_set_size_wildcarded (source, FALSE);

          gtk_style_context_save (context);
          gtk_style_context_set_state (context, GTK_STATE_FLAG_INSENSITIVE);
          insensitive = gtk_render_icon_pixbuf (context, source, (GtkIconSize)-1);
          gtk_style_context_restore (context);

	  gtk_icon_source_free (source);

	  pixbuf = insensitive;
	}

      if (gdk_rectangle_intersect (&draw_rect, &toggle_rect, &draw_rect))
        {
	  gdk_cairo_set_source_pixbuf (cr, pixbuf, toggle_rect.x, toggle_rect.y);
	  gdk_cairo_rectangle (cr, &draw_rect);
	  cairo_fill (cr);
	}
	      
      if (insensitive)
        g_object_unref (insensitive);
    }
}
示例#26
0
static void
gd_two_lines_renderer_get_size (GtkCellRenderer *cell,
                                GtkWidget *widget,
                                PangoLayout *layout_1,
                                PangoLayout *layout_2,
                                gint *width,
                                gint *height,
                                const GdkRectangle *cell_area,
                                gint *x_offset_1,
                                gint *x_offset_2,
                                gint *y_offset)
{
  GdTwoLinesRenderer *self = GD_TWO_LINES_RENDERER (cell);
  gint xpad, ypad;
  PangoLayout *layout_one, *layout_two;
  GdkRectangle layout_one_rect, layout_two_rect, layout_union;

  if (layout_1 == NULL)
    {
      gd_two_lines_renderer_prepare_layouts (self, cell_area, widget, &layout_one, &layout_two);
    }
  else
    {
      layout_one = g_object_ref (layout_1);

      if (layout_2 != NULL)
        layout_two = g_object_ref (layout_2);
      else
        layout_two = NULL;
    }

  gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
  pango_layout_get_pixel_extents (layout_one, NULL, (PangoRectangle *) &layout_one_rect);

  if (layout_two != NULL)
    {
      pango_layout_get_pixel_extents (layout_two, NULL, (PangoRectangle *) &layout_two_rect);

      layout_union.width = MAX (layout_one_rect.width, layout_two_rect.width);
      layout_union.height = layout_one_rect.height + layout_two_rect.height;
    }
  else
    {
      layout_union = layout_one_rect;
    }

  if (cell_area)
    {
      gfloat xalign, yalign;

      gtk_cell_renderer_get_alignment (cell, &xalign, &yalign);

      layout_union.width  = MIN (layout_union.width, cell_area->width - 2 * xpad);
      layout_union.height = MIN (layout_union.height, cell_area->height - 2 * ypad);

      if (x_offset_1)
	{
	  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
	    *x_offset_1 = (1.0 - xalign) * (cell_area->width - (layout_one_rect.width + (2 * xpad)));
	  else 
	    *x_offset_1 = xalign * (cell_area->width - (layout_one_rect.width + (2 * xpad)));

          *x_offset_1 = MAX (*x_offset_1, 0);
	}
      if (x_offset_2)
        {
          if (layout_two != NULL)
            {
              if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
                *x_offset_2 = (1.0 - xalign) * (cell_area->width - (layout_two_rect.width + (2 * xpad)));
              else 
                *x_offset_2 = xalign * (cell_area->width - (layout_two_rect.width + (2 * xpad)));

              *x_offset_2 = MAX (*x_offset_2, 0);
            }
          else
            {
              *x_offset_2 = 0;
            }
        }

      if (y_offset)
	{
	  *y_offset = yalign * (cell_area->height - (layout_union.height + (2 * ypad)));
	  *y_offset = MAX (*y_offset, 0);
	}
    }
  else
    {
      if (x_offset_1) *x_offset_1 = 0;
      if (x_offset_2) *x_offset_2 = 0;
      if (y_offset) *y_offset = 0;
    }

  g_clear_object (&layout_one);
  g_clear_object (&layout_two);

  if (height)
    *height = ypad * 2 + layout_union.height;

  if (width)
    *width = xpad * 2 + layout_union.width;
}
static void
gimp_cell_renderer_toggle_render (GtkCellRenderer      *cell,
                                  GdkWindow            *window,
                                  GtkWidget            *widget,
                                  GdkRectangle         *background_area,
                                  GdkRectangle         *cell_area,
                                  GdkRectangle         *expose_area,
                                  GtkCellRendererState  flags)
{
  GimpCellRendererToggle *toggle = GIMP_CELL_RENDERER_TOGGLE (cell);
  GtkStyle               *style  = gtk_widget_get_style (widget);
  GdkRectangle            toggle_rect;
  GdkRectangle            draw_rect;
  GtkStateType            state;
  gboolean                active;
  gint                    xpad;
  gint                    ypad;

  if (! toggle->stock_id)
    {
      GTK_CELL_RENDERER_CLASS (parent_class)->render (cell, window, widget,
                                                      background_area,
                                                      cell_area, expose_area,
                                                      flags);
      return;
    }

  gimp_cell_renderer_toggle_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;

  active =
    gtk_cell_renderer_toggle_get_active (GTK_CELL_RENDERER_TOGGLE (cell));

  if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED)
    {
      if (gtk_widget_has_focus (widget))
        state = GTK_STATE_SELECTED;
      else
        state = GTK_STATE_ACTIVE;
    }
  else
    {
      if (gtk_cell_renderer_toggle_get_activatable (GTK_CELL_RENDERER_TOGGLE (cell)))
        state = GTK_STATE_NORMAL;
      else
        state = GTK_STATE_INSENSITIVE;
    }

  if (gdk_rectangle_intersect (expose_area, cell_area, &draw_rect) &&
      (flags & GTK_CELL_RENDERER_PRELIT))
    gtk_paint_shadow (style,
                      window,
                      state,
                      active ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
                      &draw_rect,
                      widget, NULL,
                      toggle_rect.x,     toggle_rect.y,
                      toggle_rect.width, toggle_rect.height);

  if (active)
    {
      toggle_rect.x      += style->xthickness;
      toggle_rect.y      += style->ythickness;
      toggle_rect.width  -= style->xthickness * 2;
      toggle_rect.height -= style->ythickness * 2;

      if (gdk_rectangle_intersect (&draw_rect, &toggle_rect, &draw_rect))
        {
          cairo_t  *cr = gdk_cairo_create (window);
          gboolean  inconsistent;

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

          gdk_cairo_set_source_pixbuf (cr, toggle->pixbuf,
                                       toggle_rect.x, toggle_rect.y);
          cairo_paint (cr);

          g_object_get (toggle,
                        "inconsistent", &inconsistent,
                        NULL);

          if (inconsistent)
            {
              gdk_cairo_set_source_color (cr, &style->fg[state]);
              cairo_set_line_width (cr, 1.5);
              cairo_move_to (cr,
                             toggle_rect.x + toggle_rect.width - 1,
                             toggle_rect.y + 1);
              cairo_line_to (cr,
                             toggle_rect.x + 1,
                             toggle_rect.y + toggle_rect.height - 1);
              cairo_stroke (cr);
            }

          cairo_destroy (cr);
        }
    }
}
static void
gimp_cell_renderer_toggle_get_size (GtkCellRenderer *cell,
                                    GtkWidget       *widget,
                                    GdkRectangle    *cell_area,
                                    gint            *x_offset,
                                    gint            *y_offset,
                                    gint            *width,
                                    gint            *height)
{
  GimpCellRendererToggle *toggle = GIMP_CELL_RENDERER_TOGGLE (cell);
  GtkStyle               *style  = gtk_widget_get_style (widget);
  gint                    calc_width;
  gint                    calc_height;
  gint                    pixbuf_width;
  gint                    pixbuf_height;
  gfloat                  xalign;
  gfloat                  yalign;
  gint                    xpad;
  gint                    ypad;

  if (! toggle->stock_id)
    {
      GTK_CELL_RENDERER_CLASS (parent_class)->get_size (cell,
                                                        widget,
                                                        cell_area,
                                                        x_offset, y_offset,
                                                        width, height);
      return;
    }

  gtk_cell_renderer_get_alignment (cell, &xalign, &yalign);
  gtk_cell_renderer_get_padding (cell, &xpad, &ypad);

  if (! toggle->pixbuf)
    gimp_cell_renderer_toggle_create_pixbuf (toggle, widget);

  pixbuf_width  = gdk_pixbuf_get_width  (toggle->pixbuf);
  pixbuf_height = gdk_pixbuf_get_height (toggle->pixbuf);

  calc_width  = (pixbuf_width +
                 (gint) xpad * 2 + style->xthickness * 2);
  calc_height = (pixbuf_height +
                 (gint) ypad * 2 + style->ythickness * 2);

  if (width)
    *width  = calc_width;

  if (height)
    *height = calc_height;

  if (cell_area)
    {
      if (x_offset)
        {
          *x_offset = (((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ?
                        (1.0 - xalign) : xalign) *
                       (cell_area->width - calc_width));
          *x_offset = MAX (*x_offset, 0);
        }

      if (y_offset)
        {
          *y_offset = yalign * (cell_area->height - calc_height);
          *y_offset = MAX (*y_offset, 0);
        }
    }
}
示例#29
0
static void
gd_two_lines_renderer_render (GtkCellRenderer      *cell,
                              cairo_t              *cr,
                              GtkWidget            *widget,
                              const GdkRectangle   *background_area,
                              const GdkRectangle   *cell_area,
                              GtkCellRendererState  flags)
{
  GdTwoLinesRenderer *self = GD_TWO_LINES_RENDERER (cell);
  GtkStyleContext *context;
  gint line_one_height;
  GtkStateFlags state;
  GdkRectangle area, render_area = *cell_area;
  gint xpad, ypad, x_offset_1, x_offset_2, y_offset;
  PangoLayout *layout_one, *layout_two;
  PangoRectangle layout_rect;

  /* fetch common information */
  context = gtk_widget_get_style_context (widget);
  gd_two_lines_renderer_prepare_layouts (self, cell_area, widget, &layout_one, &layout_two);
  gd_two_lines_renderer_get_size (cell, widget,
                                  layout_one, layout_two,
                                  NULL, NULL,
                                  cell_area,
                                  &x_offset_1, &x_offset_2, &y_offset);
  gtk_cell_renderer_get_padding (cell, &xpad, &ypad);

  area = *cell_area;
  area.x += xpad;
  area.y += ypad;

  /* now render the first layout */
  pango_layout_get_pixel_extents (layout_one, NULL, &layout_rect);

  render_area = area;
  render_area.x += x_offset_1 - layout_rect.x;

  gtk_render_layout (context, cr,
                     render_area.x,
                     render_area.y,
                     layout_one);

  /* render the second layout */
  if (layout_two != NULL)
    {
      pango_layout_get_pixel_size (layout_one,
                                   NULL, &line_one_height);

      gtk_style_context_save (context);

      apply_subtitle_style_to_layout (context, layout_two, flags);

      state = gtk_cell_renderer_get_state (cell, widget, flags);
      gtk_style_context_set_state (context, state);

      pango_layout_get_pixel_extents (layout_two, NULL, &layout_rect);

      render_area = area;
      render_area.x += x_offset_2 - layout_rect.x;
      render_area.y += line_one_height;

      gtk_render_layout (context, cr,
                         render_area.x,
                         render_area.y,
                         layout_two);

      gtk_style_context_restore (context);
    }

  g_clear_object (&layout_one);
  g_clear_object (&layout_two);
}
示例#30
0
static void
gd_two_lines_renderer_get_preferred_width (GtkCellRenderer *cell,
                                           GtkWidget       *widget,
                                           gint            *minimum_size,
                                           gint            *natural_size)
{
  PangoContext *context;
  PangoFontMetrics *metrics;
  PangoFontDescription *font_desc;
  GtkStyleContext *style_context;
  gint nat_width, min_width;
  gint xpad, char_width, wrap_width, text_width;
  gint width_chars, ellipsize_chars;

  g_object_get (cell,
                "xpad", &xpad,
                "width-chars", &width_chars,
                "wrap-width", &wrap_width,
                NULL);
  style_context = gtk_widget_get_style_context (widget);
  gtk_cell_renderer_get_padding (cell, &xpad, NULL);

  gd_two_lines_renderer_get_size (cell, widget,
                                  NULL, NULL,
                                  &text_width, NULL,
                                  NULL, 
                                  NULL, NULL, NULL);

  /* Fetch the average size of a character */
  context = gtk_widget_get_pango_context (widget);
  gtk_style_context_save (style_context);
  gtk_style_context_set_state (style_context, 0);
  gtk_style_context_get (style_context, gtk_style_context_get_state (style_context),
                         "font", &font_desc, NULL);
  gtk_style_context_restore (style_context);
  metrics = pango_context_get_metrics (context, font_desc,
                                       pango_context_get_language (context));

  char_width = pango_font_metrics_get_approximate_char_width (metrics);

  pango_font_metrics_unref (metrics);
  pango_font_description_free (font_desc);

  /* enforce minimum width for ellipsized labels at ~3 chars */
  ellipsize_chars = 3;

  /* If no width-chars set, minimum for wrapping text will be the wrap-width */
  if (wrap_width > -1)
    min_width = xpad * 2 + MIN (text_width, wrap_width);
  else
    min_width = xpad * 2 +
      MIN (text_width,
           (PANGO_PIXELS (char_width) * MAX (width_chars, ellipsize_chars)));

  if (width_chars > 0)
    nat_width = xpad * 2 +
      MAX ((PANGO_PIXELS (char_width) * width_chars), text_width);
  else
    nat_width = xpad * 2 + text_width;

  nat_width = MAX (nat_width, min_width);

  if (minimum_size)
    *minimum_size = min_width;

  if (natural_size)
    *natural_size = nat_width;
}