X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkframe.c;h=e118823204405cc3a5ed87d93bf4ad9cdf5e78ae;hb=f35439bfacf90900e2c24f7ae3da173183c79d34;hp=36c9c1c7c02fef134674189e5134f00159cb63bc;hpb=4c28ce0877e5749d9d930304397995535190a168;p=~andy%2Fgtk diff --git a/gtk/gtkframe.c b/gtk/gtkframe.c index 36c9c1c7c..e11882320 100644 --- a/gtk/gtkframe.c +++ b/gtk/gtkframe.c @@ -30,6 +30,7 @@ #include "gtklabel.h" #include "gtkprivate.h" #include "gtkintl.h" +#include "gtkbuildable.h" #include "gtkalias.h" #define LABEL_PAD 1 @@ -45,9 +46,6 @@ enum { PROP_LABEL_WIDGET }; - -static void gtk_frame_class_init (GtkFrameClass *klass); -static void gtk_frame_init (GtkFrame *frame); static void gtk_frame_set_property (GObject *object, guint param_id, const GValue *value, @@ -76,35 +74,16 @@ static void gtk_frame_compute_child_allocation (GtkFrame *frame, static void gtk_frame_real_compute_child_allocation (GtkFrame *frame, GtkAllocation *child_allocation); -static GtkBinClass *parent_class = NULL; - - -GType -gtk_frame_get_type (void) -{ - static GType frame_type = 0; +/* GtkBuildable */ +static void gtk_frame_buildable_init (GtkBuildableIface *iface); +static void gtk_frame_buildable_add_child (GtkBuildable *buildable, + GtkBuilder *builder, + GObject *child, + const gchar *type); - if (!frame_type) - { - static const GTypeInfo frame_info = - { - sizeof (GtkFrameClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) gtk_frame_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (GtkFrame), - 0, /* n_preallocs */ - (GInstanceInitFunc) gtk_frame_init, - }; - - frame_type = g_type_register_static (GTK_TYPE_BIN, "GtkFrame", - &frame_info, 0); - } - - return frame_type; -} +G_DEFINE_TYPE_WITH_CODE (GtkFrame, gtk_frame, GTK_TYPE_BIN, + G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, + gtk_frame_buildable_init)) static void gtk_frame_class_init (GtkFrameClass *class) @@ -117,8 +96,6 @@ gtk_frame_class_init (GtkFrameClass *class) widget_class = GTK_WIDGET_CLASS (class); container_class = GTK_CONTAINER_CLASS (class); - parent_class = g_type_class_peek_parent (class); - gobject_class->set_property = gtk_frame_set_property; gobject_class->get_property = gtk_frame_get_property; @@ -137,7 +114,7 @@ gtk_frame_class_init (GtkFrameClass *class) P_("The horizontal alignment of the label"), 0.0, 1.0, - 0.5, + 0.0, GTK_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_LABEL_YALIGN, @@ -182,6 +159,26 @@ gtk_frame_class_init (GtkFrameClass *class) class->compute_child_allocation = gtk_frame_real_compute_child_allocation; } +static void +gtk_frame_buildable_init (GtkBuildableIface *iface) +{ + iface->add_child = gtk_frame_buildable_add_child; +} + +static void +gtk_frame_buildable_add_child (GtkBuildable *buildable, + GtkBuilder *builder, + GObject *child, + const gchar *type) +{ + if (type && strcmp (type, "label") == 0) + gtk_frame_set_label_widget (GTK_FRAME (buildable), GTK_WIDGET (child)); + else if (!type) + gtk_container_add (GTK_CONTAINER (buildable), GTK_WIDGET (child)); + else + GTK_BUILDER_WARN_INVALID_CHILD_TYPE (GTK_FRAME (buildable), type); +} + static void gtk_frame_init (GtkFrame *frame) { @@ -287,7 +284,7 @@ gtk_frame_remove (GtkContainer *container, if (frame->label_widget == child) gtk_frame_set_label_widget (frame, NULL); else - GTK_CONTAINER_CLASS (parent_class)->remove (container, child); + GTK_CONTAINER_CLASS (gtk_frame_parent_class)->remove (container, child); } static void @@ -428,7 +425,9 @@ gtk_frame_get_label_widget (GtkFrame *frame) * of the widget. A value of 0.0 represents left alignment; * 1.0 represents right alignment. * @yalign: The y alignment of the label. A value of 0.0 aligns under - * the frame; 1.0 aligns above the frame. + * the frame; 1.0 aligns above the frame. If the values are exactly + * 0.0 or 1.0 the gap in the frame won't be painted because the label + * will be completely above or below the frame. * * Sets the alignment of the frame widget's label. The * default values for a newly created frame are 0.0 and 0.5. @@ -556,20 +555,26 @@ gtk_frame_paint (GtkWidget *widget, else xalign = 1 - frame->label_xalign; - height_extra = MAX (0, child_requisition.height - widget->style->ythickness); - height_extra *= (1 - frame->label_yalign); + height_extra = MAX (0, child_requisition.height - widget->style->ythickness) + - frame->label_yalign * child_requisition.height; y -= height_extra; height += height_extra; x2 = widget->style->xthickness + (frame->child_allocation.width - child_requisition.width - 2 * LABEL_PAD - 2 * LABEL_SIDE_PAD) * xalign + LABEL_SIDE_PAD; - - gtk_paint_shadow_gap (widget->style, widget->window, - widget->state, frame->shadow_type, - area, widget, "frame", - x, y, width, height, - GTK_POS_TOP, - x2, child_requisition.width + 2 * LABEL_PAD); + /* If the label is completely over or under the frame we can omit the gap */ + if (frame->label_yalign == 0.0 || frame->label_yalign == 1.0) + gtk_paint_shadow (widget->style, widget->window, + widget->state, frame->shadow_type, + area, widget, "frame", + x, y, width, height); + else + gtk_paint_shadow_gap (widget->style, widget->window, + widget->state, frame->shadow_type, + area, widget, "frame", + x, y, width, height, + GTK_POS_TOP, + x2, child_requisition.width + 2 * LABEL_PAD); } else gtk_paint_shadow (widget->style, widget->window, @@ -587,7 +592,7 @@ gtk_frame_expose (GtkWidget *widget, { gtk_frame_paint (widget, &event->area); - (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event); + (* GTK_WIDGET_CLASS (gtk_frame_parent_class)->expose_event) (widget, event); } return FALSE; @@ -607,7 +612,7 @@ gtk_frame_size_request (GtkWidget *widget, requisition->width = child_requisition.width + 2 * LABEL_PAD + 2 * LABEL_SIDE_PAD; requisition->height = - MAX (0, child_requisition.height - GTK_WIDGET (widget)->style->ythickness); + MAX (0, child_requisition.height - widget->style->ythickness); } else { @@ -671,9 +676,9 @@ gtk_frame_size_allocate (GtkWidget *widget, child_allocation.x = frame->child_allocation.x + LABEL_SIDE_PAD + (frame->child_allocation.width - child_requisition.width - 2 * LABEL_PAD - 2 * LABEL_SIDE_PAD) * xalign + LABEL_PAD; - child_allocation.width = child_requisition.width; + child_allocation.width = MIN (child_requisition.width, new_allocation.width - 2 * LABEL_PAD - 2 * LABEL_SIDE_PAD); - child_allocation.y = frame->child_allocation.y - child_requisition.height; + child_allocation.y = frame->child_allocation.y - MAX (child_requisition.height, widget->style->ythickness); child_allocation.height = child_requisition.height; gtk_widget_size_allocate (frame->label_widget, &child_allocation);