Barf still doesn't work
[rodin/chimara.git] / tests / barf.c
1 /*
2  * Compile me with:
3  * gcc -g -O0 -Wall -pthread -o barf barf.c `pkg-config --cflags --libs gtk+-2.0`
4  */
5
6 #include <gtk/gtk.h>
7
8 static glong pager_handler = 0;
9
10 static gboolean
11 quit()
12 {
13         gtk_main_quit();
14         return TRUE;
15 }
16
17 static void
18 barf(GtkButton *button, GtkTextBuffer *buffer)
19 {
20         GtkTextIter end;
21         gtk_text_buffer_get_end_iter(buffer, &end);
22         
23         gtk_text_buffer_move_mark_by_name(buffer, "pager_position", &end);
24         
25         gchar *loremipsum;
26         g_file_get_contents("loremipsum.txt", &loremipsum, NULL, NULL);
27         gtk_text_buffer_insert(buffer, &end, loremipsum, -1);
28         g_free(loremipsum);
29 }
30
31 static void
32 after_insert(GtkTextBuffer *buffer, GtkTextIter *location, gchar *text, gint len, GtkTextView *textview)
33 {
34         while(gtk_events_pending())
35                 gtk_main_iteration();
36
37         GdkRectangle pagerpos, endpos, visiblerect;
38         GtkTextIter pager, end;
39         gtk_text_buffer_get_end_iter(buffer, &end);
40         gtk_text_view_get_visible_rect(textview, &visiblerect);
41         
42         /* Move the pager to the last visible character in the buffer */
43         gtk_text_view_get_line_at_y(textview, &pager, visiblerect.y, NULL);
44         if(!gtk_text_iter_ends_line(&pager))
45                 gtk_text_iter_forward_to_line_end(&pager);
46         gtk_text_buffer_move_mark_by_name(buffer, "pager_position", &pager);
47
48         gtk_text_view_get_iter_location(textview, &pager, &pagerpos);
49         gtk_text_view_get_iter_location(textview, &end, &endpos);
50         
51         g_printerr("View height = %d\n", visiblerect.height);
52         g_printerr("End - Pager = %d\n", endpos.y - pagerpos.y);
53         
54         /* Wait for a keypress to advance the pager */
55         if(endpos.y > pagerpos.y)
56                 g_signal_handler_unblock(textview, pager_handler);
57 }
58
59 static gboolean
60 pager_wait(GtkTextView *textview, GdkEventKey *event, GtkTextBuffer *buffer)
61 {
62         GdkRectangle pagerpos, endpos, visiblerect;
63         GtkTextIter pager, end;
64         GtkTextMark *pagermark = gtk_text_buffer_get_mark(buffer, "pager_position");
65         gtk_text_view_scroll_to_mark(textview, pagermark, 0.0, TRUE, 0.0, 0.0);
66
67         while(gtk_events_pending())
68                 gtk_main_iteration();
69
70         /* Move the pager to the last visible character in the buffer */
71         gtk_text_view_get_line_at_y(textview, &pager, visiblerect.y, NULL);
72         if(!gtk_text_iter_ends_line(&pager))
73                 gtk_text_iter_forward_to_line_end(&pager);
74         gtk_text_buffer_move_mark(buffer, pagermark, &pager);
75
76         gtk_text_buffer_get_end_iter(buffer, &end);
77         gtk_text_view_get_visible_rect(textview, &visiblerect);
78         gtk_text_view_get_iter_location(textview, &pager, &pagerpos);
79         gtk_text_view_get_iter_location(textview, &end, &endpos);
80         
81         g_printerr("View height = %d\n", visiblerect.height);
82         g_printerr("End - Pager = %d\n", endpos.y - pagerpos.y);
83
84         if(endpos.y == pagerpos.y)
85                 g_signal_handler_block(textview, pager_handler);
86
87         return TRUE; /* block further handlers */
88 }
89
90 int
91 main(int argc, char **argv)
92 {
93         gtk_init(&argc, &argv);
94         
95         GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
96         gtk_widget_set_size_request(window, 400, 400);
97         GtkWidget *button = gtk_button_new_with_label("Barf");
98         GtkWidget *scrolledwindow = gtk_scrolled_window_new(NULL, NULL);
99         GtkWidget *textview = gtk_text_view_new();
100         gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), GTK_WRAP_WORD_CHAR);
101         gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), FALSE);
102         GtkWidget *vbox = gtk_vbox_new(FALSE, 6);
103         
104         gtk_container_add(GTK_CONTAINER(scrolledwindow), textview);
105         gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
106         gtk_box_pack_start(GTK_BOX(vbox), scrolledwindow, TRUE, TRUE, 0);
107         gtk_container_add(GTK_CONTAINER(window), vbox);
108         gtk_widget_show_all(window);
109
110         GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
111         g_signal_connect_after(buffer, "insert-text", G_CALLBACK(after_insert), textview);
112         pager_handler = g_signal_connect(textview, "key-press-event", G_CALLBACK(pager_wait), buffer);
113         g_signal_handler_block(textview, pager_handler);
114         
115         GtkTextIter end;
116         gtk_text_buffer_get_end_iter(buffer, &end);
117         GtkTextMark *pagermark = gtk_text_buffer_create_mark(buffer, "pager_position", &end, TRUE);
118         gtk_text_mark_set_visible(pagermark, TRUE);
119         
120         g_signal_connect(window, "delete-event", G_CALLBACK(quit), NULL);
121         g_signal_connect(button, "clicked", G_CALLBACK(barf), buffer);
122         
123         gtk_main();
124         return 0;
125 }