X-Git-Url: http://git.draconx.ca/gitweb/aspectbin.git/blobdiff_plain/ae774d97cc05fdcc8baf5b916be66f99f4f33a77..8e40543a4d1d56de06f8ab28eb110439f18ff06e:/aspectbin.c diff --git a/aspectbin.c b/aspectbin.c index 339c8ae..77fa519 100644 --- a/aspectbin.c +++ b/aspectbin.c @@ -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)); }