4 static void aspect_bin_size_request(GtkWidget *, GtkRequisition *);
5 static void aspect_bin_size_allocate(GtkWidget *, GtkAllocation *);
6 static void aspect_bin_remove(GtkContainer *, GtkWidget *);
7 static void aspect_bin_forall(GtkContainer *, gboolean, GtkCallback, gpointer);
9 G_DEFINE_TYPE(AspectBin, aspect_bin, GTK_TYPE_BIN)
11 static void aspect_bin_init(AspectBin *ab)
17 static void aspect_bin_class_init(AspectBinClass *abc)
19 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(abc);
20 GtkContainerClass *container_class = GTK_CONTAINER_CLASS(abc);
22 widget_class->size_request = aspect_bin_size_request;
23 widget_class->size_allocate = aspect_bin_size_allocate;
25 container_class->remove = aspect_bin_remove;
26 container_class->forall = aspect_bin_forall;
29 GtkWidget *aspect_bin_new(void)
31 return GTK_WIDGET(g_object_new(ASPECT_BIN_TYPE, NULL));
34 static void aspect_bin_remove(GtkContainer *container, GtkWidget *child)
36 AspectBin *abin = ASPECT_BIN(container);
38 if (abin->child == child) {
39 aspect_bin_set_body_widget(abin, NULL, 1);
41 GTK_CONTAINER_CLASS(aspect_bin_parent_class)->remove
46 static void aspect_bin_forall(GtkContainer *container,
47 gboolean include_internals,
49 gpointer callback_data)
51 AspectBin *abin = ASPECT_BIN(container);
52 GtkBin *bin = GTK_BIN(container);
55 callback(bin->child, callback_data);
58 callback(abin->child, callback_data);
62 aspect_bin_size_request(GtkWidget *widget, GtkRequisition *requisition)
64 AspectBin *abin = ASPECT_BIN(widget);
65 GtkBin *bin = GTK_BIN(widget);
66 GtkRequisition creq = {0}, areq = {0};
68 if (bin->child && GTK_WIDGET_VISIBLE(bin->child)) {
69 gtk_widget_size_request(bin->child, &creq);
72 if (abin->child && GTK_WIDGET_VISIBLE(abin->child)) {
74 gtk_widget_size_request(abin->child, &areq);
75 wtmp = areq.height * abin->ratio + 0.5;
76 htmp = areq.width / abin->ratio + 0.5;
78 if (wtmp > areq.width) {
85 requisition->width = areq.width + creq.width;
86 requisition->height = MAX(areq.height, creq.height);
90 aspect_bin_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
92 AspectBin *abin = ASPECT_BIN(widget);
93 GtkBin *bin = GTK_BIN(widget);
94 GtkRequisition creq = {0};
95 GtkAllocation csize = {0}, asize = {0};
97 if (abin->child && GTK_WIDGET_VISIBLE(abin->child)) {
98 asize.height = allocation->height;
99 asize.width = asize.height * abin->ratio + 0.5;
101 if (asize.width > allocation->width) {
102 asize.width = allocation->width;
103 asize.height = asize.width / abin->ratio + 0.5;
107 if (bin->child && GTK_WIDGET_VISIBLE(bin->child)) {
108 gtk_widget_get_child_requisition(bin->child, &creq);
110 if (allocation->width - asize.width < creq.width) {
111 asize.width = allocation->width - creq.width;
112 asize.height = asize.width / abin->ratio + 0.5;
115 csize.width = allocation->width - asize.width;
116 csize.height = allocation->height;
117 csize.x = asize.width;
122 gtk_widget_size_allocate(bin->child, &csize);
124 gtk_widget_size_allocate(abin->child, &asize);
128 aspect_bin_set_body_widget(AspectBin *ab, GtkWidget *widget, gfloat ratio)
130 gboolean need_resize = FALSE;
132 g_return_if_fail(IS_ASPECT_BIN(ab));
133 g_return_if_fail(widget == NULL || GTK_IS_WIDGET(widget));
134 g_return_if_fail(widget == NULL || widget->parent == NULL);
136 if (ab->child == widget)
140 need_resize |= GTK_WIDGET_VISIBLE(ab->child);
141 gtk_widget_unparent(ab->child);
146 gtk_widget_set_parent(widget, GTK_WIDGET(ab));
147 need_resize |= GTK_WIDGET_VISIBLE(widget);
150 if (GTK_WIDGET_VISIBLE(ab) && need_resize)
151 gtk_widget_queue_resize(GTK_WIDGET(ab));