]> git.draconx.ca Git - aspectbin.git/blobdiff - aspectbin.c
Rename the "child" member to "body" for less confusion.
[aspectbin.git] / aspectbin.c
index 339c8aec916a7ca610d71b827c664c7d375f6821..77fa5196ae3820a4e1e31fb1096ba0a04ddf85e2 100644 (file)
@@ -8,16 +8,18 @@ static void aspect_bin_forall(GtkContainer *, gboolean, GtkCallback, gpointer);
 
 G_DEFINE_TYPE(AspectBin, aspect_bin, GTK_TYPE_BIN)
 
-static void aspect_bin_init(AspectBin *ab)
+static void aspect_bin_init(AspectBin *abin)
 {
-       ab->child = NULL;
-       ab->ratio = 1;
+       abin->body      = NULL;
+       abin->ratio     = 1;
+       abin->constrain = FALSE;
+       abin->align     = 0;
 }
 
-static void aspect_bin_class_init(AspectBinClass *abc)
+static void aspect_bin_class_init(AspectBinClass *class)
 {
-       GtkWidgetClass    *widget_class    = GTK_WIDGET_CLASS(abc);
-       GtkContainerClass *container_class = GTK_CONTAINER_CLASS(abc);
+       GtkWidgetClass    *widget_class    = GTK_WIDGET_CLASS(class);
+       GtkContainerClass *container_class = GTK_CONTAINER_CLASS(class);
 
        widget_class->size_request  = aspect_bin_size_request;
        widget_class->size_allocate = aspect_bin_size_allocate;
@@ -35,7 +37,7 @@ static void aspect_bin_remove(GtkContainer *container, GtkWidget *child)
 {
        AspectBin *abin = ASPECT_BIN(container);
 
-       if (abin->child == child) {
+       if (abin->body == child) {
                aspect_bin_set_body_widget(abin, NULL, 1);
        } else {
                GTK_CONTAINER_CLASS(aspect_bin_parent_class)->remove
@@ -54,8 +56,8 @@ static void aspect_bin_forall(GtkContainer *container,
        if (bin->child)
                callback(bin->child, callback_data);
        
-       if (abin->child)
-               callback(abin->child, callback_data);
+       if (abin->body)
+               callback(abin->body, callback_data);
 }
 
 static void
@@ -69,9 +71,9 @@ aspect_bin_size_request(GtkWidget *widget, GtkRequisition *requisition)
                gtk_widget_size_request(bin->child, &creq);
        }
 
-       if (abin->child && GTK_WIDGET_VISIBLE(abin->child)) {
+       if (abin->body && GTK_WIDGET_VISIBLE(abin->body)) {
                int wtmp, htmp;
-               gtk_widget_size_request(abin->child, &areq);
+               gtk_widget_size_request(abin->body, &areq);
                wtmp = areq.height * abin->ratio + 0.5;
                htmp = areq.width  / abin->ratio + 0.5;
 
@@ -94,7 +96,8 @@ aspect_bin_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
        GtkRequisition creq = {0};
        GtkAllocation csize = {0}, asize = {0};
        
-       if (abin->child && GTK_WIDGET_VISIBLE(abin->child)) {
+       /* First find the best fit for the constrained child. */
+       if (abin->body && GTK_WIDGET_VISIBLE(abin->body)) {
                asize.height = allocation->height;
                asize.width  = asize.height * abin->ratio + 0.5;
 
@@ -104,49 +107,56 @@ aspect_bin_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
                }
        }
 
+       /* Now try to fit the other child. */
        if (bin->child && GTK_WIDGET_VISIBLE(bin->child)) {
                gtk_widget_get_child_requisition(bin->child, &creq);
 
                if (allocation->width - asize.width < creq.width) {
+                       /* It didn't fit, squish the constrained guy. */
                        asize.width  = allocation->width - creq.width;
                        asize.height = asize.width / abin->ratio + 0.5;
                }
 
-               csize.width = allocation->width - asize.width;
-               csize.height = allocation->height;
+               csize.width  = allocation->width - asize.width;
+               csize.height = MIN(allocation->height, creq.height);
+               if (abin->constrain) {
+                       csize.height = MAX(csize.height, asize.height);
+               }
                csize.x = asize.width;
-               csize.y = 0;
        }
 
+       csize.y = (allocation->height - csize.height) * abin->align + 0.5;
+       asize.y = (allocation->height - asize.height) * abin->align + 0.5;
+
        if (bin->child)
                gtk_widget_size_allocate(bin->child, &csize);
-       if (abin->child)
-               gtk_widget_size_allocate(abin->child, &asize);
+       if (abin->body)
+               gtk_widget_size_allocate(abin->body, &asize);
 }
 
 void
-aspect_bin_set_body_widget(AspectBin *ab, GtkWidget *widget, gfloat ratio)
+aspect_bin_set_body_widget(AspectBin *abin, GtkWidget *widget, gfloat ratio)
 {
        gboolean need_resize = FALSE;
 
-       g_return_if_fail(IS_ASPECT_BIN(ab));
+       g_return_if_fail(IS_ASPECT_BIN(abin));
        g_return_if_fail(widget == NULL || GTK_IS_WIDGET(widget));
        g_return_if_fail(widget == NULL || widget->parent == NULL);
 
-       if (ab->child == widget)
+       if (abin->body == widget)
                return;
        
-       if (ab->child) {
-               need_resize |= GTK_WIDGET_VISIBLE(ab->child);
-               gtk_widget_unparent(ab->child);
+       if (abin->body) {
+               need_resize |= GTK_WIDGET_VISIBLE(abin->body);
+               gtk_widget_unparent(abin->body);
        }
 
-       ab->child = widget;
+       abin->body = widget;
        if (widget) {
-               gtk_widget_set_parent(widget, GTK_WIDGET(ab));
+               gtk_widget_set_parent(widget, GTK_WIDGET(abin));
                need_resize |= GTK_WIDGET_VISIBLE(widget);
        }
 
-       if (GTK_WIDGET_VISIBLE(ab) && need_resize)
-               gtk_widget_queue_resize(GTK_WIDGET(ab));
+       if (GTK_WIDGET_VISIBLE(abin) && need_resize)
+               gtk_widget_queue_resize(GTK_WIDGET(abin));
 }