forked from AuroraMiddleware/gtk
685 lines
21 KiB
C
685 lines
21 KiB
C
/* GTK - The GIMP Toolkit
|
||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||
*
|
||
* GtkAspectFrame: Ensure that the child window has a specified aspect ratio
|
||
* or, if obey_child, has the same aspect ratio as its requested size
|
||
*
|
||
* Copyright Owen Taylor 4/9/97
|
||
*
|
||
* This library is free software; you can redistribute it and/or
|
||
* modify it under the terms of the GNU Lesser General Public
|
||
* License as published by the Free Software Foundation; either
|
||
* version 2 of the License, or (at your option) any later version.
|
||
*
|
||
* This library is distributed in the hope that it will be useful,
|
||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
* Lesser General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU Lesser General Public
|
||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
/*
|
||
* Modified by the GTK+ Team and others 1997-2001. See the AUTHORS
|
||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||
* files for a list of changes. These files are distributed with
|
||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||
*/
|
||
|
||
/**
|
||
* GtkAspectFrame:
|
||
*
|
||
* `GtkAspectFrame` preserves the aspect ratio of its child.
|
||
*
|
||
* The frame can respect the aspect ratio of the child widget,
|
||
* or use its own aspect ratio.
|
||
*
|
||
* # CSS nodes
|
||
*
|
||
* `GtkAspectFrame` uses a CSS node with name `frame`.
|
||
*/
|
||
|
||
#include "config.h"
|
||
|
||
#include "gtkaspectframe.h"
|
||
|
||
#include "gtksizerequest.h"
|
||
|
||
#include "gtkbuildable.h"
|
||
|
||
#include "gtkwidgetprivate.h"
|
||
#include "gtkprivate.h"
|
||
#include "gtkintl.h"
|
||
|
||
|
||
typedef struct _GtkAspectFrameClass GtkAspectFrameClass;
|
||
|
||
struct _GtkAspectFrame
|
||
{
|
||
GtkWidget parent_instance;
|
||
|
||
GtkWidget *child;
|
||
gboolean obey_child;
|
||
float xalign;
|
||
float yalign;
|
||
float ratio;
|
||
};
|
||
|
||
struct _GtkAspectFrameClass
|
||
{
|
||
GtkWidgetClass parent_class;
|
||
};
|
||
|
||
enum {
|
||
PROP_0,
|
||
PROP_XALIGN,
|
||
PROP_YALIGN,
|
||
PROP_RATIO,
|
||
PROP_OBEY_CHILD,
|
||
PROP_CHILD
|
||
};
|
||
|
||
static void gtk_aspect_frame_dispose (GObject *object);
|
||
static void gtk_aspect_frame_set_property (GObject *object,
|
||
guint prop_id,
|
||
const GValue *value,
|
||
GParamSpec *pspec);
|
||
static void gtk_aspect_frame_get_property (GObject *object,
|
||
guint prop_id,
|
||
GValue *value,
|
||
GParamSpec *pspec);
|
||
static void gtk_aspect_frame_size_allocate (GtkWidget *widget,
|
||
int width,
|
||
int height,
|
||
int baseline);
|
||
static void gtk_aspect_frame_measure (GtkWidget *widget,
|
||
GtkOrientation orientation,
|
||
int for_size,
|
||
int *minimum,
|
||
int *natural,
|
||
int *minimum_baseline,
|
||
int *natural_baseline);
|
||
|
||
static void gtk_aspect_frame_compute_expand (GtkWidget *widget,
|
||
gboolean *hexpand,
|
||
gboolean *vexpand);
|
||
static GtkSizeRequestMode
|
||
gtk_aspect_frame_get_request_mode (GtkWidget *widget);
|
||
|
||
static void gtk_aspect_frame_buildable_init (GtkBuildableIface *iface);
|
||
|
||
#define MAX_RATIO 10000.0
|
||
#define MIN_RATIO 0.0001
|
||
|
||
|
||
G_DEFINE_TYPE_WITH_CODE (GtkAspectFrame, gtk_aspect_frame, GTK_TYPE_WIDGET,
|
||
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
|
||
gtk_aspect_frame_buildable_init))
|
||
|
||
|
||
static void
|
||
gtk_aspect_frame_class_init (GtkAspectFrameClass *class)
|
||
{
|
||
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||
|
||
gobject_class->dispose = gtk_aspect_frame_dispose;
|
||
gobject_class->set_property = gtk_aspect_frame_set_property;
|
||
gobject_class->get_property = gtk_aspect_frame_get_property;
|
||
|
||
widget_class->measure = gtk_aspect_frame_measure;
|
||
widget_class->size_allocate = gtk_aspect_frame_size_allocate;
|
||
widget_class->compute_expand = gtk_aspect_frame_compute_expand;
|
||
widget_class->get_request_mode = gtk_aspect_frame_get_request_mode;
|
||
|
||
/**
|
||
* GtkAspectFrame:xalign: (attributes org.gtk.Property.get=gtk_aspect_frame_get_xalign org.gtk.Property.set=gtk_aspect_frame_set_xalign)
|
||
*
|
||
* The horizontal alignment of the child.
|
||
*/
|
||
g_object_class_install_property (gobject_class,
|
||
PROP_XALIGN,
|
||
g_param_spec_float ("xalign",
|
||
P_("Horizontal Alignment"),
|
||
P_("X alignment of the child"),
|
||
0.0, 1.0, 0.5,
|
||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||
/**
|
||
* GtkAspectFrame:yalign: (attributes org.gtk.Property.get=gtk_aspect_frame_get_yalign org.gtk.Property.set=gtk_aspect_frame_set_yalign)
|
||
*
|
||
* The vertical alignment of the child.
|
||
*/
|
||
g_object_class_install_property (gobject_class,
|
||
PROP_YALIGN,
|
||
g_param_spec_float ("yalign",
|
||
P_("Vertical Alignment"),
|
||
P_("Y alignment of the child"),
|
||
0.0, 1.0, 0.5,
|
||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||
/**
|
||
* GtkAspectFrame:ratio: (attributes org.gtk.Property.get=gtk_aspect_frame_get_ratio org.gtk.Property.set=gtk_aspect_frame_set_ratio)
|
||
*
|
||
* The aspect ratio to be used by the `GtkAspectFrame`.
|
||
*
|
||
* This property is only used if
|
||
* [property@Gtk.AspectFrame:obey-child] is set to %FALSE.
|
||
*/
|
||
g_object_class_install_property (gobject_class,
|
||
PROP_RATIO,
|
||
g_param_spec_float ("ratio",
|
||
P_("Ratio"),
|
||
P_("Aspect ratio if obey_child is FALSE"),
|
||
MIN_RATIO, MAX_RATIO, 1.0,
|
||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||
/**
|
||
* GtkAspectFrame:obey-child: (attributes org.gtk.Property.get=gtk_aspect_frame_get_obey_child org.gtk.Property.set=gtk_aspect_frame_set_obey_child)
|
||
*
|
||
* Whether the `GtkAspectFrame` should use the aspect ratio of its child.
|
||
*/
|
||
g_object_class_install_property (gobject_class,
|
||
PROP_OBEY_CHILD,
|
||
g_param_spec_boolean ("obey-child",
|
||
P_("Obey child"),
|
||
P_("Force aspect ratio to match that of the frame’s child"),
|
||
TRUE,
|
||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||
/**
|
||
* GtkAspectFrame:child: (attributes org.gtk.Property.get=gtk_aspect_frame_get_child org.gtk.Property.set=gtk_aspect_frame_set_child)
|
||
*
|
||
* The child widget.
|
||
*/
|
||
g_object_class_install_property (gobject_class,
|
||
PROP_CHILD,
|
||
g_param_spec_object ("child",
|
||
P_("Child"),
|
||
P_("The child widget"),
|
||
GTK_TYPE_WIDGET,
|
||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||
|
||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), I_("aspectframe"));
|
||
gtk_widget_class_set_accessible_role (GTK_WIDGET_CLASS (class), GTK_ACCESSIBLE_ROLE_GROUP);
|
||
}
|
||
|
||
static void
|
||
gtk_aspect_frame_init (GtkAspectFrame *self)
|
||
{
|
||
self->xalign = 0.5;
|
||
self->yalign = 0.5;
|
||
self->ratio = 1.0;
|
||
self->obey_child = TRUE;
|
||
}
|
||
|
||
static void
|
||
gtk_aspect_frame_dispose (GObject *object)
|
||
{
|
||
GtkAspectFrame *self = GTK_ASPECT_FRAME (object);
|
||
|
||
g_clear_pointer (&self->child, gtk_widget_unparent);
|
||
|
||
G_OBJECT_CLASS (gtk_aspect_frame_parent_class)->dispose (object);
|
||
}
|
||
|
||
static void
|
||
gtk_aspect_frame_set_property (GObject *object,
|
||
guint prop_id,
|
||
const GValue *value,
|
||
GParamSpec *pspec)
|
||
{
|
||
GtkAspectFrame *self = GTK_ASPECT_FRAME (object);
|
||
|
||
switch (prop_id)
|
||
{
|
||
/* g_object_notify is handled by the _frame_set function */
|
||
case PROP_XALIGN:
|
||
gtk_aspect_frame_set_xalign (self, g_value_get_float (value));
|
||
break;
|
||
case PROP_YALIGN:
|
||
gtk_aspect_frame_set_yalign (self, g_value_get_float (value));
|
||
break;
|
||
case PROP_RATIO:
|
||
gtk_aspect_frame_set_ratio (self, g_value_get_float (value));
|
||
break;
|
||
case PROP_OBEY_CHILD:
|
||
gtk_aspect_frame_set_obey_child (self, g_value_get_boolean (value));
|
||
break;
|
||
case PROP_CHILD:
|
||
gtk_aspect_frame_set_child (self, g_value_get_object (value));
|
||
break;
|
||
default:
|
||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||
break;
|
||
}
|
||
}
|
||
|
||
static void
|
||
gtk_aspect_frame_get_property (GObject *object,
|
||
guint prop_id,
|
||
GValue *value,
|
||
GParamSpec *pspec)
|
||
{
|
||
GtkAspectFrame *self = GTK_ASPECT_FRAME (object);
|
||
|
||
switch (prop_id)
|
||
{
|
||
case PROP_XALIGN:
|
||
g_value_set_float (value, self->xalign);
|
||
break;
|
||
case PROP_YALIGN:
|
||
g_value_set_float (value, self->yalign);
|
||
break;
|
||
case PROP_RATIO:
|
||
g_value_set_float (value, self->ratio);
|
||
break;
|
||
case PROP_OBEY_CHILD:
|
||
g_value_set_boolean (value, self->obey_child);
|
||
break;
|
||
case PROP_CHILD:
|
||
g_value_set_object (value, gtk_aspect_frame_get_child (self));
|
||
break;
|
||
default:
|
||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||
break;
|
||
}
|
||
}
|
||
|
||
static GtkBuildableIface *parent_buildable_iface;
|
||
|
||
static void
|
||
gtk_aspect_frame_buildable_add_child (GtkBuildable *buildable,
|
||
GtkBuilder *builder,
|
||
GObject *child,
|
||
const char *type)
|
||
{
|
||
if (GTK_IS_WIDGET (child))
|
||
gtk_aspect_frame_set_child (GTK_ASPECT_FRAME (buildable), GTK_WIDGET (child));
|
||
else
|
||
parent_buildable_iface->add_child (buildable, builder, child, type);
|
||
}
|
||
|
||
static void
|
||
gtk_aspect_frame_buildable_init (GtkBuildableIface *iface)
|
||
{
|
||
parent_buildable_iface = g_type_interface_peek_parent (iface);
|
||
|
||
iface->add_child = gtk_aspect_frame_buildable_add_child;
|
||
}
|
||
|
||
/**
|
||
* gtk_aspect_frame_new:
|
||
* @xalign: Horizontal alignment of the child within the parent.
|
||
* Ranges from 0.0 (left aligned) to 1.0 (right aligned)
|
||
* @yalign: Vertical alignment of the child within the parent.
|
||
* Ranges from 0.0 (top aligned) to 1.0 (bottom aligned)
|
||
* @ratio: The desired aspect ratio.
|
||
* @obey_child: If %TRUE, @ratio is ignored, and the aspect
|
||
* ratio is taken from the requistion of the child.
|
||
*
|
||
* Create a new `GtkAspectFrame`.
|
||
*
|
||
* Returns: the new `GtkAspectFrame`.
|
||
*/
|
||
GtkWidget *
|
||
gtk_aspect_frame_new (float xalign,
|
||
float yalign,
|
||
float ratio,
|
||
gboolean obey_child)
|
||
{
|
||
GtkAspectFrame *self;
|
||
|
||
self = g_object_new (GTK_TYPE_ASPECT_FRAME, NULL);
|
||
|
||
self->xalign = CLAMP (xalign, 0.0, 1.0);
|
||
self->yalign = CLAMP (yalign, 0.0, 1.0);
|
||
self->ratio = CLAMP (ratio, MIN_RATIO, MAX_RATIO);
|
||
self->obey_child = obey_child != FALSE;
|
||
|
||
return GTK_WIDGET (self);
|
||
}
|
||
|
||
/**
|
||
* gtk_aspect_frame_set_xalign: (attributes org.gtk.Method.set_property=xalign)
|
||
* @self: a `GtkAspectFrame`
|
||
* @xalign: horizontal alignment, from 0.0 (left aligned) to 1.0 (right aligned)
|
||
*
|
||
* Sets the horizontal alignment of the child within the allocation
|
||
* of the `GtkAspectFrame`.
|
||
*/
|
||
void
|
||
gtk_aspect_frame_set_xalign (GtkAspectFrame *self,
|
||
float xalign)
|
||
{
|
||
g_return_if_fail (GTK_IS_ASPECT_FRAME (self));
|
||
|
||
xalign = CLAMP (xalign, 0.0, 1.0);
|
||
|
||
if (self->xalign == xalign)
|
||
return;
|
||
|
||
self->xalign = xalign;
|
||
|
||
g_object_notify (G_OBJECT (self), "xalign");
|
||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||
}
|
||
|
||
/**
|
||
* gtk_aspect_frame_get_xalign: (attributes org.gtk.Method.get_property=xalign)
|
||
* @self: a `GtkAspectFrame`
|
||
*
|
||
* Returns the horizontal alignment of the child within the
|
||
* allocation of the `GtkAspectFrame`.
|
||
*
|
||
* Returns: the horizontal alignment
|
||
*/
|
||
float
|
||
gtk_aspect_frame_get_xalign (GtkAspectFrame *self)
|
||
{
|
||
g_return_val_if_fail (GTK_IS_ASPECT_FRAME (self), 0.5);
|
||
|
||
return self->xalign;
|
||
}
|
||
|
||
/**
|
||
* gtk_aspect_frame_set_yalign: (attributes org.gtk.Method.set_property=yalign)
|
||
* @self: a `GtkAspectFrame`
|
||
* @yalign: horizontal alignment, from 0.0 (top aligned) to 1.0 (bottom aligned)
|
||
*
|
||
* Sets the vertical alignment of the child within the allocation
|
||
* of the `GtkAspectFrame`.
|
||
*/
|
||
void
|
||
gtk_aspect_frame_set_yalign (GtkAspectFrame *self,
|
||
float yalign)
|
||
{
|
||
g_return_if_fail (GTK_IS_ASPECT_FRAME (self));
|
||
|
||
yalign = CLAMP (yalign, 0.0, 1.0);
|
||
|
||
if (self->yalign == yalign)
|
||
return;
|
||
|
||
self->yalign = yalign;
|
||
|
||
g_object_notify (G_OBJECT (self), "yalign");
|
||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||
}
|
||
|
||
/**
|
||
* gtk_aspect_frame_get_yalign: (attributes org.gtk.Method.get_property=yalign)
|
||
* @self: a `GtkAspectFrame`
|
||
*
|
||
* Returns the vertical alignment of the child within the
|
||
* allocation of the `GtkAspectFrame`.
|
||
*
|
||
* Returns: the vertical alignment
|
||
*/
|
||
float
|
||
gtk_aspect_frame_get_yalign (GtkAspectFrame *self)
|
||
{
|
||
g_return_val_if_fail (GTK_IS_ASPECT_FRAME (self), 0.5);
|
||
|
||
return self->xalign;
|
||
}
|
||
|
||
/**
|
||
* gtk_aspect_frame_set_ratio: (attributes org.gtk.Method.set_property=ratio)
|
||
* @self: a `GtkAspectFrame`
|
||
* @ratio: aspect ratio of the child
|
||
*
|
||
* Sets the desired aspect ratio of the child.
|
||
*/
|
||
void
|
||
gtk_aspect_frame_set_ratio (GtkAspectFrame *self,
|
||
float ratio)
|
||
{
|
||
g_return_if_fail (GTK_IS_ASPECT_FRAME (self));
|
||
|
||
ratio = CLAMP (ratio, MIN_RATIO, MAX_RATIO);
|
||
|
||
if (self->ratio == ratio)
|
||
return;
|
||
|
||
self->ratio = ratio;
|
||
|
||
g_object_notify (G_OBJECT (self), "ratio");
|
||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||
}
|
||
|
||
/**
|
||
* gtk_aspect_frame_get_ratio: (attributes org.gtk.Method.get_property=ratio)
|
||
* @self: a `GtkAspectFrame`
|
||
*
|
||
* Returns the desired aspect ratio of the child.
|
||
*
|
||
* Returns: the desired aspect ratio
|
||
*/
|
||
float
|
||
gtk_aspect_frame_get_ratio (GtkAspectFrame *self)
|
||
{
|
||
g_return_val_if_fail (GTK_IS_ASPECT_FRAME (self), 1.0);
|
||
|
||
return self->ratio;
|
||
}
|
||
|
||
/**
|
||
* gtk_aspect_frame_set_obey_child: (attributes org.gtk.Method.set_propery=obey-child)
|
||
* @self: a `GtkAspectFrame`
|
||
* @obey_child: If %TRUE, @ratio is ignored, and the aspect
|
||
* ratio is taken from the requistion of the child.
|
||
*
|
||
* Sets whether the aspect ratio of the child's size
|
||
* request should override the set aspect ratio of
|
||
* the `GtkAspectFrame`.
|
||
*/
|
||
void
|
||
gtk_aspect_frame_set_obey_child (GtkAspectFrame *self,
|
||
gboolean obey_child)
|
||
{
|
||
g_return_if_fail (GTK_IS_ASPECT_FRAME (self));
|
||
|
||
if (self->obey_child == obey_child)
|
||
return;
|
||
|
||
self->obey_child = obey_child;
|
||
|
||
g_object_notify (G_OBJECT (self), "obey-child");
|
||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||
|
||
}
|
||
|
||
/**
|
||
* gtk_aspect_frame_get_obey_child: (attributes org.gtk.Method.get_property=obey-child)
|
||
* @self: a `GtkAspectFrame`
|
||
*
|
||
* Returns whether the child's size request should override
|
||
* the set aspect ratio of the `GtkAspectFrame`.
|
||
*
|
||
* Returns: whether to obey the child's size request
|
||
*/
|
||
gboolean
|
||
gtk_aspect_frame_get_obey_child (GtkAspectFrame *self)
|
||
{
|
||
g_return_val_if_fail (GTK_IS_ASPECT_FRAME (self), TRUE);
|
||
|
||
return self->obey_child;
|
||
}
|
||
|
||
static void
|
||
get_full_allocation (GtkAspectFrame *self,
|
||
GtkAllocation *child_allocation)
|
||
{
|
||
child_allocation->x = 0;
|
||
child_allocation->y = 0;
|
||
child_allocation->width = gtk_widget_get_width (GTK_WIDGET (self));
|
||
child_allocation->height = gtk_widget_get_height (GTK_WIDGET (self));
|
||
}
|
||
|
||
static void
|
||
compute_child_allocation (GtkAspectFrame *self,
|
||
GtkAllocation *child_allocation)
|
||
{
|
||
double ratio;
|
||
|
||
if (self->child && gtk_widget_get_visible (self->child))
|
||
{
|
||
GtkAllocation full_allocation;
|
||
|
||
if (self->obey_child)
|
||
{
|
||
GtkRequisition child_requisition;
|
||
|
||
gtk_widget_get_preferred_size (self->child, &child_requisition, NULL);
|
||
if (child_requisition.height != 0)
|
||
{
|
||
ratio = ((double) child_requisition.width /
|
||
child_requisition.height);
|
||
if (ratio < MIN_RATIO)
|
||
ratio = MIN_RATIO;
|
||
}
|
||
else if (child_requisition.width != 0)
|
||
ratio = MAX_RATIO;
|
||
else
|
||
ratio = 1.0;
|
||
}
|
||
else
|
||
ratio = self->ratio;
|
||
|
||
get_full_allocation (self, &full_allocation);
|
||
|
||
if (ratio * full_allocation.height > full_allocation.width)
|
||
{
|
||
child_allocation->width = full_allocation.width;
|
||
child_allocation->height = full_allocation.width / ratio + 0.5;
|
||
}
|
||
else
|
||
{
|
||
child_allocation->width = ratio * full_allocation.height + 0.5;
|
||
child_allocation->height = full_allocation.height;
|
||
}
|
||
|
||
child_allocation->x = full_allocation.x + self->xalign * (full_allocation.width - child_allocation->width);
|
||
child_allocation->y = full_allocation.y + self->yalign * (full_allocation.height - child_allocation->height);
|
||
}
|
||
else
|
||
get_full_allocation (self, child_allocation);
|
||
}
|
||
|
||
static void
|
||
gtk_aspect_frame_measure (GtkWidget *widget,
|
||
GtkOrientation orientation,
|
||
int for_size,
|
||
int *minimum,
|
||
int *natural,
|
||
int *minimum_baseline,
|
||
int *natural_baseline)
|
||
{
|
||
GtkAspectFrame *self = GTK_ASPECT_FRAME (widget);
|
||
|
||
if (self->child && gtk_widget_get_visible (self->child))
|
||
{
|
||
int child_min, child_nat;
|
||
|
||
gtk_widget_measure (self->child,
|
||
orientation, for_size,
|
||
&child_min, &child_nat,
|
||
NULL, NULL);
|
||
|
||
*minimum = child_min;
|
||
*natural = child_nat;
|
||
}
|
||
else
|
||
{
|
||
*minimum = 0;
|
||
*natural = 0;
|
||
}
|
||
}
|
||
|
||
static void
|
||
gtk_aspect_frame_size_allocate (GtkWidget *widget,
|
||
int width,
|
||
int height,
|
||
int baseline)
|
||
{
|
||
GtkAspectFrame *self = GTK_ASPECT_FRAME (widget);
|
||
GtkAllocation new_allocation;
|
||
|
||
compute_child_allocation (self, &new_allocation);
|
||
|
||
if (self->child && gtk_widget_get_visible (self->child))
|
||
gtk_widget_size_allocate (self->child, &new_allocation, -1);
|
||
}
|
||
|
||
static void
|
||
gtk_aspect_frame_compute_expand (GtkWidget *widget,
|
||
gboolean *hexpand,
|
||
gboolean *vexpand)
|
||
{
|
||
GtkAspectFrame *self = GTK_ASPECT_FRAME (widget);
|
||
|
||
if (self->child)
|
||
{
|
||
*hexpand = gtk_widget_compute_expand (self->child, GTK_ORIENTATION_HORIZONTAL);
|
||
*vexpand = gtk_widget_compute_expand (self->child, GTK_ORIENTATION_VERTICAL);
|
||
}
|
||
else
|
||
{
|
||
*hexpand = FALSE;
|
||
*vexpand = FALSE;
|
||
}
|
||
}
|
||
|
||
static GtkSizeRequestMode
|
||
gtk_aspect_frame_get_request_mode (GtkWidget *widget)
|
||
{
|
||
GtkAspectFrame *self = GTK_ASPECT_FRAME (widget);
|
||
|
||
if (self->child)
|
||
return gtk_widget_get_request_mode (self->child);
|
||
else
|
||
return GTK_SIZE_REQUEST_CONSTANT_SIZE;
|
||
}
|
||
|
||
/**
|
||
* gtk_aspect_frame_set_child: (attributes org.gtk.Method.set_property=child)
|
||
* @self: a `GtkAspectFrame`
|
||
* @child: (allow-none): the child widget
|
||
*
|
||
* Sets the child widget of @self.
|
||
*/
|
||
void
|
||
gtk_aspect_frame_set_child (GtkAspectFrame *self,
|
||
GtkWidget *child)
|
||
{
|
||
g_return_if_fail (GTK_IS_ASPECT_FRAME (self));
|
||
g_return_if_fail (child == NULL || GTK_IS_WIDGET (child));
|
||
|
||
if (self->child == child)
|
||
return;
|
||
|
||
g_clear_pointer (&self->child, gtk_widget_unparent);
|
||
|
||
if (child)
|
||
{
|
||
self->child = child;
|
||
gtk_widget_set_parent (child, GTK_WIDGET (self));
|
||
}
|
||
|
||
g_object_notify (G_OBJECT (self), "child");
|
||
}
|
||
|
||
/**
|
||
* gtk_aspect_frame_get_child: (attributes org.gtk.Method.get_property=child)
|
||
* @self: a `GtkAspectFrame`
|
||
*
|
||
* Gets the child widget of @self.
|
||
*
|
||
* Returns: (nullable) (transfer none): the child widget of self@
|
||
*/
|
||
GtkWidget *
|
||
gtk_aspect_frame_get_child (GtkAspectFrame *self)
|
||
{
|
||
g_return_val_if_fail (GTK_IS_ASPECT_FRAME (self), NULL);
|
||
|
||
return self->child;
|
||
}
|