From 4b6acfc09d3af7822977aedd04dfadd47aa210d9 Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Sat, 14 Mar 2009 20:28:41 -0400 Subject: [PATCH] Make AspectBin a direct subclass of container. --- aspectbin.c | 84 +++++++++++++++++++++++++++++++---------------------- aspectbin.h | 7 +++-- main.c | 5 ++-- 3 files changed, 56 insertions(+), 40 deletions(-) diff --git a/aspectbin.c b/aspectbin.c index 77fa519..1b2af29 100644 --- a/aspectbin.c +++ b/aspectbin.c @@ -6,14 +6,17 @@ static void aspect_bin_size_allocate(GtkWidget *, GtkAllocation *); static void aspect_bin_remove(GtkContainer *, GtkWidget *); static void aspect_bin_forall(GtkContainer *, gboolean, GtkCallback, gpointer); -G_DEFINE_TYPE(AspectBin, aspect_bin, GTK_TYPE_BIN) +G_DEFINE_TYPE(AspectBin, aspect_bin, GTK_TYPE_CONTAINER) static void aspect_bin_init(AspectBin *abin) { + GTK_WIDGET_SET_FLAGS(abin, GTK_NO_WINDOW); + abin->body = NULL; + abin->side = NULL; abin->ratio = 1; - abin->constrain = FALSE; abin->align = 0; + abin->constrain = FALSE; } static void aspect_bin_class_init(AspectBinClass *class) @@ -38,10 +41,9 @@ static void aspect_bin_remove(GtkContainer *container, GtkWidget *child) AspectBin *abin = ASPECT_BIN(container); if (abin->body == child) { - aspect_bin_set_body_widget(abin, NULL, 1); - } else { - GTK_CONTAINER_CLASS(aspect_bin_parent_class)->remove - (container, child); + aspect_bin_set_body(abin, NULL, 1); + } else if (abin->side == child) { + aspect_bin_set_side(abin, NULL); } } @@ -51,24 +53,22 @@ static void aspect_bin_forall(GtkContainer *container, gpointer callback_data) { AspectBin *abin = ASPECT_BIN(container); - GtkBin *bin = GTK_BIN(container); + g_return_if_fail(callback != NULL); - if (bin->child) - callback(bin->child, callback_data); - if (abin->body) callback(abin->body, callback_data); + if (abin->side) + callback(abin->side, callback_data); } static void aspect_bin_size_request(GtkWidget *widget, GtkRequisition *requisition) { AspectBin *abin = ASPECT_BIN(widget); - GtkBin *bin = GTK_BIN(widget); GtkRequisition creq = {0}, areq = {0}; - if (bin->child && GTK_WIDGET_VISIBLE(bin->child)) { - gtk_widget_size_request(bin->child, &creq); + if (abin->side && GTK_WIDGET_VISIBLE(abin->side)) { + gtk_widget_size_request(abin->side, &creq); } if (abin->body && GTK_WIDGET_VISIBLE(abin->body)) { @@ -92,11 +92,10 @@ static void aspect_bin_size_allocate(GtkWidget *widget, GtkAllocation *allocation) { AspectBin *abin = ASPECT_BIN(widget); - GtkBin *bin = GTK_BIN(widget); GtkRequisition creq = {0}; GtkAllocation csize = {0}, asize = {0}; - - /* First find the best fit for the constrained child. */ + + /* First find the best fit for the body. */ if (abin->body && GTK_WIDGET_VISIBLE(abin->body)) { asize.height = allocation->height; asize.width = asize.height * abin->ratio + 0.5; @@ -107,9 +106,9 @@ 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); + /* Now try to fit the side. */ + if (abin->side && GTK_WIDGET_VISIBLE(abin->side)) { + gtk_widget_get_child_requisition(abin->side, &creq); if (allocation->width - asize.width < creq.width) { /* It didn't fit, squish the constrained guy. */ @@ -128,35 +127,50 @@ aspect_bin_size_allocate(GtkWidget *widget, GtkAllocation *allocation) 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->body) gtk_widget_size_allocate(abin->body, &asize); + if (abin->side) + gtk_widget_size_allocate(abin->side, &csize); } -void -aspect_bin_set_body_widget(AspectBin *abin, GtkWidget *widget, gfloat ratio) +static gboolean +set_widget(GtkWidget **dest, GtkWidget *parent, GtkWidget *widget) { gboolean need_resize = FALSE; - 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 (*dest == widget) + return FALSE; - if (abin->body == widget) - return; - - if (abin->body) { - need_resize |= GTK_WIDGET_VISIBLE(abin->body); - gtk_widget_unparent(abin->body); + if (*dest) { + need_resize |= GTK_WIDGET_VISIBLE(*dest); + gtk_widget_unparent(*dest); } - abin->body = widget; + *dest = widget; if (widget) { - gtk_widget_set_parent(widget, GTK_WIDGET(abin)); + gtk_widget_set_parent(widget, parent); need_resize |= GTK_WIDGET_VISIBLE(widget); } - if (GTK_WIDGET_VISIBLE(abin) && need_resize) + return GTK_WIDGET_VISIBLE(parent) && need_resize; +} + +void aspect_bin_set_body(AspectBin *abin, GtkWidget *widget, gfloat ratio) +{ + 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 (set_widget(&abin->body, GTK_WIDGET(abin), widget)) + gtk_widget_queue_resize(GTK_WIDGET(abin)); +} + +void aspect_bin_set_side(AspectBin *abin, GtkWidget *widget) +{ + 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 (set_widget(&abin->side, GTK_WIDGET(abin), widget)) gtk_widget_queue_resize(GTK_WIDGET(abin)); } diff --git a/aspectbin.h b/aspectbin.h index 34bc969..b4ce50d 100644 --- a/aspectbin.h +++ b/aspectbin.h @@ -15,9 +15,9 @@ typedef struct AspectBin AspectBin; typedef struct AspectBinClass AspectBinClass; struct AspectBin { - GtkBin bin; + GtkContainer parent; - GtkWidget *body; + GtkWidget *body, *side; gfloat ratio; gfloat align; @@ -30,6 +30,7 @@ struct AspectBinClass { GType aspect_bin_get_type(void); GtkWidget *aspect_bin_new(void); -void aspect_bin_set_body_widget(AspectBin *, GtkWidget *, gfloat); +void aspect_bin_set_body(AspectBin *, GtkWidget *, gfloat); +void aspect_bin_set_side(AspectBin *, GtkWidget *); #endif diff --git a/main.c b/main.c index 0485862..947ac9b 100644 --- a/main.c +++ b/main.c @@ -16,12 +16,13 @@ int main(int argc, char **argv) aspectbin = aspect_bin_new(); button1 = gtk_button_new_with_label("Square"); button2 = gtk_button_new_with_label("Rectangle"); - aspect_bin_set_body_widget(ASPECT_BIN(aspectbin), button1, 1); + + aspect_bin_set_body(ASPECT_BIN(aspectbin), button1, 1); + aspect_bin_set_side(ASPECT_BIN(aspectbin), button2); ASPECT_BIN(aspectbin)->constrain = TRUE; ASPECT_BIN(aspectbin)->align = 0.5; - gtk_container_add(GTK_CONTAINER(aspectbin), button2); gtk_container_add(GTK_CONTAINER(window), aspectbin); gtk_widget_show_all(window); -- 2.43.0