static EelIRect wrap_table_get_content_bounds (const EelWrapTable *wrap_table) { EelIRect content_bounds; guint border; g_assert (EEL_IS_WRAP_TABLE (wrap_table)); content_bounds = eel_gtk_widget_get_bounds (GTK_WIDGET (wrap_table)); border = gtk_container_get_border_width (GTK_CONTAINER (wrap_table)); content_bounds.x0 += border; content_bounds.y0 += border; content_bounds.x1 -= border; content_bounds.y1 -= border; return content_bounds; }
/* GtkWidgetClass methods */ static void eel_wrap_table_size_request (GtkWidget *widget, GtkRequisition *requisition) { EelWrapTable *wrap_table; EelDimensions content_dimensions; g_assert (EEL_IS_WRAP_TABLE (widget)); g_assert (requisition != NULL); wrap_table = EEL_WRAP_TABLE (widget); content_dimensions = wrap_table_get_content_dimensions (wrap_table); /* The -1 tells Satan to use as much space as is available */ requisition->width = -1; requisition->height = content_dimensions.height + gtk_container_get_border_width (GTK_CONTAINER (widget)) * 2; }
/* GtkContainerClass methods */ static void eel_wrap_table_add (GtkContainer *container, GtkWidget *child) { EelWrapTable *wrap_table; GtkWidget *widget; g_assert (container != NULL); g_assert (EEL_IS_WRAP_TABLE (container)); g_assert (GTK_IS_WIDGET (child)); widget = GTK_WIDGET (container); wrap_table = EEL_WRAP_TABLE (container); gtk_widget_set_parent (child, GTK_WIDGET (container)); wrap_table->details->children = g_list_append (wrap_table->details->children, child); if (gtk_widget_get_realized (widget)) { gtk_widget_realize (child); } if (gtk_widget_get_visible (widget) && gtk_widget_get_visible (child)) { if (gtk_widget_get_mapped (widget)) { gtk_widget_map (child); } gtk_widget_queue_resize (child); } if (wrap_table->details->is_scrolled) { g_signal_connect (child, "focus_in_event", G_CALLBACK (wrap_table_child_focus_in), wrap_table); } }
static void eel_wrap_table_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data) { EelWrapTable *wrap_table; GList *node; GList *next; g_assert (EEL_IS_WRAP_TABLE (container)); g_assert (callback != NULL); wrap_table = EEL_WRAP_TABLE (container);; for (node = wrap_table->details->children; node != NULL; node = next) { g_assert (GTK_IS_WIDGET (node->data)); next = node->next; (* callback) (GTK_WIDGET (node->data), callback_data); } }
static void eel_wrap_table_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { EelWrapTable *wrap_table; g_assert (EEL_IS_WRAP_TABLE (object)); wrap_table = EEL_WRAP_TABLE (object); switch (property_id) { case PROP_X_SPACING: eel_wrap_table_set_x_spacing (wrap_table, g_value_get_uint (value)); break; case PROP_Y_SPACING: eel_wrap_table_set_y_spacing (wrap_table, g_value_get_uint (value)); break; case PROP_X_JUSTIFICATION: eel_wrap_table_set_x_justification (wrap_table, g_value_get_enum (value)); break; case PROP_Y_JUSTIFICATION: eel_wrap_table_set_y_justification (wrap_table, g_value_get_enum (value)); break; case PROP_HOMOGENEOUS: eel_wrap_table_set_homogeneous (wrap_table, g_value_get_boolean (value)); break; default: g_assert_not_reached (); } }
/** * eel_wrap_table_reorder_child: * @wrap_table: A EelWrapTable. * @child: Child to reorder. * @position: New position to put child at. * * Reorder the given chilren into the given position. * * Position is interpreted as follows: * * 0 - Place child at start of table. * -1 - Place child at end of table. * n - Place child at nth position. Count starts at 0. */ void eel_wrap_table_reorder_child (EelWrapTable *wrap_table, GtkWidget *child, int position) { GList *node; gboolean found_child = FALSE; g_return_if_fail (EEL_IS_WRAP_TABLE (wrap_table)); g_return_if_fail (g_list_length (wrap_table->details->children) > 0); if (position == -1) { position = g_list_length (wrap_table->details->children) - 1; } g_return_if_fail (position >= 0); g_return_if_fail ((guint) position < g_list_length (wrap_table->details->children)); for (node = wrap_table->details->children; node != NULL; node = node->next) { GtkWidget *next_child; next_child = node->data; if (next_child == child) { g_assert (found_child == FALSE); found_child = TRUE; } } g_return_if_fail (found_child); wrap_table->details->children = g_list_remove (wrap_table->details->children, child); wrap_table->details->children = g_list_insert (wrap_table->details->children, child, position); gtk_widget_queue_resize (GTK_WIDGET (wrap_table)); }
static int eel_wrap_table_expose_event (GtkWidget *widget, GdkEventExpose *event) { EelWrapTable *wrap_table; GList *iterator; g_assert (EEL_IS_WRAP_TABLE (widget)); g_assert (gtk_widget_get_realized (widget)); g_assert (event != NULL); wrap_table = EEL_WRAP_TABLE (widget); for (iterator = wrap_table->details->children; iterator; iterator = iterator->next) { g_assert (GTK_IS_WIDGET (iterator->data)); gtk_container_propagate_expose (GTK_CONTAINER (widget), GTK_WIDGET (iterator->data), event); } return FALSE; }
static void eel_wrap_table_unmap (GtkWidget *widget) { EelWrapTable *wrap_table; GList *iterator; g_assert (EEL_IS_WRAP_TABLE (widget)); wrap_table = EEL_WRAP_TABLE (widget); gtk_widget_set_mapped (widget, FALSE); for (iterator = wrap_table->details->children; iterator; iterator = iterator->next) { GtkWidget *item; item = iterator->data; if (gtk_widget_get_visible (item) && gtk_widget_get_mapped (item)) { gtk_widget_unmap (item); } } }
static void wrap_table_layout (EelWrapTable *wrap_table) { GList *iterator; EelIPoint pos; EelDimensions max_child_dimensions; EelIRect content_bounds; guint num_cols; GtkAllocation allocation; g_assert (EEL_IS_WRAP_TABLE (wrap_table)); max_child_dimensions = wrap_table_get_max_child_dimensions (wrap_table); max_child_dimensions.width = MAX (max_child_dimensions.width, 1); max_child_dimensions.height = MAX (max_child_dimensions.height, 1); content_bounds = wrap_table_get_content_bounds (wrap_table); pos.x = content_bounds.x0; pos.y = content_bounds.y0; gtk_widget_get_allocation (GTK_WIDGET (wrap_table), &allocation); num_cols = wrap_table_get_num_fitting (allocation.width - gtk_container_get_border_width (GTK_CONTAINER (wrap_table)) * 2, wrap_table->details->x_spacing, max_child_dimensions.width); if (num_cols != wrap_table->details->cols) { wrap_table->details->cols = num_cols; gtk_widget_queue_resize (GTK_WIDGET (wrap_table)); return; } for (iterator = wrap_table->details->children; iterator; iterator = iterator->next) { GtkWidget *item; item = iterator->data; if (gtk_widget_get_visible (item)) { GtkAllocation item_allocation; if (wrap_table->details->homogeneous) { item_allocation.x = pos.x; item_allocation.y = pos.y; item_allocation.width = max_child_dimensions.width; item_allocation.height = max_child_dimensions.height; if ((pos.x + max_child_dimensions.width) > content_bounds.x1) { pos.x = content_bounds.x0 + wrap_table->details->x_spacing + max_child_dimensions.width; pos.y += (max_child_dimensions.height + wrap_table->details->y_spacing); item_allocation.x = content_bounds.x0; item_allocation.y = pos.y; } else { pos.x += (wrap_table->details->x_spacing + max_child_dimensions.width); } } else { GtkRequisition item_requisition; gtk_widget_get_preferred_size (item, &item_requisition, NULL); item_allocation.x = pos.x; item_allocation.y = pos.y; item_allocation.width = item_requisition.width; item_allocation.height = item_requisition.height; g_assert (item_allocation.width <= max_child_dimensions.width); g_assert (item_allocation.height <= max_child_dimensions.height); if ((pos.x + max_child_dimensions.width) > content_bounds.x1) { pos.x = content_bounds.x0 + wrap_table->details->x_spacing + max_child_dimensions.width; pos.y += (max_child_dimensions.height + wrap_table->details->y_spacing); item_allocation.x = content_bounds.x0; item_allocation.y = pos.y; } else { pos.x += (wrap_table->details->x_spacing + max_child_dimensions.width); } switch (wrap_table->details->x_justification) { case EEL_JUSTIFICATION_MIDDLE: item_allocation.x += (max_child_dimensions.width - (int) item_allocation.width) / 2; break; case EEL_JUSTIFICATION_END: item_allocation.x += (max_child_dimensions.width - (int) item_allocation.width); break; default: break; } switch (wrap_table->details->y_justification) { case EEL_JUSTIFICATION_MIDDLE: item_allocation.y += (max_child_dimensions.height - (int) item_allocation.height) / 2; break; case EEL_JUSTIFICATION_END: item_allocation.y += (max_child_dimensions.height - (int) item_allocation.height); break; default: break; } } gtk_widget_size_allocate (item, &item_allocation); } } }