guint need_resize : 1;
guint reallocate_redraws : 1;
guint resize_mode : 2;
+ guint request_mode : 2;
};
enum {
gint *natural_size,
gint *allocated_pos,
gint *allocated_size);
+static GtkSizeRequestMode gtk_container_get_request_mode (GtkWidget *widget);
static gchar* gtk_container_child_default_composite_name (GtkContainer *container,
GtkWidget *child);
widget_class->adjust_size_request = gtk_container_adjust_size_request;
widget_class->adjust_size_allocation = gtk_container_adjust_size_allocation;
+ widget_class->get_request_mode = gtk_container_get_request_mode;
class->add = gtk_container_add_unimplemented;
class->remove = gtk_container_remove_unimplemented;
}
/* --- GtkContainer child property mechanism --- */
+
+/**
+ * gtk_container_child_notify:
+ * @container: the #GtkContainer
+ * @widget: the child widget
+ * @child_property: the name of a chld property installed on
+ * the class of @container
+ *
+ * Emits a #GtkWidget::child-notify signal for the
+ * <link linkend="child-properties">child property</link>
+ * @child_property on widget.
+ *
+ * This is an analogue of g_object_notify() for child properties.
+ *
+ * Also see gtk_widget_child_notify().
+ *
+ * Since: 3.2
+ */
+void
+gtk_container_child_notify (GtkContainer *container,
+ GtkWidget *widget,
+ const gchar *child_property)
+{
+ GObject *obj;
+ GParamSpec *pspec;
+
+ g_return_if_fail (GTK_IS_CONTAINER (container));
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (child_property != NULL);
+
+ obj = G_OBJECT (widget);
+
+ if (obj->ref_count == 0)
+ return;
+
+ g_object_ref (obj);
+
+ pspec = g_param_spec_pool_lookup (_gtk_widget_child_property_pool,
+ child_property,
+ G_OBJECT_TYPE (container),
+ TRUE);
+
+ if (pspec == NULL)
+ {
+ g_warning ("%s: container class `%s' has no child property named `%s'",
+ G_STRLOC,
+ G_OBJECT_TYPE_NAME (container),
+ child_property);
+ }
+ else
+ {
+ GObjectNotifyQueue *nqueue;
+
+ nqueue = g_object_notify_queue_freeze (obj, _gtk_widget_child_property_notify_context);
+
+ g_object_notify_queue_add (obj, nqueue, pspec);
+ g_object_notify_queue_thaw (obj, nqueue);
+ }
+
+ g_object_unref (obj);
+}
+
static inline void
container_get_child_property (GtkContainer *container,
GtkWidget *child,
g_return_if_fail (GTK_IS_CONTAINER (container));
g_return_if_fail (GTK_IS_WIDGET (child));
- g_return_if_fail (gtk_widget_get_parent (child) == GTK_WIDGET (container));
g_object_ref (container);
g_object_ref (child);
g_return_if_fail (GTK_IS_CONTAINER (container));
g_return_if_fail (GTK_IS_WIDGET (child));
- g_return_if_fail (gtk_widget_get_parent (child) == GTK_WIDGET (container));
g_return_if_fail (property_name != NULL);
g_return_if_fail (G_IS_VALUE (value));
g_return_if_fail (GTK_IS_CONTAINER (container));
g_return_if_fail (GTK_IS_WIDGET (child));
- g_return_if_fail (gtk_widget_get_parent (child) == GTK_WIDGET (container));
g_object_ref (container);
g_object_ref (child);
g_return_if_fail (GTK_IS_CONTAINER (container));
g_return_if_fail (GTK_IS_WIDGET (child));
- g_return_if_fail (gtk_widget_get_parent (child) == GTK_WIDGET (container));
g_return_if_fail (property_name != NULL);
g_return_if_fail (G_IS_VALUE (value));
*
* Adds @widget to @container, setting child properties at the same time.
* See gtk_container_add() and gtk_container_child_set() for more details.
- **/
+ */
void
gtk_container_add_with_properties (GtkContainer *container,
GtkWidget *widget,
* with @first_prop_name
*
* Sets one or more child properties for @child and @container.
- **/
+ */
void
gtk_container_child_set (GtkContainer *container,
GtkWidget *child,
{
va_list var_args;
- g_return_if_fail (GTK_IS_CONTAINER (container));
- g_return_if_fail (GTK_IS_WIDGET (child));
- g_return_if_fail (gtk_widget_get_parent (child) == GTK_WIDGET (container));
-
va_start (var_args, first_prop_name);
gtk_container_child_set_valist (container, child, first_prop_name, var_args);
va_end (var_args);
{
va_list var_args;
- g_return_if_fail (GTK_IS_CONTAINER (container));
- g_return_if_fail (GTK_IS_WIDGET (child));
- g_return_if_fail (gtk_widget_get_parent (child) == GTK_WIDGET (container));
-
va_start (var_args, first_prop_name);
gtk_container_child_get_valist (container, child, first_prop_name, var_args);
va_end (var_args);
allocated_size);
}
+typedef struct {
+ gint hfw;
+ gint wfh;
+} RequestModeCount;
+
+static void
+count_request_modes (GtkWidget *widget,
+ RequestModeCount *count)
+{
+ GtkSizeRequestMode mode = gtk_widget_get_request_mode (widget);
+
+ switch (mode)
+ {
+ case GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH:
+ count->hfw++;
+ break;
+ case GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT:
+ count->wfh++;
+ break;
+ case GTK_SIZE_REQUEST_CONSTANT_SIZE:
+ default:
+ break;
+ }
+}
+
+static GtkSizeRequestMode
+gtk_container_get_request_mode (GtkWidget *widget)
+{
+ GtkContainer *container = GTK_CONTAINER (widget);
+ GtkContainerPrivate *priv = container->priv;
+
+ /* Recalculate the request mode of the children by majority
+ * vote whenever the internal content changes */
+ if (_gtk_widget_get_width_request_needed (widget) ||
+ _gtk_widget_get_height_request_needed (widget))
+ {
+ RequestModeCount count = { 0, 0 };
+
+ gtk_container_forall (container, (GtkCallback)count_request_modes, &count);
+
+ if (!count.hfw && !count.wfh)
+ priv->request_mode = GTK_SIZE_REQUEST_CONSTANT_SIZE;
+ else
+ priv->request_mode = count.wfh > count.hfw ?
+ GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT :
+ GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
+ }
+
+ return priv->request_mode;
+}
+
/**
* gtk_container_class_handle_border_width:
* @klass: the class struct of a #GtkContainer subclass
/**
* gtk_container_forall:
* @container: a #GtkContainer
- * @callback: (scope call): a callback
+ * @callback: (scope call) (closure callback_data): a callback
* @callback_data: callback user data
*
* Invokes @callback on each child of @container, including children
* of the container, but were added by the container implementation
* itself. Most applications should use gtk_container_foreach(),
* rather than gtk_container_forall().
+ *
+ * Virtual: forall
**/
void
gtk_container_forall (GtkContainer *container,