libgimpwidgets: remove all size negotiation/allocation code from GimpFrame

Let GtkFrame handle things and simply set "spacing" and "indent" as
left and top margins on the frame's child.

This fixes all tests \o/
This commit is contained in:
Michael Natterer 2018-05-30 00:37:15 +02:00
parent 23a718c1dc
commit 0f484ed3d5
1 changed files with 40 additions and 185 deletions

View File

@ -23,11 +23,14 @@
#include <string.h>
#include <babl/babl.h>
#include <gtk/gtk.h>
#include "gimpwidgetstypes.h"
#include "gimpframe.h"
#include "gimpwidgetsutils.h"
/**
@ -47,22 +50,13 @@
#define GIMP_FRAME_IN_EXPANDER_KEY "gimp-frame-in-expander"
static void gimp_frame_get_preferred_width (GtkWidget *widget,
gint *minimum_width,
gint *natural_width);
static void gimp_frame_get_preferred_height (GtkWidget *widget,
gint *minimum_height,
gint *natural_height);
static void gimp_frame_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static void gimp_frame_style_updated (GtkWidget *widget);
static gboolean gimp_frame_draw (GtkWidget *widget,
cairo_t *cr);
static void gimp_frame_child_allocate (GtkFrame *frame,
GtkAllocation *allocation);
static void gimp_frame_label_widget_notify (GtkFrame *frame);
static gint gimp_frame_get_indent (GtkWidget *widget);
static gint gimp_frame_get_label_spacing (GtkFrame *frame);
static void gimp_frame_label_widget_notify (GimpFrame *frame);
static void gimp_frame_child_notify (GimpFrame *frame);
static gint gimp_frame_get_indent (GimpFrame *frame);
static gint gimp_frame_get_label_spacing (GimpFrame *frame);
G_DEFINE_TYPE (GimpFrame, gimp_frame, GTK_TYPE_FRAME)
@ -75,11 +69,8 @@ gimp_frame_class_init (GimpFrameClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
widget_class->get_preferred_width = gimp_frame_get_preferred_width;
widget_class->get_preferred_height = gimp_frame_get_preferred_height;
widget_class->size_allocate = gimp_frame_size_allocate;
widget_class->style_updated = gimp_frame_style_updated;
widget_class->draw = gimp_frame_draw;
widget_class->style_updated = gimp_frame_style_updated;
widget_class->draw = gimp_frame_draw;
gtk_widget_class_install_style_property (widget_class,
g_param_spec_boolean ("label-bold",
@ -104,147 +95,9 @@ gimp_frame_init (GimpFrame *frame)
g_signal_connect (frame, "notify::label-widget",
G_CALLBACK (gimp_frame_label_widget_notify),
NULL);
}
static void
gimp_frame_size_request (GtkWidget *widget,
GtkRequisition *requisition)
{
GtkFrame *frame = GTK_FRAME (widget);
GtkWidget *label_widget = gtk_frame_get_label_widget (frame);
GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget));
GtkRequisition child_requisition;
gint border_width;
if (label_widget && gtk_widget_get_visible (label_widget))
{
gtk_widget_get_preferred_size (label_widget, requisition, NULL);
}
else
{
requisition->width = 0;
requisition->height = 0;
}
requisition->height += gimp_frame_get_label_spacing (frame);
if (child && gtk_widget_get_visible (child))
{
gint indent = gimp_frame_get_indent (widget);
gtk_widget_get_preferred_size (child, &child_requisition, NULL);
requisition->width = MAX (requisition->width,
child_requisition.width + indent);
requisition->height += child_requisition.height;
}
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
requisition->width += 2 * border_width;
requisition->height += 2 * border_width;
}
static void
gimp_frame_get_preferred_width (GtkWidget *widget,
gint *minimum_width,
gint *natural_width)
{
GtkRequisition requisition;
gimp_frame_size_request (widget, &requisition);
*minimum_width = *natural_width = requisition.width;
}
static void
gimp_frame_get_preferred_height (GtkWidget *widget,
gint *minimum_height,
gint *natural_height)
{
GtkRequisition requisition;
gimp_frame_size_request (widget, &requisition);
*minimum_height = *natural_height = requisition.height;
}
static void
gimp_frame_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkFrame *frame = GTK_FRAME (widget);
GtkWidget *label_widget = gtk_frame_get_label_widget (frame);
GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget));
GtkAllocation child_allocation;
/* must not chain up here */
gtk_widget_set_allocation (widget, allocation);
gimp_frame_child_allocate (frame, &child_allocation);
if (child && gtk_widget_get_visible (child))
gtk_widget_size_allocate (child, &child_allocation);
if (label_widget && gtk_widget_get_visible (label_widget))
{
GtkAllocation label_allocation;
GtkRequisition label_requisition;
gint border_width;
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
gtk_widget_get_preferred_size (label_widget, &label_requisition, NULL);
label_allocation.x = allocation->x + border_width;
label_allocation.y = allocation->y + border_width;
label_allocation.width = MAX (label_requisition.width,
allocation->width - 2 * border_width);
label_allocation.height = label_requisition.height;
gtk_widget_size_allocate (label_widget, &label_allocation);
}
}
static void
gimp_frame_child_allocate (GtkFrame *frame,
GtkAllocation *child_allocation)
{
GtkWidget *widget = GTK_WIDGET (frame);
GtkWidget *label_widget = gtk_frame_get_label_widget (frame);
GtkAllocation allocation;
gint border_width;
gint spacing = 0;
gint indent = gimp_frame_get_indent (widget);
gtk_widget_get_allocation (widget, &allocation);
border_width = gtk_container_get_border_width (GTK_CONTAINER (frame));
if (label_widget && gtk_widget_get_visible (label_widget))
{
GtkRequisition child_requisition;
gtk_widget_get_preferred_size (label_widget, &child_requisition, NULL);
spacing += child_requisition.height;
}
spacing += gimp_frame_get_label_spacing (frame);
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
child_allocation->x = border_width + indent;
else
child_allocation->x = border_width;
child_allocation->y = border_width + spacing;
child_allocation->width = MAX (1,
allocation.width - 2 * border_width - indent);
child_allocation->height = MAX (1,
allocation.height -
child_allocation->y - border_width);
child_allocation->x += allocation.x;
child_allocation->y += allocation.y;
g_signal_connect (frame, "notify::child",
G_CALLBACK (gimp_frame_child_notify),
NULL);
}
static void
@ -255,8 +108,8 @@ gimp_frame_style_updated (GtkWidget *widget)
/* font changes invalidate the indentation */
g_object_set_data (G_OBJECT (widget), GIMP_FRAME_INDENT_KEY, NULL);
/* for "label_bold" */
gimp_frame_label_widget_notify (GTK_FRAME (widget));
gimp_frame_label_widget_notify (GIMP_FRAME (widget));
gimp_frame_child_notify (GIMP_FRAME (widget));
}
static gboolean
@ -269,9 +122,9 @@ gimp_frame_draw (GtkWidget *widget,
}
static void
gimp_frame_label_widget_notify (GtkFrame *frame)
gimp_frame_label_widget_notify (GimpFrame *frame)
{
GtkWidget *label_widget = gtk_frame_get_label_widget (frame);
GtkWidget *label_widget = gtk_frame_get_label_widget (GTK_FRAME (frame));
if (label_widget)
{
@ -283,7 +136,7 @@ gimp_frame_label_widget_notify (GtkFrame *frame)
label = GTK_LABEL (label_widget);
gtk_frame_get_label_align (frame, &xalign, &yalign);
gtk_frame_get_label_align (GTK_FRAME (frame), &xalign, &yalign);
gtk_label_set_xalign (GTK_LABEL (label), xalign);
gtk_label_set_yalign (GTK_LABEL (label), yalign);
}
@ -297,30 +150,32 @@ gimp_frame_label_widget_notify (GtkFrame *frame)
if (label)
{
PangoAttrList *attrs = pango_attr_list_new ();
PangoAttribute *attr;
gboolean bold;
gboolean bold;
gtk_widget_style_get (GTK_WIDGET (frame), "label_bold", &bold, NULL);
gtk_widget_style_get (GTK_WIDGET (frame),
"label-bold", &bold,
NULL);
attr = pango_attr_weight_new (bold ?
PANGO_WEIGHT_BOLD :
PANGO_WEIGHT_NORMAL);
attr->start_index = 0;
attr->end_index = -1;
pango_attr_list_insert (attrs, attr);
gtk_label_set_attributes (label, attrs);
pango_attr_list_unref (attrs);
gimp_label_set_attributes (label,
PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD,
-1);
}
}
}
static gint
gimp_frame_get_indent (GtkWidget *widget)
static void
gimp_frame_child_notify (GimpFrame *frame)
{
gint width = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
GtkWidget *child = gtk_bin_get_child (GTK_BIN (frame));
gtk_widget_set_margin_start (child, gimp_frame_get_indent (frame));
gtk_widget_set_margin_top (child, gimp_frame_get_label_spacing (frame));
}
static gint
gimp_frame_get_indent (GimpFrame *frame)
{
gint width = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (frame),
GIMP_FRAME_INDENT_KEY));
if (! width)
@ -328,11 +183,11 @@ gimp_frame_get_indent (GtkWidget *widget)
PangoLayout *layout;
/* the HIG suggests to use four spaces so do just that */
layout = gtk_widget_create_pango_layout (widget, " ");
layout = gtk_widget_create_pango_layout (GTK_WIDGET (frame), " ");
pango_layout_get_pixel_size (layout, &width, NULL);
g_object_unref (layout);
g_object_set_data (G_OBJECT (widget),
g_object_set_data (G_OBJECT (frame),
GIMP_FRAME_INDENT_KEY, GINT_TO_POINTER (width));
}
@ -340,9 +195,9 @@ gimp_frame_get_indent (GtkWidget *widget)
}
static gint
gimp_frame_get_label_spacing (GtkFrame *frame)
gimp_frame_get_label_spacing (GimpFrame *frame)
{
GtkWidget *label_widget = gtk_frame_get_label_widget (frame);
GtkWidget *label_widget = gtk_frame_get_label_widget (GTK_FRAME (frame));
gint spacing = 0;
if ((label_widget && gtk_widget_get_visible (label_widget)) ||