示例#1
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);
}
示例#2
0
static void
exo_cell_renderer_icon_render (GtkCellRenderer     *renderer,
                               GdkWindow           *window,
                               GtkWidget           *widget,
                               GdkRectangle        *background_area,
                               GdkRectangle        *cell_area,
                               GdkRectangle        *expose_area,
                               GtkCellRendererState flags)
{
  const ExoCellRendererIconPrivate *priv = EXO_CELL_RENDERER_ICON_GET_PRIVATE (renderer);
  GtkIconSource                    *icon_source;
  GtkIconTheme                     *icon_theme;
  GdkRectangle                      icon_area;
  GdkRectangle                      draw_area;
  GtkStateType                      state;
  const gchar                      *filename;
  GtkIconInfo                      *icon_info = NULL;
  GdkPixbuf                        *icon = NULL;
  GdkPixbuf                        *temp;
  GError                           *err = NULL;
  gchar                            *display_name = NULL;
  gint                             *icon_sizes;
  gint                              icon_size;
  gint                              n;

  /* verify that we have an icon */
  if (G_UNLIKELY (priv->icon == NULL && priv->gicon == NULL))
    return;

  /* icon may be either an image file or a named icon */
  if (priv->icon != NULL && g_path_is_absolute (priv->icon))
    {
      /* load the icon via the thumbnail database */
      icon = _exo_thumbnail_get_for_file (priv->icon, (priv->size > 128) ? EXO_THUMBNAIL_SIZE_LARGE : EXO_THUMBNAIL_SIZE_NORMAL, &err);
    }
  else if (priv->icon != NULL || priv->gicon != NULL)
    {
      /* determine the best icon size (GtkIconTheme is somewhat messy scaling up small icons) */
      icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));

      if (priv->icon != NULL)
        {
          icon_sizes = gtk_icon_theme_get_icon_sizes (icon_theme, priv->icon);
          for (icon_size = -1, n = 0; icon_sizes[n] != 0; ++n)
            {
              /* we can use any size if scalable, because we load the file directly */
              if (icon_sizes[n] == -1)
                icon_size = priv->size;
              else if (icon_sizes[n] > icon_size && icon_sizes[n] <= priv->size)
                icon_size = icon_sizes[n];
            }
          g_free (icon_sizes);

          /* if we don't know any icon sizes at all, the icon is probably not present */
          if (G_UNLIKELY (icon_size < 0))
            icon_size = priv->size;

          /* lookup the icon in the icon theme */
          icon_info = gtk_icon_theme_lookup_icon (icon_theme, priv->icon, icon_size, 0);
        }
      else if (priv->gicon != NULL)
        {
          icon_info = gtk_icon_theme_lookup_by_gicon (icon_theme,
                                                      priv->gicon,
                                                      priv->size,
                                                      GTK_ICON_LOOKUP_USE_BUILTIN);
        }

      if (G_UNLIKELY (icon_info == NULL))
        return;

      /* check if we have an SVG icon here */
      filename = gtk_icon_info_get_filename (icon_info);
      if (filename != NULL && g_str_has_suffix (filename, ".svg"))
        {
          /* loading SVG icons is terribly slow, so we try to use thumbnail instead, and we use the
           * real available cell area directly here, because loading thumbnails involves scaling anyway
           * and this way we need to the thumbnail pixbuf scale only once.
           */
          icon = _exo_thumbnail_get_for_file (filename, (priv->size > 128) ? EXO_THUMBNAIL_SIZE_LARGE : EXO_THUMBNAIL_SIZE_NORMAL, &err);
        }
      else
        {
          /* regularly load the icon from the theme */
          icon = gtk_icon_info_load_icon (icon_info, &err);
        }
      gtk_icon_info_free (icon_info);
    }

  /* check if we failed */
  if (G_UNLIKELY (icon == NULL))
    {
      /* better let the user know whats going on, might be surprising otherwise */
      if (G_LIKELY (priv->icon != NULL))
        {
          display_name = g_filename_display_name (priv->icon);
        }
      else if (G_UNLIKELY (priv->gicon != NULL
                           && g_object_class_find_property (G_OBJECT_GET_CLASS (priv->gicon),
                                                            "name")))
        {
          g_object_get (priv->gicon, "name", &display_name, NULL);
        }

      if (display_name != NULL)
        {
          g_warning ("Failed to load \"%s\": %s", display_name, err->message);
          g_free (display_name);
        }

      g_error_free (err);
      return;
    }

  /* determine the real icon size */
  icon_area.width = gdk_pixbuf_get_width (icon);
  icon_area.height = gdk_pixbuf_get_height (icon);

  /* scale down the icon on-demand */
  if (G_UNLIKELY (icon_area.width > cell_area->width || icon_area.height > cell_area->height))
    {
      /* scale down to fit */
      temp = exo_gdk_pixbuf_scale_down (icon, TRUE, cell_area->width, cell_area->height);
      g_object_unref (G_OBJECT (icon));
      icon = temp;

      /* determine the icon dimensions again */
      icon_area.width = gdk_pixbuf_get_width (icon);
      icon_area.height = gdk_pixbuf_get_height (icon);
    }

  icon_area.x = cell_area->x + (cell_area->width - icon_area.width) / 2;
  icon_area.y = cell_area->y + (cell_area->height - icon_area.height) / 2;

  /* check whether the icon is affected by the expose event */
  if (gdk_rectangle_intersect (expose_area, &icon_area, &draw_area))
    {
      /* colorize the icon if we should follow the selection state */
      if ((flags & (GTK_CELL_RENDERER_SELECTED | GTK_CELL_RENDERER_PRELIT)) != 0 && priv->follow_state)
        {
          if ((flags & GTK_CELL_RENDERER_SELECTED) != 0)
            {
              state = GTK_WIDGET_HAS_FOCUS (widget) ? GTK_STATE_SELECTED : GTK_STATE_ACTIVE;
              temp = exo_gdk_pixbuf_colorize (icon, &widget->style->base[state]);
              g_object_unref (G_OBJECT (icon));
              icon = temp;
            }

          if ((flags & GTK_CELL_RENDERER_PRELIT) != 0)
            {
              temp = exo_gdk_pixbuf_spotlight (icon);
              g_object_unref (G_OBJECT (icon));
              icon = temp;
            }
        }

      /* check if we should render an insensitive icon */
      if (G_UNLIKELY (GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE || !renderer->sensitive))
        {
          /* allocate an icon source */
          icon_source = gtk_icon_source_new ();
          gtk_icon_source_set_pixbuf (icon_source, icon);
          gtk_icon_source_set_size_wildcarded (icon_source, FALSE);
          gtk_icon_source_set_size (icon_source, GTK_ICON_SIZE_SMALL_TOOLBAR);

          /* render the insensitive icon */
          temp = gtk_style_render_icon (widget->style, icon_source, gtk_widget_get_direction (widget),
                                        GTK_STATE_INSENSITIVE, -1, widget, "gtkcellrendererpixbuf");
          g_object_unref (G_OBJECT (icon));
          icon = temp;

          /* release the icon source */
          gtk_icon_source_free (icon_source);
        }

      /* render the invalid parts of the icon */
      gdk_draw_pixbuf (window, widget->style->black_gc, icon,
                       draw_area.x - icon_area.x, draw_area.y - icon_area.y,
                       draw_area.x, draw_area.y, draw_area.width, draw_area.height,
                       GDK_RGB_DITHER_NORMAL, 0, 0);
    }

  /* release the file's icon */
  g_object_unref (G_OBJECT (icon));
}
示例#3
0
文件: gtklevelbar.c 项目: Therzok/gtk
static void
gtk_level_bar_draw_fill_continuous (GtkLevelBar           *self,
                                    cairo_t               *cr,
                                    cairo_rectangle_int_t *fill_area)
{
  GtkWidget *widget = GTK_WIDGET (self);
  GtkStyleContext *context;
  cairo_rectangle_int_t base_area, block_area;
  GtkBorder block_margin;
  gdouble fill_percentage;
  gboolean inverted;

  inverted = self->priv->inverted;
  if (gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_RTL)
    {
      if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
        inverted = !inverted;
    }

  context = gtk_widget_get_style_context (widget);

  /* render the empty (unfilled) part */
  gtk_style_context_save_to_node (context, self->priv->block_node[inverted ? 0 : 1]);
  gtk_style_context_get_margin (context, gtk_style_context_get_state (context), &block_margin);

  base_area = *fill_area;
  base_area.x += block_margin.left;
  base_area.y += block_margin.top;
  base_area.width -= block_margin.left + block_margin.right;
  base_area.height -= block_margin.top + block_margin.bottom;

  gtk_render_background (context, cr, base_area.x, base_area.y,
                         base_area.width, base_area.height);
  gtk_render_frame (context, cr, base_area.x, base_area.y,
                    base_area.width, base_area.height);

  gtk_style_context_restore (context);

  /* now render the filled part on top of it */

  block_area = base_area;

  fill_percentage = (self->priv->cur_value - self->priv->min_value) /
    (self->priv->max_value - self->priv->min_value);

  if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
    {
      block_area.width = (gint) floor (block_area.width * fill_percentage);

      if (inverted)
        block_area.x += base_area.width - block_area.width;
    }
  else
    {
      block_area.height = (gint) floor (block_area.height * fill_percentage);

      if (inverted)
        block_area.y += base_area.height - block_area.height;
    }

  gtk_style_context_save_to_node (context, self->priv->block_node[inverted ? 1 : 0]);

  gtk_render_background (context, cr, block_area.x, block_area.y,
                         block_area.width, block_area.height);
  gtk_render_frame (context, cr, block_area.x, block_area.y,
                    block_area.width, block_area.height);

  gtk_style_context_restore (context);
}
示例#4
0
cairo_surface_t *
gtk_icon_helper_load_surface (GtkIconHelper   *self,
                              int              scale)
{
  cairo_surface_t *surface;
  GtkIconSet *icon_set;
  GIcon *gicon;

  switch (gtk_image_definition_get_storage_type (self->priv->def))
    {
    case GTK_IMAGE_SURFACE:
      surface = ensure_surface_from_surface (self, gtk_image_definition_get_surface (self->priv->def));
      break;

    case GTK_IMAGE_PIXBUF:
      surface = ensure_surface_from_pixbuf (self,
                                            gtk_css_node_get_style (gtk_css_gadget_get_node (GTK_CSS_GADGET (self))),
                                            scale,
                                            gtk_image_definition_get_pixbuf (self->priv->def),
                                            gtk_image_definition_get_scale (self->priv->def));
      break;

    case GTK_IMAGE_STOCK:
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
      icon_set = gtk_icon_factory_lookup_default (gtk_image_definition_get_stock (self->priv->def));
G_GNUC_END_IGNORE_DEPRECATIONS;
      if (icon_set != NULL)
	surface = ensure_surface_for_icon_set (self,
                                               gtk_css_node_get_style (gtk_css_gadget_get_node (GTK_CSS_GADGET (self))),
                                               gtk_widget_get_direction (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self))), 
                                               scale, icon_set);
      else
	surface = NULL;
      break;

    case GTK_IMAGE_ICON_SET:
      icon_set = gtk_image_definition_get_icon_set (self->priv->def);
      surface = ensure_surface_for_icon_set (self,
                                             gtk_css_node_get_style (gtk_css_gadget_get_node (GTK_CSS_GADGET (self))),
                                             gtk_widget_get_direction (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self))), 
                                             scale, icon_set);
      break;

    case GTK_IMAGE_ICON_NAME:
      if (self->priv->use_fallback)
        gicon = g_themed_icon_new_with_default_fallbacks (gtk_image_definition_get_icon_name (self->priv->def));
      else
        gicon = g_themed_icon_new (gtk_image_definition_get_icon_name (self->priv->def));
      surface = ensure_surface_for_gicon (self,
                                          gtk_css_node_get_style (gtk_css_gadget_get_node (GTK_CSS_GADGET (self))),
                                          gtk_widget_get_direction (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self))), 
                                          scale, 
                                          gicon);
      g_object_unref (gicon);
      break;

    case GTK_IMAGE_GICON:
      surface = ensure_surface_for_gicon (self, 
                                          gtk_css_node_get_style (gtk_css_gadget_get_node (GTK_CSS_GADGET (self))),
                                          gtk_widget_get_direction (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self))), 
                                          scale,
                                          gtk_image_definition_get_gicon (self->priv->def));
      break;

    case GTK_IMAGE_ANIMATION:
    case GTK_IMAGE_EMPTY:
    default:
      surface = NULL;
      break;
    }

  return surface;

}
示例#5
0
static gint
gimp_tag_popup_layout_tags (GimpTagPopup *popup,
                            gint          width)
{
    PangoFontMetrics *font_metrics;
    gint              x;
    gint              y;
    gint              height = 0;
    gint              i;
    gint              line_height;
    gint              space_width;

    x = GIMP_TAG_POPUP_MARGIN;
    y = GIMP_TAG_POPUP_MARGIN;

    font_metrics = pango_context_get_metrics (popup->context,
                   pango_context_get_font_description (popup->context),
                   NULL);

    line_height = PANGO_PIXELS ((pango_font_metrics_get_ascent (font_metrics) +
                                 pango_font_metrics_get_descent (font_metrics)));
    space_width = PANGO_PIXELS (pango_font_metrics_get_approximate_char_width (font_metrics));

    pango_font_metrics_unref (font_metrics);

    for (i = 0; i < popup->tag_count; i++)
    {
        PopupTagData *tag_data = &popup->tag_data[i];
        gint          w, h;

        pango_layout_set_text (popup->layout,
                               gimp_tag_get_name (tag_data->tag), -1);
        pango_layout_get_pixel_size (popup->layout, &w, &h);

        tag_data->bounds.width  = w + 2 * GIMP_TAG_POPUP_PADDING;
        tag_data->bounds.height = h + 2 * GIMP_TAG_POPUP_PADDING;

        if (x + space_width + tag_data->bounds.width +
                GIMP_TAG_POPUP_MARGIN - 1 > width)
        {
            x = GIMP_TAG_POPUP_MARGIN;
            y += line_height + 2 * GIMP_TAG_POPUP_PADDING + GIMP_TAG_POPUP_LINE_SPACING;
        }

        tag_data->bounds.x = x;
        tag_data->bounds.y = y;

        x += tag_data->bounds.width + space_width;
    }

    if (gtk_widget_get_direction (GTK_WIDGET (popup)) == GTK_TEXT_DIR_RTL)
    {
        for (i = 0; i < popup->tag_count; i++)
        {
            PopupTagData *tag_data = &popup->tag_data[i];

            tag_data->bounds.x = (width -
                                  tag_data->bounds.x -
                                  tag_data->bounds.width);
        }
    }

    height = y + line_height + GIMP_TAG_POPUP_MARGIN;

    return height;
}
示例#6
0
static gboolean applet_scroll(MatePanelApplet* applet, GdkEventScroll* event, PagerData* pager)
{
	GdkScrollDirection absolute_direction;
	int index;
	int n_workspaces;
	int n_columns;
	int in_last_row;

	if (event->type != GDK_SCROLL)
		return FALSE;

	index = wnck_workspace_get_number(wnck_screen_get_active_workspace(pager->screen));
	n_workspaces = wnck_screen_get_workspace_count(pager->screen);
	n_columns = n_workspaces / pager->n_rows;

	if (n_workspaces % pager->n_rows != 0)
		n_columns++;

	in_last_row    = n_workspaces % n_columns;

	absolute_direction = event->direction;

	if (gtk_widget_get_direction(GTK_WIDGET(applet)) == GTK_TEXT_DIR_RTL)
	{
		switch (event->direction)
		{
			case GDK_SCROLL_DOWN:
			case GDK_SCROLL_UP:
				break;
			case GDK_SCROLL_RIGHT:
				absolute_direction = GDK_SCROLL_LEFT;
				break;
			case GDK_SCROLL_LEFT:
				absolute_direction = GDK_SCROLL_RIGHT;
				break;
		}
	}

	switch (absolute_direction)
	{
		case GDK_SCROLL_DOWN:
			if (index + n_columns < n_workspaces)
			{
				index += n_columns;
			}
			else if (pager->wrap_workspaces && index == n_workspaces - 1)
			{
				index = 0;
			}
			else if ((index < n_workspaces - 1 && index + in_last_row != n_workspaces - 1) || (index == n_workspaces - 1 && in_last_row != 0))
			{
				index = (index % n_columns) + 1;
			}
			break;

		case GDK_SCROLL_RIGHT:
			if (index < n_workspaces - 1)
			{
				index++;
			}
			else if (pager->wrap_workspaces)
			{
			        index = 0;
			}
			break;

		case GDK_SCROLL_UP:
			if (index - n_columns >= 0)
			{
				index -= n_columns;
			}
			else if (index > 0)
			{
				index = ((pager->n_rows - 1) * n_columns) + (index % n_columns) - 1;
			}
			else if (pager->wrap_workspaces)
			{
				index = n_workspaces - 1;
			}

			if (index >= n_workspaces)
				index -= n_columns;
			break;

		case GDK_SCROLL_LEFT:
			if (index > 0)
			{
				index--;
			}
			else if (pager->wrap_workspaces)
			{
				index = n_workspaces - 1;
			}
			break;
		default:
			g_assert_not_reached();
			break;
	}

	wnck_workspace_activate(wnck_screen_get_workspace(pager->screen, index), event->time);

	return TRUE;
}
static void
gdl_dock_item_grip_size_allocate (GtkWidget     *widget,
                                  GtkAllocation *allocation)
{
    GdlDockItemGrip *grip;
    GtkContainer    *container;
    GtkRequisition   button_requisition = { 0, };
    GtkAllocation    child_allocation;

    g_return_if_fail (GDL_IS_DOCK_ITEM_GRIP (widget));
    g_return_if_fail (allocation != NULL);
  
    grip = GDL_DOCK_ITEM_GRIP (widget);
    container = GTK_CONTAINER (widget);

    GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);

    if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
        child_allocation.x = allocation->x + container->border_width + ALIGN_BORDER;
    else
        child_allocation.x = allocation->x + allocation->width - container->border_width;
    child_allocation.y = allocation->y + container->border_width;

    gtk_widget_size_request (grip->_priv->close_button, &button_requisition);

    if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL)
        child_allocation.x -= button_requisition.width;

    child_allocation.width = button_requisition.width;
    child_allocation.height = button_requisition.height;

    gtk_widget_size_allocate (grip->_priv->close_button, &child_allocation);

    if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
        child_allocation.x += button_requisition.width;
    

    gtk_widget_size_request (grip->_priv->iconify_button, &button_requisition);

    if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL)
        child_allocation.x -= button_requisition.width;

    child_allocation.width = button_requisition.width;
    child_allocation.height = button_requisition.height;

    gtk_widget_size_allocate (grip->_priv->iconify_button, &child_allocation);

    if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
        child_allocation.x += button_requisition.width;

    
    if (grip->title_window) {
        GdkRectangle area;
        
        /* set layout text */
        ensure_title_and_icon_pixbuf (grip);
        pango_layout_set_text (grip->_priv->title_layout, grip->_priv->title, -1);

        gdl_dock_item_grip_get_title_area (grip, &area);

        gdk_window_move_resize (grip->title_window,
                                area.x, area.y, area.width, area.height);

        if (grip->_priv->icon_pixbuf)
            area.width -= gdk_pixbuf_get_width (grip->_priv->icon_pixbuf) + 1;
            
        /* ellipsize title if it doesn't fit the title area */
        ellipsize_layout (grip->_priv->title_layout, area.width);
    }
}
示例#8
0
文件: icon-grid.c 项目: hsgg/lxpanel
/* Establish the widget placement of an icon grid. */
static gboolean icon_grid_placement(IconGrid * ig)
{
    /* Make sure the container is visible. */
    gtk_widget_show(ig->container);

    /* Erase the window. */
    GdkWindow * window = ig->widget->window;
    if (window != NULL)
        panel_determine_background_pixmap(ig->panel, ig->widget, window);

    /* Get and save the desired container geometry. */
    ig->container_width = ig->container->allocation.width;
    ig->container_height = ig->container->allocation.height;
    int child_width = ig->child_width;
    int child_height = ig->child_height;

    /* Get the required container geometry if all elements get the client's desired allocation. */
    int container_width_needed = (ig->columns * (child_width + ig->spacing)) - ig->spacing;
    int container_height_needed = (ig->rows * (child_height + ig->spacing)) - ig->spacing;

    /* Get the constrained child geometry if the allocated geometry is insufficient.
     * All children are still the same size and share equally in the deficit. */
    ig->constrained_child_width = ig->child_width;
    if ((ig->columns != 0) && (ig->rows != 0) && (ig->container_width > 1))
    {
        if (container_width_needed > ig->container_width)
            ig->constrained_child_width = child_width = (ig->container_width - ((ig->columns - 1) * ig->spacing)) / ig->columns;
        if (container_height_needed > ig->container_height)
            child_height = (ig->container_height - ((ig->rows - 1) * ig->spacing)) / ig->rows;
    }

    /* Initialize parameters to control repositioning each visible child. */
    GtkTextDirection direction = gtk_widget_get_direction(ig->container);
    int limit = ig->border + ((ig->orientation == GTK_ORIENTATION_HORIZONTAL)
                              ?  (ig->rows * (child_height + ig->spacing))
                              :  (ig->columns * (child_width + ig->spacing)));
    int x_initial = ((direction == GTK_TEXT_DIR_RTL)
                     ? ig->widget->allocation.width - child_width - ig->border
                     : ig->border);
    int x_delta = child_width + ig->spacing;
    if (direction == GTK_TEXT_DIR_RTL) x_delta = - x_delta;

    /* Reposition each visible child. */
    int x = x_initial;
    int y = ig->border;
    gboolean contains_sockets = FALSE;
    IconGridElement * ige;
    for (ige = ig->child_list; ige != NULL; ige = ige->flink)
    {
        if (ige->visible)
        {
            /* Do necessary operations on the child. */
            gtk_widget_show(ige->widget);
            if (((child_width != ige->widget->allocation.width) || (child_height != ige->widget->allocation.height))
                    && (child_width > 0) && (child_height > 0))
            {
                GtkAllocation alloc;
                alloc.x = x;
                alloc.y = y;
                alloc.width = child_width;
                alloc.height = child_height;
                gtk_widget_size_allocate(ige->widget, &alloc);
                gtk_widget_queue_resize(ige->widget);		/* Get labels to redraw ellipsized */
            }
            gtk_fixed_move(GTK_FIXED(ig->widget), ige->widget, x, y);
            gtk_widget_queue_draw(ige->widget);

            /* Note if a socket is placed. */
            if (GTK_IS_SOCKET(ige->widget))
                contains_sockets = TRUE;

            /* Advance to the next grid position. */
            if (ig->orientation == GTK_ORIENTATION_HORIZONTAL)
            {
                y += child_height + ig->spacing;
                if (y >= limit)
                {
                    y = ig->border;
                    x += x_delta;
                }
            }
            else
            {
                x += x_delta;
                if ((direction == GTK_TEXT_DIR_RTL) ? (x <= 0) : (x >= limit))
                {
                    x = x_initial;
                    y += child_height + ig->spacing;
                }
            }
        }
    }

    /* Redraw the container. */
    if (window != NULL)
        gdk_window_invalidate_rect(window, NULL, TRUE);
    gtk_widget_queue_draw(ig->container);

    /* If the icon grid contains sockets, do special handling to get the background erased. */
    if (contains_sockets)
        plugin_widget_set_background(ig->widget, ig->panel);
    return FALSE;
}
示例#9
0
static void
anjuta_tabber_size_allocate(GtkWidget* widget, GtkAllocation* allocation)
{
	g_return_if_fail (ANJUTA_IS_TABBER (widget));
	AnjutaTabber* tabber = ANJUTA_TABBER (widget);

	GList* child;
	gint focus_width;
	gint tab_curvature;
	gint tab_overlap;
	gint n_children = g_list_length (tabber->priv->children);
	gint x;
	gint padding;
	gint tab_space;
	
	gtk_widget_style_get (GTK_WIDGET (tabber),
	                      "focus-line-width", &focus_width,
	                      "tab-curvature", &tab_curvature,
	                      "tab-overlap", &tab_overlap,
	                      NULL);

	padding = focus_width + tabber->priv->tab_hborder;
	tab_space = tab_curvature - tab_overlap;
	
	gtk_widget_set_allocation (widget, allocation);

	switch (gtk_widget_get_direction (widget))
	{
		case GTK_TEXT_DIR_RTL:
			x = allocation->x + allocation->width;
			break;
		case GTK_TEXT_DIR_LTR:
		default:
			x = allocation->x;
	}

	if (gtk_widget_get_realized (widget))
	{
		gdk_window_move_resize (tabber->priv->event_window,
		                        allocation->x, allocation->y,
		                        allocation->width, allocation->height);
		if (gtk_widget_get_mapped (widget))
			gdk_window_show_unraised (tabber->priv->event_window);
	}

	if (n_children > 0)
	{
		gint total_width = 2 * tab_overlap;
		gboolean use_natural = FALSE;
		gint child_equal;
		gint extra_space = 0;
		gint real_width = allocation->width;

		/* Check if we have enough space for all widgets natural size */
		child_equal = real_width / n_children - 
			 n_children * 2 * (padding + tab_space) - 2 * tab_overlap;

		if (child_equal < 0)
			return;
		
		for (child = tabber->priv->children; child != NULL; child = g_list_next (child))
		{
			GtkWidget* child_widget = GTK_WIDGET (child->data);
			gint natural;
			gtk_widget_get_preferred_width (child_widget, NULL,
			                                &natural);

			total_width += natural + 2 * (padding + tab_space);
			if (natural < child_equal)
				extra_space += child_equal - natural;
		}
		use_natural = (total_width <= real_width);
		child_equal += extra_space / n_children;
		
		for (child = tabber->priv->children; child != NULL; child = g_list_next (child))
		{
			GtkWidget* child_widget = GTK_WIDGET (child->data);
			GtkAllocation child_alloc;
			gint natural;
			gint minimal;
			gint begin_tab = tab_space;
			gint end_tab = tab_space;

			if (child == g_list_first (tabber->priv->children))
				begin_tab += tab_overlap;
			if (child == g_list_last (tabber->priv->children))
				end_tab += tab_overlap;
			
			gtk_widget_get_preferred_width (child_widget, &minimal,
				                            &natural);

			if (use_natural)
			{
				child_alloc.width = natural;
			}
			else
			{
				if (natural < child_equal)
					child_alloc.width = natural;
				else
					child_alloc.width = child_equal;
			}
			child_alloc.height = allocation->height
				- 2 * (focus_width + tabber->priv->tab_vborder);
			switch (gtk_widget_get_direction (widget))
			{
				case GTK_TEXT_DIR_RTL:
					child_alloc.x = x - padding - begin_tab - child_alloc.width;
					x = child_alloc.x - padding - end_tab;
					break;
				case GTK_TEXT_DIR_LTR:
				default:
					child_alloc.x = x + padding + begin_tab;
					x = child_alloc.x + child_alloc.width + padding + end_tab;
			}
			child_alloc.y = allocation->y +
				tabber->priv->tab_vborder + focus_width;

			gtk_widget_size_allocate (GTK_WIDGET (child->data), &child_alloc);
		}
	}
}
static void
gnome_control_center_init (GnomeControlCenter *self)
{
  GError *err = NULL;
  GnomeControlCenterPrivate *priv;
  GdkScreen *screen;
  GtkWidget *frame;

  priv = self->priv = CONTROL_CENTER_PRIVATE (self);

#if 0 /* ifdef HAVE_CHEESE */
  if (gtk_clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS)
    {
      g_critical ("Clutter-GTK init failed");
      return;
    }
#endif /* HAVE_CHEESE */

  priv->monitor_num = -1;
  self->priv->small_screen = SMALL_SCREEN_UNSET;

  /* load the user interface */
  priv->builder = gtk_builder_new ();

  if (!gtk_builder_add_from_file (priv->builder, UIDIR "/shell.ui", &err))
    {
      g_critical ("Could not build interface: %s", err->message);
      g_error_free (err);

      return;
    }

  /* connect various signals */
  priv->window = W (priv->builder, "main-window");
#if 0
  gtk_window_set_hide_titlebar_when_maximized (GTK_WINDOW (priv->window), TRUE);
#endif
  screen = gtk_widget_get_screen (priv->window);
  g_signal_connect (screen, "monitors-changed", G_CALLBACK (monitors_changed_cb), self);
  g_signal_connect (priv->window, "configure-event", G_CALLBACK (main_window_configure_cb), self);
  g_signal_connect (priv->window, "notify::application", G_CALLBACK (application_set_cb), self);
  g_signal_connect_swapped (priv->window, "delete-event", G_CALLBACK (g_object_unref), self);
  g_signal_connect_after (priv->window, "key_press_event",
                          G_CALLBACK (window_key_press_event), self);

  priv->notebook = W (priv->builder, "notebook");

  /* Main scrolled window */
  priv->scrolled_window = W (priv->builder, "scrolledwindow1");
  gtk_widget_set_size_request (priv->scrolled_window, FIXED_WIDTH, priv->small_screen == SMALL_SCREEN_TRUE ? SMALL_SCREEN_FIXED_HEIGHT : YAST_FIXED_HEIGHT);
#if 0
  gtk_widget_set_size_request (priv->scrolled_window, FIXED_WIDTH, -1);
#endif
  priv->main_vbox = W (priv->builder, "main-vbox");
  g_signal_connect (priv->notebook, "notify::page",
                    G_CALLBACK (notebook_page_notify_cb), priv);

  /* Set the alignment for the home button */
  frame = W(priv->builder, "home-aspect-frame");
  if (gtk_widget_get_direction (frame) == GTK_TEXT_DIR_RTL)
    g_object_set (frame, "xalign", 1.0, NULL);

  g_signal_connect (gtk_builder_get_object (priv->builder, "home-button"),
                    "clicked", G_CALLBACK (home_button_clicked_cb), self);

  /* keep a list of custom widgets to unload on panel change */
  priv->custom_widgets = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);

  /* load the available settings panels */
  setup_model (self);

  /* load the panels that are implemented as plugins */
  load_panel_plugins (self);

  /* setup search functionality */
  setup_search (self);

  setup_lock (self);

  /* store default window title and name */
  priv->default_window_title = g_strdup (gtk_window_get_title (GTK_WINDOW (priv->window)));
  priv->default_window_icon = g_strdup (gtk_window_get_icon_name (GTK_WINDOW (priv->window)));

  notebook_page_notify_cb (GTK_NOTEBOOK (priv->notebook), NULL, priv);
}
static void
thunar_icon_renderer_render (GtkCellRenderer     *renderer,
                             GdkWindow           *window,
                             GtkWidget           *widget,
                             GdkRectangle        *background_area,
                             GdkRectangle        *cell_area,
                             GdkRectangle        *expose_area,
                             GtkCellRendererState flags)
{
  ThunarClipboardManager *clipboard;
  ThunarFileIconState     icon_state;
  ThunarIconRenderer     *icon_renderer = THUNAR_ICON_RENDERER (renderer);
  ThunarIconFactory      *icon_factory;
  GtkIconSource          *icon_source;
  GtkIconTheme           *icon_theme;
  GdkRectangle            emblem_area;
  GdkRectangle            icon_area;
  GdkRectangle            draw_area;
  GtkStateType            state;
  GdkPixbuf              *emblem;
  GdkPixbuf              *icon;
  GdkPixbuf              *temp;
  GList                  *emblems;
  GList                  *lp;
  gint                    max_emblems;
  gint                    position;

  if (G_UNLIKELY (icon_renderer->file == NULL))
    return;

  /* determine the icon state */
  icon_state = (icon_renderer->drop_file != icon_renderer->file)
             ? renderer->is_expanded
              ? THUNAR_FILE_ICON_STATE_OPEN
              : THUNAR_FILE_ICON_STATE_DEFAULT
             : THUNAR_FILE_ICON_STATE_DROP;

  /* load the main icon */
  icon_theme = gtk_icon_theme_get_for_screen (gdk_drawable_get_screen (window));
  icon_factory = thunar_icon_factory_get_for_icon_theme (icon_theme);
  icon = thunar_icon_factory_load_file_icon (icon_factory, icon_renderer->file, icon_state, icon_renderer->size);
  if (G_UNLIKELY (icon == NULL))
    {
      g_object_unref (G_OBJECT (icon_factory));
      return;
    }

  /* pre-light the item if we're dragging about it */
  if (G_UNLIKELY (icon_state == THUNAR_FILE_ICON_STATE_DROP))
    flags |= GTK_CELL_RENDERER_PRELIT;

  /* determine the real icon size */
  icon_area.width = gdk_pixbuf_get_width (icon);
  icon_area.height = gdk_pixbuf_get_height (icon);

  /* scale down the icon on-demand */
  if (G_UNLIKELY (icon_area.width > cell_area->width || icon_area.height > cell_area->height))
    {
      /* scale down to fit */
      temp = exo_gdk_pixbuf_scale_down (icon, TRUE, cell_area->width, cell_area->height);
      g_object_unref (G_OBJECT (icon));
      icon = temp;

      /* determine the icon dimensions again */
      icon_area.width = gdk_pixbuf_get_width (icon);
      icon_area.height = gdk_pixbuf_get_height (icon);
    }

  icon_area.x = cell_area->x + (cell_area->width - icon_area.width) / 2;
  icon_area.y = cell_area->y + (cell_area->height - icon_area.height) / 2;

  /* check whether the icon is affected by the expose event */
  if (gdk_rectangle_intersect (expose_area, &icon_area, &draw_area))
    {
      /* use a translucent icon to represent cutted and hidden files to the user */
      clipboard = thunar_clipboard_manager_get_for_display (gtk_widget_get_display (widget));
      if (thunar_clipboard_manager_has_cutted_file (clipboard, icon_renderer->file))
        {
          /* 50% translucent for cutted files */
          temp = exo_gdk_pixbuf_lucent (icon, 50);
          g_object_unref (G_OBJECT (icon));
          icon = temp;
        }
      else if (thunar_file_is_hidden (icon_renderer->file))
        {
          /* 75% translucent for hidden files */
          temp = exo_gdk_pixbuf_lucent (icon, 75);
          g_object_unref (G_OBJECT (icon));
          icon = temp;
        }
      g_object_unref (G_OBJECT (clipboard));

      /* colorize the icon if we should follow the selection state */
      if ((flags & (GTK_CELL_RENDERER_SELECTED | GTK_CELL_RENDERER_PRELIT)) != 0 && icon_renderer->follow_state)
        {
          if ((flags & GTK_CELL_RENDERER_SELECTED) != 0)
            {
              state = GTK_WIDGET_HAS_FOCUS (widget) ? GTK_STATE_SELECTED : GTK_STATE_ACTIVE;
              temp = exo_gdk_pixbuf_colorize (icon, &widget->style->base[state]);
              g_object_unref (G_OBJECT (icon));
              icon = temp;
            }

          if ((flags & GTK_CELL_RENDERER_PRELIT) != 0)
            {
              temp = exo_gdk_pixbuf_spotlight (icon);
              g_object_unref (G_OBJECT (icon));
              icon = temp;
            }
        }

      /* check if we should render an insensitive icon */
      if (G_UNLIKELY (GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE || !renderer->sensitive))
        {
          /* allocate an icon source */
          icon_source = gtk_icon_source_new ();
          gtk_icon_source_set_pixbuf (icon_source, icon);
          gtk_icon_source_set_size_wildcarded (icon_source, FALSE);
          gtk_icon_source_set_size (icon_source, GTK_ICON_SIZE_SMALL_TOOLBAR);

          /* render the insensitive icon */
          temp = gtk_style_render_icon (widget->style, icon_source, gtk_widget_get_direction (widget),
                                        GTK_STATE_INSENSITIVE, -1, widget, "gtkcellrendererpixbuf");
          g_object_unref (G_OBJECT (icon));
          icon = temp;

          /* release the icon source */
          gtk_icon_source_free (icon_source);
        }

      /* render the invalid parts of the icon */
      gdk_draw_pixbuf (window, widget->style->black_gc, icon,
                       draw_area.x - icon_area.x, draw_area.y - icon_area.y,
                       draw_area.x, draw_area.y, draw_area.width, draw_area.height,
                       GDK_RGB_DITHER_NORMAL, 0, 0);
    }

  /* release the file's icon */
  g_object_unref (G_OBJECT (icon));

  /* check if we should render emblems as well */
  if (G_LIKELY (icon_renderer->emblems))
    {
      /* display the primary emblem as well (if any) */
      emblems = thunar_file_get_emblem_names (icon_renderer->file);
      if (G_UNLIKELY (emblems != NULL))
        {
          /* render up to four emblems for sizes from 48 onwards, else up to 2 emblems */
          max_emblems = (icon_renderer->size < 48) ? 2 : 4;

          /* render the emblems */
          for (lp = emblems, position = 0; lp != NULL && position < max_emblems; lp = lp->next)
            {
              /* check if we have the emblem in the icon theme */
              emblem = thunar_icon_factory_load_icon (icon_factory, lp->data, icon_renderer->size, NULL, FALSE);
              if (G_UNLIKELY (emblem == NULL))
                continue;

              /* determine the dimensions of the emblem */
              emblem_area.width = gdk_pixbuf_get_width (emblem);
              emblem_area.height = gdk_pixbuf_get_height (emblem);

              /* shrink insane emblems */
              if (G_UNLIKELY (MAX (emblem_area.width, emblem_area.height) > (gint) MIN ((2 * icon_renderer->size) / 3, 36)))
                {
                  /* scale down the emblem */
                  temp = exo_gdk_pixbuf_scale_ratio (emblem, MIN ((2 * icon_renderer->size) / 3, 36));
                  g_object_unref (G_OBJECT (emblem));
                  emblem = temp;

                  /* determine the size again */
                  emblem_area.width = gdk_pixbuf_get_width (emblem);
                  emblem_area.height = gdk_pixbuf_get_height (emblem);
                }

              /* determine a good position for the emblem, depending on the position index */
              switch (position)
                {
                case 0: /* right/bottom */
                  emblem_area.x = MIN (icon_area.x + icon_area.width - emblem_area.width / 2,
                                       cell_area->x + cell_area->width - emblem_area.width);
                  emblem_area.y = MIN (icon_area.y + icon_area.height - emblem_area.height / 2,
                                       cell_area->y + cell_area->height -emblem_area.height);
                  break;

                case 1: /* left/bottom */
                  emblem_area.x = MAX (icon_area.x - emblem_area.width / 2,
                                       cell_area->x);
                  emblem_area.y = MIN (icon_area.y + icon_area.height - emblem_area.height / 2,
                                       cell_area->y + cell_area->height -emblem_area.height);
                  break;

                case 2: /* left/top */
                  emblem_area.x = MAX (icon_area.x - emblem_area.width / 2,
                                       cell_area->x);
                  emblem_area.y = MAX (icon_area.y - emblem_area.height / 2,
                                       cell_area->y);
                  break;

                case 3: /* right/top */
                  emblem_area.x = MIN (icon_area.x + icon_area.width - emblem_area.width / 2,
                                       cell_area->x + cell_area->width - emblem_area.width);
                  emblem_area.y = MAX (icon_area.y - emblem_area.height / 2,
                                       cell_area->y);
                  break;

                default:
                  _thunar_assert_not_reached ();
                }

              /* render the emblem */
              if (gdk_rectangle_intersect (expose_area, &emblem_area, &draw_area))
                {
                  gdk_draw_pixbuf (window, widget->style->black_gc, emblem,
                                   draw_area.x - emblem_area.x, draw_area.y - emblem_area.y,
                                   draw_area.x, draw_area.y, draw_area.width, draw_area.height,
                                   GDK_RGB_DITHER_NORMAL, 0, 0);
                }

              /* release the emblem */
              g_object_unref (G_OBJECT (emblem));

              /* advance the position index */
              ++position;
            }

          /* release the emblem name list */
          g_list_free (emblems);
        }
    }

  /* release our reference on the icon factory */
  g_object_unref (G_OBJECT (icon_factory));
}
static void
torrent_cell_renderer_render(
    GtkCellRenderer *                  cell,
    GdkDrawable *                      window,
    GtkWidget *                        widget,
    GdkRectangle *
                                       background_area,
    GdkRectangle         * cell_area   UNUSED,
    GdkRectangle         * expose_area UNUSED,
    GtkCellRendererState               flags )
{
    TorrentCellRenderer * self = TORRENT_CELL_RENDERER( cell );

#ifdef TEST_RTL
    GtkTextDirection      real_dir = gtk_widget_get_direction( widget );
    gtk_widget_set_direction( widget, GTK_TEXT_DIR_RTL );
#endif

    if( self && self->priv->tor )
    {
        const tr_torrent *                  tor = self->priv->tor;
        const tr_info *                     info = tr_torrentInfo( tor );
        const char *                        name = info->name;
        const tr_stat *                     torStat =
            tr_torrentStatCached( (tr_torrent*)tor );
        GdkRectangle                        my_bg;
        GdkRectangle                        my_cell;
        GdkRectangle                        my_expose;
        int                                 w, h;
        struct TorrentCellRendererPrivate * p = self->priv;
示例#13
0
static void
gtk_real_check_menu_item_draw_indicator (GtkCheckMenuItem *check_menu_item,
                                         cairo_t          *cr)
{
  GtkCheckMenuItemPrivate *priv = check_menu_item->priv;
  GtkWidget *widget;
  gint x, y;

  widget = GTK_WIDGET (check_menu_item);

  if (gtk_widget_is_drawable (widget))
    {
      GtkAllocation allocation;
      GtkStyleContext *context;
      guint border_width;
      guint offset;
      guint toggle_size;
      guint toggle_spacing;
      guint horizontal_padding;
      guint indicator_size;
      GtkStateFlags state;
      GtkBorder padding;

      context = gtk_widget_get_style_context (widget);
      state = gtk_widget_get_state_flags (widget);
      gtk_style_context_get_padding (context, state, &padding);

      gtk_widget_get_allocation (widget, &allocation);

      gtk_widget_style_get (widget,
                            "toggle-spacing", &toggle_spacing,
                            "horizontal-padding", &horizontal_padding,
                            "indicator-size", &indicator_size,
                            NULL);

      toggle_size = GTK_MENU_ITEM (check_menu_item)->priv->toggle_size;
      border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
      offset = border_width + padding.left + 2;

      if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
        {
          x = offset + horizontal_padding +
            (toggle_size - toggle_spacing - indicator_size) / 2;
        }
      else
        {
          x = allocation.width -
            offset - horizontal_padding - toggle_size + toggle_spacing +
            (toggle_size - toggle_spacing - indicator_size) / 2;
        }

      y = (allocation.height - indicator_size) / 2;

      gtk_style_context_save (context);

      if (priv->inconsistent)
        state |= GTK_STATE_FLAG_INCONSISTENT;
      else if (priv->active)
        state |= GTK_STATE_FLAG_ACTIVE;

      gtk_style_context_set_state (context, state);

      if (priv->draw_as_radio)
        {
          gtk_style_context_add_class (context, GTK_STYLE_CLASS_RADIO);
          gtk_render_option (context, cr, x, y,
                             indicator_size, indicator_size);
        }
      else
        {
          gtk_style_context_add_class (context, GTK_STYLE_CLASS_CHECK);
          gtk_render_check (context, cr, x, y,
                            indicator_size, indicator_size);
        }

      gtk_style_context_restore (context);
    }
}
示例#14
0
static void
gcal_event_widget_set_event_tooltip (GcalEventWidget *self,
                                     GcalEvent       *event)
{
  g_autoptr (GDateTime) tooltip_start, tooltip_end;
  g_autofree gchar *start, *end, *escaped_summary;
  GString *tooltip_mesg;
  gboolean allday, multiday, is_ltr;
  guint description_len;

  tooltip_mesg = g_string_new (NULL);
  escaped_summary = g_markup_escape_text (gcal_event_get_summary (event), -1);
  g_string_append_printf (tooltip_mesg, "<b>%s</b>", escaped_summary);

  allday = gcal_event_get_all_day (event);
  multiday = gcal_event_is_multiday (event);

  is_ltr = gtk_widget_get_direction (GTK_WIDGET (self)) != GTK_TEXT_DIR_RTL;

  if (allday)
    {
      /* All day events span from [ start, end - 1 day ] */
      tooltip_start = g_date_time_ref (gcal_event_get_date_start (event));
      tooltip_end = g_date_time_add_days (gcal_event_get_date_end (event), -1);

      if (multiday)
        {
          start = g_date_time_format (tooltip_start, "%x");
          end = g_date_time_format (tooltip_end, "%x");
        }
      else
        {
          start = g_date_time_format (tooltip_start, "%x");
          end = NULL;
        }
    }
  else
    {
      tooltip_start = g_date_time_to_local (gcal_event_get_date_start (event));
      tooltip_end = g_date_time_to_local (gcal_event_get_date_end (event));

      if (multiday)
        {
          if (self->clock_format_24h)
            {
              if (is_ltr)
                {
                  start = g_date_time_format (tooltip_start, "%x %R");
                  end = g_date_time_format (tooltip_end, "%x %R");
                }
              else
                {
                  start = g_date_time_format (tooltip_start, "%R %x");
                  end = g_date_time_format (tooltip_end, "%R %x");
                }
            }
          else
            {
              if (is_ltr)
                {
                  start = g_date_time_format (tooltip_start, "%x %I:%M %P");
                  end = g_date_time_format (tooltip_end, "%x %I:%M %P");
                }
              else
                {
                  start = g_date_time_format (tooltip_start, "%P %M:%I %x");
                  end = g_date_time_format (tooltip_end, "%P %M:%I %x");
                }
            }
        }
      else
        {
          if (self->clock_format_24h)
            {
              if (is_ltr)
                {
                  start = g_date_time_format (tooltip_start, "%x, %R");
                  end = g_date_time_format (tooltip_end, "%R");
                }
              else
                {
                  start = g_date_time_format (tooltip_start, "%R ,%x");
                  end = g_date_time_format (tooltip_end, "%R");
                }
            }
          else
            {
              if (is_ltr)
                {
                  start = g_date_time_format (tooltip_start, "%x, %I:%M %P");
                  end = g_date_time_format (tooltip_end, "%I:%M %P");
                }
              else
                {
                  start = g_date_time_format (tooltip_start, "%P %M:%I ,%x");
                  end = g_date_time_format (tooltip_end, "%P %M:%I");
                }
            }
        }
    }

  if (allday && !multiday)
    {
      g_string_append_printf (tooltip_mesg, "\n%s", start);
    }
  else
    {
      g_string_append_printf (tooltip_mesg,
                              "\n%s - %s",
                              is_ltr ? start : end,
                              is_ltr ? end : start);
    }

  /* Append event location */
  if (g_utf8_strlen (gcal_event_get_location (event), -1) > 0)
    {
      g_autofree gchar *escaped_location;

      escaped_location = g_markup_escape_text (gcal_event_get_location (event), -1);

      g_string_append (tooltip_mesg, "\n\n");

      /* Translators: %s is the location of the event (e.g. "Downtown, 3rd Avenue") */
      g_string_append_printf (tooltip_mesg, _("At %s"), escaped_location);
    }

  description_len = g_utf8_strlen (gcal_event_get_description (event), -1);

  /* Truncate long descriptions at a white space and ellipsize */
  if (description_len > 0)
    {
      g_autofree gchar *escaped_description;
      GString *tooltip_desc;

      tooltip_desc = g_string_new (gcal_event_get_description (event));

      /* If the description is larger than DESC_MAX_CHAR, ellipsize it */
      if (description_len > DESC_MAX_CHAR)
        {
          g_string_truncate (tooltip_desc, DESC_MAX_CHAR - 1);
          g_string_append (tooltip_desc, "…");
        }

      escaped_description = g_markup_escape_text (tooltip_desc->str, -1);

      g_string_append_printf (tooltip_mesg, "\n\n%s", escaped_description);

      g_string_free (tooltip_desc, TRUE);
    }

  gtk_widget_set_tooltip_markup (GTK_WIDGET (self), tooltip_mesg->str);

  g_string_free (tooltip_mesg, TRUE);
}
示例#15
0
文件: applet.c 项目: dnk/mate-panel
void
mate_panel_applet_position_menu (GtkMenu   *menu,
			    int       *x,
			    int       *y,
			    gboolean  *push_in,
			    GtkWidget *applet)
{
	GtkAllocation   allocation;
	GtkRequisition  requisition;
	GdkDevice      *device;
	GdkScreen      *screen;
	GtkWidget      *parent;
	int             menu_x = 0;
	int             menu_y = 0;
	int             pointer_x;
	int             pointer_y;

	parent = gtk_widget_get_parent (applet);

	g_return_if_fail (PANEL_IS_WIDGET (parent));

	screen = gtk_widget_get_screen (applet);

	gtk_widget_get_preferred_size (GTK_WIDGET (menu), &requisition, NULL);

	gdk_window_get_origin (gtk_widget_get_window (applet), &menu_x, &menu_y);
#if GTK_CHECK_VERSION(3, 20, 0)
	device = gdk_seat_get_pointer (gdk_display_get_default_seat (gtk_widget_get_display (applet)));
	gdk_window_get_device_position (gtk_widget_get_window (applet), device, &pointer_x, &pointer_y, NULL);
#else
	device = gdk_device_manager_get_client_pointer (gdk_display_get_device_manager (gtk_widget_get_display (applet)));
	gdk_window_get_device_position (gtk_widget_get_window (applet), device, &pointer_x, &pointer_y, NULL);
#endif
	gtk_widget_get_allocation (applet, &allocation);

	if (!gtk_widget_get_has_window (applet)) {
		menu_x += allocation.x;
		menu_y += allocation.y;
	}

	if (PANEL_WIDGET (parent)->orient == GTK_ORIENTATION_HORIZONTAL) {
		if (gtk_widget_get_direction (GTK_WIDGET (menu)) != GTK_TEXT_DIR_RTL) {
			if (pointer_x < allocation.width &&
			    requisition.width < pointer_x)
				menu_x += MIN (pointer_x,
					       allocation.width - requisition.width);
		} else {
			menu_x += allocation.width - requisition.width;
			if (pointer_x > 0 && pointer_x < allocation.width &&
			    pointer_x < allocation.width - requisition.width) {
				menu_x -= MIN (allocation.width - pointer_x,
					       allocation.width - requisition.width);
			}
		}
		menu_x = MIN (menu_x, gdk_screen_get_width (screen) - requisition.width);

		if (menu_y > gdk_screen_get_height (screen) / 2)
			menu_y -= requisition.height;
		else
			menu_y += allocation.height;
	} else {
		if (pointer_y < allocation.height &&
		    requisition.height < pointer_y)
			menu_y += MIN (pointer_y, allocation.height - requisition.height);
		menu_y = MIN (menu_y, gdk_screen_get_height (screen) - requisition.height);

		if (menu_x > gdk_screen_get_width (screen) / 2)
			menu_x -= requisition.width;
		else
			menu_x += allocation.width;
	}

	*x = menu_x;
	*y = menu_y;
	*push_in = FALSE;
}
示例#16
0
static void
anjuta_tabber_render_tab (GtkWidget* widget,
                          GtkWidget* tab,
                          cairo_t* cr,
                          gboolean current,
                          GtkRegionFlags region_flags)
{
	AnjutaTabber* tabber = ANJUTA_TABBER (widget);
	GtkAllocation alloc;
	GtkAllocation widget_alloc;

	gint focus_width;
	gint tab_curvature;
	gint tab_overlap;
	gint tab_begin;
	gint tab_end;

	gint xpadding;
	gint ypadding;
	GtkStyleContext* context = gtk_widget_get_style_context (widget);

	if (current)
		gtk_widget_set_state_flags (tab, GTK_STATE_FLAG_ACTIVE, TRUE);
	else
		gtk_widget_unset_state_flags (tab, GTK_STATE_FLAG_ACTIVE);		
	
	gtk_widget_style_get (widget,
	                      "focus-line-width", &focus_width,
	                      "tab-curvature", &tab_curvature,
	                      "tab-overlap", &tab_overlap,
	                      NULL);

	 /* Get border/padding for tab */
	gtk_style_context_save (context);
	gtk_style_context_add_class (context, GTK_STYLE_CLASS_NOTEBOOK);
	gtk_style_context_add_region (context, GTK_STYLE_REGION_TAB,
	                              region_flags);
	if (current)
		gtk_style_context_set_state (context, GTK_STATE_FLAG_ACTIVE);
	if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
		gtk_style_context_set_junction_sides (context,
			                                  GTK_JUNCTION_CORNER_TOPLEFT);
	else
		gtk_style_context_set_junction_sides (context,
			                                  GTK_JUNCTION_CORNER_TOPRIGHT);		
	
	gtk_widget_get_allocation (widget, &widget_alloc);
	gtk_widget_get_allocation (tab, &alloc);

	xpadding = focus_width + tabber->priv->tab_hborder;
	ypadding = focus_width + tabber->priv->tab_vborder;

	tab_begin = tab_curvature - tab_overlap;
	tab_end = tab_curvature - tab_overlap;

	if (region_flags | GTK_REGION_FIRST)
		tab_begin += tab_overlap;
	if (region_flags | GTK_REGION_LAST)
		tab_end += tab_overlap;
	
	alloc.x -= widget_alloc.x;
	alloc.x -= tab_begin;
	alloc.x -= xpadding;
	alloc.y -= widget_alloc.y;
	alloc.y -= ypadding;
	alloc.width += 2 * (xpadding) + tab_begin + tab_end;
	alloc.height += 2 * ypadding;
	
	gtk_render_extension (context,
	                      cr,
	                      alloc.x, 
	                      alloc.y,
	                      alloc.width, 
	                      alloc.height,
	                      GTK_POS_BOTTOM);

	if (gtk_widget_has_focus (widget) &&
	    current)
	{
		GtkAllocation allocation;
		
		gtk_widget_get_allocation (tab, &allocation);

		gtk_render_focus (context, cr,
		                  allocation.x - focus_width,
		                  allocation.y - focus_width,
		                  allocation.width + 2 * focus_width,
		                  allocation.height + 2 * focus_width);
	}
	
	gtk_style_context_restore (context);
}
示例#17
0
static void
gtk_tearoff_menu_item_paint (GtkWidget   *widget,
			     GdkRectangle *area)
{
  GtkMenuItem *menu_item;
  GtkShadowType shadow_type;
  gint width, height;
  gint x, y;
  gint right_max;
  GtkArrowType arrow_type;
  GtkTextDirection direction;
  
  if (GTK_WIDGET_DRAWABLE (widget))
    {
      menu_item = GTK_MENU_ITEM (widget);

      direction = gtk_widget_get_direction (widget);

      x = widget->allocation.x + GTK_CONTAINER (menu_item)->border_width;
      y = widget->allocation.y + GTK_CONTAINER (menu_item)->border_width;
      width = widget->allocation.width - GTK_CONTAINER (menu_item)->border_width * 2;
      height = widget->allocation.height - GTK_CONTAINER (menu_item)->border_width * 2;
      right_max = x + width;

      if (widget->state == GTK_STATE_PRELIGHT)
	{
	  gint selected_shadow_type;
	  
	  gtk_widget_style_get (widget,
				"selected-shadow-type", &selected_shadow_type,
				NULL);
	  gtk_paint_box (widget->style,
			 widget->window,
			 GTK_STATE_PRELIGHT,
			 selected_shadow_type,
			 area, widget, "menuitem",
			 x, y, width, height);
	}
      else
	gdk_window_clear_area (widget->window, area->x, area->y, area->width, area->height);

      if (GTK_IS_MENU (widget->parent) && GTK_MENU (widget->parent)->torn_off)
	{
	  gint arrow_x;

	  if (widget->state == GTK_STATE_PRELIGHT)
	    shadow_type = GTK_SHADOW_IN;
	  else
	    shadow_type = GTK_SHADOW_OUT;

	  if (menu_item->toggle_size > ARROW_SIZE)
	    {
	      if (direction == GTK_TEXT_DIR_LTR) {
		arrow_x = x + (menu_item->toggle_size - ARROW_SIZE)/2;
		arrow_type = GTK_ARROW_LEFT;
	      }
	      else {
		arrow_x = x + width - menu_item->toggle_size + (menu_item->toggle_size - ARROW_SIZE)/2; 
		arrow_type = GTK_ARROW_RIGHT;	    
	      }
	      x += menu_item->toggle_size + BORDER_SPACING;
	    }
	  else
	    {
	      if (direction == GTK_TEXT_DIR_LTR) {
		arrow_x = ARROW_SIZE / 2;
		arrow_type = GTK_ARROW_LEFT;
	      }
	      else {
		arrow_x = x + width - 2 * ARROW_SIZE + ARROW_SIZE / 2; 
		arrow_type = GTK_ARROW_RIGHT;	    
	      }
	      x += 2 * ARROW_SIZE;
	    }


	  gtk_paint_arrow (widget->style, widget->window,
			   widget->state, shadow_type,
			   NULL, widget, "tearoffmenuitem",
			   arrow_type, FALSE,
			   arrow_x, y + height / 2 - 5, 
			   ARROW_SIZE, ARROW_SIZE);
	}

      while (x < right_max)
	{
	  gint x1, x2;

	  if (direction == GTK_TEXT_DIR_LTR) {
	    x1 = x;
	    x2 = MIN (x + TEAR_LENGTH, right_max);
	  }
	  else {
	    x1 = right_max - x;
	    x2 = MAX (right_max - x - TEAR_LENGTH, 0);
	  }
	  
	  gtk_paint_hline (widget->style, widget->window, GTK_STATE_NORMAL,
			   NULL, widget, "tearoffmenuitem",
			   x1, x2, y + (height - widget->style->ythickness) / 2);
	  x += 2 * TEAR_LENGTH;
	}
    }
}
static void
anjuta_tabber_size_allocate(GtkWidget* widget, GtkAllocation* allocation)
{
	g_return_if_fail (ANJUTA_IS_TABBER (widget));
	AnjutaTabber* tabber = ANJUTA_TABBER (widget);

	GtkStyleContext* context;
	GList* child;
	gint focus_width;
	gint focus_pad;
	gint tab_curvature;
	gint tab_overlap;
	gint n_children = g_list_length (tabber->priv->children);
	gint x;
	gint focus_space;
	gint tab_space;

	context = gtk_widget_get_style_context (widget);

	gtk_widget_style_get (GTK_WIDGET (tabber),
	                      "focus-line-width", &focus_width,
	                      "focus-padding", &focus_pad,
	                      "tab-curvature", &tab_curvature,
	                      "tab-overlap", &tab_overlap,
	                      NULL);

	focus_space = focus_width + focus_pad;
	tab_space = tab_curvature - tab_overlap;
	
	gtk_widget_set_allocation (widget, allocation);

	switch (gtk_widget_get_direction (widget))
	{
		case GTK_TEXT_DIR_RTL:
			x = allocation->x + allocation->width;
			break;
		case GTK_TEXT_DIR_LTR:
		default:
			x = allocation->x;
	}

	if (gtk_widget_get_realized (widget))
	{
		gdk_window_move_resize (tabber->priv->event_window,
		                        allocation->x, allocation->y,
		                        allocation->width, allocation->height);
		if (gtk_widget_get_mapped (widget))
			gdk_window_show_unraised (tabber->priv->event_window);
	}

	if (n_children > 0)
	{
		gint total_space;
		gint total_width;
		gboolean use_natural = FALSE;
		gint child_equal;
		gint extra_space = 0;
		gint real_width = allocation->width;

		/* Calculate the total space that is used for padding/overlap */
		total_space = 2 * tab_curvature
			+ 2 * tab_space * (n_children - 1)
			+  2 * focus_space * n_children;

		for (child = tabber->priv->children; child != NULL; child = g_list_next (child))
		{
			GtkStateFlags state;
			GtkBorder tab_padding;

			/* Get the padding of the tab */
			gtk_style_context_save (context);
			anjuta_tabber_setup_style_context (tabber, context, child, &state, NULL);
			gtk_style_context_get_padding (context, state, &tab_padding);
			gtk_style_context_restore (context);

			total_space += tab_padding.left + tab_padding.right;
		}

		/* Check if we have enough space for all widgets natural size */
		child_equal = (real_width - total_space) / n_children;

		if (child_equal < 0)
			return;

		/* Calculate the total width of the tabs */
		total_width = total_space;
		for (child = tabber->priv->children; child != NULL; child = g_list_next (child))
		{
			GtkWidget* child_widget = GTK_WIDGET (child->data);
			gint natural;

			gtk_widget_get_preferred_width (child_widget, NULL,
			                                &natural);

			total_width += natural;

			if (natural < child_equal)
				extra_space += child_equal - natural;
		}

		use_natural = (total_width <= real_width);
		child_equal += extra_space / n_children;
		
		for (child = tabber->priv->children; child != NULL; child = g_list_next (child))
		{
			GtkWidget* child_widget = GTK_WIDGET (child->data);
			GtkStateFlags state;
			GtkBorder tab_padding, active_padding;
			GtkAllocation child_alloc;
			gint natural;
			gint minimal;
			gint begin_tab = tab_space;
			gint end_tab = tab_space;

			/* Get the padding of the tab */
			gtk_style_context_save (context);
			anjuta_tabber_setup_style_context (tabber, context, child, &state, NULL);
			gtk_style_context_get_padding (context, state, &tab_padding);
			gtk_style_context_get_padding (context, state | GTK_STATE_ACTIVE, &active_padding);
			gtk_style_context_restore (context);

			if (child->prev == NULL)
				begin_tab = tab_curvature;
			if (child->next == NULL)
				end_tab = tab_curvature;
			
			gtk_widget_get_preferred_width (child_widget, &minimal,
				                            &natural);

			if (use_natural)
			{
				child_alloc.width = natural;
			}
	 		else
			{
				if (natural < child_equal)
					child_alloc.width = natural;
				else
					child_alloc.width = child_equal;
			}
			/* The active pad is by definition at least the same height
			 * as the inactive one. Therefore we always use the padding of the
			 * active tab to calculate the height and y position of the child.
			 */
			child_alloc.height = allocation->height - 2 * focus_space
				- active_padding.top - active_padding.bottom;
			child_alloc.y = allocation->y + focus_space + active_padding.top;

			switch (gtk_widget_get_direction (widget))
			{
				case GTK_TEXT_DIR_RTL:
					child_alloc.x = x - focus_space - tab_padding.right
						- begin_tab - child_alloc.width;
					x = child_alloc.x - focus_space - tab_padding.left - end_tab;
					break;
				case GTK_TEXT_DIR_LTR:
				default:
					child_alloc.x = x + focus_space + tab_padding.left + begin_tab;
					x = child_alloc.x + child_alloc.width + focus_space
						+ tab_padding.right + end_tab;
			}

			gtk_widget_size_allocate (child_widget, &child_alloc);
		}
	}
}
static gint
gdl_dock_item_grip_expose (GtkWidget      *widget,
			   GdkEventExpose *event)
{
    GdlDockItemGrip *grip;
    GdkRectangle     title_area;
    GdkRectangle     expose_area;
    GtkStyle        *bg_style;
    gint             layout_width;
    gint             layout_height;
    gint             text_x;
    gint             text_y;
    gboolean         item_or_child_has_focus;

    grip = GDL_DOCK_ITEM_GRIP (widget);
    gdl_dock_item_grip_get_title_area (grip, &title_area);

    /* draw background, highlight it if the dock item or any of its
     * descendants have focus */
    bg_style = (gdl_dock_item_or_child_has_focus (grip->item) ?
                gtk_widget_get_style (widget)->dark_gc[widget->state] :
                gtk_widget_get_style (widget)->mid_gc[widget->state]);

    gdk_draw_rectangle (GDK_DRAWABLE (widget->window), bg_style, TRUE,
                        1, 0, widget->allocation.width - 1, widget->allocation.height);

    if (grip->_priv->icon_pixbuf) {
        GdkRectangle pixbuf_rect;
        
        pixbuf_rect.width = gdk_pixbuf_get_width (grip->_priv->icon_pixbuf);
        pixbuf_rect.height = gdk_pixbuf_get_height (grip->_priv->icon_pixbuf);
        if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) {
            pixbuf_rect.x = title_area.x + title_area.width - pixbuf_rect.width;
        } else {
            pixbuf_rect.x = title_area.x;
            title_area.x += pixbuf_rect.width + 1;
        }
        /* shrink title area by the pixbuf width plus a 1px spacing */
        title_area.width -= pixbuf_rect.width + 1;
        pixbuf_rect.y = title_area.y + (title_area.height - pixbuf_rect.height) / 2;

        if (gdk_rectangle_intersect (&event->area, &pixbuf_rect, &expose_area)) {
            GdkGC *gc;
            GtkStyle *style;

            style = gtk_widget_get_style (widget);
            gc = style->bg_gc[widget->state];
            gdk_draw_pixbuf (GDK_DRAWABLE (widget->window), gc,
                             grip->_priv->icon_pixbuf,
                             0, 0, pixbuf_rect.x, pixbuf_rect.y,
                             pixbuf_rect.width, pixbuf_rect.height,
                             GDK_RGB_DITHER_NONE, 0, 0);
	}
    }

    if (gdk_rectangle_intersect (&title_area, &event->area, &expose_area)) {
        pango_layout_get_pixel_size (grip->_priv->title_layout, &layout_width,
                                     &layout_height);

        if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
            text_x = title_area.x + title_area.width - layout_width;
        else
            text_x = title_area.x;

        text_y = title_area.y + (title_area.height - layout_height) / 2;

        gtk_paint_layout (widget->style, widget->window, widget->state, TRUE,
                          &expose_area, widget, NULL, text_x, text_y,
                          grip->_priv->title_layout);
    }

    return GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
}  
示例#20
0
static void
ephy_toolbar_constructed (GObject *object)
{
  EphyToolbarPrivate *priv = EPHY_TOOLBAR (object)->priv;
  GtkActionGroup *action_group;
  GtkAction *action;
  GtkToolItem *back_forward, *location_stop_reload, *tool_item;
  GtkWidget *tool_button, *box, *location, *toolbar;
  GtkSizeGroup *size;

  G_OBJECT_CLASS (ephy_toolbar_parent_class)->constructed (object);

  toolbar = GTK_WIDGET (object);

  /* Create a GtkSizeGroup to sync the height of the location entry, and
   * the stop/reload button. */
  size = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);

  /* Set the MENUBAR style class so it's possible to drag the app
   * using the toolbar. */
  gtk_style_context_add_class (gtk_widget_get_style_context (toolbar),
                               GTK_STYLE_CLASS_MENUBAR);

  /* Back and Forward */
  back_forward = gtk_tool_item_new ();
  box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);

  /* Back */
  tool_button = ephy_middle_clickable_button_new ();
  /* FIXME: apparently we need an image inside the button for the action
   * icon to appear. */
  gtk_button_set_image (GTK_BUTTON (tool_button), gtk_image_new ());
  action_group = ephy_window_get_toolbar_action_group (priv->window);
  action = gtk_action_group_get_action (action_group, "NavigationBack");
  gtk_activatable_set_related_action (GTK_ACTIVATABLE (tool_button),
                                      action);
  gtk_button_set_label (GTK_BUTTON (tool_button), NULL);
  gtk_container_add (GTK_CONTAINER (box), GTK_WIDGET (tool_button));

  /* Forward */
  tool_button = ephy_middle_clickable_button_new ();
  /* FIXME: apparently we need an image inside the button for the action
   * icon to appear. */
  gtk_button_set_image (GTK_BUTTON (tool_button), gtk_image_new ());
  action = gtk_action_group_get_action (action_group, "NavigationForward");
  gtk_activatable_set_related_action (GTK_ACTIVATABLE (tool_button),
                                      action);
  gtk_button_set_label (GTK_BUTTON (tool_button), NULL);
  gtk_container_add (GTK_CONTAINER (box), GTK_WIDGET (tool_button));

  gtk_style_context_add_class (gtk_widget_get_style_context (box),
                               "raised");
  gtk_style_context_add_class (gtk_widget_get_style_context (box),
                               "linked");

  gtk_container_add (GTK_CONTAINER (back_forward), box);
  gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (back_forward));
  gtk_widget_show_all (GTK_WIDGET (back_forward));
  if (gtk_widget_get_direction (GTK_WIDGET (back_forward)) == GTK_TEXT_DIR_RTL)
    gtk_widget_set_margin_left (GTK_WIDGET (back_forward), 12);
  else
    gtk_widget_set_margin_right (GTK_WIDGET (back_forward), 12);

  /* Location and Reload/Stop */
  location_stop_reload = gtk_tool_item_new ();
  box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);

  /* Location */
  priv->entry = location = ephy_location_entry_new ();
  gtk_box_pack_start (GTK_BOX (box), location,
                      TRUE, TRUE, 0);
  gtk_style_context_add_class (gtk_widget_get_style_context (box),
                               "location-entry");

  /* Reload/Stop */
  tool_button = gtk_button_new ();
  /* FIXME: apparently we need an image inside the button for the action
   * icon to appear. */
  gtk_button_set_image (GTK_BUTTON (tool_button), gtk_image_new ());
  action = gtk_action_group_get_action (action_group, "ViewCombinedStopReload");
  gtk_activatable_set_related_action (GTK_ACTIVATABLE (tool_button),
                                      action);
  gtk_container_add (GTK_CONTAINER (box), GTK_WIDGET (tool_button));

  gtk_container_add (GTK_CONTAINER (location_stop_reload), box);
  gtk_container_child_set (GTK_CONTAINER (toolbar),
                           GTK_WIDGET (location_stop_reload),
                           "expand", TRUE,
                           NULL);
  
  gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (location_stop_reload));

  gtk_size_group_add_widget (size, tool_button);
  gtk_size_group_add_widget (size, location);
  g_object_unref (size);

  if (gtk_widget_get_direction (GTK_WIDGET (location_stop_reload)) == GTK_TEXT_DIR_RTL)
    gtk_widget_set_margin_left (GTK_WIDGET (location_stop_reload), 12);
  else
    gtk_widget_set_margin_right (GTK_WIDGET (location_stop_reload), 12);

  gtk_widget_show_all (GTK_WIDGET (location_stop_reload));

  /* New Tab */
  tool_item = gtk_tool_item_new ();
  tool_button = gtk_button_new ();
  /* FIXME: apparently we need an image inside the button for the action
   * icon to appear. */
  gtk_button_set_image (GTK_BUTTON (tool_button), gtk_image_new ());
  action = gtk_action_group_get_action (action_group, "FileNewTab");
  gtk_activatable_set_related_action (GTK_ACTIVATABLE (tool_button),
                                      action);
  gtk_button_set_label (GTK_BUTTON (tool_button), NULL);
  gtk_container_add (GTK_CONTAINER (tool_item), tool_button);
  gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (tool_item));

  if (gtk_widget_get_direction (GTK_WIDGET (tool_item)) == GTK_TEXT_DIR_RTL)
    gtk_widget_set_margin_left (GTK_WIDGET (tool_item), 4);
  else
    gtk_widget_set_margin_right (GTK_WIDGET (tool_item), 4);

  gtk_widget_show_all (GTK_WIDGET (tool_item));


  /* Page Menu */
  tool_item = gtk_tool_item_new ();
  tool_button = gtk_button_new ();
  gtk_widget_set_name (GTK_WIDGET (tool_button), "ephy-page-menu-button");
  /* FIXME: apparently we need an image inside the button for the action
   * icon to appear. */
  gtk_button_set_image (GTK_BUTTON (tool_button), gtk_image_new ());
  action = gtk_action_group_get_action (action_group, "PageMenu");
  gtk_activatable_set_related_action (GTK_ACTIVATABLE (tool_button),
                                      action);
  gtk_container_add (GTK_CONTAINER (tool_item), tool_button);
  gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (tool_item));
  gtk_widget_show_all (GTK_WIDGET (tool_item));
}
示例#21
0
/**
 * gimp_button_menu_position:
 * @button: a button widget to popup the menu from
 * @menu: the menu to position
 * @position: the preferred popup direction for the menu (left or right)
 * @x: return location for x coordinate
 * @y: return location for y coordinate
 *
 * Utility function to position a menu that pops up from a button.
 **/
void
gimp_button_menu_position (GtkWidget       *button,
                           GtkMenu         *menu,
                           GtkPositionType  position,
                           gint            *x,
                           gint            *y)
{
  GdkScreen      *screen;
  GtkRequisition  menu_requisition;
  GdkRectangle    rect;
  gint            monitor;

  g_return_if_fail (GTK_WIDGET_REALIZED (button));
  g_return_if_fail (GTK_IS_MENU (menu));
  g_return_if_fail (x != NULL);
  g_return_if_fail (y != NULL);

  if (gtk_widget_get_direction (button) == GTK_TEXT_DIR_RTL)
    {
      switch (position)
        {
        case GTK_POS_LEFT:   position = GTK_POS_RIGHT;  break;
        case GTK_POS_RIGHT:  position = GTK_POS_LEFT;   break;
        default:
          break;
        }
    }

  gdk_window_get_origin (button->window, x, y);

  gtk_widget_size_request (GTK_WIDGET (menu), &menu_requisition);

  screen = gtk_widget_get_screen (button);

  monitor = gdk_screen_get_monitor_at_point (screen, *x, *y);
  gdk_screen_get_monitor_geometry (screen, monitor, &rect);

  gtk_menu_set_screen (menu, screen);

  if (GTK_WIDGET_NO_WINDOW (button))
    *x += button->allocation.x;

  switch (position)
    {
    case GTK_POS_LEFT:
      *x -= menu_requisition.width;
      if (*x < rect.x)
        *x += menu_requisition.width + button->allocation.width;
      break;

    case GTK_POS_RIGHT:
      *x += button->allocation.width;
      if (*x + menu_requisition.width > rect.x + rect.width)
        *x -= button->allocation.width + menu_requisition.width;
      break;

    default:
      g_warning ("%s: unhandled position (%d)", G_STRFUNC, position);
      break;
    }

  if (GTK_WIDGET_NO_WINDOW (button))
    *y += button->allocation.y;

  *y += button->allocation.height / 2;

  if (*y + menu_requisition.height > rect.y + rect.height)
    *y -= menu_requisition.height;

  if (*y < rect.y)
    *y = rect.y;
}
示例#22
0
static FocusSite
get_next_site (GtkExpander      *expander,
	       FocusSite         site,
	       GtkDirectionType  direction)
{
  gboolean ltr;

  ltr = gtk_widget_get_direction (GTK_WIDGET (expander)) != GTK_TEXT_DIR_RTL;

  switch (site)
    {
    case FOCUS_NONE:
      switch (direction)
	{
	case GTK_DIR_TAB_BACKWARD:
	case GTK_DIR_LEFT:
	case GTK_DIR_UP:
	  return FOCUS_CHILD;
	case GTK_DIR_TAB_FORWARD:
	case GTK_DIR_DOWN:
	case GTK_DIR_RIGHT:
	  return FOCUS_WIDGET;
	}
    case FOCUS_WIDGET:
      switch (direction)
	{
	case GTK_DIR_TAB_BACKWARD:
	case GTK_DIR_UP:
	  return FOCUS_NONE;
	case GTK_DIR_LEFT:
	  return ltr ? FOCUS_NONE : FOCUS_LABEL;
	case GTK_DIR_TAB_FORWARD:
	case GTK_DIR_DOWN:
	  return FOCUS_LABEL;
	case GTK_DIR_RIGHT:
	  return ltr ? FOCUS_LABEL : FOCUS_NONE;
	  break;
	}
    case FOCUS_LABEL:
      switch (direction)
	{
	case GTK_DIR_TAB_BACKWARD:
	case GTK_DIR_UP:
	  return FOCUS_WIDGET;
	case GTK_DIR_LEFT:
	  return ltr ? FOCUS_WIDGET : FOCUS_CHILD;
	case GTK_DIR_TAB_FORWARD:
	case GTK_DIR_DOWN:
	  return FOCUS_CHILD;
	case GTK_DIR_RIGHT:
	  return ltr ? FOCUS_CHILD : FOCUS_WIDGET;
	  break;
	}
    case FOCUS_CHILD:
      switch (direction)
	{
	case GTK_DIR_TAB_BACKWARD:
	case GTK_DIR_LEFT:
	case GTK_DIR_UP:
	  return FOCUS_LABEL;
	case GTK_DIR_TAB_FORWARD:
	case GTK_DIR_DOWN:
	case GTK_DIR_RIGHT:
	  return FOCUS_NONE;
	}
    }

  g_assert_not_reached ();
  return FOCUS_NONE;
}
示例#23
0
static void
gtk_image_menu_item_size_allocate (GtkWidget     *widget,
                                   GtkAllocation *allocation)
{
  GtkImageMenuItem *image_menu_item = GTK_IMAGE_MENU_ITEM (widget);
  GtkImageMenuItemPrivate *priv = image_menu_item->priv;
  GtkAllocation widget_allocation;
  GtkPackDirection pack_dir;
  GtkWidget *parent;

  parent = gtk_widget_get_parent (widget);

  if (GTK_IS_MENU_BAR (parent))
    pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent));
  else
    pack_dir = GTK_PACK_DIRECTION_LTR;

  GTK_WIDGET_CLASS (gtk_image_menu_item_parent_class)->size_allocate (widget, allocation);

  if (priv->image && gtk_widget_get_visible (priv->image))
    {
      gint x, y, offset;
      GtkStyleContext *context;
      GtkStateFlags state;
      GtkBorder padding;
      GtkRequisition child_requisition;
      GtkAllocation child_allocation;
      guint toggle_spacing;
      gint toggle_size;

      toggle_size = GTK_MENU_ITEM (image_menu_item)->priv->toggle_size;
      gtk_widget_style_get (widget,
                            "toggle-spacing", &toggle_spacing,
                            NULL);

      /* Man this is lame hardcoding action, but I can't
       * come up with a solution that's really better.
       */

      gtk_widget_get_preferred_size (priv->image, &child_requisition, NULL);

      gtk_widget_get_allocation (widget, &widget_allocation);

      context = gtk_widget_get_style_context (widget);
      state = gtk_widget_get_state_flags (widget);
      gtk_style_context_get_padding (context, state, &padding);
      offset = gtk_container_get_border_width (GTK_CONTAINER (image_menu_item));

      if (pack_dir == GTK_PACK_DIRECTION_LTR ||
          pack_dir == GTK_PACK_DIRECTION_RTL)
        {
          if ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) ==
              (pack_dir == GTK_PACK_DIRECTION_LTR))
            x = offset + padding.left +
               (toggle_size - toggle_spacing - child_requisition.width) / 2;
          else
            x = widget_allocation.width - offset - padding.right -
              toggle_size + toggle_spacing +
              (toggle_size - toggle_spacing - child_requisition.width) / 2;

          y = (widget_allocation.height - child_requisition.height) / 2;
        }
      else
        {
          if ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) ==
              (pack_dir == GTK_PACK_DIRECTION_TTB))
            y = offset + padding.top +
              (toggle_size - toggle_spacing - child_requisition.height) / 2;
          else
            y = widget_allocation.height - offset - padding.bottom -
              toggle_size + toggle_spacing +
              (toggle_size - toggle_spacing - child_requisition.height) / 2;

          x = (widget_allocation.width - child_requisition.width) / 2;
        }

      child_allocation.width = child_requisition.width;
      child_allocation.height = child_requisition.height;
      child_allocation.x = widget_allocation.x + MAX (x, 0);
      child_allocation.y = widget_allocation.y + MAX (y, 0);

      gtk_widget_size_allocate (priv->image, &child_allocation);
    }
}
示例#24
0
static void
get_expander_bounds (GtkExpander  *expander,
		     GdkRectangle *rect)
{
  GtkWidget *widget;
  GtkExpanderPrivate *priv;
  gint border_width;
  gint expander_size;
  gint expander_spacing;
  gboolean interior_focus;
  gint focus_width;
  gint focus_pad;
  gboolean ltr;

  widget = GTK_WIDGET (expander);
  priv = expander->priv;

  border_width = GTK_CONTAINER (expander)->border_width;

  gtk_widget_style_get (widget,
			"interior-focus", &interior_focus,
			"focus-line-width", &focus_width,
			"focus-padding", &focus_pad,
			"expander-size", &expander_size,
			"expander-spacing", &expander_spacing,
			NULL);

  ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL;

  rect->x = widget->allocation.x + border_width;
  rect->y = widget->allocation.y + border_width;

  if (ltr)
    rect->x += expander_spacing;
  else
    rect->x += widget->allocation.width - 2 * border_width -
               expander_spacing - expander_size;

  if (priv->label_widget && gtk_widget_get_visible (priv->label_widget))
    {
      GtkAllocation label_allocation;

      label_allocation = priv->label_widget->allocation;

      if (expander_size < label_allocation.height)
	rect->y += focus_width + focus_pad + (label_allocation.height - expander_size) / 2;
      else
	rect->y += expander_spacing;
    }
  else
    {
      rect->y += expander_spacing;
    }

  if (!interior_focus)
    {
      if (ltr)
	rect->x += focus_width + focus_pad;
      else
	rect->x -= focus_width + focus_pad;
      rect->y += focus_width + focus_pad;
    }

  rect->width = rect->height = expander_size;
}
示例#25
0
static gboolean
gcal_week_view_draw_hours (GcalWeekView *self,
                           cairo_t      *cr,
                           GtkWidget    *widget)
{
  GtkStyleContext *context;
  GtkStateFlags state;
  GtkBorder padding;
  GdkRGBA color;

  gboolean ltr;
  gint i, width, height;
  gint font_width;

  PangoLayout *layout;
  PangoFontDescription *font_desc;

  context = gtk_widget_get_style_context (widget);
  state = gtk_widget_get_state_flags (widget);
  ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL;

  gtk_style_context_save (context);

  gtk_style_context_add_class (context, "hours");
  gtk_style_context_get_color (context, state, &color);
  gtk_style_context_get_padding (context, state, &padding);
  gtk_style_context_get (context, state, "font", &font_desc, NULL);

  layout = pango_cairo_create_layout (cr);
  pango_layout_set_font_description (layout, font_desc);
  gdk_cairo_set_source_rgba (cr, &color);

  /* Gets the size of the widget */
  width = gtk_widget_get_allocated_width (widget);
  height = gtk_widget_get_allocated_height (widget);

  /* Draws the hours in the sidebar */
  for (i = 0; i < 24; i++)
    {
      gchar *hours;

      if (self->use_24h_format)
        {
          hours = g_strdup_printf ("%02d:00", i);
        }
      else
        {
          hours = g_strdup_printf ("%d %s",
                                   i % 12 == 0 ? 12 : i % 12,
                                   i > 12 ? _("PM") : _("AM"));
        }

      pango_layout_set_text (layout, hours, -1);
      pango_layout_get_pixel_size (layout, &font_width, NULL);

      gtk_render_layout (context,
                         cr,
                         ltr ? padding.left : width - font_width - padding.right,
                         (height / 24) * i + padding.top,
                         layout);

      g_free (hours);
    }

  gtk_style_context_restore (context);

  gtk_style_context_save (context);
  gtk_style_context_add_class (context, "lines");
  gtk_style_context_get_color (context, state, &color);

  gdk_cairo_set_source_rgba (cr, &color);
  cairo_set_line_width (cr, 0.65);

  if (!ltr)
    {
      cairo_move_to (cr, 0.5, 0);
      cairo_rel_line_to (cr, 0, height);
    }

  /* Draws the horizontal complete lines */
  for (i = 1; i < 24; i++)
    {
      cairo_move_to (cr, 0, (height / 24) * i + 0.4);
      cairo_rel_line_to (cr, width, 0);
    }

  cairo_stroke (cr);

  cairo_set_dash (cr, dashed, 2, 0);

  /* Draws the horizontal dashed lines */
  for (i = 0; i < 24; i++)
    {
      cairo_move_to (cr, 0, (height / 24) * i + (height / 48) + 0.4);
      cairo_rel_line_to (cr, width, 0);
    }

  cairo_stroke (cr);

  gtk_style_context_restore (context);

  pango_font_description_free (font_desc);
  g_object_unref (layout);

  return FALSE;
}
示例#26
0
static void
gtk_expander_size_allocate (GtkWidget     *widget,
			    GtkAllocation *allocation)
{
  GtkExpander *expander;
  GtkBin *bin;
  GtkExpanderPrivate *priv;
  GtkRequisition child_requisition;
  gboolean child_visible = FALSE;
  gint border_width;
  gint expander_size;
  gint expander_spacing;
  gboolean interior_focus;
  gint focus_width;
  gint focus_pad;
  gint label_height;

  expander = GTK_EXPANDER (widget);
  bin = GTK_BIN (widget);
  priv = expander->priv;

  border_width = GTK_CONTAINER (widget)->border_width;

  gtk_widget_style_get (widget,
			"interior-focus", &interior_focus,
			"focus-line-width", &focus_width,
			"focus-padding", &focus_pad,
			"expander-size", &expander_size,
			"expander-spacing", &expander_spacing,
			NULL);

  child_requisition.width = 0;
  child_requisition.height = 0;
  if (bin->child && GTK_WIDGET_CHILD_VISIBLE (bin->child))
    {
      child_visible = TRUE;
      gtk_widget_get_child_requisition (bin->child, &child_requisition);
    }

  widget->allocation = *allocation;

  if (priv->label_widget && gtk_widget_get_visible (priv->label_widget))
    {
      GtkAllocation label_allocation;
      GtkRequisition label_requisition;
      gboolean ltr;

      gtk_widget_get_child_requisition (priv->label_widget, &label_requisition);

      ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL;

      if (priv->label_fill)
	label_allocation.x = (widget->allocation.x +
                              border_width + focus_width + focus_pad +
                              expander_size + 2 * expander_spacing);
      else if (ltr)
	label_allocation.x = (widget->allocation.x +
                              border_width + focus_width + focus_pad +
                              expander_size + 2 * expander_spacing);
      else
        label_allocation.x = (widget->allocation.x + widget->allocation.width -
                              (label_requisition.width +
                               border_width + focus_width + focus_pad +
                               expander_size + 2 * expander_spacing));

      label_allocation.y = widget->allocation.y + border_width + focus_width + focus_pad;

      if (priv->label_fill)
        label_allocation.width = allocation->width - 2 * border_width -
				 expander_size - 2 * expander_spacing -
				 2 * focus_width - 2 * focus_pad;
      else
        label_allocation.width = MIN (label_requisition.width,
				      allocation->width - 2 * border_width -
				      expander_size - 2 * expander_spacing -
				      2 * focus_width - 2 * focus_pad);
      label_allocation.width = MAX (label_allocation.width, 1);

      label_allocation.height = MIN (label_requisition.height,
				     allocation->height - 2 * border_width -
				     2 * focus_width - 2 * focus_pad -
				     (child_visible ? priv->spacing : 0));
      label_allocation.height = MAX (label_allocation.height, 1);

      gtk_widget_size_allocate (priv->label_widget, &label_allocation);

      label_height = label_allocation.height;
    }
  else
    {
      label_height = 0;
    }

  if (gtk_widget_get_realized (widget))
    {
      GdkRectangle rect;

      get_expander_bounds (expander, &rect);

      gdk_window_move_resize (priv->event_window,
			      allocation->x + border_width,
			      allocation->y + border_width,
			      MAX (allocation->width - 2 * border_width, 1),
			      MAX (rect.height, label_height - 2 * border_width));
    }

  if (child_visible)
    {
      GtkAllocation child_allocation;
      gint top_height;

      top_height = MAX (2 * expander_spacing + expander_size,
			label_height +
			(interior_focus ? 2 * focus_width + 2 * focus_pad : 0));

      child_allocation.x = widget->allocation.x + border_width;
      child_allocation.y = widget->allocation.y + border_width + top_height + priv->spacing;

      if (!interior_focus)
	child_allocation.y += 2 * focus_width + 2 * focus_pad;

      child_allocation.width = MAX (allocation->width - 2 * border_width, 1);

      child_allocation.height = allocation->height - top_height -
				2 * border_width - priv->spacing -
				(!interior_focus ? 2 * focus_width + 2 * focus_pad : 0);
      child_allocation.height = MAX (child_allocation.height, 1);

      gtk_widget_size_allocate (bin->child, &child_allocation);
    }
}
示例#27
0
static void
gtk_tool_button_construct_contents (GtkToolItem *tool_item)
{
  GtkToolButton *button = GTK_TOOL_BUTTON (tool_item);
  GtkWidget *child;
  GtkWidget *label = NULL;
  GtkWidget *icon = NULL;
  GtkToolbarStyle style;
  gboolean need_label = FALSE;
  gboolean need_icon = FALSE;
  GtkIconSize icon_size;
  GtkWidget *box = NULL;
  guint icon_spacing;
  GtkOrientation text_orientation = GTK_ORIENTATION_HORIZONTAL;
  GtkSizeGroup *size_group = NULL;
  GtkWidget *parent;

  button->priv->contents_invalid = FALSE;

  gtk_widget_style_get (GTK_WIDGET (tool_item), 
			"icon-spacing", &icon_spacing,
			NULL);

  if (button->priv->icon_widget)
    {
      parent = gtk_widget_get_parent (button->priv->icon_widget);
      if (parent)
        {
          gtk_container_remove (GTK_CONTAINER (parent),
                                button->priv->icon_widget);
        }
    }

  if (button->priv->label_widget)
    {
      parent = gtk_widget_get_parent (button->priv->label_widget);
      if (parent)
        {
          gtk_container_remove (GTK_CONTAINER (parent),
                                button->priv->label_widget);
        }
    }

  child = gtk_bin_get_child (GTK_BIN (button->priv->button));
  if (child)
    {
      /* Note: we are not destroying the label_widget or icon_widget
       * here because they were removed from their containers above
       */
      gtk_widget_destroy (child);
    }

  style = gtk_tool_item_get_toolbar_style (GTK_TOOL_ITEM (button));
  
  if (style != GTK_TOOLBAR_TEXT)
    need_icon = TRUE;

  if (style != GTK_TOOLBAR_ICONS && style != GTK_TOOLBAR_BOTH_HORIZ)
    need_label = TRUE;

  if (style == GTK_TOOLBAR_BOTH_HORIZ &&
      (gtk_tool_item_get_is_important (GTK_TOOL_ITEM (button)) ||
       gtk_tool_item_get_orientation (GTK_TOOL_ITEM (button)) == GTK_ORIENTATION_VERTICAL ||
       gtk_tool_item_get_text_orientation (GTK_TOOL_ITEM (button)) == GTK_ORIENTATION_VERTICAL))
    {
      need_label = TRUE;
    }
  
  if (style != GTK_TOOLBAR_TEXT && button->priv->icon_widget == NULL &&
      button->priv->stock_id == NULL && button->priv->icon_name == NULL)
    {
      need_label = TRUE;
      need_icon = FALSE;
      style = GTK_TOOLBAR_TEXT;
    }

  if (style == GTK_TOOLBAR_TEXT && button->priv->label_widget == NULL &&
      button->priv->stock_id == NULL && button->priv->label_text == NULL)
    {
      need_label = FALSE;
      need_icon = TRUE;
      style = GTK_TOOLBAR_ICONS;
    }

  if (need_label)
    {
      if (button->priv->label_widget)
	{
	  label = button->priv->label_widget;
	}
      else
	{
	  GtkStockItem stock_item;
	  gboolean elide;
	  gchar *label_text;

          G_GNUC_BEGIN_IGNORE_DEPRECATIONS;

	  if (button->priv->label_text)
	    {
	      label_text = button->priv->label_text;
	      elide = button->priv->use_underline;
	    }
	  else if (button->priv->stock_id && gtk_stock_lookup (button->priv->stock_id, &stock_item))
	    {
	      label_text = stock_item.label;
	      elide = TRUE;
	    }
	  else
	    {
	      label_text = "";
	      elide = FALSE;
	    }

          G_GNUC_END_IGNORE_DEPRECATIONS;

	  if (elide)
	    label_text = _gtk_toolbar_elide_underscores (label_text);
	  else
	    label_text = g_strdup (label_text);

	  label = gtk_label_new (label_text);

	  g_free (label_text);
	  
	  gtk_widget_show (label);
	}

      if (GTK_IS_LABEL (label))
        {
          gtk_label_set_ellipsize (GTK_LABEL (label),
			           gtk_tool_item_get_ellipsize_mode (GTK_TOOL_ITEM (button)));
          text_orientation = gtk_tool_item_get_text_orientation (GTK_TOOL_ITEM (button));
          if (text_orientation == GTK_ORIENTATION_HORIZONTAL)
	    {
              gfloat align;

              gtk_label_set_angle (GTK_LABEL (label), 0);
              align = gtk_tool_item_get_text_alignment (GTK_TOOL_ITEM (button));
              if (align < 0.4)
                gtk_widget_set_halign (label, GTK_ALIGN_START);
              else if (align > 0.6)
                gtk_widget_set_halign (label, GTK_ALIGN_END);
              else
                gtk_widget_set_halign (label, GTK_ALIGN_CENTER);
            }
          else
            {
              gfloat align;

              gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_NONE);
	      if (gtk_widget_get_direction (GTK_WIDGET (tool_item)) == GTK_TEXT_DIR_RTL)
	        gtk_label_set_angle (GTK_LABEL (label), -90);
	      else
	        gtk_label_set_angle (GTK_LABEL (label), 90);
              align = gtk_tool_item_get_text_alignment (GTK_TOOL_ITEM (button));
              if (align < 0.4)
                gtk_widget_set_valign (label, GTK_ALIGN_END);
              else if (align > 0.6)
                gtk_widget_set_valign (label, GTK_ALIGN_START);
              else
                gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
            }
        }
    }

  icon_size = gtk_tool_item_get_icon_size (GTK_TOOL_ITEM (button));
  if (need_icon)
    {
      GtkIconSet *icon_set = NULL;

      if (button->priv->stock_id)
        {
          G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
          icon_set = gtk_icon_factory_lookup_default (button->priv->stock_id);
          G_GNUC_END_IGNORE_DEPRECATIONS;
        }

      if (button->priv->icon_widget)
	{
	  icon = button->priv->icon_widget;
	  
	  if (GTK_IS_IMAGE (icon))
	    {
	      g_object_set (button->priv->icon_widget,
			    "icon-size", icon_size,
			    NULL);
	    }
	}
      else if (icon_set != NULL)
	{
          G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
	  icon = gtk_image_new_from_stock (button->priv->stock_id, icon_size);
          G_GNUC_END_IGNORE_DEPRECATIONS;
	  gtk_widget_show (icon);
	}
      else if (button->priv->icon_name)
	{
	  icon = gtk_image_new_from_icon_name (button->priv->icon_name, icon_size);
	  gtk_widget_show (icon);
	}

      if (icon)
	{
          if (text_orientation == GTK_ORIENTATION_HORIZONTAL)
            {
              gfloat align;

              align = gtk_tool_item_get_text_alignment (GTK_TOOL_ITEM (button));
              if (align > 0.6) 
                gtk_widget_set_halign (icon, GTK_ALIGN_START);
              else if (align < 0.4)
                gtk_widget_set_halign (icon, GTK_ALIGN_END);
              else
                gtk_widget_set_halign (icon, GTK_ALIGN_CENTER);
            }
          else
            {
              gfloat align;

              align = gtk_tool_item_get_text_alignment (GTK_TOOL_ITEM (button));
              if (align > 0.6) 
                gtk_widget_set_valign (icon, GTK_ALIGN_END);
              else if (align < 0.4)
                gtk_widget_set_valign (icon, GTK_ALIGN_START);
              else
               gtk_widget_set_valign (icon, GTK_ALIGN_CENTER);
            }

	  size_group = gtk_tool_item_get_text_size_group (GTK_TOOL_ITEM (button));
	  if (size_group != NULL)
	    gtk_size_group_add_widget (size_group, icon);
	}
    }

  switch (style)
    {
    case GTK_TOOLBAR_ICONS:
      if (icon)
        gtk_container_add (GTK_CONTAINER (button->priv->button), icon);
      gtk_style_context_add_class (gtk_widget_get_style_context (button->priv->button), "image-button");
      break;

    case GTK_TOOLBAR_BOTH:
      if (text_orientation == GTK_ORIENTATION_HORIZONTAL)
	box = gtk_box_new (GTK_ORIENTATION_VERTICAL, icon_spacing);
      else
	box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, icon_spacing);
      if (icon)
	gtk_box_pack_start (GTK_BOX (box), icon, TRUE, TRUE, 0);
      gtk_box_pack_end (GTK_BOX (box), label, FALSE, TRUE, 0);
      gtk_container_add (GTK_CONTAINER (button->priv->button), box);
      break;

    case GTK_TOOLBAR_BOTH_HORIZ:
      if (text_orientation == GTK_ORIENTATION_HORIZONTAL)
	{
	  box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, icon_spacing);
	  if (icon)
	    gtk_box_pack_start (GTK_BOX (box), icon, label? FALSE : TRUE, TRUE, 0);
	  if (label)
	    gtk_box_pack_end (GTK_BOX (box), label, TRUE, TRUE, 0);
	}
      else
	{
	  box = gtk_box_new (GTK_ORIENTATION_VERTICAL, icon_spacing);
	  if (icon)
	    gtk_box_pack_end (GTK_BOX (box), icon, label ? FALSE : TRUE, TRUE, 0);
	  if (label)
	    gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
	}
      gtk_container_add (GTK_CONTAINER (button->priv->button), box);
      break;

    case GTK_TOOLBAR_TEXT:
      gtk_container_add (GTK_CONTAINER (button->priv->button), label);
      gtk_style_context_add_class (gtk_widget_get_style_context (button->priv->button), "text-button");
      break;
    }

  if (box)
    gtk_widget_show (box);

  gtk_button_set_relief (GTK_BUTTON (button->priv->button),
			 gtk_tool_item_get_relief_style (GTK_TOOL_ITEM (button)));

  gtk_tool_item_rebuild_menu (tool_item);
  
  gtk_widget_queue_resize (GTK_WIDGET (button));
}
示例#28
0
static void
gtk_expander_paint_focus (GtkExpander  *expander,
			  GdkRectangle *area)
{
  GtkWidget *widget;
  GtkExpanderPrivate *priv;
  GdkRectangle rect;
  gint x, y, width, height;
  gboolean interior_focus;
  gint border_width;
  gint focus_width;
  gint focus_pad;
  gint expander_size;
  gint expander_spacing;
  gboolean ltr;

  widget = GTK_WIDGET (expander);
  priv = expander->priv;

  border_width = GTK_CONTAINER (widget)->border_width;

  gtk_widget_style_get (widget,
			"interior-focus", &interior_focus,
			"focus-line-width", &focus_width,
			"focus-padding", &focus_pad,
			"expander-size", &expander_size,
			"expander-spacing", &expander_spacing,
			NULL);

  ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL;
  
  width = height = 0;

  if (priv->label_widget)
    {
      if (gtk_widget_get_visible (priv->label_widget))
	{
	  GtkAllocation label_allocation = priv->label_widget->allocation;

	  width  = label_allocation.width;
	  height = label_allocation.height;
	}

      width  += 2 * focus_pad + 2 * focus_width;
      height += 2 * focus_pad + 2 * focus_width;

      x = widget->allocation.x + border_width;
      y = widget->allocation.y + border_width;

      if (ltr)
	{
	  if (interior_focus)
	    x += expander_spacing * 2 + expander_size;
	}
      else
	{
	  x += widget->allocation.width - 2 * border_width
	    - expander_spacing * 2 - expander_size - width;
	}

      if (!interior_focus)
	{
	  width += expander_size + 2 * expander_spacing;
	  height = MAX (height, expander_size + 2 * expander_spacing);
	}
    }
  else
    {
      get_expander_bounds (expander, &rect);

      x = rect.x - focus_pad;
      y = rect.y - focus_pad;
      width = rect.width + 2 * focus_pad;
      height = rect.height + 2 * focus_pad;
    }
      
  gtk_paint_focus (widget->style, widget->window, gtk_widget_get_state (widget),
		   area, widget, "expander",
		   x, y, width, height);
}
示例#29
0
static void
gtk_image_menu_item_size_allocate (GtkWidget     *widget,
                                   GtkAllocation *allocation)
{
    GtkImageMenuItem *image_menu_item;
    GtkPackDirection pack_dir;

    if (GTK_IS_MENU_BAR (widget->parent))
        pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (widget->parent));
    else
        pack_dir = GTK_PACK_DIRECTION_LTR;

    image_menu_item = GTK_IMAGE_MENU_ITEM (widget);

    GTK_WIDGET_CLASS (gtk_image_menu_item_parent_class)->size_allocate (widget, allocation);

    if (image_menu_item->image && GTK_WIDGET_VISIBLE (image_menu_item->image))
    {
        gint x, y, offset;
        GtkRequisition child_requisition;
        GtkAllocation child_allocation;
        guint horizontal_padding, toggle_spacing;

        gtk_widget_style_get (widget,
                              "horizontal-padding", &horizontal_padding,
                              "toggle-spacing", &toggle_spacing,
                              NULL);

        /* Man this is lame hardcoding action, but I can't
         * come up with a solution that's really better.
         */

        gtk_widget_get_child_requisition (image_menu_item->image,
                                          &child_requisition);

        if (pack_dir == GTK_PACK_DIRECTION_LTR ||
                pack_dir == GTK_PACK_DIRECTION_RTL)
        {
            offset = GTK_CONTAINER (image_menu_item)->border_width +
                     widget->style->xthickness;

            if ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) ==
                    (pack_dir == GTK_PACK_DIRECTION_LTR))
                x = offset + horizontal_padding +
                    (GTK_MENU_ITEM (image_menu_item)->toggle_size -
                     toggle_spacing - child_requisition.width) / 2;
            else
                x = widget->allocation.width - offset - horizontal_padding -
                    GTK_MENU_ITEM (image_menu_item)->toggle_size + toggle_spacing +
                    (GTK_MENU_ITEM (image_menu_item)->toggle_size -
                     toggle_spacing - child_requisition.width) / 2;

            y = (widget->allocation.height - child_requisition.height) / 2;
        }
        else
        {
            offset = GTK_CONTAINER (image_menu_item)->border_width +
                     widget->style->ythickness;

            if ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) ==
                    (pack_dir == GTK_PACK_DIRECTION_TTB))
                y = offset + horizontal_padding +
                    (GTK_MENU_ITEM (image_menu_item)->toggle_size -
                     toggle_spacing - child_requisition.height) / 2;
            else
                y = widget->allocation.height - offset - horizontal_padding -
                    GTK_MENU_ITEM (image_menu_item)->toggle_size + toggle_spacing +
                    (GTK_MENU_ITEM (image_menu_item)->toggle_size -
                     toggle_spacing - child_requisition.height) / 2;

            x = (widget->allocation.width - child_requisition.width) / 2;
        }

        child_allocation.width = child_requisition.width;
        child_allocation.height = child_requisition.height;
        child_allocation.x = widget->allocation.x + MAX (x, 0);
        child_allocation.y = widget->allocation.y + MAX (y, 0);

        gtk_widget_size_allocate (image_menu_item->image, &child_allocation);
    }
}
示例#30
0
static gboolean
gtk_cell_view_expose (GtkWidget      *widget,
                      GdkEventExpose *event)
{
  GList *i;
  GtkCellView *cellview;
  GdkRectangle area;
  GtkCellRendererState state;
  gboolean rtl = (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL);

  cellview = GTK_CELL_VIEW (widget);

  if (! GTK_WIDGET_DRAWABLE (widget))
    return FALSE;

  /* "blank" background */
  if (cellview->priv->background_set)
    {
      GdkGC *gc;

      gc = gdk_gc_new (GTK_WIDGET (cellview)->window);
      gdk_gc_set_rgb_fg_color (gc, &cellview->priv->background);

      gdk_draw_rectangle (GTK_WIDGET (cellview)->window,
                          gc,
                          TRUE,

                          /*0, 0,*/
                          widget->allocation.x,
                          widget->allocation.y,

                          widget->allocation.width,
                          widget->allocation.height);

      g_object_unref (G_OBJECT (gc));
    }

  /* set cell data (if available) */
  if (cellview->priv->displayed_row)
    gtk_cell_view_set_cell_data (cellview);
  else if (cellview->priv->model)
    return FALSE;

  /* render cells */
  area = widget->allocation;

  /* we draw on our very own window, initialize x and y to zero */
  area.x = widget->allocation.x + (rtl ? widget->allocation.width : 0); 
  area.y = widget->allocation.y;

  if (GTK_WIDGET_STATE (widget) == GTK_STATE_PRELIGHT)
    state = GTK_CELL_RENDERER_PRELIT;
  else
    state = 0;
      
  /* PACK_START */
  for (i = cellview->priv->cell_list; i; i = i->next)
    {
      GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)i->data;

      if (info->pack == GTK_PACK_END)
        continue;

      if (!info->cell->visible)
        continue;

      area.width = info->real_width;
      if (rtl)                                             
         area.x -= area.width;

      gtk_cell_renderer_render (info->cell,
                                event->window,
                                widget,
                                /* FIXME! */
                                &area, &area, &event->area, state);

      if (!rtl)                                           
         area.x += info->real_width;
    }

   area.x = rtl ? widget->allocation.x : (widget->allocation.x + widget->allocation.width);  

  /* PACK_END */
  for (i = cellview->priv->cell_list; i; i = i->next)
    {
      GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)i->data;

      if (info->pack == GTK_PACK_START)
        continue;

      if (!info->cell->visible)
        continue;

      area.width = info->real_width;
      if (!rtl)
         area.x -= area.width;   

      gtk_cell_renderer_render (info->cell,
                                widget->window,
                                widget,
                                /* FIXME ! */
                                &area, &area, &event->area, state);
      if (rtl)
         area.x += info->real_width;
    }

  return FALSE;
}