Reputation: 1102
I'm trying my hand at writing a C program using GTK (GTK 3 to be precise) (up to now, my experience has mainly been using ObjC, Visual Studio and so on but Cross Platform FTW!)
I need to have a scrollable table, so I've been playing with some of the example code that I've found on the web. The only table code that I've been able to find so far grows the window, and pushes any other elements down the screen as rows are added. I need the table to be a fixed size and to scroll (leaving the header row visible, of course).
This is what I've got so far:
#include <gtk/gtk.h>
enum {
FILE_NAME,
FILE_OFFSET,
FILE_SIZE,
FILE_DESCRIPTION, /* Not used by the view, maybe used elsewhere */
COLOR, /* Just to show how the model can affect the view */
N_COLUMNS
};
void add_row (GtkWidget *widget, gpointer data) {
gtk_list_store_insert_with_values(data, NULL, -1,
COLOR, "blue",
-1);
}
void destroy (GtkWidget *widget,gpointer data) {
gtk_main_quit ();
}
gint main(gint argc, gchar **argv)
{
GtkListStore* model;
GtkWidget* view;
GtkTreeViewColumn* column;
gtk_init(&argc, &argv);
/* MODEL */
model = gtk_list_store_new(N_COLUMNS,
G_TYPE_STRING, /* FILE_NAME */
G_TYPE_UINT, /* FILE_OFFSET */
G_TYPE_UINT, /* FILE_SIZE */
G_TYPE_STRING, /* FILE_DESCRIPTION */
G_TYPE_STRING /* COLOR */
);
gtk_list_store_insert_with_values(model, NULL, -1,
FILE_NAME, "test name",
FILE_OFFSET, 0,
FILE_SIZE, 10,
-1);
gtk_list_store_insert_with_values(model, NULL, -1,
FILE_NAME, "Dummy",
FILE_OFFSET, 123,
COLOR, "black",
-1);
/* VIEW */
view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model));
g_object_unref(model);
column = gtk_tree_view_column_new_with_attributes("Name",
gtk_cell_renderer_text_new(),
"text", FILE_NAME,
"background", COLOR,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
column = gtk_tree_view_column_new_with_attributes("Offset",
gtk_cell_renderer_spin_new(),
"text", FILE_OFFSET,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
column = gtk_tree_view_column_new_with_attributes("Size",
gtk_cell_renderer_text_new(),
"text", FILE_SIZE,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Test App");
gtk_window_set_default_size (GTK_WINDOW (window), 400, 600);
g_signal_connect (window, "destroy", G_CALLBACK (destroy), NULL);
/* Button */
GtkWidget *button;
button = gtk_button_new_with_label ("Add row");
g_signal_connect (button, "clicked", G_CALLBACK(add_row), model);
/* Layoutbox */
GtkWidget *layout_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
gtk_container_add (GTK_CONTAINER (window), layout_box);
/* Scrollview */
GtkWidget *scrollview = gtk_layout_new(NULL, NULL);
g_object_set(G_OBJECT(scrollview), "app-paintable", TRUE, NULL);
gtk_widget_add_events (scrollview, GDK_ALL_EVENTS_MASK);
gtk_layout_put (GTK_LAYOUT (scrollview), view, 10, 10);
gtk_widget_set_size_request(view, 300, 200);
gtk_container_add (GTK_CONTAINER (layout_box), scrollview); //view
gtk_widget_show_all(window);
GdkWindow *win = gtk_layout_get_bin_window (GTK_LAYOUT(scrollview));
gdk_window_set_events (win, gdk_window_get_events (win) | GDK_STRUCTURE_MASK);
gtk_main ();
return 0;
}
It is a bit of a mess at the moment! My apologies - that's partly inexperience with GTK and mostly multiple iterations in trying to get it to work.
At the moment the table displays very briefly before disappearing (that interesting behaviour only started when I tried to make it into a scroll box).
Note, I only want the table to scroll - not the entire window. In a perfect world, the table would be the width of the window (or layout that contains it) but limited to n pixels high, with a scrollbar if the height exceeds that limit.
I'm a simple guy though, so I also want any solution to be simple - so that I can wrap my brain around it!
Any ideas?
Upvotes: 1
Views: 1578
Reputation: 958
You are using a GtkLayout but the widget to use for scrolling is GtkScrolledWindow.
Here's the adapted code:
#include <gtk/gtk.h>
enum {
FILE_NAME,
FILE_OFFSET,
FILE_SIZE,
FILE_DESCRIPTION, /* Not used by the view, maybe used elsewhere */
COLOR, /* Just to show how the model can affect the view */
N_COLUMNS
};
void add_row (GtkWidget *widget, gpointer data) {
gtk_list_store_insert_with_values(data, NULL, -1,
COLOR, "blue",
-1);
}
void destroy (GtkWidget *widget,gpointer data) {
gtk_main_quit ();
}
gint main(gint argc, gchar **argv)
{
GtkListStore* model;
GtkWidget* view;
GtkTreeViewColumn* column;
gtk_init(&argc, &argv);
/* MODEL */
model = gtk_list_store_new(N_COLUMNS,
G_TYPE_STRING, /* FILE_NAME */
G_TYPE_UINT, /* FILE_OFFSET */
G_TYPE_UINT, /* FILE_SIZE */
G_TYPE_STRING, /* FILE_DESCRIPTION */
G_TYPE_STRING /* COLOR */
);
gtk_list_store_insert_with_values(model, NULL, -1,
FILE_NAME, "test name",
FILE_OFFSET, 0,
FILE_SIZE, 10,
-1);
gtk_list_store_insert_with_values(model, NULL, -1,
FILE_NAME, "Dummy",
FILE_OFFSET, 123,
COLOR, "black",
-1);
/* VIEW */
view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model));
g_object_unref(model);
column = gtk_tree_view_column_new_with_attributes("Name",
gtk_cell_renderer_text_new(),
"text", FILE_NAME,
"background", COLOR,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
column = gtk_tree_view_column_new_with_attributes("Offset",
gtk_cell_renderer_spin_new(),
"text", FILE_OFFSET,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
column = gtk_tree_view_column_new_with_attributes("Size",
gtk_cell_renderer_text_new(),
"text", FILE_SIZE,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Test App");
gtk_window_set_default_size (GTK_WINDOW (window), 400, 600);
g_signal_connect (window, "destroy", G_CALLBACK (destroy), NULL);
/* Button */
GtkWidget *button;
button = gtk_button_new_with_label ("Add row");
g_signal_connect (button, "clicked", G_CALLBACK(add_row), model);
/* Layoutbox */
GtkWidget *layout_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
gtk_container_add (GTK_CONTAINER (window), layout_box);
/* Scrollview */
GtkWidget *scrollview = gtk_scrolled_window_new(NULL, NULL);
gtk_container_add (GTK_CONTAINER (scrollview), view);
/* expand to fill all available space left in the window */
gtk_widget_set_hexpand(scrollview, TRUE);
gtk_widget_set_vexpand(scrollview, TRUE);
gtk_container_add (GTK_CONTAINER (layout_box), scrollview); //view
gtk_container_add (GTK_CONTAINER (layout_box), button);
gtk_widget_show_all(window);
gtk_main ();
return 0;
}
Upvotes: 4