static void
gtk_revealer_get_child_allocation (GtkRevealer   *revealer,
                                   GtkAllocation *allocation,
                                   GtkAllocation *child_allocation)
{
  GtkWidget *child;
  GtkRevealerTransitionType transition;

  g_return_if_fail (revealer != NULL);
  g_return_if_fail (allocation != NULL);

  child_allocation->x = 0;
  child_allocation->y = 0;
  child_allocation->width = allocation->width;
  child_allocation->height = allocation->height;

  child = gtk_bin_get_child (GTK_BIN (revealer));
  if (child != NULL && gtk_widget_get_visible (child))
    {
      transition = effective_transition (revealer);
      if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT ||
          transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
        gtk_widget_get_preferred_width_for_height (child, child_allocation->height, NULL,
                                                   &child_allocation->width);
      else
        gtk_widget_get_preferred_height_for_width (child, child_allocation->width, NULL,
                                                   &child_allocation->height);
    }
}
示例#2
0
static void
gtk_application_window_real_get_preferred_width_for_height (GtkWidget *widget,
                                                            gint       height,
                                                            gint      *minimum_width,
                                                            gint      *natural_width)
{
  GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (widget);
  gint menubar_height;

  if (window->priv->menubar != NULL)
    gtk_widget_get_preferred_height (window->priv->menubar, &menubar_height, NULL);
  else
    menubar_height = 0;

  GTK_WIDGET_CLASS (gtk_application_window_parent_class)
    ->get_preferred_width_for_height (widget, height - menubar_height, minimum_width, natural_width);

  if (window->priv->menubar != NULL)
    {
      gint menubar_min_width, menubar_nat_width;

      gtk_widget_get_preferred_width_for_height (window->priv->menubar, menubar_height, &menubar_min_width, &menubar_nat_width);
      *minimum_width = MAX (*minimum_width, menubar_min_width);
      *natural_width = MAX (*natural_width, menubar_nat_width);
    }
}
static void
gtk_application_window_real_get_preferred_width_for_height (GtkWidget *widget,
                                                            gint       height,
                                                            gint      *minimum_width,
                                                            gint      *natural_width)
{
  GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (widget);
  gint menubar_height;

  if (window->priv->menubar != NULL)
    gtk_widget_get_preferred_height (window->priv->menubar, &menubar_height, NULL);
  else
    menubar_height = 0;

  GTK_WIDGET_CLASS (gtk_application_window_parent_class)
    ->get_preferred_width_for_height (widget, height - menubar_height, minimum_width, natural_width);

  if (window->priv->menubar != NULL)
    {
      gint menubar_min_width, menubar_nat_width;
      gint border_width;
      GtkBorder border = { 0 };

      gtk_widget_get_preferred_width_for_height (window->priv->menubar, menubar_height, &menubar_min_width, &menubar_nat_width);

      border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
      _gtk_window_get_shadow_width (GTK_WINDOW (widget), &border);

      menubar_min_width += 2 * border_width + border.left + border.right;
      menubar_nat_width += 2 * border_width + border.left + border.right;

      *minimum_width = MAX (*minimum_width, menubar_min_width);
      *natural_width = MAX (*natural_width, menubar_nat_width);
    }
}
示例#4
0
static gint columns_gtk3_get_minfh_width(ColumnsChild *child)
{
  gint ret;
  gtk_widget_get_preferred_width_for_height(
      child->widget, child->h, &ret, NULL);
  return ret;
}
示例#5
0
wxSize wxControl::DoGetBestSize() const
{
    // Do not return any arbitrary default value...
    wxASSERT_MSG( m_widget, wxT("DoGetBestSize called before creation") );

    wxSize best;
    if (m_wxwindow)
    {
        // this is not a native control, size_request is likely to be (0,0)
        best = wxControlBase::DoGetBestSize();
    }
    else
    {
        GtkRequisition req;
#ifdef __WXGTK3__
        if (gtk_widget_get_request_mode(m_widget) != GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
        {
            gtk_widget_get_preferred_height(m_widget, NULL, &req.height);
            gtk_widget_get_preferred_width_for_height(m_widget, req.height, NULL, &req.width);
        }
        else
        {
            gtk_widget_get_preferred_width(m_widget, NULL, &req.width);
            gtk_widget_get_preferred_height_for_width(m_widget, req.width, NULL, &req.height);
        }
#else
        GTK_WIDGET_GET_CLASS(m_widget)->size_request(m_widget, &req);
#endif
        best.Set(req.width, req.height);
    }
    CacheBestSize(best);
    return best;
}
示例#6
0
/**
 * gtk_widget_get_preferred_size:
 * @widget: a #GtkWidget instance
 * @minimum_size: (out) (allow-none): location for storing the minimum size, or %NULL
 * @natural_size: (out) (allow-none): location for storing the natural size, or %NULL
 *
 * Retrieves the minimum and natural size of a widget, taking
 * into account the widget's preference for height-for-width management.
 *
 * This is used to retrieve a suitable size by container widgets which do
 * not impose any restrictions on the child placement. It can be used
 * to deduce toplevel window and menu sizes as well as child widgets in
 * free-form containers such as GtkLayout.
 *
 * <note><para>Handle with care. Note that the natural height of a height-for-width
 * widget will generally be a smaller size than the minimum height, since the required
 * height for the natural width is generally smaller than the required height for
 * the minimum width.</para></note>
 *
 * Since: 3.0
 */
void
gtk_widget_get_preferred_size (GtkWidget      *widget,
                               GtkRequisition *minimum_size,
                               GtkRequisition *natural_size)
{
  gint min_width, nat_width;
  gint min_height, nat_height;

  g_return_if_fail (GTK_IS_WIDGET (widget));

  if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
    {
      gtk_widget_get_preferred_width (widget, &min_width, &nat_width);

      if (minimum_size)
	{
	  minimum_size->width = min_width;
	  gtk_widget_get_preferred_height_for_width (widget, min_width,
                                                     &minimum_size->height, NULL);
	}

      if (natural_size)
	{
	  natural_size->width = nat_width;
	  gtk_widget_get_preferred_height_for_width (widget, nat_width,
                                                     NULL, &natural_size->height);
	}
    }
  else /* GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT or CONSTANT_SIZE */
    {
      gtk_widget_get_preferred_height (widget, &min_height, &nat_height);

      if (minimum_size)
	{
	  minimum_size->height = min_height;
	  gtk_widget_get_preferred_width_for_height (widget, min_height,
                                                     &minimum_size->width, NULL);
	}

      if (natural_size)
	{
	  natural_size->height = nat_height;
	  gtk_widget_get_preferred_width_for_height (widget, nat_height,
                                                     NULL, &natural_size->width);
	}
    }
}
示例#7
0
static void
gd_notification_get_preferred_width_for_height (GtkWidget *widget,
                                                 gint height,
                                                 gint *minimum_width,
                                                 gint *natural_width)
{
  GdNotification *notification = GD_NOTIFICATION (widget);
  GdNotificationPrivate *priv = notification->priv;
  GtkBin *bin = GTK_BIN (widget);
  gint child_min, child_nat, child_height;
  GtkWidget *child;
  GtkBorder padding;
  gint minimum, natural;

  get_padding_and_border (notification, &padding);

  minimum = 0;
  natural = 0;

  child_height = height - SHADOW_OFFSET_Y - padding.top - padding.bottom;

  child = gtk_bin_get_child (bin);
  if (child && gtk_widget_get_visible (child))
    {
      gtk_widget_get_preferred_width_for_height (child, child_height,
                                                 &child_min, &child_nat);
      minimum += child_min;
      natural += child_nat;
    }

  if (priv->show_close_button)
    {
      gtk_widget_get_preferred_width_for_height (priv->close_button, child_height,
                                                 &child_min, &child_nat);
      minimum += child_min;
      natural += child_nat;
    }

  minimum += padding.left + padding.right + 2 * SHADOW_OFFSET_X;
  natural += padding.left + padding.right + 2 * SHADOW_OFFSET_X;

 if (minimum_width)
    *minimum_width = minimum;

  if (natural_width)
    *natural_width = natural;
}
示例#8
0
static void
gtk_notification_size_allocate (GtkWidget *widget,
                                GtkAllocation *allocation)
{
  GtkNotification *notification = GTK_NOTIFICATION (widget);
  GtkNotificationPrivate *priv = notification->priv;
  GtkBin *bin = GTK_BIN (widget);
  GtkAllocation child_allocation;
  GtkBorder padding;
  GtkWidget *child;
  int button_width;

  gtk_widget_set_allocation (widget, allocation);

  /* If somehow the notification changes while not hidden
     and we're not animating, immediately follow the resize */
  if (priv->animate_y > 0 &&
      !priv->animate_timeout)
    priv->animate_y = allocation->height;

  get_padding_and_border (notification, &padding);

  if (gtk_widget_get_realized (widget))
    {
      gdk_window_move_resize (gtk_widget_get_window (widget),
                              allocation->x,
                              allocation->y,
                              allocation->width,
                              allocation->height);
      gdk_window_move_resize (priv->bin_window,
                              0,
                              -allocation->height + priv->animate_y,
                              allocation->width,
                              allocation->height);
    }

  child_allocation.x = SHADOW_OFFSET_X + padding.left;
  child_allocation.y = padding.top;
  child_allocation.height = MAX (1, allocation->height - SHADOW_OFFSET_Y - padding.top - padding.bottom);
  gtk_widget_get_preferred_width_for_height (priv->close_button, child_allocation.height,
                                             NULL, &button_width);

  child_allocation.width = MAX (1, allocation->width - 2 * SHADOW_OFFSET_X - padding.left - padding.right - button_width);

  child = gtk_bin_get_child (bin);
  if (child && gtk_widget_get_visible (child))
    gtk_widget_size_allocate (child, &child_allocation);

  child_allocation.x += child_allocation.width;
  child_allocation.width = button_width;

  gtk_widget_size_allocate (priv->close_button, &child_allocation);
}
示例#9
0
/* Like get_group_sizes(), but gets height for width or width for height */
static GtkRequestedSize *
get_group_sizes_for_sizes(PSquare *self, GtkOrientation direction, GtkRequestedSize *perpendicular_sizes, unsigned n_groups)
{
	PSquarePrivate *priv = P_SQUARE_PRIVATE(self);

	/* Allocate an array for the size of each column/row */
	GtkRequestedSize *sizes = g_new0(GtkRequestedSize, n_groups);

	/* Get each child's size; set the width of each group
	 * to the maximum size of each child in that group */
	unsigned count = 0;
	GList *iter;
	for(iter = priv->children; iter; iter = g_list_next(iter)) {
		if(!gtk_widget_get_visible(iter->data))
			continue;

		int child_minimal, child_natural;
		unsigned group_num;
		if(direction == GTK_ORIENTATION_HORIZONTAL) {
			gtk_widget_get_preferred_width_for_height(iter->data,
				perpendicular_sizes[count / n_groups].minimum_size,
				&child_minimal, &child_natural);
			group_num = count % n_groups;
		} else {
			gtk_widget_get_preferred_height_for_width(iter->data,
				perpendicular_sizes[count % n_groups].minimum_size,
				&child_minimal, &child_natural);
			group_num = count / n_groups;
		}

		sizes[group_num].minimum_size =
			MAX(child_minimal, sizes[group_num].minimum_size);
		sizes[group_num].natural_size =
			MAX(child_natural, sizes[group_num].natural_size);

		count++;
	}

	return sizes;
}
示例#10
0
static void
gd_stack_get_preferred_width_for_height (GtkWidget* widget,
					 gint height,
					 gint *minimum_width,
					 gint *natural_width)
{
  GdStack *stack = GD_STACK (widget);
  GdStackPrivate *priv = stack->priv;
  GdStackChildInfo *child_info;
  GtkWidget *child;
  gint child_min, child_nat;
  GList *l;

  *minimum_width = 0;
  *natural_width = 0;

  for (l = priv->children; l != NULL; l = l->next)
    {
      child_info = l->data;
      child = child_info->widget;

      if (!priv->homogeneous &&
	  (priv->visible_child != child_info &&
           priv->last_visible_child != child_info))
	continue;
      if (gtk_widget_get_visible (child))
	{
	  gtk_widget_get_preferred_width_for_height (child, height, &child_min, &child_nat);

	  *minimum_width = MAX (*minimum_width, child_min);
	  *natural_width = MAX (*natural_width, child_nat);
	}
    }

  if (priv->last_visible_surface != NULL)
    {
      *minimum_width = MAX (*minimum_width, priv->last_visible_surface_allocation.width);
      *natural_width = MAX (*natural_width, priv->last_visible_surface_allocation.width);
    }
}
示例#11
0
static void
gtk_revealer_get_child_allocation (GtkRevealer   *revealer,
                                   GtkAllocation *allocation,
                                   GtkAllocation *child_allocation)
{
  GtkWidget *child;
  GtkRevealerTransitionType transition;
  GtkBorder padding;
  gint vertical_padding, horizontal_padding;

  g_return_if_fail (revealer != NULL);
  g_return_if_fail (allocation != NULL);

  /* See explanation on gtk_revealer_real_size_allocate */
  gtk_revealer_get_padding (revealer, &padding);
  vertical_padding = padding.top + padding.bottom;
  horizontal_padding = padding.left + padding.right;

  child_allocation->x = 0;
  child_allocation->y = 0;
  child_allocation->width = 0;
  child_allocation->height = 0;

  child = gtk_bin_get_child (GTK_BIN (revealer));
  if (child != NULL && gtk_widget_get_visible (child))
    {
      transition = effective_transition (revealer);
      if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT ||
          transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
        gtk_widget_get_preferred_width_for_height (child, MAX (0, allocation->height - vertical_padding), NULL,
                                                   &child_allocation->width);
      else
        gtk_widget_get_preferred_height_for_width (child, MAX (0, allocation->width - horizontal_padding), NULL,
                                                   &child_allocation->height);
    }

  child_allocation->width = MAX (child_allocation->width, allocation->width - horizontal_padding);
  child_allocation->height = MAX (child_allocation->height, allocation->height - vertical_padding);
}
static void
greeter_menu_bar_size_allocate(GtkWidget* widget, GtkAllocation* allocation)
{
    GList* item;
    GList* shell_children;
    GList* expand_nums = NULL;
    guint visible_count = 0, expand_count = 0;

	g_return_if_fail(allocation != NULL);
	g_return_if_fail(GREETER_IS_MENU_BAR(widget));

    gtk_widget_set_allocation(widget, allocation);

    GtkPackDirection pack_direction = gtk_menu_bar_get_pack_direction(GTK_MENU_BAR(widget));
    g_return_if_fail(pack_direction == GTK_PACK_DIRECTION_LTR || pack_direction == GTK_PACK_DIRECTION_RTL);

    shell_children = gtk_container_get_children(GTK_CONTAINER(widget));

    for(item = shell_children; item; item = g_list_next(item))
        if(gtk_widget_get_visible(item->data))
        {
            if(gtk_widget_compute_expand(item->data, GTK_ORIENTATION_HORIZONTAL))
            {
                expand_nums = g_list_prepend(expand_nums, GINT_TO_POINTER(visible_count));
                expand_count++;
            }
            visible_count++;
        }

    if(gtk_widget_get_realized(widget))
        gdk_window_move_resize(gtk_widget_get_window(widget),
                               allocation->x, allocation->y,
                               allocation->width, allocation->height);

    if(visible_count > 0)
    {
        GtkAllocation remaining_space;
        GtkStyleContext* context = gtk_widget_get_style_context(widget);
        GtkStateFlags flags = gtk_widget_get_state_flags(widget);
        GtkRequestedSize* requested_sizes = g_newa(GtkRequestedSize, visible_count);
        guint border_width = gtk_container_get_border_width(GTK_CONTAINER(widget));
        GtkShadowType shadow_type = GTK_SHADOW_OUT;
        GtkBorder border;
        gint toggle_size;

        gtk_style_context_get_padding(context, flags, &border);
        gtk_widget_style_get(widget, "shadow-type", &shadow_type, NULL);

        remaining_space.x = (border_width + border.left);
        remaining_space.y = (border_width + border.top);
        remaining_space.width = allocation->width -
                                2 * border_width - border.left - border.right;
        remaining_space.height = allocation->height -
                                 2 * border_width - border.top - border.bottom;

        if (shadow_type != GTK_SHADOW_NONE)
        {
            gtk_style_context_get_border(context, flags, &border);

            remaining_space.x += border.left;
            remaining_space.y += border.top;
            remaining_space.width -= border.left + border.right;
            remaining_space.height -= border.top + border.bottom;
        }

        GtkRequestedSize* request = requested_sizes;
        int size = remaining_space.width;
        gboolean ltr = (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_LTR) == (pack_direction == GTK_PACK_DIRECTION_LTR);

        for(item = shell_children; item; item = g_list_next(item))
        {
            if (!gtk_widget_get_visible(item->data))
                continue;

            request->data = item->data;
            gtk_widget_get_preferred_width_for_height(item->data, remaining_space.height,
                    &request->minimum_size,
                    &request->natural_size);
            gtk_menu_item_toggle_size_request(GTK_MENU_ITEM(item->data),
                                              &toggle_size);
            request->minimum_size += toggle_size;
            request->natural_size += toggle_size;

            gtk_menu_item_toggle_size_allocate(GTK_MENU_ITEM(item->data), toggle_size);

            size -= request->minimum_size;
            request++;
        }

        size = gtk_distribute_natural_allocation(size, visible_count, requested_sizes);

        /* Distribution extra space for widgets with expand=True */
        if(size > 0 && expand_nums)
        {
            expand_nums = g_list_sort_with_data(expand_nums, (GCompareDataFunc)sort_minimal_size,
                                                requested_sizes);
            GList* first_item = expand_nums;
            gint needed_size = -1;
            gint max_size = requested_sizes[GPOINTER_TO_INT(first_item->data)].natural_size;
            gint total_needed_size = 0;


            /* Free space that all widgets need to have the same (max_size) width
             * [___max_width___][widget         ][widget____     ]
             * total_needed_size := [] + [         ] + [     ]
             * total_needed_size = [              ]
             */
            for(item = g_list_next(expand_nums); item; item = g_list_next(item))
                total_needed_size += max_size - requested_sizes[GPOINTER_TO_INT(item->data)].natural_size;

            while(first_item)
            {
                if(size >= total_needed_size)
                {
                    /* total_needed_size is enough for all remaining widgets */
                    needed_size = max_size + (size - total_needed_size)/expand_count;
                    break;
                }
                /* Removing current maximal widget from list */
                total_needed_size -= max_size - requested_sizes[GPOINTER_TO_INT(item->data)].natural_size;
                first_item = g_list_next(first_item);
                if(first_item)
                    max_size = requested_sizes[GPOINTER_TO_INT(first_item->data)].natural_size;
            }

            for(item = first_item; item; item = g_list_next(item))
            {
                request = &requested_sizes[GPOINTER_TO_INT(item->data)];
                gint dsize = needed_size - request->natural_size;
                if(size < dsize)
                    dsize = size;
                size -= dsize;
                request->natural_size += dsize;
            }
        }
        
        gint i;
        for(i = 0; i < visible_count; i++)
        {
            GtkAllocation child_allocation = remaining_space;
            request = &requested_sizes[i];

            child_allocation.width = request->natural_size;
            remaining_space.width -= request->natural_size;
            if (ltr)
                remaining_space.x += request->natural_size;
            else
                child_allocation.x += remaining_space.width;
            gtk_widget_size_allocate(request->data, &child_allocation);
        }
        g_list_free(expand_nums);
    }
    g_list_free(shell_children);
}