Hello,
I’m currently helping with the development of a simulator that requires large amounts of data to be displayed in the form of tables. The tables themselves are GtkColumnViews that contain boxes on each column. The creation of said boxes is handled by a GtkListItemFactory and a setup callback, and the data updates are handled by a bind callback.
GtkListItemFactory *factory = gtk_signal_list_item_factory_new();
g_signal_connect(factory, "setup", G_CALLBACK(setup_cb),NULL);
g_signal_connect(factory, "bind", G_CALLBACK(bind_address_cb),NULL);
GtkColumnViewColumn *column = gtk_column_view_column_new(M_ADDR, factory);
gtk_column_view_append_column (GTK_COLUMN_VIEW (column_view), column);
g_object_unref (column);
The setup callback:
static void setup_cb(GtkSignalListItemFactory *factory, GObject *listitem) {
GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
GtkWidget *label = gtk_label_new(NULL);
// The box is compacted with some CSS
g_object_set(label,"height-request", 5, NULL);
apply_css(box, CSS_COMPACT, CSS_COMPACT_R);
// The box is assigned both style providers (Read and Write)
GdkDisplay *display = gtk_widget_get_display(box);
gtk_style_context_add_provider_for_display(
display,
GTK_STYLE_PROVIDER(write_provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION
);
gtk_style_context_add_provider_for_display(
display,
GTK_STYLE_PROVIDER(read_provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION
);
gtk_box_append(GTK_BOX(box), label);
gtk_list_item_set_child(GTK_LIST_ITEM(listitem), box);
}
The bind callback:
static void bind_address_cb(GtkSignalListItemFactory *factory, GtkListItem *listitem) {
// The elements of the cell get created
GtkWidget *box = gtk_list_item_get_child(listitem);
GtkWidget *label = gtk_widget_get_first_child(box);
MemoryLine *item = gtk_list_item_get_item(GTK_LIST_ITEM(listitem));
// A pointer to the widget is saved
item->widget[ADDRESS] = box;
// A string with the address gets created
char *string = g_strdup_printf("0x%x", item->address);
gtk_label_set_text(GTK_LABEL(label), string);
g_free(string);
// The color of the background is set to be the same as the item's.
if (item->color_changed[ADDRESS] == TRUE && item->color != NULL) {
set_memory_widget_background_color(box, item, ADDRESS);
}
}
Some of the rows have CSS styling applied to them by the following GtkCssProvider:
char *css = g_strdup_printf(CSS_READ_R, READ_COLOR); // The color is calculated
read_provider = gtk_css_provider_new();
gtk_css_provider_load_from_string(read_provider, css);
When applying some CSS to some of the rows at the top, the same CSS also gets applied to some of the ones near the bottom. When the table is twice as large, it gets applied to some elements in the middle and some in the bottom as well. This is the function that applies CSS to a certain cell of the table:
static void set_memory_widget_background_color(GtkWidget *widget, MemoryLine *item, int column) {
// The previous CSS class is removed from the item
gtk_widget_remove_css_class(item->widget[column], CSS_READ);
gtk_widget_remove_css_class(item->widget[column], CSS_WRITE);
// If the item has been read
if (g_strcmp0(item->color, READ_COLOR) == 0) {
// The read selector is assigned to the widget
gtk_widget_add_css_class(widget, CSS_READ);
} else if (g_strcmp0(item->color, WRITE_COLOR) == 0) {
// The write selector is assigned to the widget
gtk_widget_add_css_class(widget, CSS_WRITE);
}
item->color_changed[column] = FALSE;
}
After checking with GDB, both rows contain pointers to the same box, so when the CSS is applied to the first one, it is also applied to the rows that have the same pointers at the bottom.
Is this some memory saving feature ? If so, is there a way to disable it ?
Thanks in advance.